<commit_before>/*
Copyright (c) 2014-2019 AscEmu Team <http://www.ascemu.org>
This file is released under the MIT license. See README-MIT for more information.
*/

#include "SpellMgr.h"

#include "Spell/Definitions/AuraEffects.h"
#include "Spell/Definitions/ProcFlags.h"
#include "Spell/Definitions/SpellDamageType.h"
#include "Spell/Definitions/SpellEffects.h"
#include "Spell/Definitions/SpellEffectTarget.h"
#include "Spell/Definitions/SpellFamily.h"

#include "Map/Area/AreaStorage.hpp"
#include "shared/Log.hpp"
#include "Storage/MySQLDataStore.hpp"
#include "Storage/DBC/DBCStores.h"

bool SpellArea::fitsToRequirements(Player* player, uint32_t newZone, uint32_t newArea) const
{
    if (gender != GENDER_NONE)
    {
        if (player == nullptr || gender != player->getGender())
            return false;
    }

    if (raceMask != 0)
    {
        if (player == nullptr || !(raceMask & player->getRaceMask()))
            return false;
    }

    if (areaId != 0)
    {
        if (newZone != areaId && newArea != areaId)
            return false;
    }

    if (questStart != 0)
    {
        if (player == nullptr || !player->HasQuest(questStart))
            return false;
    }

    if (questEnd != 0)
    {
        if (player == nullptr || player->GetQuestRewardStatus(questEnd))
            return false;
    }

    if (auraSpell != 0)
    {
        if (player == nullptr || (auraSpell > 0 && !player->HasAura(auraSpell)) || (auraSpell < 0 && player->HasAura(-auraSpell)))
            return false;
    }

    // Misc Conditions
    switch (spellId)
    {
        case 58600: //Restricted Flight Zone (Dalaran)
        {
            if (player == nullptr)
                return false;

            if (!player->hasAuraWithAuraEffect(SPELL_AURA_ENABLE_FLIGHT2) && !player->hasAuraWithAuraEffect(SPELL_AURA_FLY))
                return false;
            break;
        }
    }

    return true;
}

SpellMgr& SpellMgr::getInstance()
{
    static SpellMgr mInstance;
    return mInstance;
}

void SpellMgr::startSpellMgr()
{
    // Load spell data from DBC
    loadSpellInfoData();

    for (const auto itr : mSpellInfoMapStore)
    {
        auto spellInfo = itr.second;

        // Calculate spell coefficient
        setSpellCoefficient(&spellInfo);

        // Custom values
        // todo: if possible, get rid of these
        setSpellEffectAmplitude(&spellInfo);
        setSpellMeleeSpellBool(&spellInfo);
        setSpellRangedSpellBool(&spellInfo);
        setSpellMissingCIsFlags(&spellInfo);
        setSpellOnShapeshiftChange(&spellInfo);
    }

    // Hackfixes
    applyHackFixes();
}

void SpellMgr::loadSpellDataFromDatabase()
{
    // Load spell related SQL tables
    loadSpellCustomOverride();
    loadSpellCoefficientOverride();
    loadSpellAIThreat();
    loadSpellEffectOverride();
    loadSpellAreas();
}

void SpellMgr::loadSpellScripts()
{
    // Setup scripts
    setupSpellScripts();
}

Spell* SpellMgr::newSpell(Object* caster, SpellInfo const* info, bool triggered, Aura* aur)
{
    // For now we send non-const spellinfo to Spell class
    // This will of course be changed later
    auto spellInfo = info != nullptr ? getMutableSpellInfo(info->getId()) : nullptr;

    // Spells with a script
    if (info->spellScriptLink != nullptr)
        return (*SpellScriptLinker(info->spellScriptLink))(caster, spellInfo, triggered, aur);
    
    // Standard spells without a script
    return new Spell(caster, spellInfo, triggered, aur);
}

