Scripts/InstanceScript: Implement database framework for managing spawn groups based on boss state.
Port From (https://github.com/TrinityCore/TrinityCore/commit/608c9aaabfcdbaf09edd11cdf268c243b3e69478)
This commit is contained in:
@@ -113,7 +113,7 @@ namespace Framework.Constants
|
|||||||
AreaTrigger = 0x20,
|
AreaTrigger = 0x20,
|
||||||
Conversation = 0x40,
|
Conversation = 0x40,
|
||||||
All = 0x7F,
|
All = 0x7F,
|
||||||
|
|
||||||
//GameObjects, Creatures(except pets), DynamicObject, Corpse(Bones), AreaTrigger
|
//GameObjects, Creatures(except pets), DynamicObject, Corpse(Bones), AreaTrigger
|
||||||
AllGrid = GameObject | Creature | DynamicObject | Corpse | AreaTrigger | Conversation,
|
AllGrid = GameObject | Creature | DynamicObject | Corpse | AreaTrigger | Conversation,
|
||||||
|
|
||||||
@@ -231,4 +231,13 @@ namespace Framework.Constants
|
|||||||
|
|
||||||
All = (System | CompatibilityMode | ManualSpawn | DynamicSpawnRate | EscortQuestNpc)
|
All = (System | CompatibilityMode | ManualSpawn | DynamicSpawnRate | EscortQuestNpc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum InstanceSpawnGroupFlags
|
||||||
|
{
|
||||||
|
ActivateSpawn = 0x01,
|
||||||
|
BlockSpawn = 0x02,
|
||||||
|
|
||||||
|
All = (ActivateSpawn | BlockSpawn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
using Framework.Collections;
|
using Framework.Collections;
|
||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
using Framework.Database;
|
using Framework.Database;
|
||||||
|
using Framework.Dynamic;
|
||||||
using Framework.GameMath;
|
using Framework.GameMath;
|
||||||
|
using Framework.IO;
|
||||||
using Game.Conditions;
|
using Game.Conditions;
|
||||||
using Game.DataStorage;
|
using Game.DataStorage;
|
||||||
using Game.Entities;
|
using Game.Entities;
|
||||||
@@ -31,8 +33,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Framework.Dynamic;
|
|
||||||
using Framework.IO;
|
|
||||||
|
|
||||||
namespace Game
|
namespace Game
|
||||||
{
|
{
|
||||||
@@ -5375,6 +5375,61 @@ namespace Game
|
|||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {numMembers} spawn group members in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {numMembers} spawn group members in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
}
|
}
|
||||||
|
public void LoadInstanceSpawnGroups()
|
||||||
|
{
|
||||||
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
|
// 0 1 2 3 4
|
||||||
|
SQLResult result = DB.World.Query("SELECT instanceMapId, bossStateId, bossStates, spawnGroupId, flags FROM instance_spawn_groups");
|
||||||
|
if (result.IsEmpty())
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.ServerLoading, "Loaded 0 instance spawn groups. DB table `instance_spawn_groups` is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ushort instanceMapId = result.Read<ushort>(0);
|
||||||
|
uint spawnGroupId = result.Read<uint>(3);
|
||||||
|
|
||||||
|
var spawnGroupTemplate = _spawnGroupDataStorage.LookupByKey(spawnGroupId);
|
||||||
|
if (spawnGroupTemplate == null || spawnGroupTemplate.flags.HasAnyFlag(SpawnGroupFlags.System))
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.ServerLoading, $"Invalid spawn group {spawnGroupId} specified for instance {instanceMapId}. Skipped.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceSpawnGroupInfo info = new InstanceSpawnGroupInfo();
|
||||||
|
info.SpawnGroupId = spawnGroupId;
|
||||||
|
info.BossStateId = result.Read<byte>(1);
|
||||||
|
|
||||||
|
byte ALL_STATES = (1 << (int)EncounterState.ToBeDecided) - 1;
|
||||||
|
byte states = result.Read<byte>(2);
|
||||||
|
if ((states & ~ALL_STATES) != 0)
|
||||||
|
{
|
||||||
|
info.BossStates = (byte)(states & ALL_STATES);
|
||||||
|
Log.outError(LogFilter.ServerLoading, $"Instance spawn group ({instanceMapId},{spawnGroupId}) had invalid boss state mask {states} - truncated to {info.BossStates}.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
info.BossStates = states;
|
||||||
|
|
||||||
|
InstanceSpawnGroupFlags flags = (InstanceSpawnGroupFlags)result.Read<byte>(4);
|
||||||
|
if ((flags & ~InstanceSpawnGroupFlags.All) != 0)
|
||||||
|
{
|
||||||
|
info.Flags = flags & InstanceSpawnGroupFlags.All;
|
||||||
|
Log.outError(LogFilter.ServerLoading, $"Instance spawn group ({instanceMapId},{spawnGroupId}) had invalid flags {flags} - truncated to {info.Flags}.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
info.Flags = flags;
|
||||||
|
|
||||||
|
_instanceSpawnGroupStorage.Add(instanceMapId, info);
|
||||||
|
|
||||||
|
++count;
|
||||||
|
} while (result.NextRow());
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} instance spawn groups in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||||
|
}
|
||||||
void OnDeleteSpawnData(SpawnData data)
|
void OnDeleteSpawnData(SpawnData data)
|
||||||
{
|
{
|
||||||
var templateIt = _spawnGroupDataStorage.LookupByKey(data.spawnGroupData.groupId);
|
var templateIt = _spawnGroupDataStorage.LookupByKey(data.spawnGroupData.groupId);
|
||||||
@@ -5394,24 +5449,24 @@ namespace Game
|
|||||||
|
|
||||||
Cypher.Assert(false, $"Spawn data ({data.type},{data.spawnId}) being removed is member of spawn group {data.spawnGroupData.groupId}, but not actually listed in the lookup table for that group!");
|
Cypher.Assert(false, $"Spawn data ({data.type},{data.spawnId}) being removed is member of spawn group {data.spawnGroupData.groupId}, but not actually listed in the lookup table for that group!");
|
||||||
}
|
}
|
||||||
public bool SpawnGroupSpawn(uint groupId, Map map, bool ignoreRespawn, bool force = false, List<WorldObject> spawnedObjects = null)
|
public bool SpawnGroupSpawn(uint groupId, Map map, bool ignoreRespawn = false, bool force = false, List<WorldObject> spawnedObjects = null)
|
||||||
{
|
{
|
||||||
var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId);
|
var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId);
|
||||||
if (spawnGroup == null || spawnGroup.flags.HasAnyFlag(SpawnGroupFlags.System))
|
if (spawnGroup == null || spawnGroup.flags.HasAnyFlag(SpawnGroupFlags.System))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Maps, $"Tried to despawn non-existing (or system) spawn group {groupId}. Blocked.");
|
Log.outError(LogFilter.Maps, $"Tried to spawn non-existing (or system) spawn group {groupId}. Blocked.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Maps, $"Tried to despawn creature group {groupId}, but no map was supplied. Blocked.");
|
Log.outError(LogFilter.Maps, $"Tried to spawn creature group {groupId}, but no map was supplied. Blocked.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spawnGroup.mapId != map.GetId())
|
if (spawnGroup.mapId != map.GetId())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Maps, $"Tried to despawn creature group {groupId}, but supplied map is {map.GetId()}, creature group has map {spawnGroup.mapId}. Blocked.");
|
Log.outError(LogFilter.Maps, $"Tried to spawn creature group {groupId}, but supplied map is {map.GetId()}, creature group has map {spawnGroup.mapId}. Blocked.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5543,13 +5598,14 @@ namespace Game
|
|||||||
return _dungeonEncounterStorage.LookupByKey(MathFunctions.MakePair64(mapId, (uint)difficulty));
|
return _dungeonEncounterStorage.LookupByKey(MathFunctions.MakePair64(mapId, (uint)difficulty));
|
||||||
}
|
}
|
||||||
public bool IsTransportMap(uint mapId) { return _transportMaps.Contains((ushort)mapId); }
|
public bool IsTransportMap(uint mapId) { return _transportMaps.Contains((ushort)mapId); }
|
||||||
void SetSpawnGroupActive(uint groupId, bool state)
|
SpawnGroupTemplateData GetSpawnGroupData(uint groupId) { return _spawnGroupDataStorage.LookupByKey(groupId); }
|
||||||
|
public void SetSpawnGroupActive(uint groupId, bool state)
|
||||||
{
|
{
|
||||||
var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId);
|
var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId);
|
||||||
if (spawnGroup != null)
|
if (spawnGroup != null)
|
||||||
spawnGroup.isActive = state;
|
spawnGroup.isActive = state;
|
||||||
}
|
}
|
||||||
bool IsSpawnGroupActive(uint groupId)
|
public bool IsSpawnGroupActive(uint groupId)
|
||||||
{
|
{
|
||||||
var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId);
|
var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId);
|
||||||
return (spawnGroup != null) && spawnGroup.isActive;
|
return (spawnGroup != null) && spawnGroup.isActive;
|
||||||
@@ -5567,6 +5623,7 @@ namespace Game
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
public List<InstanceSpawnGroupInfo> GetSpawnGroupsForInstance(uint instanceId) { return _instanceSpawnGroupStorage.LookupByKey(instanceId); }
|
||||||
|
|
||||||
//Player
|
//Player
|
||||||
public void LoadPlayerInfo()
|
public void LoadPlayerInfo()
|
||||||
@@ -10098,6 +10155,7 @@ namespace Game
|
|||||||
List<ushort> _transportMaps = new List<ushort>();
|
List<ushort> _transportMaps = new List<ushort>();
|
||||||
Dictionary<uint, SpawnGroupTemplateData> _spawnGroupDataStorage = new Dictionary<uint, SpawnGroupTemplateData>();
|
Dictionary<uint, SpawnGroupTemplateData> _spawnGroupDataStorage = new Dictionary<uint, SpawnGroupTemplateData>();
|
||||||
MultiMap<uint, SpawnData> _spawnGroupMapStorage = new MultiMap<uint, SpawnData>();
|
MultiMap<uint, SpawnData> _spawnGroupMapStorage = new MultiMap<uint, SpawnData>();
|
||||||
|
MultiMap<ushort, InstanceSpawnGroupInfo> _instanceSpawnGroupStorage = new MultiMap<ushort, InstanceSpawnGroupInfo>();
|
||||||
|
|
||||||
//Spells /Skills / Phases
|
//Spells /Skills / Phases
|
||||||
Dictionary<uint, PhaseInfoStruct> _phaseInfoById = new Dictionary<uint, PhaseInfoStruct>();
|
Dictionary<uint, PhaseInfoStruct> _phaseInfoById = new Dictionary<uint, PhaseInfoStruct>();
|
||||||
@@ -10512,6 +10570,14 @@ namespace Game
|
|||||||
public uint armor;
|
public uint armor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct InstanceSpawnGroupInfo
|
||||||
|
{
|
||||||
|
public byte BossStateId;
|
||||||
|
public byte BossStates;
|
||||||
|
public uint SpawnGroupId;
|
||||||
|
public InstanceSpawnGroupFlags Flags;
|
||||||
|
}
|
||||||
|
|
||||||
public class SpellClickInfo
|
public class SpellClickInfo
|
||||||
{
|
{
|
||||||
public uint spellId;
|
public uint spellId;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ using Game.Entities;
|
|||||||
using Game.Groups;
|
using Game.Groups;
|
||||||
using Game.Networking.Packets;
|
using Game.Networking.Packets;
|
||||||
using Game.Scenarios;
|
using Game.Scenarios;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ namespace Game.Maps
|
|||||||
public InstanceScript(InstanceMap map)
|
public InstanceScript(InstanceMap map)
|
||||||
{
|
{
|
||||||
instance = map;
|
instance = map;
|
||||||
|
_instanceSpawnGroups = Global.ObjectMgr.GetSpawnGroupsForInstance(map.GetId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveToDB()
|
public void SaveToDB()
|
||||||
@@ -161,27 +163,6 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateMinionState(Creature minion, EncounterState state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case EncounterState.NotStarted:
|
|
||||||
if (!minion.IsAlive())
|
|
||||||
minion.Respawn();
|
|
||||||
else if (minion.IsInCombat())
|
|
||||||
minion.GetAI().EnterEvadeMode();
|
|
||||||
break;
|
|
||||||
case EncounterState.InProgress:
|
|
||||||
if (!minion.IsAlive())
|
|
||||||
minion.Respawn();
|
|
||||||
else if (minion.GetVictim() == null)
|
|
||||||
minion.GetAI().DoZoneInCombat();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void UpdateDoorState(GameObject door)
|
public virtual void UpdateDoorState(GameObject door)
|
||||||
{
|
{
|
||||||
var range = doors.LookupByKey(door.GetEntry());
|
var range = doors.LookupByKey(door.GetEntry());
|
||||||
@@ -213,6 +194,65 @@ namespace Game.Maps
|
|||||||
door.SetGoState(open ? GameObjectState.Active : GameObjectState.Ready);
|
door.SetGoState(open ? GameObjectState.Active : GameObjectState.Ready);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateMinionState(Creature minion, EncounterState state)
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case EncounterState.NotStarted:
|
||||||
|
if (!minion.IsAlive())
|
||||||
|
minion.Respawn();
|
||||||
|
else if (minion.IsInCombat())
|
||||||
|
minion.GetAI().EnterEvadeMode();
|
||||||
|
break;
|
||||||
|
case EncounterState.InProgress:
|
||||||
|
if (!minion.IsAlive())
|
||||||
|
minion.Respawn();
|
||||||
|
else if (minion.GetVictim() == null)
|
||||||
|
minion.GetAI().DoZoneInCombat();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum states { Block, Spawn, ForceBlock };
|
||||||
|
void UpdateSpawnGroups()
|
||||||
|
{
|
||||||
|
if (_instanceSpawnGroups.Empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Dictionary<uint, states> newStates = new Dictionary<uint, states>();
|
||||||
|
foreach (var info in _instanceSpawnGroups)
|
||||||
|
{
|
||||||
|
if (!newStates.ContainsKey(info.SpawnGroupId))
|
||||||
|
newStates[info.SpawnGroupId] = 0;// makes sure there's a BLOCK value in the map
|
||||||
|
|
||||||
|
if (newStates[info.SpawnGroupId] == states.ForceBlock) // nothing will change this
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (((1 << (int)GetBossState(info.BossStateId)) & info.BossStates) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (info.Flags.HasAnyFlag(InstanceSpawnGroupFlags.BlockSpawn))
|
||||||
|
newStates[info.SpawnGroupId] = states.ForceBlock;
|
||||||
|
else if (info.Flags.HasAnyFlag(InstanceSpawnGroupFlags.ActivateSpawn))
|
||||||
|
newStates[info.SpawnGroupId] = states.Spawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var pair in newStates)
|
||||||
|
{
|
||||||
|
uint groupId = pair.Key;
|
||||||
|
bool doSpawn = pair.Value == states.Spawn;
|
||||||
|
if (Global.ObjectMgr.IsSpawnGroupActive(groupId) == doSpawn)
|
||||||
|
continue; // nothing to do here
|
||||||
|
// if we should spawn group, then spawn it...
|
||||||
|
if (doSpawn)
|
||||||
|
Global.ObjectMgr.SpawnGroupSpawn(groupId, instance);
|
||||||
|
else // otherwise, set it as inactive so it no longer respawns (but don't despawn it)
|
||||||
|
Global.ObjectMgr.SetSpawnGroupActive(groupId, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public BossInfo GetBossInfo(uint id)
|
public BossInfo GetBossInfo(uint id)
|
||||||
{
|
{
|
||||||
Cypher.Assert(id < bosses.Count);
|
Cypher.Assert(id < bosses.Count);
|
||||||
@@ -291,7 +331,7 @@ namespace Game.Maps
|
|||||||
if (bossInfo.state == EncounterState.ToBeDecided) // loading
|
if (bossInfo.state == EncounterState.ToBeDecided) // loading
|
||||||
{
|
{
|
||||||
bossInfo.state = state;
|
bossInfo.state = state;
|
||||||
//Log.outError(LogFilter.General "Inialize boss {0} state as {1}.", id, (uint32)state);
|
Log.outDebug(LogFilter.Scripts, $"InstanceScript: Inialize boss {id} state as {state}.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -354,6 +394,7 @@ namespace Game.Maps
|
|||||||
UpdateMinionState(minion, state);
|
UpdateMinionState(minion, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateSpawnGroups();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -364,6 +405,14 @@ namespace Game.Maps
|
|||||||
return player && player.GetSession().HasPermission(RBACPermissions.SkipCheckInstanceRequiredBosses);
|
return player && player.GetSession().HasPermission(RBACPermissions.SkipCheckInstanceRequiredBosses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void Create()
|
||||||
|
{
|
||||||
|
for (uint i = 0; i < bosses.Count; ++i)
|
||||||
|
SetBossState(i, EncounterState.NotStarted);
|
||||||
|
|
||||||
|
UpdateSpawnGroups();
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Load(string data)
|
public virtual void Load(string data)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(data))
|
if (string.IsNullOrEmpty(data))
|
||||||
@@ -411,6 +460,7 @@ namespace Game.Maps
|
|||||||
if (buff < EncounterState.ToBeDecided)
|
if (buff < EncounterState.ToBeDecided)
|
||||||
SetBossState(pair.Key, buff);
|
SetBossState(pair.Key, buff);
|
||||||
}
|
}
|
||||||
|
UpdateSpawnGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual string GetSaveData()
|
public virtual string GetSaveData()
|
||||||
@@ -852,6 +902,7 @@ namespace Game.Maps
|
|||||||
Dictionary<uint, uint> _gameObjectInfo = new Dictionary<uint, uint>();
|
Dictionary<uint, uint> _gameObjectInfo = new Dictionary<uint, uint>();
|
||||||
Dictionary<uint, ObjectGuid> _objectGuids = new Dictionary<uint, ObjectGuid>();
|
Dictionary<uint, ObjectGuid> _objectGuids = new Dictionary<uint, ObjectGuid>();
|
||||||
uint completedEncounters;
|
uint completedEncounters;
|
||||||
|
List<InstanceSpawnGroupInfo> _instanceSpawnGroups = new List<InstanceSpawnGroupInfo>();
|
||||||
uint _entranceId;
|
uint _entranceId;
|
||||||
uint _temporaryEntranceId;
|
uint _temporaryEntranceId;
|
||||||
uint _combatResurrectionTimer;
|
uint _combatResurrectionTimer;
|
||||||
|
|||||||
@@ -5173,6 +5173,8 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
i_data.Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Reset(InstanceResetMethod method)
|
public bool Reset(InstanceResetMethod method)
|
||||||
|
|||||||
@@ -586,6 +586,9 @@ namespace Game
|
|||||||
Log.outInfo(LogFilter.ServerLoading, "Loading Spawn Group Templates...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading Spawn Group Templates...");
|
||||||
Global.ObjectMgr.LoadSpawnGroupTemplates();
|
Global.ObjectMgr.LoadSpawnGroupTemplates();
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loading instance spawn groups...");
|
||||||
|
Global.ObjectMgr.LoadInstanceSpawnGroups();
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loading Creature Data...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading Creature Data...");
|
||||||
Global.ObjectMgr.LoadCreatures();
|
Global.ObjectMgr.LoadCreatures();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
--
|
||||||
|
DROP TABLE IF EXISTS `instance_spawn_groups`;
|
||||||
|
CREATE TABLE `instance_spawn_groups` (
|
||||||
|
`instanceMapId` smallint(5) unsigned not null,
|
||||||
|
`bossStateId` tinyint(3) unsigned not null,
|
||||||
|
`bossStates` tinyint(3) unsigned not null,
|
||||||
|
`spawnGroupId` int(10) unsigned not null,
|
||||||
|
`flags` tinyint(3) unsigned not null,
|
||||||
|
PRIMARY KEY (`instanceMapId`,`bossStateId`,`spawnGroupId`,`bossStates`)
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
Reference in New Issue
Block a user