@@ -72,6 +72,8 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c)
|
||||
|
||||
mcanSpawn = true;
|
||||
|
||||
_chaseOnInterrupt = false;
|
||||
|
||||
// Xinef: Vehicle conditions
|
||||
m_ConditionsTimer = 0;
|
||||
if (me->GetVehicleKit())
|
||||
|
||||
@@ -212,6 +212,9 @@ public:
|
||||
// Xinef
|
||||
void SetWPPauseTimer(uint32 time) { mWPPauseTimer = time; }
|
||||
|
||||
void SetChaseOnInterrupt(bool apply) { _chaseOnInterrupt = apply; }
|
||||
[[nodiscard]] bool CanChaseOnInterrupt() const { return _chaseOnInterrupt; }
|
||||
|
||||
private:
|
||||
bool mIsCharmed;
|
||||
uint32 mFollowCreditType;
|
||||
@@ -257,6 +260,8 @@ private:
|
||||
void CheckConditions(const uint32 diff);
|
||||
ConditionList conditions;
|
||||
uint32 m_ConditionsTimer;
|
||||
|
||||
bool _chaseOnInterrupt;
|
||||
};
|
||||
|
||||
class SmartGameObjectAI : public GameObjectAI
|
||||
|
||||
@@ -742,6 +742,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE)
|
||||
{
|
||||
CAST_AI(SmartAI, me->AI())->SetChaseOnInterrupt(true);
|
||||
|
||||
if (!me->isMoving()) // Don't try to reposition while we are moving
|
||||
{
|
||||
// If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS.
|
||||
@@ -893,7 +895,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
go->SetLootState(GO_READY);
|
||||
}
|
||||
|
||||
go->UseDoorOrButton(0, !!e.action.activateObject.alternative, unit);
|
||||
go->UseDoorOrButton(0, e.action.activateObject.alternative, unit);
|
||||
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject {} activated", go->GetGUID().ToString());
|
||||
}
|
||||
}
|
||||
@@ -1483,14 +1485,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
{
|
||||
for (WorldObject* target : targets)
|
||||
if (IsUnit(target))
|
||||
target->ToUnit()->SetVisible(!!e.action.visibility.state);
|
||||
target->ToUnit()->SetVisible(e.action.visibility.state);
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SET_ACTIVE:
|
||||
{
|
||||
for (WorldObject* target : targets)
|
||||
target->setActive(!!e.action.setActive.state);
|
||||
target->setActive(e.action.setActive.state);
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_ATTACK_START:
|
||||
|
||||
@@ -202,10 +202,29 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid))))
|
||||
switch (source_type)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid ({}) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid)));
|
||||
continue;
|
||||
case SMART_SCRIPT_TYPE_CREATURE:
|
||||
{
|
||||
if (!sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid))))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid ({}) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid)));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_SCRIPT_TYPE_GAMEOBJECT:
|
||||
{
|
||||
if (!sObjectMgr->GetGameObjectData(uint32(std::abs(temp.entryOrGuid))))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: GameObject guid ({}) does not exist, skipped loading.", uint32(temp.entryOrGuid));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: not yet implemented source_type {}", (uint32)source_type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -488,7 +488,7 @@ void AuctionHouseObject::AddAuction(AuctionEntry* auction)
|
||||
|
||||
bool AuctionHouseObject::RemoveAuction(AuctionEntry* auction)
|
||||
{
|
||||
bool wasInMap = !!_auctionsMap.erase(auction->Id);
|
||||
bool wasInMap = _auctionsMap.erase(auction->Id);
|
||||
sAuctionMgr->GetAuctionHouseSearcher()->RemoveAuction(auction);
|
||||
|
||||
sScriptMgr->OnAuctionRemove(this, auction);
|
||||
|
||||
@@ -206,7 +206,7 @@ bool Acore::Hyperlinks::LinkTags::spell::StoreTo(SpellInfo const*& val, std::str
|
||||
if (!(t.TryConsumeTo(spellId) && t.IsEmpty()))
|
||||
return false;
|
||||
|
||||
return !!(val = sSpellMgr->GetSpellInfo(spellId));
|
||||
return (val = sSpellMgr->GetSpellInfo(spellId));
|
||||
}
|
||||
|
||||
bool Acore::Hyperlinks::LinkTags::talent::StoreTo(TalentLinkData& val, std::string_view text)
|
||||
|
||||
@@ -68,7 +68,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
|
||||
{
|
||||
// don't allow 0 items (it's checked during table load)
|
||||
ASSERT(ConditionValue2);
|
||||
bool checkBank = !!ConditionValue3;
|
||||
bool checkBank = ConditionValue3;
|
||||
condMeets = player->HasItemCount(ConditionValue1, ConditionValue2, checkBank);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1987,8 +1987,6 @@ void Creature::setDeathState(DeathState state, bool despawn)
|
||||
|
||||
Dismount(); // if creature is mounted on a virtual mount, remove it at death
|
||||
|
||||
setActive(false);
|
||||
|
||||
if (HasSearchedAssistance())
|
||||
{
|
||||
SetNoSearchAssistance(false);
|
||||
@@ -3904,7 +3902,7 @@ bool Creature::IsUpdateNeeded()
|
||||
if (IsInCombat())
|
||||
return true;
|
||||
|
||||
if (IsVisibilityOverridden())
|
||||
if (!GetObjectVisibilityContainer().GetVisiblePlayersMap().empty())
|
||||
return true;
|
||||
|
||||
if (ToTempSummon())
|
||||
|
||||
@@ -67,7 +67,7 @@ struct FormationInfo
|
||||
uint32 point_1;
|
||||
uint32 point_2;
|
||||
|
||||
bool HasGroupFlag(uint16 flag) const { return !!(groupAI & flag); }
|
||||
bool HasGroupFlag(uint16 flag) const { return (groupAI & flag); }
|
||||
};
|
||||
|
||||
typedef std::unordered_map<ObjectGuid::LowType/*memberDBGUID*/, FormationInfo /*formationInfo*/> CreatureGroupInfoType;
|
||||
|
||||
@@ -3086,7 +3086,7 @@ bool GameObject::IsUpdateNeeded()
|
||||
if (GetMap()->isCellMarked(GetCurrentCell().GetCellCoord().GetId()))
|
||||
return true;
|
||||
|
||||
if (IsVisibilityOverridden())
|
||||
if (!GetObjectVisibilityContainer().GetVisiblePlayersMap().empty())
|
||||
return true;
|
||||
|
||||
if (IsTransport())
|
||||
|
||||
@@ -156,8 +156,8 @@ public:
|
||||
|
||||
void SaveToDB(bool saveAddon = false);
|
||||
void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask, bool saveAddon = false);
|
||||
bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); }
|
||||
bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true);
|
||||
virtual bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); }
|
||||
virtual bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true);
|
||||
void DeleteFromDB();
|
||||
|
||||
void SetOwnerGUID(ObjectGuid owner)
|
||||
|
||||
@@ -1696,7 +1696,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (obj->IsNeverVisible() || CanNeverSee(obj))
|
||||
if (CanNeverSee(obj))
|
||||
return false;
|
||||
|
||||
if (obj->IsAlwaysVisibleFor(this) || CanAlwaysSee(obj))
|
||||
@@ -1840,6 +1840,12 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo
|
||||
|
||||
bool WorldObject::CanNeverSee(WorldObject const* obj) const
|
||||
{
|
||||
if (!IsInWorld())
|
||||
return true;
|
||||
|
||||
if (obj->IsNeverVisible())
|
||||
return true;
|
||||
|
||||
if (IsCreature() && obj->IsCreature())
|
||||
return GetMap() != obj->GetMap() || (!InSamePhase(obj) && ToUnit()->GetVehicleBase() != obj && this != obj->ToUnit()->GetVehicleBase());
|
||||
return GetMap() != obj->GetMap() || !InSamePhase(obj);
|
||||
|
||||
@@ -66,6 +66,10 @@ void ObjectVisibilityContainer::LinkWorldObjectVisibility(WorldObject* worldObje
|
||||
if (worldObject == _selfObject)
|
||||
return;
|
||||
|
||||
// Transports are special and should not be added to our visibility map
|
||||
if (worldObject->IsGameObject() && worldObject->ToGameObject()->IsTransport())
|
||||
return;
|
||||
|
||||
// Only players can link visibility
|
||||
if (!_visibleWorldObjectsMap)
|
||||
return;
|
||||
|
||||
@@ -4552,6 +4552,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
||||
// update visibility
|
||||
UpdateObjectVisibility();
|
||||
|
||||
// recast lost by death auras of any items held in the inventory
|
||||
CastAllObtainSpells();
|
||||
|
||||
sScriptMgr->OnPlayerResurrect(this, restore_percent, applySickness);
|
||||
|
||||
if (!applySickness)
|
||||
@@ -6019,6 +6022,7 @@ void Player::RewardReputation(Unit* victim)
|
||||
if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE))
|
||||
{
|
||||
float donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue1), ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
|
||||
sScriptMgr->OnPlayerGiveReputation(this, Rep->RepFaction1, donerep1, REPUTATION_SOURCE_KILL);
|
||||
|
||||
FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
|
||||
if (factionEntry1)
|
||||
@@ -6030,6 +6034,7 @@ void Player::RewardReputation(Unit* victim)
|
||||
if (Rep->RepFaction2 && (!Rep->TeamDependent || teamId == TEAM_HORDE))
|
||||
{
|
||||
float donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue2), ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
|
||||
sScriptMgr->OnPlayerGiveReputation(this, Rep->RepFaction2, donerep2, REPUTATION_SOURCE_KILL);
|
||||
|
||||
FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
|
||||
if (factionEntry2)
|
||||
@@ -6069,22 +6074,27 @@ void Player::RewardReputation(Quest const* quest)
|
||||
if (quest->IsDaily())
|
||||
{
|
||||
rep = CalculateReputationGain(REPUTATION_SOURCE_DAILY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
|
||||
sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_DAILY_QUEST);
|
||||
}
|
||||
else if (quest->IsWeekly())
|
||||
{
|
||||
rep = CalculateReputationGain(REPUTATION_SOURCE_WEEKLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
|
||||
sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_WEEKLY_QUEST);
|
||||
}
|
||||
else if (quest->IsMonthly())
|
||||
{
|
||||
rep = CalculateReputationGain(REPUTATION_SOURCE_MONTHLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
|
||||
sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_MONTHLY_QUEST);
|
||||
}
|
||||
else if (quest->IsRepeatable())
|
||||
{
|
||||
rep = CalculateReputationGain(REPUTATION_SOURCE_REPEATABLE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
|
||||
sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_REPEATABLE_QUEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
rep = CalculateReputationGain(REPUTATION_SOURCE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
|
||||
sScriptMgr->OnPlayerGiveReputation(this, quest->RewardFactionId[i], rep, REPUTATION_SOURCE_QUEST);
|
||||
}
|
||||
|
||||
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(quest->RewardFactionId[i]))
|
||||
@@ -7028,6 +7038,46 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
|
||||
UpdateDamagePhysical(WeaponAttackType(attType));
|
||||
}
|
||||
|
||||
void Player::CastAllObtainSpells()
|
||||
{
|
||||
for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot)
|
||||
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
|
||||
ApplyItemObtainSpells(item, true);
|
||||
|
||||
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||
{
|
||||
Bag* bag = GetBagByPos(i);
|
||||
if (!bag)
|
||||
continue;
|
||||
|
||||
for (uint32 slot = 0; slot < bag->GetBagSize(); ++slot)
|
||||
if (Item* item = bag->GetItemByPos(slot))
|
||||
ApplyItemObtainSpells(item, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::ApplyItemObtainSpells(Item* item, bool apply)
|
||||
{
|
||||
ItemTemplate const* itemTemplate = item->GetTemplate();
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||
{
|
||||
if (itemTemplate->Spells[i].SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) // On obtain trigger
|
||||
continue;
|
||||
|
||||
int32 const spellId = itemTemplate->Spells[i].SpellId;
|
||||
if (spellId <= 0)
|
||||
continue;
|
||||
|
||||
if (apply)
|
||||
{
|
||||
if (!HasAura(spellId))
|
||||
CastSpell(this, spellId, true, item);
|
||||
}
|
||||
else
|
||||
RemoveAurasDueToSpell(spellId);
|
||||
}
|
||||
}
|
||||
|
||||
SpellSchoolMask Player::GetMeleeDamageSchoolMask(WeaponAttackType attackType /*= BASE_ATTACK*/, uint8 damageIndex /*= 0*/) const
|
||||
{
|
||||
if (Item const* weapon = GetWeaponForAttack(attackType, true))
|
||||
|
||||
@@ -235,17 +235,6 @@ enum ActionButtonType
|
||||
ACTION_BUTTON_ITEM = 0x80
|
||||
};
|
||||
|
||||
enum ReputationSource
|
||||
{
|
||||
REPUTATION_SOURCE_KILL,
|
||||
REPUTATION_SOURCE_QUEST,
|
||||
REPUTATION_SOURCE_DAILY_QUEST,
|
||||
REPUTATION_SOURCE_WEEKLY_QUEST,
|
||||
REPUTATION_SOURCE_MONTHLY_QUEST,
|
||||
REPUTATION_SOURCE_REPEATABLE_QUEST,
|
||||
REPUTATION_SOURCE_SPELL
|
||||
};
|
||||
|
||||
enum QuestSound
|
||||
{
|
||||
QUEST_SOUND_FAILURE = 847
|
||||
@@ -1682,7 +1671,7 @@ public:
|
||||
|
||||
bool RemoveMItem(ObjectGuid::LowType itemLowGuid)
|
||||
{
|
||||
return !!mMitems.erase(itemLowGuid);
|
||||
return mMitems.erase(itemLowGuid);
|
||||
}
|
||||
|
||||
void PetSpellInitialize();
|
||||
@@ -2208,6 +2197,9 @@ public:
|
||||
|
||||
void ResetAllPowers();
|
||||
|
||||
void CastAllObtainSpells();
|
||||
void ApplyItemObtainSpells(Item* item, bool apply);
|
||||
|
||||
SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const override;
|
||||
|
||||
void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply);
|
||||
@@ -2632,8 +2624,8 @@ public:
|
||||
std::string GetPlayerName();
|
||||
|
||||
// Settings
|
||||
[[nodiscard]] PlayerSetting GetPlayerSetting(std::string const& source, uint8 index);
|
||||
void UpdatePlayerSetting(std::string const& source, uint8 index, uint32 value);
|
||||
[[nodiscard]] PlayerSetting GetPlayerSetting(std::string const& source, uint32 index);
|
||||
void UpdatePlayerSetting(std::string const& source, uint32 index, uint32 value);
|
||||
|
||||
void SendSystemMessage(std::string_view msg, bool escapeCharacters = false);
|
||||
|
||||
|
||||
@@ -18,11 +18,95 @@
|
||||
#include "Player.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "CharacterDatabase.h"
|
||||
|
||||
/*********************************************************/
|
||||
/*** PLAYER SETTINGS SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
namespace PlayerSettingsStore
|
||||
{
|
||||
// Common helper: parse space-separated data string into PlayerSettingVector
|
||||
PlayerSettingVector ParseSettingsData(std::string const& data)
|
||||
{
|
||||
PlayerSettingVector result;
|
||||
std::vector<std::string_view> tokens = Acore::Tokenize(data, ' ', false);
|
||||
result.reserve(tokens.size());
|
||||
for (auto const& token : tokens)
|
||||
{
|
||||
if (token.empty())
|
||||
continue;
|
||||
if (auto parsed = Acore::StringTo<uint32>(token))
|
||||
result.emplace_back(*parsed);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Common helper: serialize PlayerSettingVector to space-separated string
|
||||
std::string SerializeSettingsData(PlayerSettingVector const& settings)
|
||||
{
|
||||
if (settings.empty())
|
||||
return "";
|
||||
|
||||
std::ostringstream data;
|
||||
data << settings[0].value;
|
||||
for (size_t i = 1; i < settings.size(); ++i)
|
||||
data << ' ' << settings[i].value;
|
||||
return data.str();
|
||||
}
|
||||
|
||||
// helper: load a single source row for a player and parse to vector
|
||||
static PlayerSettingVector LoadPlayerSettings(uint32 playerLowGuid, std::string const& source)
|
||||
{
|
||||
PlayerSettingVector result;
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_SETTINGS);
|
||||
stmt->SetData(0, playerLowGuid);
|
||||
PreparedQueryResult dbRes = CharacterDatabase.Query(stmt);
|
||||
if (!dbRes)
|
||||
return result;
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = dbRes->Fetch();
|
||||
std::string rowSource = fields[0].Get<std::string>();
|
||||
if (rowSource != source)
|
||||
continue;
|
||||
|
||||
std::string data = fields[1].Get<std::string>();
|
||||
return ParseSettingsData(data);
|
||||
} while (dbRes->NextRow());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint32 index, uint32 value)
|
||||
{
|
||||
if (!sWorld->getBoolConfig(CONFIG_PLAYER_SETTINGS_ENABLED))
|
||||
return;
|
||||
|
||||
PlayerSettingVector settings = LoadPlayerSettings(playerLowGuid, source);
|
||||
size_t const requiredSize = static_cast<size_t>(index) + 1;
|
||||
if (settings.size() < requiredSize)
|
||||
settings.resize(requiredSize); // zero-initialized PlayerSetting::value
|
||||
|
||||
settings[index].value = value;
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = PlayerSettingsStore::PrepareReplaceStatement(playerLowGuid, source, settings);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of PrepareReplaceStatement
|
||||
CharacterDatabasePreparedStatement* PlayerSettingsStore::PrepareReplaceStatement(uint32 playerLowGuid, std::string const& source, PlayerSettingVector const& settings)
|
||||
{
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_SETTINGS);
|
||||
stmt->SetData(0, playerLowGuid);
|
||||
stmt->SetData(1, source);
|
||||
stmt->SetData(2, SerializeSettingsData(settings));
|
||||
return stmt;
|
||||
}
|
||||
|
||||
void Player::_LoadCharacterSettings(PreparedQueryResult result)
|
||||
{
|
||||
m_charSettingsMap.clear();
|
||||
@@ -39,27 +123,13 @@ void Player::_LoadCharacterSettings(PreparedQueryResult result)
|
||||
std::string source = fields[0].Get<std::string>();
|
||||
std::string data = fields[1].Get<std::string>();
|
||||
|
||||
std::vector<std::string_view> tokens = Acore::Tokenize(data, ' ', false);
|
||||
|
||||
PlayerSettingVector settings;
|
||||
settings.reserve(tokens.size()); // reserve capacity but don't resize
|
||||
|
||||
for (auto const& token : tokens)
|
||||
{
|
||||
if (token.empty())
|
||||
continue;
|
||||
|
||||
// Try to parse the value safely
|
||||
if (auto parsed = Acore::StringTo<uint32>(token))
|
||||
settings.emplace_back(*parsed);
|
||||
}
|
||||
|
||||
PlayerSettingVector settings = PlayerSettingsStore::ParseSettingsData(data);
|
||||
m_charSettingsMap.emplace(std::move(source), std::move(settings));
|
||||
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
PlayerSetting Player::GetPlayerSetting(std::string const& source, uint8 index)
|
||||
PlayerSetting Player::GetPlayerSetting(std::string const& source, uint32 index)
|
||||
{
|
||||
auto it = m_charSettingsMap.find(source);
|
||||
if (it == m_charSettingsMap.end() || static_cast<size_t>(index) >= it->second.size())
|
||||
@@ -81,21 +151,12 @@ void Player::_SavePlayerSettings(CharacterDatabaseTransaction trans)
|
||||
if (settings.empty())
|
||||
continue;
|
||||
|
||||
std::ostringstream data;
|
||||
data << settings[0].value;
|
||||
|
||||
for (size_t i = 1; i < settings.size(); ++i)
|
||||
data << ' ' << settings[i].value;
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_SETTINGS);
|
||||
stmt->SetData(0, GetGUID().GetCounter());
|
||||
stmt->SetData(1, source);
|
||||
stmt->SetData(2, data.str());
|
||||
CharacterDatabasePreparedStatement* stmt = PlayerSettingsStore::PrepareReplaceStatement(GetGUID().GetCounter(), source, settings);
|
||||
trans->Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::UpdatePlayerSetting(std::string const& source, uint8 index, uint32 value)
|
||||
void Player::UpdatePlayerSetting(std::string const& source, uint32 index, uint32 value)
|
||||
{
|
||||
auto it = m_charSettingsMap.find(source);
|
||||
size_t const requiredSize = static_cast<size_t>(index) + 1;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#ifndef _PLAYER_SETTINGS_H
|
||||
#define _PLAYER_SETTINGS_H
|
||||
#include "DatabaseEnvFwd.h"
|
||||
|
||||
class Player;
|
||||
|
||||
@@ -51,4 +52,18 @@ struct PlayerSetting
|
||||
typedef std::vector<PlayerSetting> PlayerSettingVector;
|
||||
typedef std::map<std::string, PlayerSettingVector> PlayerSettingMap;
|
||||
|
||||
// Standalone API: update a player's setting directly on DB by GUID (low part) without requiring a Player instance
|
||||
namespace PlayerSettingsStore
|
||||
{
|
||||
// Update a single setting value for any player by GUID (works for online or offline players).
|
||||
// This reads the existing "source" row from character_settings, adjusts the index, and REPLACE's it back.
|
||||
void UpdateSetting(uint32 playerLowGuid, std::string const& source, uint32 index, uint32 value);
|
||||
|
||||
// Common helpers for parsing and serializing settings data
|
||||
PlayerSettingVector ParseSettingsData(std::string const& data);
|
||||
std::string SerializeSettingsData(PlayerSettingVector const& settings);
|
||||
// Prepare a REPLACE statement populated with given settings data. Caller may execute or append to a transaction.
|
||||
CharacterDatabasePreparedStatement* PrepareReplaceStatement(uint32 playerLowGuid, std::string const& source, PlayerSettingVector const& settings);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2577,8 +2577,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update)
|
||||
return nullptr;
|
||||
|
||||
Item* lastItem = pItem;
|
||||
ItemTemplate const* proto = pItem->GetTemplate();
|
||||
|
||||
for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end();)
|
||||
{
|
||||
uint16 pos = itr->pos;
|
||||
@@ -2595,13 +2593,6 @@ Item* Player::StoreItem(ItemPosCountVec const& dest, Item* pItem, bool update)
|
||||
lastItem = _StoreItem(pos, pItem, count, true, update);
|
||||
}
|
||||
|
||||
// cast after item storing - some checks in checkcast requires item to be present!!
|
||||
if (lastItem)
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||
if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger
|
||||
if (!HasAura(proto->Spells[i].SpellId))
|
||||
CastSpell(this, proto->Spells[i].SpellId, true, lastItem);
|
||||
|
||||
return lastItem;
|
||||
}
|
||||
|
||||
@@ -2664,6 +2655,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
|
||||
AddEnchantmentDurations(pItem);
|
||||
AddItemDurations(pItem);
|
||||
|
||||
if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END))
|
||||
ApplyItemObtainSpells(pItem, true);
|
||||
|
||||
return pItem;
|
||||
}
|
||||
else
|
||||
@@ -2700,6 +2694,9 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
|
||||
|
||||
pItem2->SetState(ITEM_CHANGED, this);
|
||||
|
||||
if (bag == INVENTORY_SLOT_BAG_0 || (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END))
|
||||
ApplyItemObtainSpells(pItem2, true);
|
||||
|
||||
return pItem2;
|
||||
}
|
||||
}
|
||||
@@ -3046,10 +3043,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
|
||||
pItem->ClearSoulboundTradeable(this);
|
||||
RemoveTradeableItem(pItem);
|
||||
|
||||
ItemTemplate const* proto = pItem->GetTemplate();
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||
if (proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE && proto->Spells[i].SpellId > 0) // On obtain trigger
|
||||
RemoveAurasDueToSpell(proto->Spells[i].SpellId);
|
||||
ApplyItemObtainSpells(pItem, false);
|
||||
|
||||
ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
|
||||
|
||||
@@ -3102,8 +3096,9 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
|
||||
pBag->RemoveItem(slot, update);
|
||||
|
||||
// Xinef: item is removed, remove loot from storage if any
|
||||
if (proto->HasFlag(ITEM_FLAG_HAS_LOOT))
|
||||
sLootItemStorage->RemoveStoredLoot(pItem->GetGUID());
|
||||
if (ItemTemplate const* proto = pItem->GetTemplate())
|
||||
if (proto->HasFlag(ITEM_FLAG_HAS_LOOT))
|
||||
sLootItemStorage->RemoveStoredLoot(pItem->GetGUID());
|
||||
|
||||
if (IsInWorld() && update)
|
||||
{
|
||||
|
||||
@@ -1646,10 +1646,7 @@ template <>
|
||||
inline void UpdateVisibilityOf_helper(Player* player, GameObject* target,
|
||||
std::vector<Unit*>& /*v*/)
|
||||
{
|
||||
// @HACK: This is to prevent objects like deeprun tram from disappearing
|
||||
// when player moves far from its spawn point while riding it
|
||||
if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT))
|
||||
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
|
||||
player->GetObjectVisibilityContainer().LinkWorldObjectVisibility(target);
|
||||
}
|
||||
|
||||
template <>
|
||||
|
||||
@@ -607,12 +607,12 @@ void MotionTransport::DelayedTeleportTransport()
|
||||
}
|
||||
|
||||
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
|
||||
GetMap()->RemoveFromMap<MotionTransport>(this, false);
|
||||
GetMap()->RemoveFromMap<Transport>(this, false);
|
||||
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
|
||||
SetMap(newMap);
|
||||
|
||||
Relocate(x, y, z, o);
|
||||
GetMap()->AddToMap<MotionTransport>(this);
|
||||
GetMap()->AddToMap<Transport>(this);
|
||||
|
||||
LoadStaticPassengers();
|
||||
}
|
||||
@@ -690,6 +690,40 @@ StaticTransport::~StaticTransport()
|
||||
ASSERT(_passengers.empty());
|
||||
}
|
||||
|
||||
bool StaticTransport::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap)
|
||||
{
|
||||
GameObjectData const* data = sObjectMgr->GetGameObjectData(spawnId);
|
||||
|
||||
if (!data)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Gameobject (GUID: {}) not found in table `gameobject`, can't load. ", spawnId);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 entry = data->id;
|
||||
//uint32 map_id = data->mapid; // already used before call
|
||||
uint32 phaseMask = data->phaseMask;
|
||||
float x = data->posX;
|
||||
float y = data->posY;
|
||||
float z = data->posZ;
|
||||
float ang = data->orientation;
|
||||
|
||||
uint32 animprogress = data->animprogress;
|
||||
GOState go_state = data->go_state;
|
||||
uint32 artKit = data->artKit;
|
||||
|
||||
m_goData = data;
|
||||
m_spawnId = spawnId;
|
||||
|
||||
if (!Create(map->GenerateLowGuid<HighGuid::Transport>(), entry, map, phaseMask, x, y, z, ang, data->rotation, animprogress, go_state, artKit))
|
||||
return false;
|
||||
|
||||
if (addToMap && !GetMap()->AddToMap<Transport>(this))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit)
|
||||
{
|
||||
ASSERT(map);
|
||||
@@ -794,7 +828,6 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m
|
||||
LastUsedScriptID = GetGOInfo()->ScriptId;
|
||||
AIM_Initialize();
|
||||
|
||||
this->setActive(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -929,7 +962,9 @@ void StaticTransport::UpdatePosition(float x, float y, float z, float o)
|
||||
if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case
|
||||
GetMap()->LoadGrid(x, y);
|
||||
|
||||
GetMap()->GameObjectRelocation(this, x, y, z, o); // this also relocates the model
|
||||
Relocate(x, y, z, o);
|
||||
UpdateModelPosition();
|
||||
|
||||
UpdatePassengerPositions();
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
virtual void RemovePassenger(WorldObject* passenger, bool withAll = false) = 0;
|
||||
PassengerSet const& GetPassengers() const { return _passengers; }
|
||||
|
||||
virtual void DelayedUpdate(uint32 /*diff*/) {}
|
||||
|
||||
uint32 GetPathProgress() const { return GetGOValue()->Transport.PathProgress; }
|
||||
void SetPathProgress(uint32 val) { m_goValue.Transport.PathProgress = val; }
|
||||
|
||||
@@ -57,7 +59,7 @@ public:
|
||||
void BuildUpdate(UpdateDataMapType& data_map) override;
|
||||
|
||||
void Update(uint32 diff) override;
|
||||
void DelayedUpdate(uint32 diff);
|
||||
void DelayedUpdate(uint32 diff) override;
|
||||
void UpdatePosition(float x, float y, float z, float o);
|
||||
|
||||
void AddPassenger(WorldObject* passenger, bool withAll = false) override;
|
||||
@@ -115,6 +117,8 @@ public:
|
||||
StaticTransport();
|
||||
~StaticTransport() override;
|
||||
|
||||
bool LoadFromDB(ObjectGuid::LowType guid, Map* map) override { return LoadGameObjectFromDB(guid, map, false); }
|
||||
bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true) override;
|
||||
bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0) override;
|
||||
void CleanupsBeforeDelete(bool finalCleanup = true) override;
|
||||
void BuildUpdate(UpdateDataMapType& data_map) override;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "Player.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SmartAI.h"
|
||||
#include "Spell.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
@@ -4109,8 +4110,8 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi
|
||||
//LOG_DEBUG("entities.unit", "Interrupt spell for unit {}.", GetEntry());
|
||||
Spell* spell = m_currentSpells[spellType];
|
||||
if (spell
|
||||
&& (withDelayed || spell->getState() != SPELL_STATE_DELAYED)
|
||||
&& (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only)
|
||||
&& (withDelayed || spell->getState() != SPELL_STATE_DELAYED)
|
||||
&& (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only)
|
||||
{
|
||||
// for example, do not let self-stun aura interrupt itself
|
||||
if (!spell->IsInterruptable())
|
||||
@@ -4128,6 +4129,15 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi
|
||||
m_currentSpells[spellType] = nullptr;
|
||||
spell->SetReferencedFromCurrent(false);
|
||||
}
|
||||
|
||||
// SAI creatures only
|
||||
// Start chasing victim if they are spell casters (at least one SMC spell) if interrupted/silenced.
|
||||
if (IsCreature())
|
||||
{
|
||||
if (SmartAI* ai = dynamic_cast<SmartAI*>(ToCreature()->AI()))
|
||||
if (ai->CanChaseOnInterrupt())
|
||||
ai->SetCombatMove(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,15 +64,28 @@ void GridObjectLoader::LoadGameObjects(CellGuidSet const& guid_set, Map* map)
|
||||
for (ObjectGuid::LowType const& guid : guid_set)
|
||||
{
|
||||
GameObjectData const* data = sObjectMgr->GetGameObjectData(guid);
|
||||
GameObject* obj = data && sObjectMgr->IsGameObjectStaticTransport(data->id) ? new StaticTransport() : new GameObject();
|
||||
|
||||
if (!obj->LoadFromDB(guid, map))
|
||||
if (data && sObjectMgr->IsGameObjectStaticTransport(data->id))
|
||||
{
|
||||
delete obj;
|
||||
continue;
|
||||
}
|
||||
StaticTransport* transport = new StaticTransport();
|
||||
|
||||
AddObjectHelper<GameObject>(map, obj);
|
||||
// Special case for static transports - we are loaded via grids
|
||||
// but we do not want to actually be stored in the grid
|
||||
if (!transport->LoadGameObjectFromDB(guid, map, true))
|
||||
delete transport;
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject* obj = new GameObject();
|
||||
|
||||
if (!obj->LoadFromDB(guid, map))
|
||||
{
|
||||
delete obj;
|
||||
continue;
|
||||
}
|
||||
|
||||
AddObjectHelper<GameObject>(map, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "LFGMgr.h"
|
||||
#include "Log.h"
|
||||
#include "MapMgr.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
@@ -2059,6 +2060,16 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
|
||||
return GroupJoinBattlegroundResult(bgTemplate->GetBgTypeID());
|
||||
}
|
||||
|
||||
void Group::DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY)
|
||||
{
|
||||
WorldPackets::Misc::MinimapPing minimapPing;
|
||||
minimapPing.SourceGuid = sourceGuid;
|
||||
minimapPing.MapX = mapX;
|
||||
minimapPing.MapY = mapY;
|
||||
|
||||
BroadcastPacket(minimapPing.Write(), true, -1, sourceGuid);
|
||||
}
|
||||
|
||||
//===================================================
|
||||
//============== Roll ===============================
|
||||
//===================================================
|
||||
|
||||
@@ -255,6 +255,8 @@ public:
|
||||
void SetBattlefieldGroup(Battlefield* bf);
|
||||
GroupJoinBattlegroundResult CanJoinBattlegroundQueue(Battleground const* bgTemplate, BattlegroundQueueTypeId bgQueueTypeId, uint32 MinPlayerCount, uint32 MaxPlayerCount, bool isRated, uint32 arenaSlot);
|
||||
|
||||
void DoMinimapPing(ObjectGuid sourceGuid, float mapX, float mapY);
|
||||
|
||||
void ChangeMembersGroup(ObjectGuid guid, uint8 group);
|
||||
void SetTargetIcon(uint8 id, ObjectGuid whoGuid, ObjectGuid targetGuid);
|
||||
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag);
|
||||
|
||||
@@ -1175,6 +1175,10 @@ void WorldSession::HandlePlayerLoginToCharInWorld(Player* pCurrChar)
|
||||
pCurrChar->GetMap()->SendInitTransports(pCurrChar);
|
||||
pCurrChar->GetMap()->SendInitSelf(pCurrChar);
|
||||
pCurrChar->GetMap()->SendZoneDynamicInfo(pCurrChar);
|
||||
|
||||
// If we are logging into an existing player, simply clear visibility references
|
||||
// so player will receive a fresh list of new objects on the next vis update.
|
||||
pCurrChar->GetObjectVisibilityContainer().CleanVisibilityReferences();
|
||||
pCurrChar->UpdateObjectVisibility(false);
|
||||
|
||||
pCurrChar->CleanupChannels();
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "LFGMgr.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "MapMgr.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
@@ -522,24 +523,17 @@ void WorldSession::HandleLootRoll(WorldPacket& recvData)
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData)
|
||||
void WorldSession::HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet)
|
||||
{
|
||||
if (!GetPlayer()->GetGroup())
|
||||
if (!sMapMgr->IsValidMapCoord(GetPlayer()->GetMap()->GetId(), packet.MapX, packet.MapY))
|
||||
return;
|
||||
|
||||
float x, y;
|
||||
recvData >> x;
|
||||
recvData >> y;
|
||||
Group* group = GetPlayer()->GetGroup();
|
||||
|
||||
/** error handling **/
|
||||
/********************/
|
||||
if (!group)
|
||||
return;
|
||||
|
||||
// everything's fine, do it
|
||||
WorldPacket data(MSG_MINIMAP_PING, (8 + 4 + 4));
|
||||
data << GetPlayer()->GetGUID();
|
||||
data << float(x);
|
||||
data << float(y);
|
||||
GetPlayer()->GetGroup()->BroadcastPacket(&data, true, -1, GetPlayer()->GetGUID());
|
||||
group->DoMinimapPing(GetPlayer()->GetGUID(), packet.MapX, packet.MapY);
|
||||
}
|
||||
|
||||
void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet)
|
||||
@@ -549,10 +543,8 @@ void WorldSession::HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient&
|
||||
maximum = packet.Max;
|
||||
|
||||
/** error handling **/
|
||||
if (minimum > maximum || maximum > 10000) // < 32768 for urand call
|
||||
{
|
||||
if (minimum > maximum || maximum > sWorld->getIntConfig(CONFIG_RANDOM_ROLL_MAXIMUM))
|
||||
return;
|
||||
}
|
||||
|
||||
GetPlayer()->DoRandomRoll(minimum, maximum);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Opcodes.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "QueryPackets.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
@@ -32,62 +33,55 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid)
|
||||
{
|
||||
CharacterCacheEntry const* playerData = sCharacterCache->GetCharacterCacheByGuid(guid);
|
||||
|
||||
WorldPacket data(SMSG_NAME_QUERY_RESPONSE, (8 + 1 + 1 + 1 + 1 + 1 + 10));
|
||||
data << guid.WriteAsPacked();
|
||||
WorldPackets::Query::NameQueryResponse nameQueryResponse;
|
||||
nameQueryResponse.Guid = guid.WriteAsPacked();
|
||||
if (!playerData)
|
||||
{
|
||||
data << uint8(1); // name unknown
|
||||
SendPacket(&data);
|
||||
nameQueryResponse.NameUnknown = true;
|
||||
SendPacket(nameQueryResponse.Write());
|
||||
return;
|
||||
}
|
||||
|
||||
Player* player = ObjectAccessor::FindConnectedPlayer(guid);
|
||||
|
||||
data << uint8(0); // name known
|
||||
data << playerData->Name; // played name
|
||||
data << uint8(0); // realm name - only set for cross realm interaction (such as Battlegrounds)
|
||||
data << uint8(player ? player->getRace() : playerData->Race);
|
||||
data << uint8(playerData->Sex);
|
||||
data << uint8(playerData->Class);
|
||||
nameQueryResponse.NameUnknown = false;
|
||||
nameQueryResponse.Name = playerData->Name;
|
||||
nameQueryResponse.Race = player ? player->getRace() : playerData->Race;
|
||||
nameQueryResponse.Sex = player ? player->getGender() : playerData->Sex;
|
||||
nameQueryResponse.Class = player ? player->getClass() : playerData->Class;
|
||||
|
||||
// pussywizard: optimization
|
||||
/*Player* player = ObjectAccessor::FindConnectedPlayer(guid);
|
||||
if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr))
|
||||
{
|
||||
data << uint8(1); // Name is declined
|
||||
for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
|
||||
data << names->name[i];
|
||||
nameQueryResponse.Declined = true;
|
||||
nameQueryResponse.DeclinedNames = *names;
|
||||
}
|
||||
else*/
|
||||
data << uint8(0); // Name is not declined
|
||||
else
|
||||
nameQueryResponse.Declined = false;
|
||||
|
||||
SendPacket(&data);
|
||||
SendPacket(nameQueryResponse.Write());
|
||||
}
|
||||
|
||||
void WorldSession::HandleNameQueryOpcode(WorldPacket& recvData)
|
||||
void WorldSession::HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet)
|
||||
{
|
||||
ObjectGuid guid;
|
||||
recvData >> guid;
|
||||
|
||||
// This is disable by default to prevent lots of console spam
|
||||
// LOG_INFO("network.opcode", "HandleNameQueryOpcode {}", guid);
|
||||
|
||||
SendNameQueryOpcode(guid);
|
||||
SendNameQueryOpcode(packet.Guid);
|
||||
}
|
||||
|
||||
void WorldSession::HandleQueryTimeOpcode(WorldPacket& /*recvData*/)
|
||||
void WorldSession::HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& /*packet*/)
|
||||
{
|
||||
SendQueryTimeResponse();
|
||||
SendTimeQueryResponse();
|
||||
}
|
||||
|
||||
void WorldSession::SendQueryTimeResponse()
|
||||
void WorldSession::SendTimeQueryResponse()
|
||||
{
|
||||
auto timeResponse = sWorld->GetNextDailyQuestsResetTime() - GameTime::GetGameTime();
|
||||
|
||||
WorldPacket data(SMSG_QUERY_TIME_RESPONSE, 4 + 4);
|
||||
data << uint32(GameTime::GetGameTime().count());
|
||||
data << uint32(timeResponse.count());
|
||||
SendPacket(&data);
|
||||
WorldPackets::Query::TimeQueryResponse timeQueryResponse;
|
||||
timeQueryResponse.ServerTime = GameTime::GetGameTime().count();
|
||||
timeQueryResponse.TimeResponse = timeResponse.count();
|
||||
SendPacket(timeQueryResponse.Write());
|
||||
}
|
||||
|
||||
/// Only _static_ data is sent in this packet !!!
|
||||
@@ -402,13 +396,10 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket& recvData)
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleCorpseMapPositionQuery(WorldPacket& recvData)
|
||||
void WorldSession::HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& /*packet*/)
|
||||
{
|
||||
LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY");
|
||||
|
||||
uint32 unk;
|
||||
recvData >> unk;
|
||||
|
||||
WorldPacket data(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, 4 + 4 + 4 + 4);
|
||||
data << float(0);
|
||||
data << float(0);
|
||||
|
||||
@@ -172,7 +172,7 @@ void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket& /*recv_data*/)
|
||||
|
||||
void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket& /*recv_data*/)
|
||||
{
|
||||
SendQueryTimeResponse();
|
||||
SendTimeQueryResponse();
|
||||
|
||||
if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
|
||||
{
|
||||
|
||||
@@ -345,7 +345,7 @@ bool Map::AddToMap(T* obj, bool checkTransport)
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
|
||||
bool Map::AddToMap(Transport* obj, bool /*checkTransport*/)
|
||||
{
|
||||
//TODO: Needs clean up. An object should not be added to map twice.
|
||||
if (obj->IsInWorld())
|
||||
@@ -360,26 +360,22 @@ bool Map::AddToMap(MotionTransport* obj, bool /*checkTransport*/)
|
||||
}
|
||||
|
||||
Cell cell(cellCoord);
|
||||
if (obj->isActiveObject())
|
||||
EnsureGridLoaded(cell);
|
||||
EnsureGridLoaded(cell);
|
||||
|
||||
obj->AddToWorld();
|
||||
|
||||
_transports.insert(obj);
|
||||
|
||||
// Broadcast creation to players
|
||||
if (!GetPlayers().IsEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
{
|
||||
for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
|
||||
if (itr->GetSource()->GetTransport() != obj)
|
||||
{
|
||||
if (itr->GetSource()->GetTransport() != obj)
|
||||
{
|
||||
UpdateData data;
|
||||
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
|
||||
WorldPacket packet;
|
||||
data.BuildPacket(packet);
|
||||
itr->GetSource()->SendDirectMessage(&packet);
|
||||
}
|
||||
UpdateData data;
|
||||
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
|
||||
WorldPacket packet;
|
||||
data.BuildPacket(packet);
|
||||
itr->GetSource()->SendDirectMessage(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -667,7 +663,7 @@ void Map::RemoveFromMap(T* obj, bool remove)
|
||||
}
|
||||
|
||||
template<>
|
||||
void Map::RemoveFromMap(MotionTransport* obj, bool remove)
|
||||
void Map::RemoveFromMap(Transport* obj, bool remove)
|
||||
{
|
||||
obj->RemoveFromWorld();
|
||||
|
||||
@@ -697,8 +693,6 @@ void Map::RemoveFromMap(MotionTransport* obj, bool remove)
|
||||
|
||||
obj->ResetMap();
|
||||
|
||||
// Transports are never actually deleted, but it *should* be safe to clear
|
||||
// from update list when removing from world
|
||||
RemoveObjectFromMapUpdateList(obj);
|
||||
|
||||
if (remove)
|
||||
@@ -966,11 +960,10 @@ void Map::UnloadAll()
|
||||
|
||||
for (TransportsContainer::iterator itr = _transports.begin(); itr != _transports.end();)
|
||||
{
|
||||
MotionTransport* transport = *itr;
|
||||
Transport* transport = *itr;
|
||||
++itr;
|
||||
|
||||
transport->RemoveFromWorld();
|
||||
delete transport;
|
||||
RemoveFromMap<Transport>(transport, true);
|
||||
}
|
||||
|
||||
_transports.clear();
|
||||
@@ -1589,6 +1582,9 @@ void Map::SendInitSelf(Player* player)
|
||||
|
||||
void Map::SendInitTransports(Player* player)
|
||||
{
|
||||
if (_transports.empty())
|
||||
return;
|
||||
|
||||
// Hack to send out transports
|
||||
UpdateData transData;
|
||||
for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr)
|
||||
@@ -1605,24 +1601,15 @@ void Map::SendInitTransports(Player* player)
|
||||
|
||||
void Map::SendRemoveTransports(Player* player)
|
||||
{
|
||||
if (_transports.empty())
|
||||
return;
|
||||
|
||||
// Hack to send out transports
|
||||
UpdateData transData;
|
||||
for (TransportsContainer::const_iterator itr = _transports.begin(); itr != _transports.end(); ++itr)
|
||||
if (*itr != player->GetTransport())
|
||||
(*itr)->BuildOutOfRangeUpdateBlock(&transData);
|
||||
|
||||
// pussywizard: remove static transports from client
|
||||
/*for (GuidUnorderedSet::const_iterator it = player->m_clientGUIDs.begin(); it != player->m_clientGUIDs.end(); )
|
||||
{
|
||||
if ((*it).IsTransport())
|
||||
{
|
||||
transData.AddOutOfRangeGUID(*it);
|
||||
it = player->m_clientGUIDs.erase(it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}*/
|
||||
|
||||
if (!transData.HasData())
|
||||
return;
|
||||
|
||||
@@ -1699,7 +1686,7 @@ void Map::DelayedUpdate(const uint32 t_diff)
|
||||
{
|
||||
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();)
|
||||
{
|
||||
MotionTransport* transport = *_transportsUpdateIter;
|
||||
Transport* transport = *_transportsUpdateIter;
|
||||
++_transportsUpdateIter;
|
||||
|
||||
if (!transport->IsInWorld())
|
||||
@@ -1744,7 +1731,7 @@ void Map::RemoveAllObjectsInRemoveList()
|
||||
RemoveFromMap((DynamicObject*)obj, true);
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
if (MotionTransport* transport = obj->ToGameObject()->ToMotionTransport())
|
||||
if (Transport* transport = obj->ToGameObject()->ToTransport())
|
||||
RemoveFromMap(transport, true);
|
||||
else
|
||||
RemoveFromMap(obj->ToGameObject(), true);
|
||||
|
||||
@@ -146,7 +146,7 @@ struct ZoneDynamicInfo
|
||||
|
||||
typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType;
|
||||
typedef std::unordered_map<uint32 /*zoneId*/, ZoneDynamicInfo> ZoneDynamicInfoMap;
|
||||
typedef std::set<MotionTransport*> TransportsContainer;
|
||||
typedef std::unordered_set<Transport*> TransportsContainer;
|
||||
|
||||
enum EncounterCreditType : uint8
|
||||
{
|
||||
@@ -479,7 +479,7 @@ public:
|
||||
_updateObjects.erase(obj);
|
||||
}
|
||||
|
||||
size_t GetUpdateObjectsCount() const { return _updateObjects.size(); }
|
||||
size_t GetUpdatableObjectsCount() const { return _updatableObjectList.size(); }
|
||||
|
||||
virtual std::string GetDebugInfo() const;
|
||||
|
||||
@@ -535,7 +535,6 @@ protected:
|
||||
MapRefMgr m_mapRefMgr;
|
||||
MapRefMgr::iterator m_mapRefIter;
|
||||
|
||||
// Objects that must update even in inactive grids without activating them
|
||||
TransportsContainer _transports;
|
||||
TransportsContainer::iterator _transportsUpdateIter;
|
||||
|
||||
|
||||
@@ -412,10 +412,8 @@ MotionTransport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType
|
||||
if (map && map->IsDungeon())
|
||||
trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript();
|
||||
|
||||
// xinef: transports are active so passengers can be relocated (grids must be loaded)
|
||||
trans->setActive(true);
|
||||
HashMapHolder<MotionTransport>::Insert(trans);
|
||||
trans->GetMap()->AddToMap<MotionTransport>(trans);
|
||||
trans->GetMap()->AddToMap<Transport>(trans);
|
||||
return trans;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,11 @@ void ScriptMgr::OnPlayerReputationRankChange(Player* player, uint32 factionID, R
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_REPUTATION_RANK_CHANGE, script->OnPlayerReputationRankChange(player, factionID, newRank, oldRank, increased));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerGiveReputation(Player* player, int32 factionID, float& amount, ReputationSource repSource)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_GIVE_REPUTATION, script->OnPlayerGiveReputation(player, factionID, amount, repSource));
|
||||
}
|
||||
|
||||
void ScriptMgr::OnPlayerLearnSpell(Player* player, uint32 spellID)
|
||||
{
|
||||
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_LEARN_SPELL, script->OnPlayerLearnSpell(player, spellID));
|
||||
|
||||
@@ -211,6 +211,7 @@ enum PlayerHook
|
||||
PLAYERHOOK_CAN_RESURRECT,
|
||||
PLAYERHOOK_ON_CAN_GIVE_LEVEL,
|
||||
PLAYERHOOK_ON_SEND_LIST_INVENTORY,
|
||||
PLAYERHOOK_ON_GIVE_REPUTATION,
|
||||
PLAYERHOOK_END
|
||||
};
|
||||
|
||||
@@ -285,6 +286,9 @@ public:
|
||||
// Called when a player's reputation rank changes (before it is actually changed)
|
||||
virtual void OnPlayerReputationRankChange(Player* /*player*/, uint32 /*factionID*/, ReputationRank /*newRank*/, ReputationRank /*olRank*/, bool /*increased*/) { }
|
||||
|
||||
// Called when a player gains Reputation (before anything is given)
|
||||
virtual void OnPlayerGiveReputation(Player* /*player*/, int32 /*factionID*/, float& /*amount*/, ReputationSource /*repSource*/) { }
|
||||
|
||||
// Called when a player learned new spell
|
||||
virtual void OnPlayerLearnSpell(Player* /*player*/, uint32 /*spellID*/) {}
|
||||
|
||||
|
||||
@@ -334,6 +334,7 @@ public: /* PlayerScript */
|
||||
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource);
|
||||
bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
|
||||
void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased);
|
||||
void OnPlayerGiveReputation(Player* player, int32 factionID, float& amount, ReputationSource repSource);
|
||||
void OnPlayerLearnSpell(Player* player, uint32 spellID);
|
||||
void OnPlayerForgotSpell(Player* player, uint32 spellID);
|
||||
void OnPlayerDuelRequest(Player* target, Player* challenger);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "LFGPackets.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "PetPackets.h"
|
||||
#include "QueryPackets.h"
|
||||
#include "TotemPackets.h"
|
||||
#include "WorldStatePackets.h"
|
||||
|
||||
|
||||
@@ -67,6 +67,21 @@ WorldPacket const* WorldPackets::Misc::Playsound::Write()
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
void WorldPackets::Misc::MinimapPingClient::Read()
|
||||
{
|
||||
_worldPacket >> MapX;
|
||||
_worldPacket >> MapY;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::Misc::MinimapPing::Write()
|
||||
{
|
||||
_worldPacket << SourceGuid;
|
||||
_worldPacket << float(MapX);
|
||||
_worldPacket << float(MapY);
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
void WorldPackets::Misc::RandomRollClient::Read()
|
||||
{
|
||||
_worldPacket >> Min;
|
||||
|
||||
@@ -93,6 +93,29 @@ namespace WorldPackets
|
||||
uint32 SoundKitID = 0;
|
||||
};
|
||||
|
||||
class MinimapPingClient final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
MinimapPingClient(WorldPacket&& packet) : ClientPacket(MSG_MINIMAP_PING, std::move(packet)) {}
|
||||
|
||||
void Read() override;
|
||||
|
||||
float MapX = 0.0f; // Raw position coordinates
|
||||
float MapY = 0.0f;
|
||||
};
|
||||
|
||||
class MinimapPing final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
MinimapPing() : ServerPacket(MSG_MINIMAP_PING, 8 + 4 + 4) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
ObjectGuid SourceGuid;
|
||||
float MapX = 0.0f;
|
||||
float MapY = 0.0f;
|
||||
};
|
||||
|
||||
class RandomRollClient final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "QueryPackets.h"
|
||||
|
||||
void WorldPackets::Query::NameQuery::Read()
|
||||
{
|
||||
_worldPacket >> Guid;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::Query::NameQueryResponse::Write()
|
||||
{
|
||||
_worldPacket << Guid;
|
||||
_worldPacket << NameUnknown;
|
||||
if (NameUnknown)
|
||||
return &_worldPacket;
|
||||
|
||||
_worldPacket << Name;
|
||||
_worldPacket << RealmName;
|
||||
_worldPacket << Race;
|
||||
_worldPacket << Sex;
|
||||
_worldPacket << Class;
|
||||
_worldPacket << Declined;
|
||||
if (Declined)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
|
||||
_worldPacket << DeclinedNames.name[i];
|
||||
}
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::Query::TimeQueryResponse::Write()
|
||||
{
|
||||
_worldPacket << ServerTime;
|
||||
_worldPacket << TimeResponse;
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
void WorldPackets::Query::CorpseMapPositionQuery::Read()
|
||||
{
|
||||
_worldPacket >> unk;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QueryPackets_h__
|
||||
#define QueryPackets_h__
|
||||
|
||||
#include "Packet.h"
|
||||
#include "Unit.h"
|
||||
|
||||
namespace WorldPackets
|
||||
{
|
||||
namespace Query
|
||||
{
|
||||
class NameQuery final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
NameQuery(WorldPacket&& packet) : ClientPacket(CMSG_NAME_QUERY, std::move(packet)) {}
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid Guid;
|
||||
};
|
||||
|
||||
class NameQueryResponse final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
NameQueryResponse() : ServerPacket(SMSG_NAME_QUERY_RESPONSE, 8 + 1 + 1 + 1 + 1 + 1 + 10) {}
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
PackedGuid Guid;
|
||||
uint8 NameUnknown = false;
|
||||
std::string_view Name;
|
||||
std::string_view RealmName = ""; // Only set for cross realm interaction (such as Battlegrounds)
|
||||
uint8 Race = RACE_NONE;
|
||||
uint8 Sex = GENDER_MALE;
|
||||
uint8 Class = CLASS_NONE;
|
||||
uint8 Declined = false;
|
||||
DeclinedName DeclinedNames;
|
||||
};
|
||||
|
||||
class TimeQuery final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
TimeQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUERY_TIME, std::move(packet)) {}
|
||||
|
||||
void Read() override {};
|
||||
};
|
||||
|
||||
class TimeQueryResponse final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
TimeQueryResponse() : ServerPacket(SMSG_QUERY_TIME_RESPONSE, 4 + 4) {}
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
uint32 ServerTime;
|
||||
uint32 TimeResponse;
|
||||
};
|
||||
|
||||
class CorpseMapPositionQuery final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
CorpseMapPositionQuery(WorldPacket&& packet) : ClientPacket(CMSG_CORPSE_MAP_POSITION_QUERY, std::move(packet)) {}
|
||||
|
||||
void Read() override;
|
||||
|
||||
uint32 unk;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QueryPackets_h__
|
||||
@@ -590,7 +590,7 @@ void OpcodeTable::Initialize()
|
||||
/*0x1CB*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_NEVER);
|
||||
/*0x1CC*/ DEFINE_HANDLER(CMSG_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePlayedTime );
|
||||
/*0x1CD*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER);
|
||||
/*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQueryTimeOpcode );
|
||||
/*0x1CE*/ DEFINE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeQueryOpcode );
|
||||
/*0x1CF*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER);
|
||||
/*0x1D0*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_NEVER);
|
||||
/*0x1D1*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURACASTLOG, STATUS_NEVER);
|
||||
|
||||
@@ -148,6 +148,7 @@ namespace WorldPackets
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
class MinimapPingClient;
|
||||
class RandomRollClient;
|
||||
}
|
||||
|
||||
@@ -159,6 +160,13 @@ namespace WorldPackets
|
||||
class PetSpellAutocast;
|
||||
class RequestPetInfo;
|
||||
}
|
||||
|
||||
namespace Query
|
||||
{
|
||||
class NameQuery;
|
||||
class TimeQuery;
|
||||
class CorpseMapPositionQuery;
|
||||
}
|
||||
}
|
||||
|
||||
enum AccountDataType
|
||||
@@ -389,7 +397,7 @@ public:
|
||||
}
|
||||
|
||||
void SendSetPhaseShift(uint32 phaseShift);
|
||||
void SendQueryTimeResponse();
|
||||
void SendTimeQueryResponse();
|
||||
|
||||
void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0);
|
||||
void SendClientCacheVersion(uint32 version);
|
||||
@@ -680,9 +688,9 @@ public: // opcodes handlers
|
||||
void HandleGameObjectUseOpcode(WorldPacket& recPacket);
|
||||
void HandleGameobjectReportUse(WorldPacket& recvPacket);
|
||||
|
||||
void HandleNameQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleNameQueryOpcode(WorldPackets::Query::NameQuery& packet);
|
||||
|
||||
void HandleQueryTimeOpcode(WorldPacket& recvPacket);
|
||||
void HandleTimeQueryOpcode(WorldPackets::Query::TimeQuery& packet);
|
||||
|
||||
void HandleCreatureQueryOpcode(WorldPacket& recvPacket);
|
||||
|
||||
@@ -882,7 +890,7 @@ public: // opcodes handlers
|
||||
|
||||
void HandleReclaimCorpseOpcode(WorldPacket& recvPacket);
|
||||
void HandleCorpseQueryOpcode(WorldPacket& recvPacket);
|
||||
void HandleCorpseMapPositionQuery(WorldPacket& recvPacket);
|
||||
void HandleCorpseMapPositionQuery(WorldPackets::Query::CorpseMapPositionQuery& packet);
|
||||
void HandleResurrectResponseOpcode(WorldPacket& recvPacket);
|
||||
void HandleSummonResponseOpcode(WorldPacket& recvData);
|
||||
|
||||
@@ -953,7 +961,7 @@ public: // opcodes handlers
|
||||
|
||||
void HandleWardenDataOpcode(WorldPacket& recvData);
|
||||
void HandleWorldTeleportOpcode(WorldPacket& recvData);
|
||||
void HandleMinimapPingOpcode(WorldPacket& recvData);
|
||||
void HandleMinimapPingOpcode(WorldPackets::Misc::MinimapPingClient& packet);
|
||||
void HandleRandomRollOpcode(WorldPackets::Misc::RandomRollClient& packet);
|
||||
void HandleFarSightOpcode(WorldPacket& recvData);
|
||||
void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData);
|
||||
|
||||
@@ -492,6 +492,8 @@ void WorldConfig::BuildConfigCache()
|
||||
|
||||
SetConfigValue<bool>(CONFIG_LEAVE_GROUP_ON_LOGOUT, "LeaveGroupOnLogout.Enabled", false);
|
||||
|
||||
SetConfigValue<uint32>(CONFIG_RANDOM_ROLL_MAXIMUM, "Group.RandomRollMaximum", 1000000);
|
||||
|
||||
SetConfigValue<bool>(CONFIG_QUEST_POI_ENABLED, "QuestPOI.Enabled", true);
|
||||
|
||||
SetConfigValue<uint32>(CONFIG_CHANGE_FACTION_MAX_MONEY, "ChangeFaction.MaxMoney", 0);
|
||||
|
||||
@@ -129,6 +129,7 @@ enum ServerConfigs
|
||||
CONFIG_ALLOW_JOIN_BG_AND_LFG,
|
||||
CONFIG_MISS_CHANCE_MULTIPLIER_ONLY_FOR_PLAYERS,
|
||||
CONFIG_LEAVE_GROUP_ON_LOGOUT,
|
||||
CONFIG_RANDOM_ROLL_MAXIMUM,
|
||||
CONFIG_QUEST_POI_ENABLED,
|
||||
CONFIG_VMAP_BLIZZLIKE_PVP_LOS,
|
||||
CONFIG_VMAP_BLIZZLIKE_LOS_OPEN_WORLD,
|
||||
|
||||
Reference in New Issue
Block a user