mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-24 14:16:31 +00:00
Merge branch 'master' into Playerbot
This commit is contained in:
@@ -335,21 +335,22 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u
|
||||
|
||||
if (IsInstanceGameobject())
|
||||
{
|
||||
switch (GetStateSavedOnInstance())
|
||||
if (InstanceScript* instance = GetInstanceScript())
|
||||
{
|
||||
case 0:
|
||||
SetGoState(GO_STATE_READY);
|
||||
SwitchDoorOrButton(true);
|
||||
break;
|
||||
case 1:
|
||||
SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case 2:
|
||||
SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
|
||||
break;
|
||||
default:
|
||||
SetGoState(go_state);
|
||||
break;
|
||||
switch (uint8 state = instance->GetStoredGameObjectState(GetSpawnId()))
|
||||
{
|
||||
case 0:
|
||||
SetGoState(GO_STATE_READY);
|
||||
SwitchDoorOrButton(true);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
SetGoState((GOState)state);
|
||||
break;
|
||||
default:
|
||||
SetGoState(go_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2505,21 +2506,13 @@ void GameObject::SetGoState(GOState state)
|
||||
* save it's state on the database to be loaded properly
|
||||
* on server restart or crash.
|
||||
*/
|
||||
if (IsInstanceGameobject() && IsAbleToSaveOnDb())
|
||||
if (IsInstanceGameobject() && IsAllowedToSaveToDB())
|
||||
{
|
||||
// Save the gameobject state on the Database
|
||||
if (!FindStateSavedOnInstance())
|
||||
{
|
||||
SaveInstanceData(GameobjectStateToInt(&state));
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateInstanceData(GameobjectStateToInt(&state));
|
||||
}
|
||||
SaveStateToDB();
|
||||
}
|
||||
}
|
||||
|
||||
bool GameObject::IsInstanceGameobject()
|
||||
bool GameObject::IsInstanceGameobject() const
|
||||
{
|
||||
// Avoid checking for unecessary gameobjects whose
|
||||
// states don't matter for the dungeon progression
|
||||
@@ -2538,7 +2531,7 @@ bool GameObject::IsInstanceGameobject()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameObject::ValidateGameobjectType()
|
||||
bool GameObject::ValidateGameobjectType() const
|
||||
{
|
||||
switch (m_goInfo->type)
|
||||
{
|
||||
@@ -2553,7 +2546,7 @@ bool GameObject::ValidateGameobjectType()
|
||||
}
|
||||
}
|
||||
|
||||
uint8 GameObject::GameobjectStateToInt(GOState* state)
|
||||
uint8 GameObject::GameobjectStateToInt(GOState* state) const
|
||||
{
|
||||
uint8 m_state = 3;
|
||||
|
||||
@@ -2578,71 +2571,24 @@ uint8 GameObject::GameobjectStateToInt(GOState* state)
|
||||
return m_state;
|
||||
}
|
||||
|
||||
bool GameObject::IsAbleToSaveOnDb()
|
||||
{
|
||||
return m_saveStateOnDb;
|
||||
}
|
||||
|
||||
void GameObject::UpdateSaveToDb(bool enable)
|
||||
{
|
||||
m_saveStateOnDb = enable;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
SavingStateOnDB();
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::SavingStateOnDB()
|
||||
void GameObject::SaveStateToDB()
|
||||
{
|
||||
if (IsInstanceGameobject())
|
||||
{
|
||||
GOState param = GetGoState();
|
||||
if (!FindStateSavedOnInstance())
|
||||
if (InstanceScript* instance = GetInstanceScript())
|
||||
{
|
||||
SaveInstanceData(GameobjectStateToInt(¶m));
|
||||
GOState param = GetGoState();
|
||||
instance->StoreGameObjectState(GetSpawnId(), GameobjectStateToInt(¶m));
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INSERT_INSTANCE_SAVED_DATA);
|
||||
stmt->SetData(0, GetInstanceId());
|
||||
stmt->SetData(1, GetSpawnId());
|
||||
stmt->SetData(2, GameobjectStateToInt(¶m));
|
||||
CharacterDatabase.Execute(stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::SaveInstanceData(uint8 state)
|
||||
{
|
||||
uint32 id = GetInstanceId();
|
||||
uint32 guid = GetSpawnId();
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INSERT_INSTANCE_SAVED_DATA);
|
||||
stmt->SetData(0, id);
|
||||
stmt->SetData(1, guid);
|
||||
stmt->SetData(2, state);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
sObjectMgr->NewInstanceSavedGameobjectState(id, guid, state);
|
||||
}
|
||||
|
||||
void GameObject::UpdateInstanceData(uint8 state)
|
||||
{
|
||||
uint32 id = GetInstanceId();
|
||||
uint32 guid = GetSpawnId();
|
||||
|
||||
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_INSTANCE_SAVED_DATA);
|
||||
stmt->SetData(0, state);
|
||||
stmt->SetData(1, guid);
|
||||
stmt->SetData(2, id);
|
||||
CharacterDatabase.Execute(stmt);
|
||||
|
||||
sObjectMgr->SetInstanceSavedGameobjectState(id, guid, state);
|
||||
}
|
||||
|
||||
uint8 GameObject::GetStateSavedOnInstance()
|
||||
{
|
||||
return sObjectMgr->GetInstanceSavedGameobjectState(GetInstanceId(), GetSpawnId());
|
||||
}
|
||||
|
||||
bool GameObject::FindStateSavedOnInstance()
|
||||
{
|
||||
return sObjectMgr->FindInstanceSavedGameobjectState(GetInstanceId(), GetSpawnId());
|
||||
}
|
||||
|
||||
void GameObject::SetDisplayId(uint32 displayid)
|
||||
{
|
||||
SetUInt32Value(GAMEOBJECT_DISPLAYID, displayid);
|
||||
|
||||
@@ -350,25 +350,21 @@ public:
|
||||
|
||||
static std::unordered_map<int, goEventFlag> gameObjectToEventFlag; // Gameobject -> event flag
|
||||
|
||||
void SaveInstanceData(uint8 state);
|
||||
void UpdateInstanceData(uint8 state);
|
||||
bool FindStateSavedOnInstance();
|
||||
bool ValidateGameobjectType();
|
||||
uint8 GetStateSavedOnInstance();
|
||||
bool IsInstanceGameobject();
|
||||
uint8 GameobjectStateToInt(GOState* state);
|
||||
[[nodiscard]] bool ValidateGameobjectType() const;
|
||||
[[nodiscard]] bool IsInstanceGameobject() const;
|
||||
[[nodiscard]] uint8 GameobjectStateToInt(GOState* state) const;
|
||||
|
||||
/* A check to verify if this object is available to be saved on the DB when
|
||||
* a state change occurs
|
||||
*/
|
||||
bool IsAbleToSaveOnDb();
|
||||
[[nodiscard]] bool IsAllowedToSaveToDB() const { return m_saveStateOnDb; };
|
||||
|
||||
/* Enable or Disable the ability to save on the database this gameobject's state
|
||||
* whenever it changes
|
||||
*/
|
||||
void UpdateSaveToDb(bool enable);
|
||||
void AllowSaveToDB(bool enable) { m_saveStateOnDb = enable; };
|
||||
|
||||
void SavingStateOnDB();
|
||||
void SaveStateToDB();
|
||||
|
||||
std::string GetDebugInfo() const override;
|
||||
protected:
|
||||
|
||||
@@ -105,6 +105,14 @@ void Pet::AddToWorld()
|
||||
|
||||
if (GetOwnerGUID().IsPlayer())
|
||||
{
|
||||
if (Player* owner = GetOwner())
|
||||
{
|
||||
if (getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK)
|
||||
{
|
||||
owner->SetLastPetSpell(GetUInt32Value(UNIT_CREATED_BY_SPELL));
|
||||
}
|
||||
}
|
||||
|
||||
sScriptMgr->OnPetAddToWorld(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2524,6 +2524,11 @@ void Player::GiveLevel(uint8 level)
|
||||
sScriptMgr->OnPlayerLevelChanged(this, oldLevel);
|
||||
}
|
||||
|
||||
bool Player::IsMaxLevel() const
|
||||
{
|
||||
return GetLevel() >= GetUInt32Value(PLAYER_FIELD_MAX_LEVEL);
|
||||
}
|
||||
|
||||
void Player::InitTalentForLevel()
|
||||
{
|
||||
uint32 talentPointsForLevel = CalculateTalentsPoints();
|
||||
@@ -14166,24 +14171,21 @@ void Player::ResummonPetTemporaryUnSummonedIfAny()
|
||||
|
||||
bool Player::CanResummonPet(uint32 spellid)
|
||||
{
|
||||
switch (getClass())
|
||||
if (getClass() == CLASS_DEATH_KNIGHT)
|
||||
{
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
if (CanSeeDKPet())
|
||||
return true;
|
||||
else if (spellid == 52150) //Raise Dead
|
||||
return false;
|
||||
break;
|
||||
case CLASS_MAGE:
|
||||
if (HasSpell(31687) && HasAura(70937)) //Has [Summon Water Elemental] spell and [Glyph of Eternal Water].
|
||||
return true;
|
||||
break;
|
||||
case CLASS_HUNTER:
|
||||
case CLASS_WARLOCK:
|
||||
if (CanSeeDKPet())
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
else if (spellid == 52150) // Raise Dead
|
||||
return false;
|
||||
}
|
||||
else if (getClass() == CLASS_MAGE)
|
||||
{
|
||||
if (HasSpell(31687) && HasAura(70937)) //Has [Summon Water Elemental] spell and [Glyph of Eternal Water].
|
||||
return true;
|
||||
}
|
||||
else if (getClass() == CLASS_HUNTER)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return HasSpell(spellid);
|
||||
|
||||
@@ -1686,6 +1686,7 @@ public:
|
||||
void SetFreeTalentPoints(uint32 points);
|
||||
bool resetTalents(bool noResetCost = false);
|
||||
[[nodiscard]] uint32 resetTalentsCost() const;
|
||||
bool IsMaxLevel() const;
|
||||
void InitTalentForLevel();
|
||||
void BuildPlayerTalentsInfoData(WorldPacket* data);
|
||||
void BuildPetTalentsInfoData(WorldPacket* data);
|
||||
|
||||
@@ -2352,7 +2352,7 @@ void Player::SendQuestReward(Quest const* quest, uint32 XP)
|
||||
WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4 + 4 + 4 + 4 + 4));
|
||||
data << uint32(questid);
|
||||
|
||||
if (GetLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
if (!IsMaxLevel())
|
||||
{
|
||||
data << uint32(XP);
|
||||
data << uint32(quest->GetRewOrReqMoney(GetLevel()));
|
||||
|
||||
@@ -4468,19 +4468,12 @@ void Unit::_ApplyAura(AuraApplication* aurApp, uint8 effMask)
|
||||
SpellInfo const* spellInfo = aura->GetSpellInfo();
|
||||
if (AuraStateType aState = spellInfo->GetAuraState())
|
||||
{
|
||||
if (aState != AURA_STATE_CONFLAGRATE)
|
||||
{
|
||||
// Sting (hunter's pet ability), Faerie Fire (druid versions)
|
||||
if (aState == AURA_STATE_FAERIE_FIRE)
|
||||
aurApp->GetTarget()->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
|
||||
|
||||
uint32 aStateMask = (1 << (aState - 1));
|
||||
// force update so the new caster registers it
|
||||
if ((aStateMask & PER_CASTER_AURA_STATE_MASK) && HasFlag(UNIT_FIELD_AURASTATE, aStateMask))
|
||||
ForceValuesUpdateAtIndex(UNIT_FIELD_AURASTATE);
|
||||
else
|
||||
ModifyAuraState(aState, true);
|
||||
}
|
||||
else if (caster)
|
||||
{
|
||||
ConflagrateAuraStateDelayEvent* pEvent = new ConflagrateAuraStateDelayEvent(this, caster->GetGUID());
|
||||
m_Events.AddEvent(pEvent, m_Events.CalculateTime(700)); // intended 700ms delay before allowing to cast conflagrate
|
||||
}
|
||||
}
|
||||
|
||||
if (aurApp->GetRemoveMode())
|
||||
@@ -4575,9 +4568,19 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMo
|
||||
ToTotem()->setDeathState(DeathState::JustDied);
|
||||
}
|
||||
|
||||
// Remove aurastates only if were not found
|
||||
if (!auraStateFound)
|
||||
ModifyAuraState(auraState, false);
|
||||
// Remove aurastates only if needed and were not found
|
||||
if (auraState)
|
||||
{
|
||||
if (!auraStateFound)
|
||||
ModifyAuraState(auraState, false);
|
||||
else
|
||||
{
|
||||
// update for casters, some shouldn't 'see' the aura state
|
||||
uint32 aStateMask = (1 << (auraState - 1));
|
||||
if ((aStateMask & PER_CASTER_AURA_STATE_MASK) != 0)
|
||||
ForceValuesUpdateAtIndex(UNIT_FIELD_AURASTATE);
|
||||
}
|
||||
}
|
||||
|
||||
aura->HandleAuraSpecificMods(aurApp, caster, false, false);
|
||||
|
||||
@@ -20762,16 +20765,6 @@ int32 Unit::CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, Unit* c
|
||||
return damage;
|
||||
}
|
||||
|
||||
bool ConflagrateAuraStateDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
|
||||
{
|
||||
if (m_owner->IsInWorld())
|
||||
if (m_owner->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x4, 0, 0, m_casterGUID) || // immolate
|
||||
m_owner->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0, 0, 0x2, m_casterGUID)) // shadowflame
|
||||
m_owner->ModifyAuraState(AURA_STATE_CONFLAGRATE, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::ExecuteDelayedUnitRelocationEvent()
|
||||
{
|
||||
this->RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
|
||||
@@ -2674,17 +2674,6 @@ namespace Acore
|
||||
};
|
||||
}
|
||||
|
||||
class ConflagrateAuraStateDelayEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
ConflagrateAuraStateDelayEvent(Unit* owner, ObjectGuid casterGUID) : BasicEvent(), m_owner(owner), m_casterGUID(casterGUID) { }
|
||||
bool Execute(uint64 e_time, uint32 p_time) override;
|
||||
|
||||
private:
|
||||
Unit* m_owner;
|
||||
ObjectGuid m_casterGUID;
|
||||
};
|
||||
|
||||
class RedirectSpellEvent : public BasicEvent
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user