Aura* SpellMgr::newAura(SpellInfo const* proto, int32_t duration, Object* caster, Unit* target, bool temporary /*= false*/, Item* i_caster /*= nullptr*/)
{
    //\brief... nullptr when downgrading ae from wotlk to tbc (active auras from newer client versions should be removed before entering tbc)

    // For now we send non-const spellinfo to Aura class
    // This will of course be changed later
    auto spellInfo = proto != nullptr ? getMutableSpellInfo(proto->getId()) : nullptr;

    // Auras with a script
    if (proto->auraScriptLink != nullptr)
        return (*AuraScriptLinker(proto->auraScriptLink))(spellInfo, duration, caster, target, temporary, i_caster);
    // Auras with absorb effect
    else if (proto->hasEffectApplyAuraName(SPELL_AURA_SCHOOL_ABSORB))
        return (*AuraScriptLinker(&AbsorbAura::Create))(spellInfo, duration, caster, target, temporary, i_caster);
    
    // Standard auras without a script
    return new Aura(spellInfo, duration, caster, target, temporary, i_caster);
}

void SpellMgr::addSpellById(const uint32_t spellId, SpellScriptLinker spellScript)
{
    auto spellInfo = getMutableSpellInfo(spellId);
    if (spellInfo == nullptr)
    {
        LogError("SpellMgr::addSpellById : Unknown spell id %u tried to register a spell script, skipped");
        return;
    }
    addSpellBySpellInfo(spellInfo, spellScript);
}

void SpellMgr::addAuraById(const uint32_t spellId, AuraScriptLinker auraScript)
{
    auto spellInfo = getMutableSpellInfo(spellId);
    if (spellInfo == nullptr)
    {
        LogError("SpellMgr::addAuraById : Unknown spell id %u tried to register an aura script, skipped", spellId);
        return;
    }
    addAuraBySpellInfo(spellInfo, auraScript);
}

SpellAreaMapBounds SpellMgr::getSpellAreaMapBounds(uint32_t spellId) const
{
    return SpellAreaMapBounds(mSpellAreaMap.lower_bound(spellId), mSpellAreaMap.upper_bound(spellId));
}

SpellAreaForAreaMapBounds SpellMgr::getSpellAreaForAreaMapBounds(uint32_t areaId) const<commit_msg>Resolved CID 351596 (Missing argument to printf format specifier)<commit_after>/*
Copyright (c) 2014-2019 AscEmu Team <http://www.ascemu.org>
This file is released under the MIT license. See README-MIT for more information.
*/

#include "SpellMgr.h"

#include "Spell/Definitions/AuraEffects.h"
#include "Spell/Definitions/ProcFlags.h"
#include "Spell/Definitions/SpellDamageType.h"
#include "Spell/Definitions/SpellEffects.h"
#include "Spell/Definitions/SpellEffectTarget.h"
#include "Spell/Definitions/SpellFamily.h"

#include "Map/Area/AreaStorage.hpp"
#include "shared/Log.hpp"
#include "Storage/MySQLDataStore.hpp"
#include "Storage/DBC/DBCStores.h"

bool SpellArea::fitsToRequirements(Player* player, uint32_t newZone, uint32_t newArea) const
{
    if (gender != GENDER_NONE)
    {
        if (player == nullptr || gender != player->getGender())
            return false;
    }

    if (raceMask != 0)
    {
        if (player == nullptr || !(raceMask & player->getRaceMask()))
            return false;
    }

    if (areaId != 0)
    {
        if (newZone != areaId && newArea != areaId)
            return false;
    }

    if (questStart != 0)
    {
        if (player == nullptr || !player->HasQuest(questStart))
            return false;
    }

    if (questEnd != 0)
    {
        if (player == nullptr || player->GetQuestRewardStatus(questEnd))
            return false;
    }

    if (auraSpell != 0)
    {
        if (player == nullptr || (auraSpell > 0 && !player->HasAura(auraSpell)) || (auraSpell < 0 && player->HasAura(-auraSpell)))
            return false;
    }

    // Misc Conditions
    switch (spellId)
    {
        case 58600: //Restricted Flight Zone (Dalaran)
        {
            if (player == nullptr)
                return false;

            if (!player->hasAuraWithAuraEffect(SPELL_AURA_ENABLE_FLIGHT2) && !player->hasAuraWithAuraEffect(SPELL_AURA_FLY))
                return false;
            break;
        }
    }

    return true;
}

SpellMgr& SpellMgr::getInstance()
{
    static SpellMgr mInstance;
    return mInstance;
}

