diff --git a/data/sql/updates/pending_db_world/rev_1691529514989936100.sql b/data/sql/updates/pending_db_world/rev_1691529514989936100.sql new file mode 100644 index 000000000..8beed1c0d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1691529514989936100.sql @@ -0,0 +1,105 @@ +-- +SET @GEVENT := 46; +SET @CGUID := 152340; + +DELETE FROM `game_event` WHERE `eventEntry` = @GEVENT; +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(@GEVENT, '2008-09-08 12:00:00', '2008-09-24 12:00:00', 1051897, 23040 , 0, 0, 'Spirit of Competition', 0, 2); + +UPDATE `creature_template` SET `gossip_menu_id` = 9517, `npcflag` = 1 WHERE `entry` = 27399; + +DELETE FROM `gossip_menu_option` WHERE `MenuID` = 9517 AND `OptionID` = 0; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`) VALUES +(9517, 0, 0, 'I would like to enter the secret code to receive my Competitor''s Souvenir.', 26513, 1, 1); + +DELETE FROM `creature` WHERE `id1` IN (27346, 27398, 27399); +INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES +(@CGUID, 27398, 0, 0, 0, 1537, 1537, 0, 1, 0, -5040.92, -1250.81, 507.76, 0.70, 300, 0, 0, 0, 0, 0, 0, 0, 0, '', 0), -- Grandhammer +(@CGUID+1, 27346, 0, 0, 0, 1537, 1537, 0, 1, 0, -5041.91, -1250.2, 507.76, 1.37, 300, 0, 0, 0, 0, 0, 0, 0, 0, '', 0), -- IF Dragon +(@CGUID+2, 27399, 0, 0, 1, 1637, 1637, 0, 1, 0, 1964.39, -4798.77, 56.99, 0.08, 300, 0, 0, 0, 0, 0, 0, 0, 0, '', 0), -- Muja +(@CGUID+3, 27346, 0, 0, 1, 1637, 1637, 0, 1, 0, 1963.26, -4797.62, 56.99, 0.72, 300, 0, 0, 0, 0, 0, 0, 0, 0, '', 0); -- Org Dragon +-- Positions based on screenshots. +DELETE FROM `game_event_creature` WHERE `eventEntry` = @GEVENT; +INSERT INTO `game_event_creature` (`eventEntry`, `guid`) VALUES +(@GEVENT, @CGUID), +(@GEVENT, @CGUID+1), +(@GEVENT, @CGUID+2), +(@GEVENT, @CGUID+3), + +-- Goblin Commoneers +(@GEVENT, 724), +(@GEVENT, 725), +(@GEVENT, 726), +(@GEVENT, 727), +(@GEVENT, 91115), +(@GEVENT, 91116), +(@GEVENT, 91117), +(@GEVENT, 91118), +(@GEVENT, 91579), +(@GEVENT, 91580), +(@GEVENT, 91752), +(@GEVENT, 91753), +(@GEVENT, 91754), +(@GEVENT, 91756), +(@GEVENT, 91757), +(@GEVENT, 91758), +(@GEVENT, 91759), +(@GEVENT, 91760), +(@GEVENT, 91761), +(@GEVENT, 91762), +(@GEVENT, 91766), +(@GEVENT, 91767), +(@GEVENT, 91768), +(@GEVENT, 91769), +(@GEVENT, 91770), +(@GEVENT, 91771), +(@GEVENT, 91801), +(@GEVENT, 240327), +(@GEVENT, 240328), +(@GEVENT, 240329), +(@GEVENT, 240330), +(@GEVENT, 240331), +(@GEVENT, 240332), +(@GEVENT, 240333), +(@GEVENT, 240334), +(@GEVENT, 240335), +(@GEVENT, 240336), +(@GEVENT, 240337), +(@GEVENT, 240338); + +DELETE FROM `creature_text` WHERE `CreatureID` = 20102 AND `GroupID` = 1; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `BroadcastTextId`) VALUES +(20102, 1, 1, 'The Spirits of Competition have grown strong again.', 12, 0, 100, 26564); + +DELETE FROM `smart_scripts` WHERE `entryorguid`=20102 AND `source_type`=0 AND `id`=1 AND `link`=0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(20102, 0, 1, 0, 1, 0, 100, 0, 3000, 15000, 45000, 90000, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Goblin Commoner - OOC - Say'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceGroup`=2 AND `SourceEntry`=20102 AND `SourceId`=0 AND `ElseGroup`=0 AND `ConditionTypeOrReference`=12 AND `ConditionTarget`=1 AND `ConditionValue1`=46 AND `ConditionValue2`=0 AND `ConditionValue3`=0; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(22, 2, 20102, 0, 0, 12, 1, 46, 0, 0, 0, 0, 0, '', 'Commoner - Spirit of Competition must be active'); + +DELETE FROM `gossip_menu` WHERE `MenuID` = 10248 AND `TextID` IN (12819); +DELETE FROM `gossip_menu` WHERE `MenuID` = 90000 AND `TextID` IN (12820); +DELETE FROM `gossip_menu` WHERE `MenuID` = 90001 AND `TextID` IN (12821); +INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES +(10248, 12819), +(90000, 12820), +(90001, 12821); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=10248 AND `SourceEntry`=12819 AND `ConditionTypeOrReference`=12 AND `ConditionTarget`=0 AND `ConditionValue1`=46; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=10248 AND `SourceEntry` IN (0,1) AND `ConditionTypeOrReference`=12 AND `ConditionValue1`=46; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(14, 10248, 12819, 0, 0, 12, 0, 46, 0, 0, 0, 0, 0, '', 'Show gossip text if event 46 is active'), +(15, 10248, 0, 0, 0, 12, 0, 46, 0, 0, 0, 0, 0, '', 'Show gossip option if event 46 is active'), +(15, 10248, 1, 0, 0, 12, 0, 46, 0, 0, 0, 0, 0, '', 'Show gossip option if event 46 is active'); + +DELETE FROM `gossip_menu_option` WHERE `MenuID` = 10248 AND `OptionID` IN (0,1); +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`) VALUES +(10248, 0, 0, 'How do I earn a Competitor''s Tabard?', 26508, 1, 1, 90000), +(10248, 1, 0, 'How can I gain the favor of a Spirit of Competition?', 26509, 1, 1, 90001); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (48163,48164); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(48163,'spell_gen_spirit_of_competition_participant'), +(48164,'spell_gen_spirit_of_competition_winner'); diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 3723778ea..eac4b5595 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -916,9 +916,49 @@ void Battleground::EndBattleground(PvPTeamId winnerTeamId) player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, player->GetMapId()); } + if (IsEventActive(EVENT_SPIRIT_OF_COMPETITION) && isBattleground()) + SpiritofCompetitionEvent(winnerTeamId); + sScriptMgr->OnBattlegroundEnd(this, GetTeamId(winnerTeamId)); } +bool Battleground::SpiritofCompetitionEvent(PvPTeamId winnerTeamId) +{ + // Everyone is eligible for tabard reward + for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player* player = itr->second; + bool questStatus = player->GetQuestStatus(QUEST_FLAG_PARTICIPANT) != QUEST_STATUS_REWARDED; + + if (player && questStatus) + player->CastSpell(player, SPELL_SPIRIT_OF_COMPETITION_PARTICIPANT, true); + } + + // In case of a draw nobody get rewarded + if (winnerTeamId == PVP_TEAM_NEUTRAL) + return false; + + std::vector filteredPlayers; + + for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + Player* player = itr->second; + bool playerTeam = player->GetBgTeamId() == GetTeamId(winnerTeamId); + bool questStatus = player->GetQuestStatus(QUEST_FLAG_WINNER) != QUEST_STATUS_REWARDED; + + if (player && playerTeam && questStatus) + filteredPlayers.push_back(player); + } + + if (filteredPlayers.size()) + { + if (Player* wPlayer = filteredPlayers[rand() % filteredPlayers.size()]) + wPlayer->CastSpell(wPlayer, SPELL_SPIRIT_OF_COMPETITION_WINNER, true); + } + + return true; +} + uint32 Battleground::GetBonusHonorFromKill(uint32 kills) const { //variable kills means how many honorable kills you scored (so we need kills * honor_for_one_kill) diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 0b7aab9d9..e60c511d2 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -237,6 +237,15 @@ enum BattlegroundStartingEventsIds BG_STARTING_EVENT_FOURTH = 3 }; +enum SpiritOfCompetitionEvent +{ + EVENT_SPIRIT_OF_COMPETITION = 46, + QUEST_FLAG_PARTICIPANT = 12187, + QUEST_FLAG_WINNER = 12186, + SPELL_SPIRIT_OF_COMPETITION_PARTICIPANT = 48163, + SPELL_SPIRIT_OF_COMPETITION_WINNER = 48164, +}; + constexpr auto BG_STARTING_EVENT_COUNT = 4; class ArenaLogEntryData @@ -337,6 +346,9 @@ public: [[nodiscard]] uint32 GetScriptId() const { return ScriptId; } [[nodiscard]] uint32 GetBonusHonorFromKill(uint32 kills) const; + // Spirit of Competition event + bool SpiritofCompetitionEvent(PvPTeamId winnerTeamId); + bool IsRandom() { return m_IsRandom; } // Set methods: diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 6a24eb84f..822e05a88 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -4917,6 +4917,87 @@ class spell_gen_curse_of_pain : public AuraScript } }; +enum SpiritofCompetition +{ + // Spells + SPELL_SPIRIT_OF_COMPETITION_PARTICIPANT_EFFECT = 48056, + SPELL_SPIRIT_OF_COMPETITION_WINNER_EFFECT = 48057, + // Mail + MAIL_THE_COMPETITIORS_TABARD = 195, + MAIL_A_GOLD_MEDALLION = 196, + // NPC + NPC_SPIRIT_OF_COMPETITION = 27217, + // Items + ITEM_COMPETITORS_TABARD = 36941, + ITEM_GOLD_MEDALLION = 37297, +}; + +class spell_gen_spirit_of_competition_participant : public SpellScript +{ + PrepareSpellScript(spell_gen_spirit_of_competition_participant); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SPIRIT_OF_COMPETITION_PARTICIPANT_EFFECT }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Player* player = GetHitPlayer()) + { + player->CastSpell(player, SPELL_SPIRIT_OF_COMPETITION_PARTICIPANT_EFFECT, true); + + Item* item = Item::CreateItem(ITEM_COMPETITORS_TABARD, 1); + if (!item) + return; + + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + MailDraft(MAIL_THE_COMPETITIORS_TABARD) + .AddItem(item) + .SendMailTo(trans, player, MailSender(NPC_SPIRIT_OF_COMPETITION), MAIL_CHECK_MASK_HAS_BODY); + CharacterDatabase.CommitTransaction(trans); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_spirit_of_competition_participant::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_gen_spirit_of_competition_winner : public SpellScript +{ + PrepareSpellScript(spell_gen_spirit_of_competition_winner); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SPIRIT_OF_COMPETITION_WINNER_EFFECT }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Player* player = GetHitPlayer()) + { + player->CastSpell(player, SPELL_SPIRIT_OF_COMPETITION_WINNER_EFFECT, true); + + Item* item = Item::CreateItem(ITEM_GOLD_MEDALLION, 1); + if (!item) + return; + + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + MailDraft(MAIL_A_GOLD_MEDALLION) + .AddItem(item) + .SendMailTo(trans, player, MailSender(NPC_SPIRIT_OF_COMPETITION), MAIL_CHECK_MASK_HAS_BODY); + CharacterDatabase.CommitTransaction(trans); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_spirit_of_competition_winner::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + void AddSC_generic_spell_scripts() { RegisterSpellScript(spell_silithyst); @@ -5063,4 +5144,6 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_threshalisk_charge); RegisterSpellScript(spell_gen_shriveling_gaze); RegisterSpellScript(spell_gen_curse_of_pain); + RegisterSpellScript(spell_gen_spirit_of_competition_participant); + RegisterSpellScript(spell_gen_spirit_of_competition_winner); }