hondacrx
2023-08-21 07:22:33 -04:00
parent 794ff2bb99
commit f6807e152c
76 changed files with 3149 additions and 2233 deletions
@@ -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
+16
View File
@@ -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()]);
+2 -1
View File
@@ -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; }
+56 -4
View File
@@ -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
+40 -33
View File
@@ -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
+5 -5
View File
@@ -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)
{
+13
View File
@@ -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)
{
+24 -37
View File
@@ -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);
+3 -2
View File
@@ -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
+218 -7
View File
@@ -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)); }
+3 -4
View File
@@ -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;
}
+2 -1
View File
@@ -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)); }