<commit_before>/*
 * 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 "CellImpl.h"
#include "GameEventMgr.h"
#include "GameObjectAI.h"
#include "GameTime.h"
#include "GridNotifiers.h"
#include "Group.h"
#include "LFGMgr.h"
#include "PassiveAI.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "TaskScheduler.h"

///////////////////////////////////////
////// GOS
///////////////////////////////////////

///////////////////////////////////////
////// NPCS
///////////////////////////////////////
enum kegThrowers
{
    QUEST_THERE_AND_BACK_AGAIN_A                = 11122,
    QUEST_THERE_AND_BACK_AGAIN_H                = 11412,
    RAM_DISPLAY_ID                              = 22630,
    NPC_FLYNN_FIREBREW                          = 24364,
    NPC_BOK_DROPCERTAIN                         = 24527,
    ITEM_PORTABLE_BREWFEST_KEG                  = 33797,
    SPELL_THROW_KEG                             = 43660,
    SPELL_RAM_AURA                              = 43883,
    SPELL_ADD_TOKENS                            = 44501,
    SPELL_COOLDOWN_CHECKER                      = 43755,
    NPC_RAM_MASTER_RAY                          = 24497,
    NPC_NEILL_RAMSTEIN                          = 23558,
    KEG_KILL_CREDIT                             = 24337,
};

struct npc_brewfest_keg_thrower : public ScriptedAI
{
    npc_brewfest_keg_thrower(Creature* creature) : ScriptedAI(creature)
    {
    }

    void MoveInLineOfSight(Unit* who) override
    {
        if (me->GetDistance(who) < 10.0f && who->GetTypeId() == TYPEID_PLAYER && who->GetMountID() == RAM_DISPLAY_ID)
        {
            if (!who->ToPlayer()->HasItemCount(ITEM_PORTABLE_BREWFEST_KEG)) // portable brewfest keg
                me->CastSpell(who, SPELL_THROW_KEG, true);          // throw keg
        }
    }

    bool CanBeSeen(Player const* player) override
    {
        if (player->GetMountID() == RAM_DISPLAY_ID)
            return true;

        return false;
    }
};

struct npc_brewfest_keg_reciver : public ScriptedAI
{
    npc_brewfest_keg_reciver(Creature* creature) : ScriptedAI(creature) { }

    void MoveInLineOfSight(Unit* who) override
    {
        if (me->GetDistance(who) < 10.0f && who->GetTypeId() == TYPEID_PLAYER && who->GetMountID() == RAM_DISPLAY_ID)
        {
            Player* player = who->ToPlayer();
            if (player->HasItemCount(ITEM_PORTABLE_BREWFEST_KEG)) // portable brewfest keg
            {
                player->KilledMonsterCredit(KEG_KILL_CREDIT);
                player->CastSpell(me, SPELL_THROW_KEG, true);          // throw keg
                player->DestroyItemCount(ITEM_PORTABLE_BREWFEST_KEG, 1, true);

                // Additional Work
                uint32 spellCooldown = player->GetSpellCooldownDelay(SPELL_COOLDOWN_CHECKER) / IN_MILLISECONDS;
                if (spellCooldown > (HOUR * 18 - 900)) // max aproximated time - 12 minutes
                {
                    if (Aura* aur = player->GetAura(SPELL_RAM_AURA))
                    {
                        int32 diff = aur->GetApplyTime() - (GameTime::GetGameTime().count() - (HOUR * 18) + spellCooldown);
                        if (diff > 10) // aura applied later
                            return;

                        aur->SetDuration(aur->GetDuration() + 30000);
                        player->CastSpell(player, SPELL_ADD_TOKENS, true);
                    }
                }
            }
        }
    }

    bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*uiSender*/, uint32 uiAction)
    {
        switch (uiAction)
        {
            case GOSSIP_ACTION_INFO_DEF+1:
                CloseGossipMenuFor(player);
                player->AddSpellCooldown(SPELL_COOLDOWN_CHECKER, 0, 18 * HOUR * IN_MILLISECONDS);
                player->CastSpell(player, 43883, true);
                player->CastSpell(player, 44262, true);
                break;
        }
        return true;
    }

    bool OnGossipHello(Player* player, Creature* creature)
    {
        if (creature->IsQuestGiver())
            player->PrepareQuestMenu(creature->GetGUID());

        if (!player->HasSpellCooldown(SPELL_COOLDOWN_CHECKER) && player->GetQuestRewardStatus(player->GetTeamId() == TEAM_ALLIANCE ? QUEST_THERE_AND_BACK_AGAIN_A : QUEST_THERE_AND_BACK_AGAIN_H))
            AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Do you have additional work?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);

        SendGossipMenuFor(player, (creature->GetEntry() == NPC_NEILL_RAMSTEIN ? 8934 : 8976), creature->GetGUID());
        return true;
    }
};