void SpellMgr::startSpellMgr()
{
    // Load spell data from DBC
    loadSpellInfoData();

    for (const auto itr : mSpellInfoMapStore)
    {
        auto spellInfo = itr.second;

        // Calculate spell coefficient
        setSpellCoefficient(&spellInfo);

        // Custom values
        // todo: if possible, get rid of these
        setSpellEffectAmplitude(&spellInfo);
        setSpellMeleeSpellBool(&spellInfo);
        setSpellRangedSpellBool(&spellInfo);
        setSpellMissingCIsFlags(&spellInfo);
        setSpellOnShapeshiftChange(&spellInfo);
    }

    // Hackfixes
    applyHackFixes();
}

void SpellMgr::loadSpellDataFromDatabase()
{
    // Load spell related SQL tables
    loadSpellCustomOverride();
    loadSpellCoefficientOverride();
    loadSpellAIThreat();
    loadSpellEffectOverride();
    loadSpellAreas();
}

void SpellMgr::loadSpellScripts()
{
    // Setup scripts
    setupSpellScripts();
}

Spell* SpellMgr::newSpell(Object* caster, SpellInfo const* info, bool triggered, Aura* aur)
{
    // For now we send non-const spellinfo to Spell class
    // This will of course be changed later
    auto spellInfo = info != nullptr ? getMutableSpellInfo(info->getId()) : nullptr;

    // Spells with a script
    if (info->spellScriptLink != nullptr)
        return (*SpellScriptLinker(info->spellScriptLink))(caster, spellInfo, triggered, aur);
    
    // Standard spells without a script
    return new Spell(caster, spellInfo, triggered, aur);
}

Aura* SpellMgr::newAura(SpellInfo const* proto, int32_t duration, Object* caster, Unit* target, bool temporary /*= false*/, Item* i_caster /*= nullptr*/)
{
    //\brief... nullptr when downgrading ae from wotlk to tbc (active auras from newer client versions should be removed before entering tbc)

    // For now we send non-const spellinfo to Aura class
    // This will of course be changed later
    auto spellInfo = proto != nullptr ? getMutableSpellInfo(proto->getId()) : nullptr;

    // Auras with a script
    if (proto->auraScriptLink != nullptr)
        return (*AuraScriptLinker(proto->auraScriptLink))(spellInfo, duration, caster, target, temporary, i_caster);
    // Auras with absorb effect
    else if (proto->hasEffectApplyAuraName(SPELL_AURA_SCHOOL_ABSORB))
        return (*AuraScriptLinker(&AbsorbAura::Create))(spellInfo, duration, caster, target, temporary, i_caster);
    
    // Standard auras without a script
    return new Aura(spellInfo, duration, caster, target, temporary, i_caster);
}

void SpellMgr::addSpellById(const uint32_t spellId, SpellScriptLinker spellScript)
{
    auto spellInfo = getMutableSpellInfo(spellId);
    if (spellInfo == nullptr)
    {
        LogError("SpellMgr::addSpellById : Unknown spell id %u tried to register a spell script, skipped", spellId);
        return;
    }
    addSpellBySpellInfo(spellInfo, spellScript);
}

void SpellMgr::addAuraById(const uint32_t spellId, AuraScriptLinker auraScript)
{
    auto spellInfo = getMutableSpellInfo(spellId);
    if (spellInfo == nullptr)
    {
        LogError("SpellMgr::addAuraById : Unknown spell id %u tried to register an aura script, skipped", spellId);
        return;
    }
    addAuraBySpellInfo(spellInfo, auraScript);
}

SpellAreaMapBounds SpellMgr::getSpellAreaMapBounds(uint32_t spellId) const
{
    return SpellAreaMapBounds(mSpellAreaMap.lower_bound(spellId), mSpellAreaMap.upper_bound(spellId));
}

SpellAreaForAreaMapBounds SpellMgr::getSpellAreaForAreaMapBounds(uint32_t areaId) const
{'fraction_non_alphanumeric': 0.10928021729289271, 'fraction_numerical': 0.006880941602535084, 'mean_word_length': 3.2714617169373548, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '942882', 'n_tokens_mistral': 3495, 'n_tokens_neox': 3505, 'n_words': 840}