//todo check this void AddItemAppearance(ItemModifiedAppearanceRecord itemModifiedAppearance) { Player owner = _owner.GetPlayer(); if (_appearances.Count <= itemModifiedAppearance.Id) { uint numBlocks = (uint)(_appearances.Count << 2); _appearances.Length = (int)itemModifiedAppearance.Id + 1; numBlocks = (uint)(_appearances.Count << 2) - numBlocks; while (numBlocks-- != 0) { owner.AddTransmogBlock(0); } } _appearances.Set((int)itemModifiedAppearance.Id, true); uint blockIndex = itemModifiedAppearance.Id / 32; uint bitIndex = itemModifiedAppearance.Id % 32; owner.AddTransmogFlag((int)blockIndex, 1u << (int)bitIndex); var temporaryAppearance = _temporaryAppearances.LookupByKey(itemModifiedAppearance.Id); if (!temporaryAppearance.Empty()) { owner.RemoveConditionalTransmog(itemModifiedAppearance.Id); _temporaryAppearances.Remove(itemModifiedAppearance.Id); } ItemRecord item = CliDB.ItemStorage.LookupByKey(itemModifiedAppearance.ItemID); if (item != null) { int transmogSlot = Item.ItemTransmogrificationSlots[(int)item.inventoryType]; if (transmogSlot >= 0) { _owner.GetPlayer().UpdateCriteria(CriteriaTypes.AppearanceUnlockedBySlot, (ulong)transmogSlot, 1); } } var sets = Global.DB2Mgr.GetTransmogSetsForItemModifiedAppearance(itemModifiedAppearance.Id); foreach (TransmogSetRecord set in sets) { if (IsSetCompleted(set.Id)) { _owner.GetPlayer().UpdateCriteria(CriteriaTypes.TransmogSetUnlocked, set.TransmogSetGroupID); } } }
void LoadResetTimes() { long now = Time.UnixTime; long today = (now / Time.Day) * Time.Day; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped Dictionary <uint, Tuple <uint, long> > instResetTime = new Dictionary <uint, Tuple <uint, long> >(); // index instance ids by map/difficulty pairs for fast reset warning send MultiMap <uint, uint> mapDiffResetInstances = new MultiMap <uint, uint>(); SQLResult result = DB.Characters.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC"); if (!result.IsEmpty()) { do { uint instanceId = result.Read <uint>(0); // Instances are pulled in ascending order from db and nextInstanceId is initialized with 1, // so if the instance id is used, increment until we find the first unused one for a potential new instance if (Global.MapMgr.GetNextInstanceId() == instanceId) { Global.MapMgr.SetNextInstanceId(instanceId + 1); } // Mark instance id as being used Global.MapMgr.RegisterInstanceId(instanceId); long resettime = result.Read <uint>(3); if (resettime != 0) { uint mapid = result.Read <ushort>(1); uint difficulty = result.Read <byte>(2); instResetTime[instanceId] = Tuple.Create(MathFunctions.MakePair32(mapid, difficulty), resettime); mapDiffResetInstances.Add(MathFunctions.MakePair32(mapid, difficulty), instanceId); } }while (result.NextRow()); // update reset time for normal instances with the max creature respawn time + X hours SQLResult result2 = DB.Characters.Query(DB.Characters.GetPreparedStatement(CharStatements.SEL_MAX_CREATURE_RESPAWNS)); if (!result2.IsEmpty()) { do { uint instance = result2.Read <uint>(1); long resettime = result2.Read <uint>(0) + 2 * Time.Hour; var pair = instResetTime.LookupByKey(instance); if (pair != null && pair.Item2 != resettime) { DB.Characters.DirectExecute("UPDATE instance SET resettime = '{0}' WHERE id = '{1}'", resettime, instance); instResetTime[instance] = Tuple.Create(pair.Item1, resettime); } }while (result2.NextRow()); } // schedule the reset times foreach (var pair in instResetTime) { if (pair.Value.Item2 > now) { ScheduleReset(true, pair.Value.Item2, new InstResetEvent(0, MathFunctions.Pair32_LoPart(pair.Value.Item1), (Difficulty)MathFunctions.Pair32_HiPart(pair.Value.Item1), pair.Key)); } } } // load the global respawn times for raid/heroic instances uint diff = (uint)(WorldConfig.GetIntValue(WorldCfg.InstanceResetTimeHour) * Time.Hour); result = DB.Characters.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if (!result.IsEmpty()) { do { uint mapid = result.Read <ushort>(0); Difficulty difficulty = (Difficulty)result.Read <byte>(1); ulong oldresettime = result.Read <uint>(2); MapDifficultyRecord mapDiff = Global.DB2Mgr.GetMapDifficultyData(mapid, difficulty); if (mapDiff == null) { Log.outError(LogFilter.Server, "InstanceSaveManager.LoadResetTimes: invalid mapid({0})/difficulty({1}) pair in instance_reset!", mapid, difficulty); DB.Characters.DirectExecute("DELETE FROM instance_reset WHERE mapid = '{0}' AND difficulty = '{1}'", mapid, difficulty); continue; } // update the reset time if the hour in the configs changes ulong newresettime = (oldresettime / Time.Day) * Time.Day + diff; if (oldresettime != newresettime) { DB.Characters.DirectExecute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty = '{2}'", newresettime, mapid, difficulty); } InitializeResetTimeFor(mapid, difficulty, (long)newresettime); } while (result.NextRow()); } // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue foreach (var mapDifficultyPair in Global.DB2Mgr.GetMapDifficulties()) { uint mapid = mapDifficultyPair.Key; foreach (var difficultyPair in mapDifficultyPair.Value) { Difficulty difficulty = (Difficulty)difficultyPair.Key; MapDifficultyRecord mapDiff = difficultyPair.Value; if (mapDiff.GetRaidDuration() == 0) { continue; } // the reset_delay must be at least one day uint period = (uint)(((mapDiff.GetRaidDuration() * WorldConfig.GetFloatValue(WorldCfg.RateInstanceResetTime)) / Time.Day) * Time.Day); if (period < Time.Day) { period = Time.Day; } long t = GetResetTimeFor(mapid, difficulty); if (t == 0) { // initialize the reset time t = today + period + diff; DB.Characters.DirectExecute("INSERT INTO instance_reset VALUES ('{0}', '{1}', '{2}')", mapid, (uint)difficulty, (uint)t); } if (t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / Time.Day) * Time.Day; t += ((today - t) / period + 1) * period + diff; DB.Characters.DirectExecute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty= '{2}'", t, mapid, (uint)difficulty); } InitializeResetTimeFor(mapid, difficulty, t); // schedule the global reset/warning byte type; for (type = 1; type < 4; ++type) { if (t - ResetTimeDelay[type - 1] > now) { break; } } ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, 0)); var range = mapDiffResetInstances.LookupByKey(MathFunctions.MakePair32(mapid, (uint)difficulty)); foreach (var id in range) { ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, id)); } } } }
public List<byte> GetGroupList(byte group) { return Groups.LookupByKey(group); }
void LoadResetTimes() { long now = Time.UnixTime; long today = (now / Time.Day) * Time.Day; // NOTE: Use DirectPExecute for tables that will be queried later // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped Dictionary <uint, Tuple <uint, long> > instResetTime = new Dictionary <uint, Tuple <uint, long> >(); // index instance ids by map/difficulty pairs for fast reset warning send MultiMap <uint, uint> mapDiffResetInstances = new MultiMap <uint, uint>(); SQLResult result = DB.Characters.Query("SELECT id, map, difficulty, resettime FROM instance ORDER BY id ASC"); if (!result.IsEmpty()) { do { uint instanceId = result.Read <uint>(0); // Mark instance id as being used Global.MapMgr.RegisterInstanceId(instanceId); long resettime = result.Read <long>(3); if (resettime != 0) { uint mapid = result.Read <ushort>(1); uint difficulty = result.Read <byte>(2); instResetTime[instanceId] = Tuple.Create(MathFunctions.MakePair32(mapid, difficulty), resettime); mapDiffResetInstances.Add(MathFunctions.MakePair32(mapid, difficulty), instanceId); } }while (result.NextRow()); // schedule the reset times foreach (var pair in instResetTime) { if (pair.Value.Item2 > now) { ScheduleReset(true, pair.Value.Item2, new InstResetEvent(0, MathFunctions.Pair32_LoPart(pair.Value.Item1), (Difficulty)MathFunctions.Pair32_HiPart(pair.Value.Item1), pair.Key)); } } } // load the global respawn times for raid/heroic instances uint diff = (uint)(WorldConfig.GetIntValue(WorldCfg.InstanceResetTimeHour) * Time.Hour); result = DB.Characters.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if (!result.IsEmpty()) { do { uint mapid = result.Read <ushort>(0); Difficulty difficulty = (Difficulty)result.Read <byte>(1); long oldresettime = result.Read <long>(2); MapDifficultyRecord mapDiff = Global.DB2Mgr.GetMapDifficultyData(mapid, difficulty); if (mapDiff == null) { Log.outError(LogFilter.Server, "InstanceSaveManager.LoadResetTimes: invalid mapid({0})/difficulty({1}) pair in instance_reset!", mapid, difficulty); PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); DB.Characters.DirectExecute(stmt); continue; } // update the reset time if the hour in the configs changes long newresettime = (oldresettime / Time.Day) * Time.Day + diff; if (oldresettime != newresettime) { PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, newresettime); stmt.AddValue(1, mapid); stmt.AddValue(2, (byte)difficulty); DB.Characters.DirectExecute(stmt); } InitializeResetTimeFor(mapid, difficulty, newresettime); } while (result.NextRow()); } // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue foreach (var mapDifficultyPair in Global.DB2Mgr.GetMapDifficulties()) { uint mapid = mapDifficultyPair.Key; foreach (var difficultyPair in mapDifficultyPair.Value) { Difficulty difficulty = (Difficulty)difficultyPair.Key; MapDifficultyRecord mapDiff = difficultyPair.Value; if (mapDiff.GetRaidDuration() == 0) { continue; } // the reset_delay must be at least one day uint period = (uint)(((mapDiff.GetRaidDuration() * WorldConfig.GetFloatValue(WorldCfg.RateInstanceResetTime)) / Time.Day) * Time.Day); if (period < Time.Day) { period = Time.Day; } long t = GetResetTimeFor(mapid, difficulty); if (t == 0) { // initialize the reset time t = today + period + diff; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.INS_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, mapid); stmt.AddValue(1, (byte)difficulty); stmt.AddValue(2, t); DB.Characters.DirectExecute(stmt); } if (t < now) { // assume that expired instances have already been cleaned // calculate the next reset time t = (t / Time.Day) * Time.Day; t += ((today - t) / period + 1) * period + diff; PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_GLOBAL_INSTANCE_RESETTIME); stmt.AddValue(0, t); stmt.AddValue(1, mapid); stmt.AddValue(2, (byte)difficulty); DB.Characters.DirectExecute(stmt); } InitializeResetTimeFor(mapid, difficulty, t); // schedule the global reset/warning byte type; for (type = 1; type < 4; ++type) { if (t - ResetTimeDelay[type - 1] > now) { break; } } ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, 0)); var range = mapDiffResetInstances.LookupByKey(MathFunctions.MakePair32(mapid, (uint)difficulty)); foreach (var id in range) { ScheduleReset(true, t - ResetTimeDelay[type - 1], new InstResetEvent(type, mapid, difficulty, id)); } } } }
public List<CreatureTextEntry> GetGroupList(uint group) { return Groups.LookupByKey(group); }