enum barkTrigger
{
    QUEST_BARK_FOR_DROHN                = 11407,
    QUEST_BARK_FOR_VOODOO               = 11408,
    QUEST_BARK_FOR_BARLEY               = 11293,
    QUEST_BARK_FOR_THUNDERBREW          = 11294,<commit_msg>fix(Scripts/Brewfest): Fixed race for tokens dailies. (#13109)<commit_after>/*
 * 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 "CellImpl.h"
#include "GameEventMgr.h"
#include "GameObjectAI.h"
#include "GameTime.h"
#include "GridNotifiers.h"
#include "Group.h"
#include "LFGMgr.h"
#include "PassiveAI.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "SpellScript.h"
#include "TaskScheduler.h"

///////////////////////////////////////
////// GOS
///////////////////////////////////////

///////////////////////////////////////
////// NPCS
///////////////////////////////////////
enum kegThrowers
{
    QUEST_THERE_AND_BACK_AGAIN_A                = 11122,
    QUEST_THERE_AND_BACK_AGAIN_H                = 11412,
    RAM_DISPLAY_ID                              = 22630,
    NPC_FLYNN_FIREBREW                          = 24364,
    NPC_BOK_DROPCERTAIN                         = 24527,
    ITEM_PORTABLE_BREWFEST_KEG                  = 33797,
    SPELL_THROW_KEG                             = 43660,
    SPELL_RAM_AURA                              = 43883,
    SPELL_ADD_TOKENS                            = 44501,
    SPELL_RAM_RACING_CROP                       = 44262,
    SPELL_COOLDOWN_CHECKER                      = 44689,
    NPC_RAM_MASTER_RAY                          = 24497,
    NPC_NEILL_RAMSTEIN                          = 23558,
    KEG_KILL_CREDIT                             = 24337,
    GOSSIP_NEIL                                 = 8953,
    GOSSIP_RAY                                  = 8973
};

struct npc_brewfest_keg_thrower : public ScriptedAI
{
    npc_brewfest_keg_thrower(Creature* creature) : ScriptedAI(creature)
    {
    }

    void MoveInLineOfSight(Unit* who) override
    {
        if (me->GetDistance(who) < 10.0f && who->GetTypeId() == TYPEID_PLAYER && who->GetMountID() == RAM_DISPLAY_ID)
        {
            if (!who->ToPlayer()->HasItemCount(ITEM_PORTABLE_BREWFEST_KEG)) // portable brewfest keg
                me->CastSpell(who, SPELL_THROW_KEG, true);          // throw keg
        }
    }

    bool CanBeSeen(Player const* player) override
    {
        if (player->GetMountID() == RAM_DISPLAY_ID)
            return true;

        return false;
    }
};

struct npc_brewfest_keg_reciver : public ScriptedAI
{
    npc_brewfest_keg_reciver(Creature* creature) : ScriptedAI(creature) { }

    void MoveInLineOfSight(Unit* who) override
    {
        if (me->GetDistance(who) < 10.0f && who->GetTypeId() == TYPEID_PLAYER && who->GetMountID() == RAM_DISPLAY_ID)
        {
            Player* player = who->ToPlayer();
            if (player->HasItemCount(ITEM_PORTABLE_BREWFEST_KEG)) // portable brewfest keg
            {
                player->KilledMonsterCredit(KEG_KILL_CREDIT);
                player->CastSpell(me, SPELL_THROW_KEG, true);          // throw keg
                player->DestroyItemCount(ITEM_PORTABLE_BREWFEST_KEG, 1, true);

                // Additional Work
                uint32 spellCooldown = player->GetSpellCooldownDelay(SPELL_COOLDOWN_CHECKER) / IN_MILLISECONDS;
                if (spellCooldown > (HOUR * 18 - 900)) // max aproximated time - 12 minutes
                {
                    if (Aura* aur = player->GetAura(SPELL_RAM_AURA))
                    {
                        int32 diff = aur->GetApplyTime() - (GameTime::GetGameTime().count() - (HOUR * 18) + spellCooldown);
                        if (diff > 10) // aura applied later
                            return;

                        aur->SetDuration(aur->GetDuration() + 30000);
                        player->CastSpell(player, SPELL_ADD_TOKENS, true);
                    }
                }
            }
        }
    }

    void sGossipSelect(Player* player, uint32 uiSender, uint32 uiAction) override
    {
        if (uiSender == GOSSIP_NEIL || uiSender == GOSSIP_RAY)
        {
            player->CastSpell(player, SPELL_COOLDOWN_CHECKER, true);
            player->AddSpellCooldown(SPELL_COOLDOWN_CHECKER, 0, 18 * HOUR * IN_MILLISECONDS);
        }

        if (uiAction != 4)
        {
            CloseGossipMenuFor(player);

            player->CastSpell(player, SPELL_RAM_AURA, true);
            player->CastSpell(player, SPELL_RAM_RACING_CROP, true);
        }
    }
};

enum barkTrigger
{
    QUEST_BARK_FOR_DROHN                = 11407,
    QUEST_BARK_FOR_VOODOO               = 11408,
    QUEST_BARK_FOR_BARLEY               = 11293,
    QUEST_BARK_FOR_THUNDERBREW          = 11294,
{'fraction_non_alphanumeric': 0.1182845073009459, 'fraction_numerical': 0.025622187528698687, 'mean_word_length': 1.8300415800415801, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 66, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1995858', 'n_tokens_mistral': 3641, 'n_tokens_neox': 3294, 'n_words': 702}