diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 8f9f06e45..9cf44597b 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -232,7 +232,7 @@ namespace Game.Entities SetInventorySlotCount(InventorySlots.DefaultSize); // set starting level - SetLevel((uint)GetStartLevel(createInfo.RaceId, createInfo.ClassId, createInfo.TemplateSet)); + SetLevel(GetStartLevel(createInfo.RaceId, createInfo.ClassId, createInfo.TemplateSet)); InitRunes(); diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index 50d298d9d..2eda3ed95 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -966,7 +966,7 @@ namespace Game.Entities if (vehicle.GetBase().HasUnitTypeMask(UnitTypeMask.Minion) && vehicle.GetBase().IsTypeId(TypeId.Unit)) if (((Minion)vehicle.GetBase()).GetOwner() == this) - vehicle.GetBase().ToCreature().DespawnOrUnsummon(); + vehicle.GetBase().ToCreature().DespawnOrUnsummon(vehicle.GetDespawnDelay()); if (HasUnitTypeMask(UnitTypeMask.Accessory)) { diff --git a/Source/Game/Entities/Vehicle.cs b/Source/Game/Entities/Vehicle.cs index 168f7449a..7d6cc2034 100644 --- a/Source/Game/Entities/Vehicle.cs +++ b/Source/Game/Entities/Vehicle.cs @@ -509,6 +509,15 @@ namespace Game.Entities } } + public TimeSpan GetDespawnDelay() + { + VehicleTemplate vehicleTemplate = Global.ObjectMgr.GetVehicleTemplate(this); + if (vehicleTemplate != null) + return vehicleTemplate.DespawnDelay; + + return TimeSpan.FromMilliseconds(1); + } + public Unit GetBase() { return _me; } public VehicleRecord GetVehicleInfo() { return _vehicleInfo; } public uint GetCreatureEntry() { return _creatureEntry; } @@ -718,4 +727,9 @@ namespace Game.Entities public sbyte SeatId; public byte SummonedType; } + + public class VehicleTemplate + { + public TimeSpan DespawnDelay; + } } diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index a3c7d09c6..f18d6e291 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -10022,6 +10022,38 @@ namespace Game } //Vehicles + public void LoadVehicleTemplate() + { + uint oldMSTime = Time.GetMSTime(); + + _vehicleTemplateStore.Clear(); + + // 0 1 + SQLResult result = DB.World.Query("SELECT creatureId, despawnDelayMs FROM vehicle_template"); + if (result.IsEmpty()) + { + Log.outInfo(LogFilter.ServerLoading, "Loaded 0 vehicle template. DB table `vehicle_template` is empty."); + return; + } + + do + { + uint creatureId = result.Read(0); + + if (Global.ObjectMgr.GetCreatureTemplate(creatureId) == null) + { + Log.outError(LogFilter.Sql, $"Table `vehicle_template`: Vehicle {creatureId} does not exist."); + continue; + } + + VehicleTemplate vehicleTemplate = new VehicleTemplate(); + vehicleTemplate.DespawnDelay = TimeSpan.FromMilliseconds(result.Read(1)); + _vehicleTemplateStore[creatureId] = vehicleTemplate; + + } while (result.NextRow()); + + Log.outInfo(LogFilter.ServerLoading, $"Loaded {_vehicleTemplateStore.Count} Vehicle Template entries in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); + } public void LoadVehicleTemplateAccessories() { uint oldMSTime = Time.GetMSTime(); @@ -10073,6 +10105,7 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Vehicle Template Accessories in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } + public void LoadVehicleAccessories() { uint oldMSTime = Time.GetMSTime(); @@ -10114,6 +10147,10 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loaded {0} Vehicle Accessories in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime)); } + public VehicleTemplate GetVehicleTemplate(Vehicle veh) + { + return _vehicleTemplateStore.LookupByKey(veh.GetCreatureEntry()); + } public List GetVehicleAccessoryList(Vehicle veh) { Creature cre = veh.GetBase().ToCreature(); @@ -10239,6 +10276,7 @@ namespace Game MultiMap _petHalfName1 = new MultiMap(); //Vehicles + Dictionary _vehicleTemplateStore = new Dictionary(); MultiMap _vehicleTemplateAccessoryStore = new MultiMap(); MultiMap _vehicleAccessoryStore = new MultiMap(); diff --git a/Source/Game/Server/WorldManager.cs b/Source/Game/Server/WorldManager.cs index 2346c0094..6819cfb66 100644 --- a/Source/Game/Server/WorldManager.cs +++ b/Source/Game/Server/WorldManager.cs @@ -652,6 +652,9 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loading NPCSpellClick Data..."); // must be after LoadQuests Global.ObjectMgr.LoadNPCSpellClickSpells(); + Log.outInfo(LogFilter.ServerLoading, "Loading Vehicle Templates..."); + Global.ObjectMgr.LoadVehicleTemplate(); // must be after LoadCreatureTemplates() + Log.outInfo(LogFilter.ServerLoading, "Loading Vehicle Template Accessories..."); Global.ObjectMgr.LoadVehicleTemplateAccessories(); // must be after LoadCreatureTemplates() and LoadNPCSpellClickSpells() diff --git a/sql/updates/world/master/2020_12_31_00_world.sql b/sql/updates/world/master/2020_12_31_00_world.sql new file mode 100644 index 000000000..b974c0abb --- /dev/null +++ b/sql/updates/world/master/2020_12_31_00_world.sql @@ -0,0 +1,15 @@ +-- +-- Table structure for table `vehicle_template` +-- +DROP TABLE IF EXISTS `vehicle_template`; +CREATE TABLE `vehicle_template` ( + `creatureId` int(10) unsigned NOT NULL, + `despawnDelayMs` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`creatureId`) +) ENGINE=MyISAM; + +DELETE FROM `command` WHERE `name`='reload vehicle_template'; +INSERT INTO `command` (`name`,`permission`,`help`) VALUES +('reload vehicle_template', 881, "Syntax: .reload vehicle_template + +Reloads vehicle template definitions from the database.");