Core/Instances: Instance lock rewrite (WIP)

Port From (https://github.com/TrinityCore/TrinityCore/commit/17665c929c3a9fb7fe75dd680648129bc1c1f874)
This commit is contained in:
hondacrx
2022-10-04 10:00:07 -04:00
parent d21624fd87
commit d3dde761a2
27 changed files with 907 additions and 431 deletions
+3 -3
View File
@@ -2863,7 +2863,7 @@ namespace Game.Entities
ObjectGuid transGUID = ObjectGuid.Create(HighGuid.Transport, transguid);
Transport transport = null;
Map transportMap = Global.MapMgr.CreateMap(mapId, this, instanceId);
Map transportMap = Global.MapMgr.CreateMap(mapId, this);
if (transportMap != null)
{
Transport transportOnMap = transportMap.GetTransport(transGUID);
@@ -2873,7 +2873,7 @@ namespace Game.Entities
{
mapId = transportOnMap.GetExpectedMapId();
instanceId = 0;
transportMap = Global.MapMgr.CreateMap(mapId, this, instanceId);
transportMap = Global.MapMgr.CreateMap(mapId, this);
if (transportMap)
transport = transportMap.GetTransport(transGUID);
}
@@ -2990,7 +2990,7 @@ namespace Game.Entities
// NOW player must have valid map
// load the player's map here if it's not already loaded
if (!map)
map = Global.MapMgr.CreateMap(mapId, this, instance_id);
map = Global.MapMgr.CreateMap(mapId, this);
AreaTriggerStruct areaTrigger = null;
bool check = false;
+1 -1
View File
@@ -79,6 +79,7 @@ namespace Game.Entities
GroupUpdateCounter[] m_groupUpdateSequences = new GroupUpdateCounter[2];
public Dictionary<Difficulty, Dictionary<uint, InstanceBind>> m_boundInstances = new();
Dictionary<uint, uint> m_recentInstances = new();
Dictionary<uint, long> _instanceResetTimes = new();
uint _pendingBindId;
uint _pendingBindTimer;
@@ -87,7 +88,6 @@ namespace Game.Entities
Difficulty m_dungeonDifficulty;
Difficulty m_raidDifficulty;
Difficulty m_legacyRaidDifficulty;
Difficulty m_prevMapDifficulty;
//Movement
public PlayerTaxi m_taxi = new();
+32 -44
View File
@@ -223,7 +223,7 @@ namespace Game.Entities
// call enter script hooks after everyting else has processed
Global.ScriptMgr.OnPlayerUpdateZone(this, newZone, newArea);
if (oldZone != newZone)
{
{
Global.OutdoorPvPMgr.HandlePlayerEnterZone(this, newZone);
Global.BattleFieldMgr.HandlePlayerEnterZone(this, newZone);
SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange...
@@ -288,8 +288,8 @@ namespace Game.Entities
}
public ZonePVPTypeOverride GetOverrideZonePVPType() { return (ZonePVPTypeOverride)(uint)m_activePlayerData.OverrideZonePVPType; }
public void SetOverrideZonePVPType(ZonePVPTypeOverride type) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideZonePVPType), (uint)type); }
public void SetOverrideZonePVPType(ZonePVPTypeOverride type) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideZonePVPType), (uint)type); }
public InstanceBind GetBoundInstance(uint mapid, Difficulty difficulty, bool withExpired = false)
{
// some instances only have one difficulty
@@ -355,7 +355,7 @@ namespace Game.Entities
}
if (pair.Value.perm)
GetSession().SendCalendarRaidLockout(pair.Value.save, false);
GetSession().SendCalendarRaidLockoutRemoved(pair.Value.save);
pair.Value.save.RemovePlayer(this); // save can become invalid
difficultyDic.Remove(pair.Key);
@@ -436,20 +436,14 @@ namespace Game.Entities
return null;
}
public void BindToInstance()
public void ConfirmPendingBind()
{
InstanceSave mapSave = Global.InstanceSaveMgr.GetInstanceSave(_pendingBindId);
if (mapSave == null) //it seems sometimes mapSave is NULL, but I did not check why
InstanceMap map = GetMap().ToInstanceMap();
if (map == null || map.GetInstanceId() != _pendingBindId)
return;
InstanceSaveCreated data = new();
data.Gm = IsGameMaster();
SendPacket(data);
if (!IsGameMaster())
{
BindToInstance(mapSave, true, BindExtensionState.Keep);
GetSession().SendCalendarRaidLockout(mapSave, true);
}
map.CreateInstanceLockForPlayer(this);
}
public void SetPendingBind(uint instanceId, uint bindTimer)
@@ -460,41 +454,25 @@ namespace Game.Entities
public void SendRaidInfo()
{
DateTime now = GameTime.GetSystemTime();
var instanceLocks = Global.InstanceLockMgr.GetInstanceLocksForPlayer(GetGUID());
InstanceInfoPkt instanceInfo = new();
long now = GameTime.GetGameTime();
foreach (var difficultyDic in m_boundInstances.Values)
foreach (InstanceLock instanceLock in instanceLocks)
{
foreach (var instanceBind in difficultyDic.Values)
{
if (instanceBind.perm)
{
InstanceSave save = instanceBind.save;
InstanceLockPkt lockInfos = new();
lockInfos.InstanceID = instanceLock.GetInstanceId();
lockInfos.MapID = instanceLock.GetMapId();
lockInfos.DifficultyID = (uint)instanceLock.GetDifficultyId();
lockInfos.TimeRemaining = (int)(instanceLock.GetEffectiveExpiryTime() - now).TotalSeconds;
lockInfos.CompletedMask = instanceLock.GetData().CompletedEncountersMask;
InstanceLock lockInfos;
lockInfos.InstanceID = save.GetInstanceId();
lockInfos.MapID = save.GetMapId();
lockInfos.DifficultyID = (uint)save.GetDifficultyID();
if (instanceBind.extendState != BindExtensionState.Extended)
lockInfos.TimeRemaining = (int)(save.GetResetTime() - now);
else
lockInfos.TimeRemaining = (int)(Global.InstanceSaveMgr.GetSubsequentResetTime(save.GetMapId(), save.GetDifficultyID(), save.GetResetTime()) - now);
lockInfos.Locked = !instanceLock.IsExpired();
lockInfos.Extended = instanceLock.IsExtended();
lockInfos.CompletedMask = 0;
Map map = Global.MapMgr.FindMap(save.GetMapId(), save.GetInstanceId());
if (map != null)
{
InstanceScript instanceScript = ((InstanceMap)map).GetInstanceScript();
if (instanceScript != null)
lockInfos.CompletedMask = instanceScript.GetCompletedEncounterMask();
}
lockInfos.Locked = instanceBind.extendState != BindExtensionState.Expired;
lockInfos.Extended = instanceBind.extendState == BindExtensionState.Extended;
instanceInfo.LockList.Add(lockInfos);
}
}
instanceInfo.LockList.Add(lockInfos);
}
SendPacket(instanceInfo);
@@ -820,5 +798,15 @@ namespace Game.Entities
if (HasAuraType(AuraType.ForceBeathBar))
m_MirrorTimerFlags |= PlayerUnderwaterState.InWater;
}
public uint GetRecentInstanceId(uint mapId)
{
return m_recentInstances.LookupByKey(mapId);
}
public void SetRecentInstance(uint mapId, uint instanceId)
{
m_recentInstances[mapId] = instanceId;
}
}
}
+7 -16
View File
@@ -78,7 +78,6 @@ namespace Game.Entities
m_dungeonDifficulty = Difficulty.Normal;
m_raidDifficulty = Difficulty.NormalRaid;
m_legacyRaidDifficulty = Difficulty.Raid10N;
m_prevMapDifficulty = Difficulty.NormalRaid;
m_InstanceValid = true;
_specializationInfo = new SpecializationInfo();
@@ -580,7 +579,7 @@ namespace Game.Entities
{
// Player left the instance
if (_pendingBindId == GetInstanceId())
BindToInstance();
ConfirmPendingBind();
SetPendingBind(0, 0);
}
else
@@ -4051,8 +4050,8 @@ namespace Game.Entities
corpse.UpdatePositionData();
corpse.SetZoneScript();
// we do not need to save corpses for BG/arenas
if (!GetMap().IsBattlegroundOrArena())
// we do not need to save corpses for instances
if (!GetMap().Instanceable())
corpse.SaveToDB();
return corpse;
@@ -5304,20 +5303,12 @@ namespace Game.Entities
// raid downscaling - send difficulty to player
if (GetMap().IsRaid())
{
m_prevMapDifficulty = GetMap().GetDifficultyID();
DifficultyRecord difficulty = CliDB.DifficultyStorage.LookupByKey(m_prevMapDifficulty);
SendRaidDifficulty(difficulty.Flags.HasAnyFlag(DifficultyFlags.Legacy), (int)m_prevMapDifficulty);
Difficulty mapDifficulty = GetMap().GetDifficultyID();
var difficulty = CliDB.DifficultyStorage.LookupByKey(mapDifficulty);
SendRaidDifficulty((difficulty.Flags & DifficultyFlags.Legacy) != 0, (int)mapDifficulty);
}
else if (GetMap().IsNonRaidDungeon())
{
m_prevMapDifficulty = GetMap().GetDifficultyID();
SendDungeonDifficulty((int)m_prevMapDifficulty);
}
else if (!GetMap().Instanceable())
{
DifficultyRecord difficulty = CliDB.DifficultyStorage.LookupByKey(m_prevMapDifficulty);
SendRaidDifficulty(difficulty.Flags.HasAnyFlag(DifficultyFlags.Legacy));
}
SendDungeonDifficulty((int)GetMap().GetDifficultyID());
PhasingHandler.OnMapChange(this);
-26
View File
@@ -917,32 +917,6 @@ namespace Game.Entities
summoner.ToGameObject().GetAI()?.SummonedCreatureDies(creature, attacker);
}
}
// Dungeon specific stuff, only applies to players killing creatures
if (creature.GetInstanceId() != 0)
{
Map instanceMap = creature.GetMap();
/// @todo do instance binding anyway if the charmer/owner is offline
if (instanceMap.IsDungeon() && ((attacker != null && attacker.GetCharmerOrOwnerPlayerOrPlayerItself() != null) || attacker == victim))
{
if (instanceMap.IsRaidOrHeroicDungeon())
{
if (creature.GetCreatureTemplate().FlagsExtra.HasAnyFlag(CreatureFlagsExtra.InstanceBind))
instanceMap.ToInstanceMap().PermBindAllPlayers();
}
else
{
// the reset time is set but not added to the scheduler
// until the players leave the instance
long resettime = GameTime.GetGameTime() + 2 * Time.Hour;
InstanceSave save = Global.InstanceSaveMgr.GetInstanceSave(creature.GetInstanceId());
if (save != null)
if (save.GetResetTime() < resettime)
save.SetResetTime(resettime);
}
}
}
}
// outdoor pvp things, do these after setting the death state, else the player activity notify won't work... doh...