Core/Creatures: Reworked setting move types in database
Port From (https://github.com/TrinityCore/TrinityCore/commit/f8c03a90661610e289029c78d2055d7b73a5ad98)
This commit is contained in:
@@ -375,4 +375,22 @@ namespace Framework.Constants
|
|||||||
MembersAssistMember = (MembersAssistLeader | LeaderAssistsMember), // every member will assist if any member is attacked
|
MembersAssistMember = (MembersAssistLeader | LeaderAssistsMember), // every member will assist if any member is attacked
|
||||||
IdleInFormation = 0x200, // The member will follow the leader when pathing idly
|
IdleInFormation = 0x200, // The member will follow the leader when pathing idly
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum CreatureGroundMovementType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Run,
|
||||||
|
Hover,
|
||||||
|
|
||||||
|
Max
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CreatureFlightMovementType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
DisableGravity,
|
||||||
|
CanFly,
|
||||||
|
|
||||||
|
Max
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1173,7 +1173,7 @@ namespace Framework.Constants
|
|||||||
BanAccountYoubannedmessageWorld = 11006,
|
BanAccountYoubannedmessageWorld = 11006,
|
||||||
BanAccountYoupermbannedmessageWorld = 11007,
|
BanAccountYoupermbannedmessageWorld = 11007,
|
||||||
|
|
||||||
NpcinfoInhabitType = 11008,
|
NpcinfoMovementData = 11008,
|
||||||
NpcinfoFlagsExtra = 11009,
|
NpcinfoFlagsExtra = 11009,
|
||||||
InstanceLoginGamemasterException = 11010,
|
InstanceLoginGamemasterException = 11010,
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace Framework.Database
|
|||||||
PrepareStatement(WorldStatements.SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?");
|
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.DEL_CREATURE, "DELETE FROM creature WHERE guid = ?");
|
||||||
PrepareStatement(WorldStatements.SEL_COMMANDS, "SELECT name, permission, help FROM command");
|
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, CreatureDifficultyID, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ? OR 1 = ?");
|
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, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, CreatureDifficultyID, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ? OR 1 = ?");
|
||||||
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_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_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_");
|
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_");
|
||||||
|
|||||||
@@ -121,5 +121,10 @@ namespace Framework.Database
|
|||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsNull(int column)
|
||||||
|
{
|
||||||
|
return _currentRow[column] == DBNull.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ namespace Game.Chat
|
|||||||
handler.SendSysMessage(CypherStrings.NpcinfoLevel, target.GetLevel());
|
handler.SendSysMessage(CypherStrings.NpcinfoLevel, target.GetLevel());
|
||||||
handler.SendSysMessage(CypherStrings.NpcinfoEquipment, target.GetCurrentEquipmentId(), target.GetOriginalEquipmentId());
|
handler.SendSysMessage(CypherStrings.NpcinfoEquipment, target.GetCurrentEquipmentId(), target.GetOriginalEquipmentId());
|
||||||
handler.SendSysMessage(CypherStrings.NpcinfoHealth, target.GetCreateHealth(), target.GetMaxHealth(), target.GetHealth());
|
handler.SendSysMessage(CypherStrings.NpcinfoHealth, target.GetCreateHealth(), target.GetMaxHealth(), target.GetHealth());
|
||||||
handler.SendSysMessage(CypherStrings.NpcinfoInhabitType, cInfo.InhabitType);
|
handler.SendSysMessage(CypherStrings.NpcinfoMovementData, target.GetMovementTemplate().ToString());
|
||||||
|
|
||||||
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags, (uint)target.m_unitData.Flags);
|
handler.SendSysMessage(CypherStrings.NpcinfoUnitFieldFlags, (uint)target.m_unitData.Flags);
|
||||||
foreach (UnitFlags value in Enum.GetValues(typeof(UnitFlags)))
|
foreach (UnitFlags value in Enum.GetValues(typeof(UnitFlags)))
|
||||||
|
|||||||
@@ -169,6 +169,15 @@ namespace Game.Chat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command("creature_movement_override", RBACPermissions.CommandReloadCreatureMovementOverride, true)]
|
||||||
|
static bool HandleReloadCreatureMovementOverrideCommand(StringArguments args, CommandHandler handler)
|
||||||
|
{
|
||||||
|
Log.outInfo(LogFilter.Server, "Re-Loading Creature movement overrides...");
|
||||||
|
Global.ObjectMgr.LoadCreatureMovementOverrides();
|
||||||
|
handler.SendGlobalGMSysMessage("DB table `creature_movement_override` reloaded.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
[Command("creature_onkill_reputation", RBACPermissions.CommandReloadCreatureOnkillReputation, true)]
|
[Command("creature_onkill_reputation", RBACPermissions.CommandReloadCreatureOnkillReputation, true)]
|
||||||
static bool HandleReloadOnKillReputationCommand(StringArguments args, CommandHandler handler)
|
static bool HandleReloadOnKillReputationCommand(StringArguments args, CommandHandler handler)
|
||||||
{
|
{
|
||||||
@@ -985,6 +994,7 @@ namespace Game.Chat
|
|||||||
HandleReloadCypherStringCommand(args, handler);
|
HandleReloadCypherStringCommand(args, handler);
|
||||||
HandleReloadGameTeleCommand(args, handler);
|
HandleReloadGameTeleCommand(args, handler);
|
||||||
|
|
||||||
|
HandleReloadCreatureMovementOverrideCommand(args, handler);
|
||||||
HandleReloadCreatureSummonGroupsCommand(args, handler);
|
HandleReloadCreatureSummonGroupsCommand(args, handler);
|
||||||
|
|
||||||
HandleReloadVehicleAccessoryCommand(args, handler);
|
HandleReloadVehicleAccessoryCommand(args, handler);
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ namespace Game.Entities
|
|||||||
ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, true);
|
ApplySpellImmune(0, SpellImmunity.Effect, SpellEffectName.AttackMe, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cInfo.InhabitType.HasAnyFlag(InhabitType.Root))
|
if (GetMovementTemplate().IsRooted())
|
||||||
SetControlled(true, UnitState.Root);
|
SetControlled(true, UnitState.Root);
|
||||||
|
|
||||||
UpdateMovementFlags();
|
UpdateMovementFlags();
|
||||||
@@ -2311,7 +2311,7 @@ namespace Game.Entities
|
|||||||
dist += GetCombatReach() + victim.GetCombatReach();
|
dist += GetCombatReach() + victim.GetCombatReach();
|
||||||
|
|
||||||
// to prevent creatures in air ignore attacks because distance is already too high...
|
// to prevent creatures in air ignore attacks because distance is already too high...
|
||||||
if (GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air))
|
if (GetMovementTemplate().IsFlightAllowed())
|
||||||
return victim.IsInDist2d(m_homePosition, dist);
|
return victim.IsInDist2d(m_homePosition, dist);
|
||||||
else
|
else
|
||||||
return victim.IsInDist(m_homePosition, dist);
|
return victim.IsInDist(m_homePosition, dist);
|
||||||
@@ -2356,7 +2356,7 @@ namespace Game.Entities
|
|||||||
//! Check using InhabitType as movement flags are assigned dynamically
|
//! Check using InhabitType as movement flags are assigned dynamically
|
||||||
//! basing on whether the creature is in air or not
|
//! basing on whether the creature is in air or not
|
||||||
//! Set MovementFlag_Hover. Otherwise do nothing.
|
//! Set MovementFlag_Hover. Otherwise do nothing.
|
||||||
if (Convert.ToBoolean(m_unitData.AnimTier & (byte)UnitBytes1Flags.Hover) && !Convert.ToBoolean(GetCreatureTemplate().InhabitType & InhabitType.Air))
|
if (CanHover())
|
||||||
AddUnitMovementFlag(MovementFlag.Hover);
|
AddUnitMovementFlag(MovementFlag.Hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2463,6 +2463,15 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool IsSpawnedOnTransport() { return m_creatureData != null && m_creatureData.spawnPoint.GetMapId() != GetMapId(); }
|
bool IsSpawnedOnTransport() { return m_creatureData != null && m_creatureData.spawnPoint.GetMapId() != GetMapId(); }
|
||||||
|
|
||||||
|
public CreatureMovementData GetMovementTemplate()
|
||||||
|
{
|
||||||
|
CreatureMovementData movementOverride = Global.ObjectMgr.GetCreatureMovementOverride(m_spawnId);
|
||||||
|
if (movementOverride != null)
|
||||||
|
return movementOverride;
|
||||||
|
|
||||||
|
return GetCreatureTemplate().Movement;
|
||||||
|
}
|
||||||
|
|
||||||
public void AllLootRemovedFromCorpse()
|
public void AllLootRemovedFromCorpse()
|
||||||
{
|
{
|
||||||
if (loot.loot_type != LootType.Skinning && !IsPet() && GetCreatureTemplate().SkinLootId != 0 && HasLootRecipient())
|
if (loot.loot_type != LootType.Skinning && !IsPet() && GetCreatureTemplate().SkinLootId != 0 && HasLootRecipient())
|
||||||
@@ -2822,25 +2831,31 @@ namespace Game.Entities
|
|||||||
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
||||||
float ground = GetFloorZ();
|
float ground = GetFloorZ();
|
||||||
|
|
||||||
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZ(), ground + MapConst.GroundHeightTolerance) || MathFunctions.fuzzyLt(GetPositionZ(), ground - MapConst.GroundHeightTolerance)); // Can be underground too, prevent the falling
|
bool canHover = CanHover();
|
||||||
|
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZ(), ground + (canHover ? m_unitData.HoverHeight : 0.0f) + MapConst.GroundHeightTolerance) || MathFunctions.fuzzyLt(GetPositionZ(), ground - MapConst.GroundHeightTolerance)); // Can be underground too, prevent the falling
|
||||||
|
|
||||||
if (GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air) && isInAir && !IsFalling())
|
if (GetMovementTemplate().IsFlightAllowed() && isInAir && !IsFalling())
|
||||||
{
|
{
|
||||||
if (GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Ground))
|
if (GetMovementTemplate().Flight == CreatureFlightMovementType.CanFly)
|
||||||
SetCanFly(true);
|
SetCanFly(true);
|
||||||
else
|
else
|
||||||
SetDisableGravity(true);
|
SetDisableGravity(true);
|
||||||
|
|
||||||
|
if (!HasAuraType(AuraType.Hover))
|
||||||
|
SetHover(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetCanFly(false);
|
SetCanFly(false);
|
||||||
SetDisableGravity(false);
|
SetDisableGravity(false);
|
||||||
|
if (CanHover() || HasAuraType(AuraType.Hover))
|
||||||
|
SetHover(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isInAir)
|
if (!isInAir)
|
||||||
SetFall(false);
|
SetFall(false);
|
||||||
|
|
||||||
SetSwim(GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Water) && IsInWater());
|
SetSwim(GetMovementTemplate().IsSwimAllowed() && IsInWater());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetObjectScale(float scale)
|
public override void SetObjectScale(float scale)
|
||||||
@@ -3034,18 +3049,12 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
return GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Guard);
|
return GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.Guard);
|
||||||
}
|
}
|
||||||
public bool CanWalk()
|
|
||||||
{
|
public bool CanWalk() { return GetMovementTemplate().IsGroundAllowed(); }
|
||||||
return GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Ground);
|
public override bool CanSwim() { return GetMovementTemplate().IsSwimAllowed() || IsPet();}
|
||||||
}
|
public override bool CanFly() { return GetMovementTemplate().IsFlightAllowed(); }
|
||||||
public override bool CanSwim()
|
bool CanHover() { return GetMovementTemplate().Ground == CreatureGroundMovementType.Hover; }
|
||||||
{
|
|
||||||
return GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Water);
|
|
||||||
}
|
|
||||||
public override bool CanFly()
|
|
||||||
{
|
|
||||||
return GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air);
|
|
||||||
}
|
|
||||||
public bool IsDungeonBoss() { return (GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.DungeonBoss)); }
|
public bool IsDungeonBoss() { return (GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.DungeonBoss)); }
|
||||||
public override bool IsAffectedByDiminishingReturns() { return base.IsAffectedByDiminishingReturns() || GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish); }
|
public override bool IsAffectedByDiminishingReturns() { return base.IsAffectedByDiminishingReturns() || GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.AllDiminish); }
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ namespace Game.Entities
|
|||||||
public uint MaxGold;
|
public uint MaxGold;
|
||||||
public string AIName;
|
public string AIName;
|
||||||
public uint MovementType;
|
public uint MovementType;
|
||||||
public InhabitType InhabitType;
|
public CreatureMovementData Movement;
|
||||||
public float HoverHeight;
|
public float HoverHeight;
|
||||||
public float ModHealth;
|
public float ModHealth;
|
||||||
public float ModHealthExtra;
|
public float ModHealthExtra;
|
||||||
@@ -347,6 +347,34 @@ namespace Game.Entities
|
|||||||
public CreatureData() : base(SpawnObjectType.Creature) { }
|
public CreatureData() : base(SpawnObjectType.Creature) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CreatureMovementData
|
||||||
|
{
|
||||||
|
public CreatureGroundMovementType Ground;
|
||||||
|
public CreatureFlightMovementType Flight;
|
||||||
|
public bool Swim;
|
||||||
|
public bool Rooted;
|
||||||
|
|
||||||
|
public CreatureMovementData()
|
||||||
|
{
|
||||||
|
Ground = CreatureGroundMovementType.Run;
|
||||||
|
Flight = CreatureFlightMovementType.None;
|
||||||
|
Swim = true;
|
||||||
|
Rooted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool IsGroundAllowed() { return Ground != CreatureGroundMovementType.None; }
|
||||||
|
bool IsSwimAllowed() { return Swim; }
|
||||||
|
bool IsFlightAllowed() { return Flight != CreatureFlightMovementType.None; }
|
||||||
|
bool IsRooted() { return Rooted; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Ground: {Ground}, Swim: {Swim}, Flight: {Flight} {(Rooted ? ", Rooted" : "")}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class CreatureModelInfo
|
public class CreatureModelInfo
|
||||||
{
|
{
|
||||||
public float BoundingRadius;
|
public float BoundingRadius;
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ namespace Game
|
|||||||
{
|
{
|
||||||
for (var i = 0; i < SharedConst.MaxCreatureDifficulties; ++i)
|
for (var i = 0; i < SharedConst.MaxCreatureDifficulties; ++i)
|
||||||
{
|
{
|
||||||
_difficultyEntries[i] = new List<uint>();
|
difficultyEntries[i] = new List<uint>();
|
||||||
_hasDifficultyEntries[i] = new List<uint>();
|
hasDifficultyEntries[i] = new List<uint>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1744,10 +1744,10 @@ namespace Game
|
|||||||
LoadCreatureTemplateModels();
|
LoadCreatureTemplateModels();
|
||||||
|
|
||||||
// Checking needs to be done after loading because of the difficulty self referencing
|
// Checking needs to be done after loading because of the difficulty self referencing
|
||||||
foreach (var template in _creatureTemplateStorage.Values)
|
foreach (var template in creatureTemplateStorage.Values)
|
||||||
CheckCreatureTemplate(template);
|
CheckCreatureTemplate(template);
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creature definitions in {1} ms", _creatureTemplateStorage.Count, Time.GetMSTimeDiffToNow(time));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creature definitions in {1} ms", creatureTemplateStorage.Count, Time.GetMSTimeDiffToNow(time));
|
||||||
}
|
}
|
||||||
public void LoadCreatureTemplate(SQLFields fields)
|
public void LoadCreatureTemplate(SQLFields fields)
|
||||||
{
|
{
|
||||||
@@ -1809,27 +1809,36 @@ namespace Game
|
|||||||
creature.MaxGold = fields.Read<uint>(57);
|
creature.MaxGold = fields.Read<uint>(57);
|
||||||
creature.AIName = fields.Read<string>(58);
|
creature.AIName = fields.Read<string>(58);
|
||||||
creature.MovementType = fields.Read<uint>(59);
|
creature.MovementType = fields.Read<uint>(59);
|
||||||
creature.InhabitType = (InhabitType)fields.Read<uint>(60);
|
|
||||||
creature.HoverHeight = fields.Read<float>(61);
|
|
||||||
creature.ModHealth = fields.Read<float>(62);
|
|
||||||
creature.ModHealthExtra = fields.Read<float>(63);
|
|
||||||
creature.ModMana = fields.Read<float>(64);
|
|
||||||
creature.ModManaExtra = fields.Read<float>(65);
|
|
||||||
creature.ModArmor = fields.Read<float>(66);
|
|
||||||
creature.ModDamage = fields.Read<float>(67);
|
|
||||||
creature.ModExperience = fields.Read<float>(68);
|
|
||||||
creature.RacialLeader = fields.Read<bool>(69);
|
|
||||||
creature.MovementId = fields.Read<uint>(70);
|
|
||||||
creature.CreatureDifficultyID = fields.Read<int>(71);
|
|
||||||
creature.WidgetSetID = fields.Read<int>(72);
|
|
||||||
creature.WidgetSetUnitConditionID = fields.Read<int>(73);
|
|
||||||
creature.RegenHealth = fields.Read<bool>(74);
|
|
||||||
creature.MechanicImmuneMask = fields.Read<uint>(75);
|
|
||||||
creature.SpellSchoolImmuneMask = fields.Read<uint>(76);
|
|
||||||
creature.FlagsExtra = (CreatureFlagsExtra)fields.Read<uint>(77);
|
|
||||||
creature.ScriptID = GetScriptId(fields.Read<string>(78));
|
|
||||||
|
|
||||||
_creatureTemplateStorage[entry] = creature;
|
if (!fields.IsNull(60))
|
||||||
|
creature.Movement.Ground = (CreatureGroundMovementType)fields.Read<byte>(60);
|
||||||
|
|
||||||
|
creature.Movement.Swim = fields.Read<bool>(61);
|
||||||
|
if (!fields.IsNull(62))
|
||||||
|
creature.Movement.Flight = (CreatureFlightMovementType)fields.Read<byte>(62);
|
||||||
|
|
||||||
|
|
||||||
|
creature.Movement.Rooted = fields.Read<uint>(63);
|
||||||
|
creature.HoverHeight = fields.Read<float>(64);
|
||||||
|
creature.ModHealth = fields.Read<float>(65);
|
||||||
|
creature.ModHealthExtra = fields.Read<float>(66);
|
||||||
|
creature.ModMana = fields.Read<float>(67);
|
||||||
|
creature.ModManaExtra = fields.Read<float>(68);
|
||||||
|
creature.ModArmor = fields.Read<float>(69);
|
||||||
|
creature.ModDamage = fields.Read<float>(70);
|
||||||
|
creature.ModExperience = fields.Read<float>(71);
|
||||||
|
creature.RacialLeader = fields.Read<bool>(72);
|
||||||
|
creature.MovementId = fields.Read<uint>(73);
|
||||||
|
creature.CreatureDifficultyID = fields.Read<int>(74);
|
||||||
|
creature.WidgetSetID = fields.Read<int>(75);
|
||||||
|
creature.WidgetSetUnitConditionID = fields.Read<int>(76);
|
||||||
|
creature.RegenHealth = fields.Read<bool>(77);
|
||||||
|
creature.MechanicImmuneMask = fields.Read<uint>(78);
|
||||||
|
creature.SpellSchoolImmuneMask = fields.Read<uint>(79);
|
||||||
|
creature.FlagsExtra = (CreatureFlagsExtra)fields.Read<uint>(80);
|
||||||
|
creature.ScriptID = GetScriptId(fields.Read<string>(81));
|
||||||
|
|
||||||
|
creatureTemplateStorage[entry] = creature;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadCreatureTemplateModels()
|
void LoadCreatureTemplateModels()
|
||||||
@@ -2120,7 +2129,7 @@ namespace Game
|
|||||||
uint item = result.Read<uint>(1);
|
uint item = result.Read<uint>(1);
|
||||||
uint idx = result.Read<uint>(2);
|
uint idx = result.Read<uint>(2);
|
||||||
|
|
||||||
if (!_creatureTemplateStorage.ContainsKey(entry))
|
if (!creatureTemplateStorage.ContainsKey(entry))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature_questitem` has data for nonexistent creature (entry: {0}, idx: {1}), skipped", entry, idx);
|
Log.outError(LogFilter.Sql, "Table `creature_questitem` has data for nonexistent creature (entry: {0}, idx: {1}), skipped", entry, idx);
|
||||||
continue;
|
continue;
|
||||||
@@ -2132,7 +2141,7 @@ namespace Game
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_creatureQuestItemStorage.Add(entry, item);
|
creatureQuestItemStorage.Add(entry, item);
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@@ -2224,6 +2233,42 @@ namespace Game
|
|||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} equipment templates in {1} ms", count, Time.GetMSTimeDiffToNow(time));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} equipment templates in {1} ms", count, Time.GetMSTimeDiffToNow(time));
|
||||||
}
|
}
|
||||||
|
public void LoadCreatureMovementOverrides()
|
||||||
|
{
|
||||||
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
|
creatureMovementOverrides.Clear();
|
||||||
|
|
||||||
|
SQLResult result = DB.World.Query("SELECT SpawnId, Ground, Swim, Flight, Rooted from creature_movement_override");
|
||||||
|
if (result.IsEmpty())
|
||||||
|
{
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loaded 0 creature movement overrides. DB table `creature_movement_override` is empty!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ulong spawnId = result.Read<ulong>(0);
|
||||||
|
if (GetCreatureData(spawnId) == null)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"Creature (GUID: {spawnId}) does not exist but has a record in `creature_movement_override`");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreatureMovementData movement = new();
|
||||||
|
movement.Ground = (CreatureGroundMovementType)result.Read<byte>(1);
|
||||||
|
movement.Swim = result.Read<bool>(2);
|
||||||
|
movement.Flight = (CreatureFlightMovementType)result.Read<byte>(3);
|
||||||
|
movement.Rooted = result.Read<bool>(4);
|
||||||
|
|
||||||
|
CheckCreatureMovement("creature_movement_override", spawnId, movement);
|
||||||
|
|
||||||
|
creatureMovementOverrides[spawnId] = movement;
|
||||||
|
}
|
||||||
|
while (result.NextRow());
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {creatureMovementOverrides.Count} movement overrides in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
|
}
|
||||||
public void LoadCreatureClassLevelStats()
|
public void LoadCreatureClassLevelStats()
|
||||||
{
|
{
|
||||||
var time = Time.GetMSTime();
|
var time = Time.GetMSTime();
|
||||||
@@ -2258,7 +2303,7 @@ namespace Game
|
|||||||
++count;
|
++count;
|
||||||
} while (result.NextRow());
|
} while (result.NextRow());
|
||||||
|
|
||||||
foreach (var creatureTemplate in _creatureTemplateStorage.Values)
|
foreach (var creatureTemplate in creatureTemplateStorage.Values)
|
||||||
{
|
{
|
||||||
for (short lvl = creatureTemplate.Minlevel; lvl <= creatureTemplate.Maxlevel; ++lvl)
|
for (short lvl = creatureTemplate.Minlevel; lvl <= creatureTemplate.Maxlevel; ++lvl)
|
||||||
{
|
{
|
||||||
@@ -2352,7 +2397,7 @@ namespace Game
|
|||||||
uint entry = result.Read<uint>(0);
|
uint entry = result.Read<uint>(0);
|
||||||
Difficulty difficulty = (Difficulty)result.Read<byte>(1);
|
Difficulty difficulty = (Difficulty)result.Read<byte>(1);
|
||||||
|
|
||||||
var template = _creatureTemplateStorage.LookupByKey(entry);
|
var template = creatureTemplateStorage.LookupByKey(entry);
|
||||||
if (template == null)
|
if (template == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Creature template (Entry: {entry}) does not exist but has a record in `creature_template_scaling`");
|
Log.outError(LogFilter.Sql, $"Creature template (Entry: {entry}) does not exist but has a record in `creature_template_scaling`");
|
||||||
@@ -2395,20 +2440,20 @@ namespace Game
|
|||||||
for (uint diff2 = 0; diff2 < SharedConst.MaxCreatureDifficulties && ok2; ++diff2)
|
for (uint diff2 = 0; diff2 < SharedConst.MaxCreatureDifficulties && ok2; ++diff2)
|
||||||
{
|
{
|
||||||
ok2 = false;
|
ok2 = false;
|
||||||
if (_difficultyEntries[diff2].Contains(cInfo.Entry))
|
if (difficultyEntries[diff2].Contains(cInfo.Entry))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) is listed as `difficulty_entry_{1}` of another creature, but itself lists {2} in `difficulty_entry_{3}`.",
|
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) is listed as `difficulty_entry_{1}` of another creature, but itself lists {2} in `difficulty_entry_{3}`.",
|
||||||
cInfo.Entry, diff2 + 1, cInfo.DifficultyEntry[diff], diff + 1);
|
cInfo.Entry, diff2 + 1, cInfo.DifficultyEntry[diff], diff + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_difficultyEntries[diff2].Contains(cInfo.DifficultyEntry[diff]))
|
if (difficultyEntries[diff2].Contains(cInfo.DifficultyEntry[diff]))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) already listed as `difficulty_entry_{1}` for another entry.", cInfo.DifficultyEntry[diff], diff2 + 1);
|
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) already listed as `difficulty_entry_{1}` for another entry.", cInfo.DifficultyEntry[diff], diff2 + 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_hasDifficultyEntries[diff2].Contains(cInfo.DifficultyEntry[diff]))
|
if (hasDifficultyEntries[diff2].Contains(cInfo.DifficultyEntry[diff]))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has `difficulty_entry_{1}`={2} but creature entry {3} has itself a value in `difficulty_entry_{4}`.",
|
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has `difficulty_entry_{1}`={2} but creature entry {3} has itself a value in `difficulty_entry_{4}`.",
|
||||||
cInfo.Entry, diff + 1, cInfo.DifficultyEntry[diff], cInfo.DifficultyEntry[diff], diff2 + 1);
|
cInfo.Entry, diff + 1, cInfo.DifficultyEntry[diff], cInfo.DifficultyEntry[diff], diff2 + 1);
|
||||||
@@ -2532,8 +2577,8 @@ namespace Game
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasDifficultyEntries[diff].Add(cInfo.Entry);
|
hasDifficultyEntries[diff].Add(cInfo.Entry);
|
||||||
_difficultyEntries[diff].Add(cInfo.DifficultyEntry[diff]);
|
difficultyEntries[diff].Add(cInfo.DifficultyEntry[diff]);
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2606,11 +2651,7 @@ namespace Game
|
|||||||
cInfo.Family = CreatureFamily.None;
|
cInfo.Family = CreatureFamily.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cInfo.InhabitType <= 0 || cInfo.InhabitType > InhabitType.Anywhere)
|
CheckCreatureMovement("creature_template_movement", cInfo.Entry, cInfo.Movement);
|
||||||
{
|
|
||||||
Log.outError(LogFilter.Sql, "Creature (Entry: {0}) has wrong value ({1}) in `InhabitType`, creature will not correctly walk/swim/fly.", cInfo.Entry, cInfo.InhabitType);
|
|
||||||
cInfo.InhabitType = InhabitType.Anywhere;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cInfo.HoverHeight < 0.0f)
|
if (cInfo.HoverHeight < 0.0f)
|
||||||
{
|
{
|
||||||
@@ -2676,6 +2717,20 @@ namespace Game
|
|||||||
|
|
||||||
cInfo.ModDamage *= Creature._GetDamageMod(cInfo.Rank);
|
cInfo.ModDamage *= Creature._GetDamageMod(cInfo.Rank);
|
||||||
}
|
}
|
||||||
|
void CheckCreatureMovement(string table, ulong id, CreatureMovementData creatureMovement)
|
||||||
|
{
|
||||||
|
if (creatureMovement.Ground >= CreatureGroundMovementType.Max)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"`{table}`.`Ground` wrong value ({creatureMovement.Ground}) for Id {id}, setting to Run.");
|
||||||
|
creatureMovement.Ground = CreatureGroundMovementType.Run;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creatureMovement.Flight >= CreatureFlightMovementType.Max)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"`{table}`.`Flight` wrong value ({creatureMovement.Flight}) for Id {id}, setting to None.");
|
||||||
|
creatureMovement.Flight = CreatureFlightMovementType.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
public void LoadLinkedRespawn()
|
public void LoadLinkedRespawn()
|
||||||
{
|
{
|
||||||
uint oldMSTime = Time.GetMSTime();
|
uint oldMSTime = Time.GetMSTime();
|
||||||
@@ -2865,7 +2920,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
uint oldMSTime = Time.GetMSTime();
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
_npcTextStorage.Clear();
|
npcTextStorage.Clear();
|
||||||
|
|
||||||
SQLResult result = DB.World.Query("SELECT ID, Probability0, Probability1, Probability2, Probability3, Probability4, Probability5, Probability6, Probability7, " +
|
SQLResult result = DB.World.Query("SELECT ID, Probability0, Probability1, Probability2, Probability3, Probability4, Probability5, Probability6, Probability7, " +
|
||||||
"BroadcastTextID0, BroadcastTextID1, BroadcastTextID2, BroadcastTextID3, BroadcastTextID4, BroadcastTextID5, BroadcastTextID6, BroadcastTextID7 FROM npc_text");
|
"BroadcastTextID0, BroadcastTextID1, BroadcastTextID2, BroadcastTextID3, BroadcastTextID4, BroadcastTextID5, BroadcastTextID6, BroadcastTextID7 FROM npc_text");
|
||||||
@@ -2912,10 +2967,10 @@ namespace Game
|
|||||||
npcText.Data[i].Probability = 0;
|
npcText.Data[i].Probability = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_npcTextStorage[textID] = npcText;
|
npcTextStorage[textID] = npcText;
|
||||||
} while (result.NextRow());
|
} while (result.NextRow());
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} npc texts in {1} ms", _npcTextStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} npc texts in {1} ms", npcTextStorage.Count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadTrainers()
|
public void LoadTrainers()
|
||||||
@@ -2923,7 +2978,7 @@ namespace Game
|
|||||||
uint oldMSTime = Time.GetMSTime();
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
// For reload case
|
// For reload case
|
||||||
_trainers.Clear();
|
trainers.Clear();
|
||||||
|
|
||||||
MultiMap<uint, TrainerSpell> spellsByTrainer = new();
|
MultiMap<uint, TrainerSpell> spellsByTrainer = new();
|
||||||
SQLResult trainerSpellsResult = DB.World.Query("SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell");
|
SQLResult trainerSpellsResult = DB.World.Query("SELECT TrainerId, SpellId, MoneyCost, ReqSkillLine, ReqSkillRank, ReqAbility1, ReqAbility2, ReqAbility3, ReqLevel FROM trainer_spell");
|
||||||
@@ -2990,7 +3045,7 @@ namespace Game
|
|||||||
spellsByTrainer.Remove(trainerId);
|
spellsByTrainer.Remove(trainerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_trainers.Add(trainerId, new Trainer(trainerId, trainerType, greeting, spells));
|
trainers.Add(trainerId, new Trainer(trainerId, trainerType, greeting, spells));
|
||||||
|
|
||||||
} while (trainersResult.NextRow());
|
} while (trainersResult.NextRow());
|
||||||
}
|
}
|
||||||
@@ -3013,7 +3068,7 @@ namespace Game
|
|||||||
if (!SharedConst.IsValidLocale(locale) || locale == Locale.enUS)
|
if (!SharedConst.IsValidLocale(locale) || locale == Locale.enUS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Trainer trainer = _trainers.LookupByKey(trainerId);
|
Trainer trainer = trainers.LookupByKey(trainerId);
|
||||||
if (trainer != null)
|
if (trainer != null)
|
||||||
trainer.AddGreetingLocale(locale, trainerLocalesResult.Read<String>(2));
|
trainer.AddGreetingLocale(locale, trainerLocalesResult.Read<String>(2));
|
||||||
else
|
else
|
||||||
@@ -3022,7 +3077,7 @@ namespace Game
|
|||||||
} while (trainerLocalesResult.NextRow());
|
} while (trainerLocalesResult.NextRow());
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {_trainers.Count} Trainers in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {trainers.Count} Trainers in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
}
|
}
|
||||||
public void LoadCreatureTrainers()
|
public void LoadCreatureTrainers()
|
||||||
{
|
{
|
||||||
@@ -3274,7 +3329,7 @@ namespace Game
|
|||||||
bool ok = true;
|
bool ok = true;
|
||||||
for (uint diff = 0; diff < SharedConst.MaxCreatureDifficulties && ok; ++diff)
|
for (uint diff = 0; diff < SharedConst.MaxCreatureDifficulties && ok; ++diff)
|
||||||
{
|
{
|
||||||
if (_difficultyEntries[diff].Contains(data.Id))
|
if (difficultyEntries[diff].Contains(data.Id))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0}) that listed as difficulty {1} template (entry: {2}) in `creaturetemplate`, skipped.", guid, diff + 1, data.Id);
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0}) that listed as difficulty {1} template (entry: {2}) in `creaturetemplate`, skipped.", guid, diff + 1, data.Id);
|
||||||
ok = false;
|
ok = false;
|
||||||
@@ -3471,7 +3526,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
public List<uint> GetCreatureQuestItemList(uint id)
|
public List<uint> GetCreatureQuestItemList(uint id)
|
||||||
{
|
{
|
||||||
return _creatureQuestItemStorage.LookupByKey(id);
|
return creatureQuestItemStorage.LookupByKey(id);
|
||||||
}
|
}
|
||||||
public CreatureAddon GetCreatureAddon(ulong lowguid)
|
public CreatureAddon GetCreatureAddon(ulong lowguid)
|
||||||
{
|
{
|
||||||
@@ -3479,7 +3534,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
public CreatureTemplate GetCreatureTemplate(uint entry)
|
public CreatureTemplate GetCreatureTemplate(uint entry)
|
||||||
{
|
{
|
||||||
return _creatureTemplateStorage.LookupByKey(entry);
|
return creatureTemplateStorage.LookupByKey(entry);
|
||||||
}
|
}
|
||||||
public CreatureAddon GetCreatureTemplateAddon(uint entry)
|
public CreatureAddon GetCreatureTemplateAddon(uint entry)
|
||||||
{
|
{
|
||||||
@@ -3495,7 +3550,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
public Dictionary<uint, CreatureTemplate> GetCreatureTemplates()
|
public Dictionary<uint, CreatureTemplate> GetCreatureTemplates()
|
||||||
{
|
{
|
||||||
return _creatureTemplateStorage;
|
return creatureTemplateStorage;
|
||||||
}
|
}
|
||||||
public Dictionary<ulong, CreatureData> GetAllCreatureData() { return creatureDataStorage; }
|
public Dictionary<ulong, CreatureData> GetAllCreatureData() { return creatureDataStorage; }
|
||||||
public CreatureData GetCreatureData(ulong guid)
|
public CreatureData GetCreatureData(ulong guid)
|
||||||
@@ -3622,7 +3677,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
public NpcText GetNpcText(uint textId)
|
public NpcText GetNpcText(uint textId)
|
||||||
{
|
{
|
||||||
return _npcTextStorage.LookupByKey(textId);
|
return npcTextStorage.LookupByKey(textId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//GameObjects
|
//GameObjects
|
||||||
@@ -4760,7 +4815,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
public Trainer GetTrainer(uint trainerId)
|
public Trainer GetTrainer(uint trainerId)
|
||||||
{
|
{
|
||||||
return _trainers.LookupByKey(trainerId);
|
return trainers.LookupByKey(trainerId);
|
||||||
}
|
}
|
||||||
public void AddVendorItem(uint entry, VendorItem vItem, bool persist = true)
|
public void AddVendorItem(uint entry, VendorItem vItem, bool persist = true)
|
||||||
{
|
{
|
||||||
@@ -4909,6 +4964,10 @@ namespace Game
|
|||||||
{
|
{
|
||||||
return cacheVendorItemStorage.LookupByKey(entry);
|
return cacheVendorItemStorage.LookupByKey(entry);
|
||||||
}
|
}
|
||||||
|
public CreatureMovementData GetCreatureMovementOverride(ulong spawnId)
|
||||||
|
{
|
||||||
|
return creatureMovementOverrides.lookupbykey(spawnId);
|
||||||
|
}
|
||||||
public EquipmentInfo GetEquipmentInfo(uint entry, int id)
|
public EquipmentInfo GetEquipmentInfo(uint entry, int id)
|
||||||
{
|
{
|
||||||
var equip = equipmentInfoStorage.LookupByKey(entry);
|
var equip = equipmentInfoStorage.LookupByKey(entry);
|
||||||
@@ -9664,7 +9723,7 @@ namespace Game
|
|||||||
|
|
||||||
// Initialize Query data for creatures
|
// Initialize Query data for creatures
|
||||||
if (mask.HasAnyFlag(QueryDataGroup.Creatures))
|
if (mask.HasAnyFlag(QueryDataGroup.Creatures))
|
||||||
foreach (var creaturePair in _creatureTemplateStorage)
|
foreach (var creaturePair in creatureTemplateStorage)
|
||||||
creaturePair.Value.InitializeQueryData();
|
creaturePair.Value.InitializeQueryData();
|
||||||
|
|
||||||
// Initialize Query Data for gameobjects
|
// Initialize Query Data for gameobjects
|
||||||
@@ -10282,21 +10341,22 @@ namespace Game
|
|||||||
Dictionary<uint, PointOfInterest> pointsOfInterestStorage = new();
|
Dictionary<uint, PointOfInterest> pointsOfInterestStorage = new();
|
||||||
|
|
||||||
//Creature
|
//Creature
|
||||||
Dictionary<uint, CreatureTemplate> _creatureTemplateStorage = new();
|
Dictionary<uint, CreatureTemplate> creatureTemplateStorage = new();
|
||||||
Dictionary<uint, CreatureModelInfo> creatureModelStorage = new();
|
Dictionary<uint, CreatureModelInfo> creatureModelStorage = new();
|
||||||
Dictionary<ulong, CreatureData> creatureDataStorage = new();
|
Dictionary<ulong, CreatureData> creatureDataStorage = new();
|
||||||
Dictionary<ulong, CreatureAddon> creatureAddonStorage = new();
|
Dictionary<ulong, CreatureAddon> creatureAddonStorage = new();
|
||||||
MultiMap<uint, uint> _creatureQuestItemStorage = new();
|
MultiMap<uint, uint> creatureQuestItemStorage = new();
|
||||||
Dictionary<uint, CreatureAddon> creatureTemplateAddonStorage = new();
|
Dictionary<uint, CreatureAddon> creatureTemplateAddonStorage = new();
|
||||||
|
Dictionary<ulong, CreatureMovementData> creatureMovementOverrides = new();
|
||||||
MultiMap<uint, Tuple<uint, EquipmentInfo>> equipmentInfoStorage = new();
|
MultiMap<uint, Tuple<uint, EquipmentInfo>> equipmentInfoStorage = new();
|
||||||
Dictionary<ObjectGuid, ObjectGuid> linkedRespawnStorage = new();
|
Dictionary<ObjectGuid, ObjectGuid> linkedRespawnStorage = new();
|
||||||
Dictionary<uint, CreatureBaseStats> creatureBaseStatsStorage = new();
|
Dictionary<uint, CreatureBaseStats> creatureBaseStatsStorage = new();
|
||||||
Dictionary<uint, VendorItemData> cacheVendorItemStorage = new();
|
Dictionary<uint, VendorItemData> cacheVendorItemStorage = new();
|
||||||
Dictionary<uint, Trainer> _trainers = new();
|
Dictionary<uint, Trainer> trainers = new();
|
||||||
Dictionary<(uint creatureId, uint gossipMenuId, uint gossipOptionIndex), uint> _creatureDefaultTrainers = new();
|
Dictionary<(uint creatureId, uint gossipMenuId, uint gossipOptionIndex), uint> _creatureDefaultTrainers = new();
|
||||||
List<uint>[] _difficultyEntries = new List<uint>[SharedConst.MaxCreatureDifficulties]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate
|
List<uint>[] difficultyEntries = new List<uint>[SharedConst.MaxCreatureDifficulties]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate
|
||||||
List<uint>[] _hasDifficultyEntries = new List<uint>[SharedConst.MaxCreatureDifficulties]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate
|
List<uint>[] hasDifficultyEntries = new List<uint>[SharedConst.MaxCreatureDifficulties]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate
|
||||||
Dictionary<uint, NpcText> _npcTextStorage = new();
|
Dictionary<uint, NpcText> npcTextStorage = new();
|
||||||
|
|
||||||
//GameObject
|
//GameObject
|
||||||
Dictionary<uint, GameObjectTemplate> _gameObjectTemplateStorage = new();
|
Dictionary<uint, GameObjectTemplate> _gameObjectTemplateStorage = new();
|
||||||
|
|||||||
@@ -616,6 +616,9 @@ namespace Game
|
|||||||
Log.outInfo(LogFilter.ServerLoading, "Loading Creature Addon Data...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading Creature Addon Data...");
|
||||||
Global.ObjectMgr.LoadCreatureAddons();
|
Global.ObjectMgr.LoadCreatureAddons();
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loading Creature Movement Overrides...");
|
||||||
|
Global.ObjectMgr.LoadCreatureMovementOverrides(); // must be after LoadCreatures()
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loading GameObjects...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading GameObjects...");
|
||||||
Global.ObjectMgr.LoadGameObjects();
|
Global.ObjectMgr.LoadGameObjects();
|
||||||
|
|
||||||
|
|||||||
@@ -1198,6 +1198,7 @@ INSERT INTO `rbac_linked_permissions` VALUES
|
|||||||
(196,870),
|
(196,870),
|
||||||
(196,871),
|
(196,871),
|
||||||
(196,872),
|
(196,872),
|
||||||
|
(196,873),
|
||||||
(196,881),
|
(196,881),
|
||||||
(197,232),
|
(197,232),
|
||||||
(197,236),
|
(197,236),
|
||||||
@@ -2130,6 +2131,7 @@ INSERT INTO `rbac_permissions` VALUES
|
|||||||
(870,'Command: debug threatinfo'),
|
(870,'Command: debug threatinfo'),
|
||||||
(871,'Command: debug instancespawn'),
|
(871,'Command: debug instancespawn'),
|
||||||
(872,'Command: server debug'),
|
(872,'Command: server debug'),
|
||||||
|
(873,'Command: reload creature_movement_override'),
|
||||||
(881,'Command: reload vehicle_template');
|
(881,'Command: reload vehicle_template');
|
||||||
/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */;
|
/*!40000 ALTER TABLE `rbac_permissions` ENABLE KEYS */;
|
||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
@@ -2347,6 +2349,7 @@ INSERT INTO `updates` VALUES
|
|||||||
('2018_02_18_00_auth.sql','8489DD3EFFE14A7486B593435F0BA2BC69B6EABF','ARCHIVED','2018-02-18 16:35:55',0),
|
('2018_02_18_00_auth.sql','8489DD3EFFE14A7486B593435F0BA2BC69B6EABF','ARCHIVED','2018-02-18 16:35:55',0),
|
||||||
('2018_02_19_00_auth.sql','07CE658C5EF88693D3C047EF8E724F94ADA74C15','ARCHIVED','2018-02-19 22:33:32',0),
|
('2018_02_19_00_auth.sql','07CE658C5EF88693D3C047EF8E724F94ADA74C15','ARCHIVED','2018-02-19 22:33:32',0),
|
||||||
('2018_02_28_00_auth.sql','E92EF4ABF7FA0C66649E1633DD0459F44C09EB83','ARCHIVED','2018-02-28 23:07:59',0),
|
('2018_02_28_00_auth.sql','E92EF4ABF7FA0C66649E1633DD0459F44C09EB83','ARCHIVED','2018-02-28 23:07:59',0),
|
||||||
|
('2018_03_08_00_auth.sql','624C58A07E0B4DDC4C1347E8BA8EFEEFD5B43DA7','RELEASED','2018-01-12 15:10:11',0),
|
||||||
('2018_03_14_00_auth.sql','2D71E93DF7419A30D0D21D8A80CF05698302575A','ARCHIVED','2018-03-14 23:07:59',0),
|
('2018_03_14_00_auth.sql','2D71E93DF7419A30D0D21D8A80CF05698302575A','ARCHIVED','2018-03-14 23:07:59',0),
|
||||||
('2018_04_06_00_auth.sql','D8416F0C4751763202B1997C81423F6EE2FCF9A6','ARCHIVED','2018-04-06 18:00:32',0),
|
('2018_04_06_00_auth.sql','D8416F0C4751763202B1997C81423F6EE2FCF9A6','ARCHIVED','2018-04-06 18:00:32',0),
|
||||||
('2018_05_13_00_auth.sql','A9E20F2EB1E2FDBB982DB6B00DB7301852B27CD4','ARCHIVED','2018-05-13 20:22:32',0),
|
('2018_05_13_00_auth.sql','A9E20F2EB1E2FDBB982DB6B00DB7301852B27CD4','ARCHIVED','2018-05-13 20:22:32',0),
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
DELETE FROM `rbac_permissions` WHERE `id` = 873;
|
||||||
|
INSERT INTO `rbac_permissions` (`id`,`name`) VALUES
|
||||||
|
(873, 'Command: reload creature_movement_override');
|
||||||
|
|
||||||
|
DELETE FROM `rbac_linked_permissions` WHERE `linkedId` = 873;
|
||||||
|
INSERT INTO `rbac_linked_permissions` (`id`,`linkedId`) VALUES
|
||||||
|
(196, 873);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
DROP TABLE IF EXISTS `creature_template_movement`;
|
||||||
|
CREATE TABLE `creature_template_movement` (
|
||||||
|
`CreatureId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`Ground` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||||
|
`Swim` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||||
|
`Flight` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`Rooted` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`CreatureId`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `creature_movement_override`;
|
||||||
|
CREATE TABLE `creature_movement_override` (
|
||||||
|
`SpawnId` bigint(20) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`Ground` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||||
|
`Swim` tinyint(3) unsigned NOT NULL DEFAULT '1',
|
||||||
|
`Flight` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`Rooted` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`SpawnId`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
INSERT INTO `creature_template_movement` SELECT `entry`,0,0,0,0 FROM `creature_template` WHERE `InhabitType`!=3;
|
||||||
|
UPDATE `creature_template_movement` SET `Ground`=1 WHERE `CreatureId` IN (SELECT `entry` FROM `creature_template` WHERE `InhabitType` & 1);
|
||||||
|
UPDATE `creature_template_movement` SET `Swim`=1 WHERE `CreatureId` IN (SELECT `entry` FROM `creature_template` WHERE `InhabitType` & 2);
|
||||||
|
UPDATE `creature_template_movement` SET `Flight`=1 WHERE `CreatureId` IN (SELECT `entry` FROM `creature_template` WHERE (`InhabitType` & 5) = 4);
|
||||||
|
UPDATE `creature_template_movement` SET `Flight`=2 WHERE `CreatureId` IN (SELECT `entry` FROM `creature_template` WHERE (`InhabitType` & 5) = 5);
|
||||||
|
UPDATE `creature_template_movement` SET `Rooted`=1 WHERE `CreatureId` IN (SELECT `entry` FROM `creature_template` WHERE `InhabitType` & 8);
|
||||||
|
|
||||||
|
ALTER TABLE `creature_template` DROP `InhabitType`;
|
||||||
|
|
||||||
|
UPDATE `trinity_string` SET `content_default`='Movement type: %s' WHERE `entry`=11008;
|
||||||
|
|
||||||
|
DELETE FROM `command` WHERE `name`='reload creature_movement_override';
|
||||||
|
INSERT INTO `command` (`name`,`permission`,`help`) VALUES
|
||||||
|
('reload creature_movement_override',873,'Syntax: .reload creature_movement_override\nReload creature_movement_override table.');
|
||||||
Reference in New Issue
Block a user