Core: Update to 10.1.5
Port From (https://github.com/TrinityCore/TrinityCore/commit/0cea730fa23473a85c47451c3bd13df816f2b6e4)
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.Dynamic;
|
||||
using Game.AI;
|
||||
using Game.Maps;
|
||||
using Game.Movement;
|
||||
@@ -11,6 +10,7 @@ using Game.Networking.Packets;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Game.Entities
|
||||
@@ -537,6 +537,9 @@ namespace Game.Entities
|
||||
_ai.OnUnitExit(leavingUnit);
|
||||
}
|
||||
}
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumUnitsInside), _insideUnits.Count);
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumPlayersInside), _insideUnits.Count(guid => guid.IsPlayer()));
|
||||
}
|
||||
|
||||
public AreaTriggerTemplate GetTemplate()
|
||||
@@ -815,6 +818,8 @@ namespace Game.Entities
|
||||
m_areaTriggerData.ClearChanged(m_areaTriggerData.TimeToTarget);
|
||||
});
|
||||
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.OrbitPathTarget), orbit.PathTarget.GetValueOrDefault(ObjectGuid.Empty));
|
||||
|
||||
_orbitInfo = orbit;
|
||||
|
||||
_orbitInfo.TimeToTarget = timeToTarget;
|
||||
|
||||
@@ -1044,6 +1044,7 @@ namespace Game.Entities
|
||||
public struct duelflag
|
||||
{
|
||||
public uint InteractRadiusOverride; // 0 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0
|
||||
public uint Willthisduelgountilaplayerdies; // 1 Will this duel go until a player dies?, enum { false, true, }; Default: false
|
||||
}
|
||||
|
||||
public struct fishingnode
|
||||
|
||||
@@ -2038,6 +2038,22 @@ namespace Game.Entities
|
||||
return (ushort)GetAppearanceModId();
|
||||
}
|
||||
|
||||
uint GetVisibleModifiedAppearanceId(Player owner)
|
||||
{
|
||||
uint itemModifiedAppearanceId = GetModifier(ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()]);
|
||||
if (itemModifiedAppearanceId == 0)
|
||||
itemModifiedAppearanceId = GetModifier(ItemModifier.TransmogAppearanceAllSpecs);
|
||||
|
||||
if (itemModifiedAppearanceId == 0)
|
||||
{
|
||||
var itemModifiedAppearance = GetItemModifiedAppearance();
|
||||
if (itemModifiedAppearance != null)
|
||||
itemModifiedAppearanceId = itemModifiedAppearance.Id;
|
||||
}
|
||||
|
||||
return itemModifiedAppearanceId;
|
||||
}
|
||||
|
||||
public uint GetVisibleSecondaryModifiedAppearanceId(Player owner)
|
||||
{
|
||||
uint itemModifiedAppearanceId = GetModifier(ItemConst.SecondaryAppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()]);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Framework.Constants;
|
||||
using Game.DataStorage;
|
||||
using Game.Miscellaneous;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -274,7 +275,7 @@ namespace Game.Entities
|
||||
public uint GetSellPrice() { return ExtendedData.SellPrice; }
|
||||
public InventoryType GetInventoryType() { return ExtendedData.inventoryType; }
|
||||
public int GetAllowableClass() { return ExtendedData.AllowableClass; }
|
||||
public long GetAllowableRace() { return ExtendedData.AllowableRace; }
|
||||
public RaceMask<long> GetAllowableRace() { return new RaceMask<long>(ExtendedData.AllowableRace); }
|
||||
public uint GetBaseItemLevel() { return ExtendedData.ItemLevel; }
|
||||
public int GetBaseRequiredLevel() { return ExtendedData.RequiredLevel; }
|
||||
public uint GetRequiredSkill() { return ExtendedData.RequiredSkill; }
|
||||
|
||||
@@ -113,6 +113,7 @@ namespace Game.Entities
|
||||
case HighGuid.UniqUserClient:
|
||||
case HighGuid.ClientSession:
|
||||
case HighGuid.ClientConnection:
|
||||
case HighGuid.LMMParty:
|
||||
return ObjectGuidFactory.CreateClient(type, 0, arg1, counter);
|
||||
default:
|
||||
return Empty;
|
||||
@@ -151,10 +152,13 @@ namespace Game.Entities
|
||||
case HighGuid.AILock:
|
||||
case HighGuid.AILockTicket:
|
||||
return ObjectGuidFactory.CreateWorldObject(type, 0, 0, (ushort)mapId, 0, entry, counter);
|
||||
case HighGuid.ToolsClient:
|
||||
return ObjectGuidFactory.CreateToolsClient(mapId, entry, counter);
|
||||
default:
|
||||
return Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static ObjectGuid Create(HighGuid type, SpellCastSource subType, uint mapId, uint entry, ulong counter)
|
||||
{
|
||||
switch (type)
|
||||
@@ -166,6 +170,22 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public static ObjectGuid Create(HighGuid type, uint arg1, ushort arg2, byte arg3, uint arg4)
|
||||
{
|
||||
if (type != HighGuid.WorldLayer)
|
||||
return Empty;
|
||||
|
||||
return ObjectGuidFactory.CreateWorldLayer(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
public static ObjectGuid Create(HighGuid type, uint arg2, byte arg3, byte arg4, ulong counter)
|
||||
{
|
||||
if (type != HighGuid.LMMLobby)
|
||||
return Empty;
|
||||
|
||||
return ObjectGuidFactory.CreateLMMLobby(0, arg2, arg3, arg4, counter);
|
||||
}
|
||||
|
||||
public byte[] GetRawValue()
|
||||
{
|
||||
byte[] temp = new byte[16];
|
||||
@@ -541,6 +561,16 @@ namespace Game.Entities
|
||||
return new ObjectGuid((ulong)(((ulong)HighGuid.WorldLayer << 58) | ((ulong)(arg1 & 0xFFFFFFFF) << 10) | (ulong)(arg2 & 0x1FFu)), (ulong)(((ulong)(arg3 & 0xFF) << 24) | (ulong)(arg4 & 0x7FFFFF)));
|
||||
}
|
||||
|
||||
public static ObjectGuid CreateLMMLobby(uint realmId, uint arg2, byte arg3, byte arg4, ulong counter)
|
||||
{
|
||||
return new ObjectGuid((ulong)(((ulong)HighGuid.LMMLobby << 58)
|
||||
| ((ulong)GetRealmIdForObjectGuid(realmId) << 42)
|
||||
| ((ulong)(arg2 & 0xFFFFFFFF) << 26)
|
||||
| ((ulong)(arg3 & 0xFF) << 18)
|
||||
| ((ulong)(arg4 & 0xFF) << 10)),
|
||||
counter);
|
||||
}
|
||||
|
||||
static uint GetRealmIdForObjectGuid(uint realmId)
|
||||
{
|
||||
if (realmId != 0)
|
||||
@@ -608,6 +638,11 @@ namespace Game.Entities
|
||||
SET_GUID_INFO(HighGuid.Cast, FormatWorldObject, ParseWorldObject);
|
||||
SET_GUID_INFO(HighGuid.ClientConnection, FormatClient, ParseClient);
|
||||
SET_GUID_INFO(HighGuid.ClubFinder, FormatClubFinder, ParseClubFinder);
|
||||
SET_GUID_INFO(HighGuid.ToolsClient, FormatToolsClient, ParseToolsClient);
|
||||
SET_GUID_INFO(HighGuid.WorldLayer, FormatWorldLayer, ParseWorldLayer);
|
||||
SET_GUID_INFO(HighGuid.ArenaTeam, FormatGuild, ParseGuild);
|
||||
SET_GUID_INFO(HighGuid.LMMParty, FormatClient, ParseClient);
|
||||
SET_GUID_INFO(HighGuid.LMMLobby, FormatLMMLobby, ParseLMMLobby);
|
||||
}
|
||||
|
||||
static void SET_GUID_INFO(HighGuid type, Func<HighGuid, ObjectGuid, string> format, Func<HighGuid, string, ObjectGuid> parse)
|
||||
@@ -993,12 +1028,12 @@ namespace Game.Entities
|
||||
return ObjectGuidFactory.CreateClubFinder(realmId, typeNum, clubFinderId, dbId);
|
||||
}
|
||||
|
||||
string FormatToolsClient(HighGuid typeName, ObjectGuid guid)
|
||||
static string FormatToolsClient(HighGuid typeName, ObjectGuid guid)
|
||||
{
|
||||
return $"{typeName}-{guid.GetMapId()}-{(uint)(guid.GetLowValue() >> 40) & 0xFFFFFF}-{guid.GetCounter():X10}";
|
||||
}
|
||||
|
||||
ObjectGuid ParseToolsClient(HighGuid type, string guidString)
|
||||
static ObjectGuid ParseToolsClient(HighGuid type, string guidString)
|
||||
{
|
||||
string[] split = guidString.Split('-');
|
||||
if (split.Length != 3)
|
||||
@@ -1010,12 +1045,12 @@ namespace Game.Entities
|
||||
return ObjectGuidFactory.CreateToolsClient(mapId, serverId, counter);
|
||||
}
|
||||
|
||||
string FormatWorldLayer(HighGuid typeName, ObjectGuid guid)
|
||||
static string FormatWorldLayer(HighGuid typeName, ObjectGuid guid)
|
||||
{
|
||||
return $"{typeName}-{(uint)((guid.GetHighValue() >> 10) & 0xFFFFFFFF)}-{(uint)(guid.GetHighValue() & 0x1FF)}-{(uint)((guid.GetLowValue() >> 24) & 0xFF)}-{(uint)(guid.GetLowValue() & 0x7FFFFF)}";
|
||||
}
|
||||
|
||||
ObjectGuid ParseWorldLayer(HighGuid type, string guidString)
|
||||
static ObjectGuid ParseWorldLayer(HighGuid type, string guidString)
|
||||
{
|
||||
string[] split = guidString.Split('-');
|
||||
if (split.Length != 4)
|
||||
@@ -1026,6 +1061,23 @@ namespace Game.Entities
|
||||
|
||||
return ObjectGuidFactory.CreateWorldLayer(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
static string FormatLMMLobby(HighGuid typeName, ObjectGuid guid)
|
||||
{
|
||||
return $"{typeName}-{guid.GetRealmId()}-{(uint)(guid.GetHighValue() >> 26) & 0xFFFFFF}-{(uint)(guid.GetHighValue() >> 18) & 0xFF}-{(uint)(guid.GetHighValue() >> 10) & 0xFF}-{guid.GetLowValue():X}";
|
||||
}
|
||||
|
||||
static ObjectGuid ParseLMMLobby(HighGuid type, string guidString)
|
||||
{
|
||||
string[] split = guidString.Split('-');
|
||||
if (split.Length != 5)
|
||||
return ObjectGuid.FromStringFailed;
|
||||
|
||||
if (!uint.TryParse(split[0], out uint realmId) || !uint.TryParse(split[1], out uint arg2) || !byte.TryParse(split[2], out byte arg3) || !byte.TryParse(split[0], out byte arg4) || !ulong.TryParse(split[0], out ulong arg5))
|
||||
return ObjectGuid.FromStringFailed;
|
||||
|
||||
return ObjectGuidFactory.CreateLMMLobby(realmId, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
}
|
||||
|
||||
public class Legacy
|
||||
|
||||
@@ -423,6 +423,12 @@ namespace Game.Entities
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public OptionalUpdateField<U> ModifyValue<U>(OptionalUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
MarkChanged(updateField);
|
||||
return updateField;
|
||||
}
|
||||
|
||||
public UpdateFieldString ModifyValue(UpdateFieldString updateField)
|
||||
{
|
||||
MarkChanged(updateField);
|
||||
@@ -464,6 +470,12 @@ namespace Game.Entities
|
||||
_changesMask.Set(updateField.Bit);
|
||||
}
|
||||
|
||||
public void MarkChanged<U>(OptionalUpdateField<U> updateField) where U : new()
|
||||
{
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
_changesMask.Set(updateField.Bit);
|
||||
}
|
||||
|
||||
public void MarkChanged(UpdateFieldString updateField)
|
||||
{
|
||||
_changesMask.Set(updateField.BlockBit);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -756,7 +756,7 @@ namespace Game.Entities
|
||||
|
||||
SetQuestSlot(slot, questId);
|
||||
SetQuestSlotEndTime(slot, endTime);
|
||||
SetQuestSlotAcceptTime(slot, acceptTime);
|
||||
questStatusData.AcceptTime = acceptTime;
|
||||
|
||||
if (questStatusData.Status == QuestStatus.Complete)
|
||||
SetQuestSlotState(slot, QuestSlotStateMask.Complete);
|
||||
@@ -1624,42 +1624,49 @@ namespace Game.Entities
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
// SELECT id, entry, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType, specialization FROM character_pet WHERE owner = ?
|
||||
if (!result.IsEmpty())
|
||||
{
|
||||
do
|
||||
{
|
||||
PetStable.PetInfo petInfo = new();
|
||||
petInfo.PetNumber = result.Read<uint>(0);
|
||||
petInfo.CreatureId = result.Read<uint>(1);
|
||||
petInfo.DisplayId = result.Read<uint>(2);
|
||||
petInfo.Level = result.Read<byte>(3);
|
||||
petInfo.Experience = result.Read<uint>(4);
|
||||
petInfo.ReactState = (ReactStates)result.Read<byte>(5);
|
||||
PetSaveMode slot = (PetSaveMode)result.Read<short>(6);
|
||||
petInfo.Name = result.Read<string>(7);
|
||||
petInfo.WasRenamed = result.Read<bool>(8);
|
||||
petInfo.Health = result.Read<uint>(9);
|
||||
petInfo.Mana = result.Read<uint>(10);
|
||||
petInfo.ActionBar = result.Read<string>(11);
|
||||
petInfo.LastSaveTime = result.Read<uint>(12);
|
||||
petInfo.CreatedBySpellId = result.Read<uint>(13);
|
||||
petInfo.Type = (PetType)result.Read<byte>(14);
|
||||
petInfo.SpecializationId = result.Read<ushort>(15);
|
||||
if (slot >= PetSaveMode.FirstActiveSlot && slot < PetSaveMode.LastActiveSlot)
|
||||
m_petStable.ActivePets[(int)slot] = petInfo;
|
||||
else if (slot >= PetSaveMode.FirstStableSlot && slot < PetSaveMode.LastStableSlot)
|
||||
m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot] = petInfo;
|
||||
else if (slot == PetSaveMode.NotInSlot)
|
||||
m_petStable.UnslottedPets.Add(petInfo);
|
||||
|
||||
} while (result.NextRow());
|
||||
}
|
||||
do
|
||||
{
|
||||
PetStable.PetInfo petInfo = new();
|
||||
petInfo.PetNumber = result.Read<uint>(0);
|
||||
petInfo.CreatureId = result.Read<uint>(1);
|
||||
petInfo.DisplayId = result.Read<uint>(2);
|
||||
petInfo.Level = result.Read<byte>(3);
|
||||
petInfo.Experience = result.Read<uint>(4);
|
||||
petInfo.ReactState = (ReactStates)result.Read<byte>(5);
|
||||
PetSaveMode slot = (PetSaveMode)result.Read<short>(6);
|
||||
petInfo.Name = result.Read<string>(7);
|
||||
petInfo.WasRenamed = result.Read<bool>(8);
|
||||
petInfo.Health = result.Read<uint>(9);
|
||||
petInfo.Mana = result.Read<uint>(10);
|
||||
petInfo.ActionBar = result.Read<string>(11);
|
||||
petInfo.LastSaveTime = result.Read<uint>(12);
|
||||
petInfo.CreatedBySpellId = result.Read<uint>(13);
|
||||
petInfo.Type = (PetType)result.Read<byte>(14);
|
||||
petInfo.SpecializationId = result.Read<ushort>(15);
|
||||
if (slot >= PetSaveMode.FirstActiveSlot && slot < PetSaveMode.LastActiveSlot)
|
||||
{
|
||||
m_petStable.ActivePets[(int)slot] = petInfo;
|
||||
|
||||
if (m_petStable.ActivePets[(int)slot].Type == PetType.Hunter)
|
||||
AddPetToUpdateFields(m_petStable.ActivePets[(int)slot], slot, PetStableFlags.Active);
|
||||
}
|
||||
else if (slot >= PetSaveMode.FirstStableSlot && slot < PetSaveMode.LastStableSlot)
|
||||
{
|
||||
m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot] = petInfo;
|
||||
|
||||
if (m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot].Type == PetType.Hunter)
|
||||
AddPetToUpdateFields(m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot], slot, PetStableFlags.Inactive);
|
||||
}
|
||||
else if (slot == PetSaveMode.NotInSlot)
|
||||
m_petStable.UnslottedPets.Add(petInfo);
|
||||
|
||||
} while (result.NextRow());
|
||||
|
||||
if (Pet.GetLoadPetInfo(m_petStable, 0, summonedPetNumber, null).Item1 != null)
|
||||
m_temporaryUnsummonedPetNumber = summonedPetNumber;
|
||||
}
|
||||
|
||||
|
||||
void _SaveInventory(SQLTransaction trans)
|
||||
{
|
||||
PreparedStatement stmt;
|
||||
@@ -2121,8 +2128,8 @@ namespace Game.Entities
|
||||
stmt.AddValue(1, save.Key);
|
||||
stmt.AddValue(2, (byte)data.Status);
|
||||
stmt.AddValue(3, data.Explored);
|
||||
stmt.AddValue(4, (long)GetQuestSlotAcceptTime(data.Slot));
|
||||
stmt.AddValue(5, (long)GetQuestSlotEndTime(data.Slot));
|
||||
stmt.AddValue(4, data.AcceptTime);
|
||||
stmt.AddValue(5, GetQuestSlotEndTime(data.Slot));
|
||||
trans.Append(stmt);
|
||||
|
||||
// Save objectives
|
||||
|
||||
@@ -1447,7 +1447,7 @@ namespace Game.Entities
|
||||
if (proto.HasFlag(ItemFlags2.FactionAlliance) && GetTeam() != Team.Alliance)
|
||||
return InventoryResult.CantEquipEver;
|
||||
|
||||
if ((proto.GetAllowableClass() & GetClassMask()) == 0 || (proto.GetAllowableRace() & (long)SharedConst.GetMaskForRace(GetRace())) == 0)
|
||||
if ((proto.GetAllowableClass() & GetClassMask()) == 0 || !proto.GetAllowableRace().HasRace(GetRace()))
|
||||
return InventoryResult.CantEquipEver;
|
||||
|
||||
if (proto.GetRequiredSkill() != 0)
|
||||
@@ -2967,7 +2967,7 @@ namespace Game.Entities
|
||||
return InventoryResult.ItemNotFound;
|
||||
|
||||
// Used by group, function GroupLoot, to know if a prototype can be used by a player
|
||||
if ((proto.GetAllowableClass() & GetClassMask()) == 0 || (proto.GetAllowableRace() & (long)SharedConst.GetMaskForRace(GetRace())) == 0)
|
||||
if ((proto.GetAllowableClass() & GetClassMask()) == 0 || !proto.GetAllowableRace().HasRace(GetRace()))
|
||||
return InventoryResult.CantEquipEver;
|
||||
|
||||
if (proto.GetRequiredSpell() != 0 && !HasSpell(proto.GetRequiredSpell()))
|
||||
@@ -3002,7 +3002,7 @@ namespace Game.Entities
|
||||
// if current back slot non-empty search oldest or free
|
||||
if (m_items[slot] != null)
|
||||
{
|
||||
ulong oldest_time = m_activePlayerData.BuybackTimestamp[0];
|
||||
long oldest_time = m_activePlayerData.BuybackTimestamp[0];
|
||||
uint oldest_slot = InventorySlots.BuyBackStart;
|
||||
|
||||
for (byte i = InventorySlots.BuyBackStart + 1; i < InventorySlots.BuyBackEnd; ++i)
|
||||
@@ -3014,7 +3014,7 @@ namespace Game.Entities
|
||||
break;
|
||||
}
|
||||
|
||||
ulong i_time = m_activePlayerData.BuybackTimestamp[i - InventorySlots.BuyBackStart];
|
||||
long i_time = m_activePlayerData.BuybackTimestamp[i - InventorySlots.BuyBackStart];
|
||||
if (oldest_time > i_time)
|
||||
{
|
||||
oldest_time = i_time;
|
||||
@@ -3466,7 +3466,7 @@ namespace Game.Entities
|
||||
DB.Characters.CommitTransaction(trans);
|
||||
}
|
||||
public void SetBuybackPrice(uint slot, uint price) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackPrice, (int)slot), price); }
|
||||
public void SetBuybackTimestamp(uint slot, ulong timestamp) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackTimestamp, (int)slot), timestamp); }
|
||||
public void SetBuybackTimestamp(uint slot, long timestamp) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackTimestamp, (int)slot), timestamp); }
|
||||
|
||||
public Item GetItemFromBuyBackSlot(uint slot)
|
||||
{
|
||||
|
||||
@@ -560,6 +560,19 @@ namespace Game.Entities
|
||||
|
||||
return (instanceLock.GetData().CompletedEncountersMask & (1u << dungeonEncounter.Bit)) != 0;
|
||||
}
|
||||
|
||||
public bool IsLockedToDungeonEncounter(uint dungeonEncounterId, Difficulty difficulty)
|
||||
{
|
||||
var dungeonEncounter = CliDB.DungeonEncounterStorage.LookupByKey(dungeonEncounterId);
|
||||
if (dungeonEncounter == null)
|
||||
return false;
|
||||
|
||||
InstanceLock instanceLock = Global.InstanceLockMgr.FindActiveInstanceLock(GetGUID(), new MapDb2Entries((uint)dungeonEncounter.MapID, difficulty));
|
||||
if (instanceLock == null)
|
||||
return false;
|
||||
|
||||
return (instanceLock.GetData().CompletedEncountersMask & (1u << dungeonEncounter.Bit)) != 0;
|
||||
}
|
||||
|
||||
public override void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, LiquidData newLiquidData)
|
||||
{
|
||||
|
||||
@@ -798,7 +798,7 @@ namespace Game.Entities
|
||||
AdjustQuestObjectiveProgress(quest);
|
||||
|
||||
long endTime = 0;
|
||||
uint limittime = quest.LimitTime;
|
||||
uint limittime = (uint)quest.LimitTime;
|
||||
if (limittime != 0)
|
||||
{
|
||||
// shared timed quest
|
||||
@@ -833,7 +833,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
SetQuestSlotEndTime(logSlot, endTime);
|
||||
SetQuestSlotAcceptTime(logSlot, GameTime.GetGameTime());
|
||||
questStatusData.AcceptTime = GameTime.GetGameTime();
|
||||
|
||||
m_QuestStatusSave[questId] = QuestSaveType.Default;
|
||||
|
||||
@@ -1591,17 +1591,12 @@ namespace Game.Entities
|
||||
|
||||
public bool SatisfyQuestRace(Quest qInfo, bool msg)
|
||||
{
|
||||
long reqraces = qInfo.AllowableRaces;
|
||||
if (reqraces == -1)
|
||||
return true;
|
||||
|
||||
if ((reqraces & (long)SharedConst.GetMaskForRace(GetRace())) == 0)
|
||||
if (!qInfo.AllowableRaces.HasRace(GetRace()))
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
SendCanTakeQuestResponse(QuestFailedReasons.FailedWrongRace);
|
||||
Log.outDebug(LogFilter.Server, "SatisfyQuestRace: Sent QuestFailedReasons.FailedWrongRace (questId: {0}) because player does not have required race.", qInfo.Id);
|
||||
|
||||
Log.outDebug(LogFilter.Server, $"SatisfyQuestRace: Sent QuestFailedReasons.FailedWrongRace (questId: {qInfo.Id}) because player '{GetName()}' ({GetGUID()}) does not have required race.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2068,7 +2063,9 @@ namespace Game.Entities
|
||||
switch (GetQuestStatus(questId))
|
||||
{
|
||||
case QuestStatus.Complete:
|
||||
if (quest.GetQuestTag() == QuestTagType.CovenantCalling)
|
||||
if (quest.IsImportant())
|
||||
result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.ImportantQuestRewardCompleteNoPOI : QuestGiverStatus.ImportantQuestRewardCompletePOI;
|
||||
else if (quest.GetQuestTag() == QuestTagType.CovenantCalling)
|
||||
result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.CovenantCallingRewardCompleteNoPOI : QuestGiverStatus.CovenantCallingRewardCompletePOI;
|
||||
else if (quest.HasFlagEx(QuestFlagsEx.Legendary))
|
||||
result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.LegendaryRewardCompleteNoPOI : QuestGiverStatus.LegendaryRewardCompletePOI;
|
||||
@@ -2076,8 +2073,12 @@ namespace Game.Entities
|
||||
result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.RewardCompleteNoPOI : QuestGiverStatus.RewardCompletePOI;
|
||||
break;
|
||||
case QuestStatus.Incomplete:
|
||||
if (quest.GetQuestTag() == QuestTagType.CovenantCalling)
|
||||
if (quest.IsImportant())
|
||||
result |= QuestGiverStatus.ImportantQuestReward;
|
||||
else if (quest.GetQuestTag() == QuestTagType.CovenantCalling)
|
||||
result |= QuestGiverStatus.CovenantCallingReward;
|
||||
else if (quest.HasFlagEx(QuestFlagsEx.Legendary))
|
||||
result |= QuestGiverStatus.LegendaryReward;
|
||||
else
|
||||
result |= QuestGiverStatus.Reward;
|
||||
break;
|
||||
@@ -2109,22 +2110,20 @@ namespace Game.Entities
|
||||
{
|
||||
if (SatisfyQuestLevel(quest, false))
|
||||
{
|
||||
if (GetLevel() <= (GetQuestLevel(quest) + WorldConfig.GetIntValue(WorldCfg.QuestLowLevelHideDiff)))
|
||||
{
|
||||
if (quest.GetQuestTag() == QuestTagType.CovenantCalling)
|
||||
result |= QuestGiverStatus.CovenantCallingQuest;
|
||||
else if (quest.HasFlagEx(QuestFlagsEx.Legendary))
|
||||
result |= QuestGiverStatus.LegendaryQuest;
|
||||
else if (quest.IsDaily())
|
||||
result |= QuestGiverStatus.DailyQuest;
|
||||
else
|
||||
result |= QuestGiverStatus.Quest;
|
||||
}
|
||||
bool isTrivial = GetLevel() <= (GetQuestLevel(quest) + WorldConfig.GetIntValue(WorldCfg.QuestLowLevelHideDiff));
|
||||
if (quest.IsImportant())
|
||||
result |= isTrivial ? QuestGiverStatus.TrivialImportantQuest : QuestGiverStatus.ImportantQuest;
|
||||
else if (quest.GetQuestTag() == QuestTagType.CovenantCalling)
|
||||
result |= isTrivial ? QuestGiverStatus.TrivialCovenantCallingQuest : QuestGiverStatus.CovenantCallingQuest;
|
||||
else if (quest.HasFlagEx(QuestFlagsEx.Legendary))
|
||||
result |= isTrivial ? QuestGiverStatus.TrivialLegendaryQuest : QuestGiverStatus.LegendaryQuest;
|
||||
else if (quest.IsDaily())
|
||||
result |= QuestGiverStatus.TrivialDailyQuest;
|
||||
result |= isTrivial ? QuestGiverStatus.TrivialDailyQuest : QuestGiverStatus.DailyQuest;
|
||||
else
|
||||
result |= QuestGiverStatus.Trivial;
|
||||
result |= isTrivial ? QuestGiverStatus.Trivial : QuestGiverStatus.Quest;
|
||||
}
|
||||
else if (quest.HasFlagEx(QuestFlagsEx.Legendary))
|
||||
result |= QuestGiverStatus.FutureLegendaryQuest;
|
||||
else
|
||||
result |= QuestGiverStatus.Future;
|
||||
}
|
||||
@@ -2201,16 +2200,11 @@ namespace Game.Entities
|
||||
return 0;
|
||||
}
|
||||
|
||||
public uint GetQuestSlotEndTime(ushort slot)
|
||||
public long GetQuestSlotEndTime(ushort slot)
|
||||
{
|
||||
return m_playerData.QuestLog[slot].EndTime;
|
||||
}
|
||||
|
||||
public uint GetQuestSlotAcceptTime(ushort slot)
|
||||
{
|
||||
return m_playerData.QuestLog[slot].AcceptTime;
|
||||
}
|
||||
|
||||
bool GetQuestSlotObjectiveFlag(ushort slot, sbyte objectiveIndex)
|
||||
{
|
||||
if (objectiveIndex < SharedConst.MaxQuestCounts)
|
||||
@@ -2244,7 +2238,6 @@ namespace Game.Entities
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.QuestID), quest_id);
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.StateFlags), 0u);
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.EndTime), 0u);
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.AcceptTime), 0u);
|
||||
SetUpdateFieldValue(questLogField.ModifyValue(questLogField.ObjectiveFlags), 0u);
|
||||
|
||||
for (int i = 0; i < SharedConst.MaxQuestCounts; ++i)
|
||||
@@ -2279,12 +2272,6 @@ namespace Game.Entities
|
||||
SetUpdateFieldValue(questLog.ModifyValue(questLog.EndTime), (uint)endTime);
|
||||
}
|
||||
|
||||
public void SetQuestSlotAcceptTime(ushort slot, long acceptTime)
|
||||
{
|
||||
QuestLog questLog = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot);
|
||||
SetUpdateFieldValue(questLog.ModifyValue(questLog.AcceptTime), (uint)acceptTime);
|
||||
}
|
||||
|
||||
void SetQuestSlotObjectiveFlag(ushort slot, sbyte objectiveIndex)
|
||||
{
|
||||
QuestLog questLog = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using Framework.Constants;
|
||||
using Framework.Dynamic;
|
||||
using Game.DataStorage;
|
||||
using Game.Miscellaneous;
|
||||
using Game.Networking.Packets;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
@@ -1627,7 +1628,6 @@ namespace Game.Entities
|
||||
|
||||
public void LearnSkillRewardedSpells(uint skillId, uint skillValue, Race race)
|
||||
{
|
||||
long raceMask = SharedConst.GetMaskForRace(race);
|
||||
uint classMask = GetClassMask();
|
||||
|
||||
List<SkillLineAbilityRecord> skillLineAbilities = Global.DB2Mgr.GetSkillLineAbilitiesBySkill(skillId);
|
||||
@@ -1659,7 +1659,8 @@ namespace Game.Entities
|
||||
continue;
|
||||
|
||||
// Check race if set
|
||||
if (ability.RaceMask != 0 && !Convert.ToBoolean(ability.RaceMask & raceMask))
|
||||
var raceMask = new RaceMask<long>(ability.RaceMask);
|
||||
if (!raceMask.IsEmpty() && !raceMask.HasRace(race))
|
||||
continue;
|
||||
|
||||
// Check class if set
|
||||
|
||||
@@ -19,6 +19,7 @@ using Game.Loots;
|
||||
using Game.Mails;
|
||||
using Game.Maps;
|
||||
using Game.Misc;
|
||||
using Game.Miscellaneous;
|
||||
using Game.Networking;
|
||||
using Game.Networking.Packets;
|
||||
using Game.Spells;
|
||||
@@ -859,6 +860,194 @@ namespace Game.Entities
|
||||
return m_petStable;
|
||||
}
|
||||
|
||||
public void AddPetToUpdateFields(PetStable.PetInfo pet, PetSaveMode slot, PetStableFlags flags)
|
||||
{
|
||||
StableInfo ufStable = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable);
|
||||
StablePetInfo ufPet = new();
|
||||
ufPet.ModifyValue(ufPet.PetSlot).SetValue((uint)slot);
|
||||
ufPet.ModifyValue(ufPet.PetNumber).SetValue(pet.PetNumber);
|
||||
ufPet.ModifyValue(ufPet.CreatureID).SetValue(pet.CreatureId);
|
||||
ufPet.ModifyValue(ufPet.DisplayID).SetValue(pet.DisplayId);
|
||||
ufPet.ModifyValue(ufPet.ExperienceLevel).SetValue(pet.Level);
|
||||
ufPet.ModifyValue(ufPet.PetFlags).SetValue((byte)flags);
|
||||
ufPet.ModifyValue(ufPet.Name).SetValue(pet.Name);
|
||||
AddDynamicUpdateFieldValue(ufStable.ModifyValue(ufStable.Pets), ufPet);
|
||||
}
|
||||
|
||||
public void SetPetSlot(uint petNumber, PetSaveMode dstPetSlot)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Interacting);
|
||||
|
||||
WorldSession sess = GetSession();
|
||||
PetStable petStable = GetPetStable();
|
||||
if (petStable == null)
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.InternalError);
|
||||
return;
|
||||
}
|
||||
|
||||
var (srcPet, srcPetSlot) = Pet.GetLoadPetInfo(petStable, 0, petNumber, null);
|
||||
PetStable.PetInfo dstPet = Pet.GetLoadPetInfo(petStable, 0, 0, dstPetSlot).Item1;
|
||||
|
||||
if (srcPet == null || srcPet.Type != PetType.Hunter)
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.InternalError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dstPet != null && dstPet.Type != PetType.Hunter)
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.InternalError);
|
||||
return;
|
||||
}
|
||||
|
||||
PetStable.PetInfo src = null;
|
||||
PetStable.PetInfo dst = null;
|
||||
uint? newActivePetIndex = null;
|
||||
|
||||
if (SharedConst.IsActivePetSlot(srcPetSlot) && SharedConst.IsActivePetSlot(dstPetSlot))
|
||||
{
|
||||
// active<.active: only swap ActivePets and CurrentPetIndex (do not despawn pets)
|
||||
src = petStable.ActivePets[srcPetSlot - PetSaveMode.FirstActiveSlot];
|
||||
dst = petStable.ActivePets[dstPetSlot - PetSaveMode.FirstActiveSlot];
|
||||
|
||||
if (petStable.GetCurrentActivePetIndex() == (uint)srcPetSlot)
|
||||
newActivePetIndex = (uint)dstPetSlot;
|
||||
else if (petStable.GetCurrentActivePetIndex() == (uint)dstPetSlot)
|
||||
newActivePetIndex = (uint)srcPetSlot;
|
||||
}
|
||||
else if (SharedConst.IsStabledPetSlot(srcPetSlot) && SharedConst.IsStabledPetSlot(dstPetSlot))
|
||||
{
|
||||
// stabled<.stabled: only swap StabledPets
|
||||
src = petStable.StabledPets[srcPetSlot - PetSaveMode.FirstStableSlot];
|
||||
dst = petStable.StabledPets[dstPetSlot - PetSaveMode.FirstStableSlot];
|
||||
}
|
||||
else if (SharedConst.IsActivePetSlot(srcPetSlot) && SharedConst.IsStabledPetSlot(dstPetSlot))
|
||||
{
|
||||
// active<.stabled: swap petStable contents and despawn active pet if it is involved in swap
|
||||
if (petStable.CurrentPetIndex == (uint)srcPetSlot)
|
||||
{
|
||||
Pet oldPet = GetPet();
|
||||
if (oldPet && !oldPet.IsAlive())
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.InternalError);
|
||||
return;
|
||||
}
|
||||
|
||||
RemovePet(oldPet, PetSaveMode.NotInSlot);
|
||||
}
|
||||
|
||||
if (dstPet != null)
|
||||
{
|
||||
CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(dstPet.CreatureId);
|
||||
if (creatureInfo == null || !creatureInfo.IsTameable(CanTameExoticPets(), creatureInfo.GetDifficulty(Difficulty.None)))
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.CantControlExotic);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
src = petStable.ActivePets[srcPetSlot - PetSaveMode.FirstActiveSlot];
|
||||
dst = petStable.StabledPets[dstPetSlot - PetSaveMode.FirstStableSlot];
|
||||
}
|
||||
else if (SharedConst.IsStabledPetSlot(srcPetSlot) && SharedConst.IsActivePetSlot(dstPetSlot))
|
||||
{
|
||||
// stabled<.active: swap petStable contents and despawn active pet if it is involved in swap
|
||||
if (petStable.CurrentPetIndex == (uint)dstPetSlot)
|
||||
{
|
||||
Pet oldPet = GetPet();
|
||||
if (oldPet != null && !oldPet.IsAlive())
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.InternalError);
|
||||
return;
|
||||
}
|
||||
|
||||
RemovePet(oldPet, PetSaveMode.NotInSlot);
|
||||
}
|
||||
|
||||
CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(srcPet.CreatureId);
|
||||
if (creatureInfo == null || !creatureInfo.IsTameable(CanTameExoticPets(), creatureInfo.GetDifficulty(Difficulty.None)))
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.CantControlExotic);
|
||||
return;
|
||||
}
|
||||
|
||||
src = petStable.StabledPets[srcPetSlot - PetSaveMode.FirstStableSlot];
|
||||
dst = petStable.ActivePets[dstPetSlot - PetSaveMode.FirstActiveSlot];
|
||||
}
|
||||
|
||||
SQLTransaction trans = new SQLTransaction();
|
||||
|
||||
PreparedStatement stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_PET_SLOT_BY_ID);
|
||||
stmt.AddValue(0, (short)dstPetSlot);
|
||||
stmt.AddValue(1, GetGUID().GetCounter());
|
||||
stmt.AddValue(2, srcPet.PetNumber);
|
||||
trans.Append(stmt);
|
||||
|
||||
if (dstPet != null)
|
||||
{
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_PET_SLOT_BY_ID);
|
||||
stmt.AddValue(0, (short)srcPetSlot);
|
||||
stmt.AddValue(1, GetGUID().GetCounter());
|
||||
stmt.AddValue(2, dstPet.PetNumber);
|
||||
trans.Append(stmt);
|
||||
}
|
||||
|
||||
|
||||
GetSession().AddTransactionCallback(DB.Characters.AsyncCommitTransaction(trans)).AfterComplete(success =>
|
||||
{
|
||||
if (sess.GetPlayer() == this)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
Extensions.Swap(ref src, ref dst);
|
||||
if (newActivePetIndex.HasValue)
|
||||
sess.GetPlayer().GetPetStable().SetCurrentActivePetIndex(newActivePetIndex.Value);
|
||||
|
||||
int srcPetIndex = m_activePlayerData.PetStable.GetValue().Pets.FindIndexIf(p => p.PetSlot == (uint)srcPetSlot);
|
||||
int dstPetIndex = m_activePlayerData.PetStable.GetValue().Pets.FindIndexIf(p => p.PetSlot == (uint)dstPetSlot);
|
||||
|
||||
if (srcPetIndex >= 0)
|
||||
{
|
||||
StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable);
|
||||
StablePetInfo stablePetInfo = stableInfo.ModifyValue(stableInfo.Pets, srcPetIndex);
|
||||
SetUpdateFieldValue(stablePetInfo.ModifyValue(stablePetInfo.PetSlot), (uint)dstPetSlot);
|
||||
}
|
||||
|
||||
if (dstPetIndex >= 0)
|
||||
{
|
||||
StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable);
|
||||
StablePetInfo stablePetInfo = stableInfo.ModifyValue(stableInfo.Pets, dstPetIndex);
|
||||
SetUpdateFieldValue(stablePetInfo.ModifyValue(stablePetInfo.PetSlot), (uint)srcPetSlot);
|
||||
}
|
||||
|
||||
sess.SendPetStableResult(StableResult.StableSuccess);
|
||||
}
|
||||
else
|
||||
{
|
||||
sess.SendPetStableResult(StableResult.InternalError);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ObjectGuid GetStableMaster()
|
||||
{
|
||||
if (!m_activePlayerData.PetStable.HasValue())
|
||||
return ObjectGuid.Empty;
|
||||
|
||||
return m_activePlayerData.PetStable.GetValue().StableMaster;
|
||||
}
|
||||
|
||||
public void SetStableMaster(ObjectGuid stableMaster)
|
||||
{
|
||||
if (!m_activePlayerData.PetStable.HasValue())
|
||||
return;
|
||||
|
||||
StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable);
|
||||
SetUpdateFieldValue(stableInfo.ModifyValue(stableInfo.StableMaster), stableMaster);
|
||||
}
|
||||
|
||||
// last used pet number (for BG's)
|
||||
public uint GetLastPetNumber() { return m_lastpetnumber; }
|
||||
public void SetLastPetNumber(uint petnumber) { m_lastpetnumber = petnumber; }
|
||||
@@ -2568,7 +2757,8 @@ namespace Game.Entities
|
||||
SendRespecWipeConfirm(guid, WorldConfig.GetBoolValue(WorldCfg.NoResetTalentCost) ? 0 : GetNextResetTalentsCost(), SpecResetType.Talents);
|
||||
break;
|
||||
case GossipOptionNpc.Stablemaster:
|
||||
GetSession().SendStablePet(guid);
|
||||
SetStableMaster(guid);
|
||||
handled = false;
|
||||
break;
|
||||
case GossipOptionNpc.PetSpecializationMaster:
|
||||
PlayerTalkClass.SendCloseGossip();
|
||||
@@ -3578,7 +3768,7 @@ namespace Game.Entities
|
||||
|
||||
public static bool IsValidGender(Gender _gender) { return _gender <= Gender.Female; }
|
||||
public static bool IsValidClass(Class _class) { return Convert.ToBoolean((1 << ((int)_class - 1)) & (int)Class.ClassMaskAllPlayable); }
|
||||
public static bool IsValidRace(Race _race) { return Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(_race) & SharedConst.RaceMaskAllPlayable); }
|
||||
public static bool IsValidRace(Race _race) { return RaceMask.AllPlayable.HasRace(_race); }
|
||||
|
||||
void LeaveLFGChannel()
|
||||
{
|
||||
@@ -4506,8 +4696,26 @@ namespace Game.Entities
|
||||
|
||||
PetStable.PetInfo currentPet = m_petStable.GetCurrentPet();
|
||||
Cypher.Assert(currentPet != null && currentPet.PetNumber == pet.GetCharmInfo().GetPetNumber());
|
||||
if (mode == PetSaveMode.NotInSlot || mode == PetSaveMode.AsDeleted)
|
||||
if (mode == PetSaveMode.NotInSlot)
|
||||
m_petStable.CurrentPetIndex = null;
|
||||
else if (mode == PetSaveMode.AsDeleted)
|
||||
{
|
||||
if (m_activePlayerData.PetStable.HasValue())
|
||||
{
|
||||
int ufIndex = m_activePlayerData.PetStable.GetValue().Pets.FindIndexIf(p => p.PetNumber == currentPet.PetNumber);
|
||||
if (ufIndex >= 0)
|
||||
{
|
||||
StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable);
|
||||
RemoveDynamicUpdateFieldValue(stableInfo.ModifyValue(stableInfo.Pets), ufIndex);
|
||||
}
|
||||
}
|
||||
|
||||
var petIndex = m_petStable.GetCurrentActivePetIndex();
|
||||
if (petIndex.HasValue)
|
||||
m_petStable.ActivePets[petIndex.Value] = null;
|
||||
|
||||
m_petStable.CurrentPetIndex = null;
|
||||
}
|
||||
// else if (stable slots) handled in opcode handlers due to required swaps
|
||||
// else (current pet) doesnt need to do anything
|
||||
|
||||
@@ -5083,7 +5291,7 @@ namespace Game.Entities
|
||||
if (pet)
|
||||
pet.SynchronizeLevelWithOwner();
|
||||
|
||||
MailLevelReward mailReward = ObjectMgr.GetMailLevelReward(level, (uint)SharedConst.GetMaskForRace(GetRace()));
|
||||
MailLevelReward mailReward = ObjectMgr.GetMailLevelReward(level, GetRace());
|
||||
if (mailReward != null)
|
||||
{
|
||||
//- TODO: Poor design of mail system
|
||||
@@ -7014,7 +7222,6 @@ namespace Game.Entities
|
||||
}
|
||||
public bool IsSpellFitByClassAndRace(uint spell_id)
|
||||
{
|
||||
long racemask = SharedConst.GetMaskForRace(GetRace());
|
||||
uint classmask = GetClassMask();
|
||||
|
||||
var bounds = SpellMgr.GetSkillLineAbilityMapBounds(spell_id);
|
||||
@@ -7025,7 +7232,8 @@ namespace Game.Entities
|
||||
foreach (var _spell_idx in bounds)
|
||||
{
|
||||
// skip wrong race skills
|
||||
if (_spell_idx.RaceMask != 0 && (_spell_idx.RaceMask & racemask) == 0)
|
||||
var raceMask = new RaceMask<long>(_spell_idx.RaceMask);
|
||||
if (!raceMask.IsEmpty() && !raceMask.HasRace(GetRace()))
|
||||
continue;
|
||||
|
||||
// skip wrong class skills
|
||||
@@ -7409,7 +7617,10 @@ namespace Game.Entities
|
||||
public void RemoveAuraVision(PlayerFieldByte2Flags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); }
|
||||
|
||||
public void SetTransportServerTime(int transportServerTime) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TransportServerTime), transportServerTime); }
|
||||
|
||||
|
||||
public void SetRequiredMountCapabilityFlag(byte flag) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RequiredMountCapabilityFlags), flag); }
|
||||
public void ReplaceAllRequiredMountCapabilityFlags(byte flags) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RequiredMountCapabilityFlags), flags); }
|
||||
|
||||
public bool CanTameExoticPets() { return IsGameMaster() || HasAuraType(AuraType.AllowTamePetType); }
|
||||
|
||||
void SendAttackSwingCantAttack() { SendPacket(new AttackSwingError(AttackSwingErr.CantAttack)); }
|
||||
|
||||
@@ -768,10 +768,8 @@ namespace Game.Entities
|
||||
|
||||
pet.SetCreatorGUID(GetGUID());
|
||||
pet.SetFaction(GetFaction());
|
||||
pet.SetCreatedBySpell(spell_id);
|
||||
|
||||
if (IsTypeId(TypeId.Player))
|
||||
pet.SetUnitFlag(UnitFlags.PlayerControlled);
|
||||
pet.SetCreatedBySpell(spell_id);
|
||||
pet.SetUnitFlag(UnitFlags.PlayerControlled);
|
||||
|
||||
if (!pet.InitStatsForLevel(level))
|
||||
{
|
||||
@@ -790,6 +788,7 @@ namespace Game.Entities
|
||||
|
||||
PetStable.PetInfo petInfo = new();
|
||||
pet.FillPetInfo(petInfo);
|
||||
player.AddPetToUpdateFields(petInfo, (PetSaveMode)petStable.GetCurrentActivePetIndex(), PetStableFlags.Active);
|
||||
petStable.ActivePets[freeActiveSlot] = petInfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1431,7 +1431,7 @@ namespace Game.Entities
|
||||
if (displayInfo != null)
|
||||
{
|
||||
ChrCustomizationReqRecord choiceReq = CliDB.ChrCustomizationReqStorage.LookupByKey(formModelData.Choices[i].ChrCustomizationReqID);
|
||||
if (choiceReq == null || thisPlayer.GetSession().MeetsChrCustomizationReq(choiceReq, GetClass(), false, thisPlayer.m_playerData.Customizations))
|
||||
if (choiceReq == null || thisPlayer.GetSession().MeetsChrCustomizationReq(choiceReq, GetRace(), GetClass(), false, thisPlayer.m_playerData.Customizations))
|
||||
displayIds.Add(displayInfo.DisplayID);
|
||||
}
|
||||
}
|
||||
@@ -1877,6 +1877,7 @@ namespace Game.Entities
|
||||
|
||||
public Race GetRace() { return (Race)(byte)m_unitData.Race; }
|
||||
public void SetRace(Race race) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Race), (byte)race); }
|
||||
public ulong GetRaceMask() { return 1UL << ((int)GetRace() - 1); }
|
||||
public Class GetClass() { return (Class)(byte)m_unitData.ClassId; }
|
||||
public void SetClass(Class classId) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ClassId), (byte)classId); }
|
||||
public uint GetClassMask() { return (uint)(1 << ((int)GetClass() - 1)); }
|
||||
|
||||
Reference in New Issue
Block a user