diff --git a/data/sql/updates/pending_db_characters/rev_1660418251471829700.sql b/data/sql/updates/pending_db_characters/rev_1660418251471829700.sql new file mode 100644 index 000000000..8a214b476 --- /dev/null +++ b/data/sql/updates/pending_db_characters/rev_1660418251471829700.sql @@ -0,0 +1,7 @@ +-- Insert world states (for conditions) +DELETE FROM `worldstates` WHERE `entry` IN (197,198,199,200); +INSERT INTO `worldstates` (`entry`, `value`, `comment`) values +(197,0,'Fishing Extravaganza - STV_FISHING_PREV_WIN_TIME'), +(198,0,'Fishing Extravaganza - STV_FISHING_HAS_WINNER'), +(199,0,'Fishing Extravaganza - STV_FISHING_ANNOUNCE_EVENT_BEGIN'), +(200,0,'Fishing Extravaganza - STV_FISHING_ANNOUNCE_POOLS_DESPAN'); diff --git a/data/sql/updates/pending_db_world/rev_1658570956441891600.sql b/data/sql/updates/pending_db_world/rev_1658570956441891600.sql new file mode 100644 index 000000000..5c9302189 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1658570956441891600.sql @@ -0,0 +1,42 @@ +-- Spawns npc's from 13:00 - 17:00 +UPDATE `game_event` SET `start_time`= '2016-10-30 13:00:00', `length` = 240, `description`= 'Stranglethorn Fishing Extravaganza - The Crew' WHERE `eventEntry` = 62; + +-- Quests can be turned in 14:00 - 17:00 +DELETE FROM `game_event` WHERE `eventEntry` = 90; +INSERT INTO `game_event` (`eventEntry`, `start_time`, `end_time`, `occurence`, `length`, `holiday`, `holidayStage`, `description`, `world_event`, `announce`) VALUES +(90,'2016-10-30 14:00:00','2030-12-31 07:00:00',10080,180,0,0,'Stranglethorn Fishing Extravaganza - Turn-ins',0,2); + +-- Minimum fishing skill for Stranglethorn Vale Fishing Extravaganza quests is 150, also [Could I get a Fishing Flier?] +DELETE FROM `quest_template_addon` WHERE `ID` IN (8194, 8193, 8225, 8224, 8221, 8228, 8229); +INSERT INTO `quest_template_addon` (`ID`, `MaxLevel`, `AllowableClasses`, `SourceSpellID`, `PrevQuestID`, `NextQuestID`, `ExclusiveGroup`, `RewardMailTemplateID`, `RewardMailDelay`, `RequiredSkillID`, `RequiredSkillPoints`, `RequiredMinRepFaction`, `RequiredMaxRepFaction`, `RequiredMinRepValue`, `RequiredMaxRepValue`, `ProvidedItemCount`, `SpecialFlags`) VALUES +(8194,0,0,0,0,0,0,0,0,356,150,0,0,0,0,0,1), +(8193,0,0,0,0,0,0,0,0,356,150,0,0,0,0,0,1), +(8225,0,0,0,0,0,0,0,0,356,150,0,0,0,0,0,1), +(8224,0,0,0,0,0,0,0,0,356,150,0,0,0,0,0,1), +(8221,0,0,0,0,0,0,0,0,356,150,0,0,0,0,0,1), +(8228,0,0,0,0,0,0,0,0,356,150,0,0,0,0,0,1), +(8229,0,0,0,0,0,0,0,0,356,150,0,0,0,0,0,1); + +-- Box on which Riggle Bassbait stands: linked to event 62 (The Crew) +UPDATE `game_event_gameobject` SET `eventEntry`= 62 WHERE `guid`= 164445; + +-- Riggle Bassbait: use broadcast texts +UPDATE `creature_text` SET `BroadcastTextId` = 10608, `Text`='Let the Fishing Tournament BEGIN!' WHERE `CreatureID` = 15077 AND `GroupID` = 0; +UPDATE `creature_text` SET `BroadcastTextId` = 10609, `Text`='And the Tastyfish have gone for the week! I will remain for another hour to allow you to turn in your fish!' WHERE `CreatureID` = 15077 AND `GroupID` = 1; +UPDATE `creature_text` SET `BroadcastTextId` = 10610, `Text`='We have a winner! $n has won FIRST PLACE in the tournament!' WHERE `CreatureID` = 15077 AND `GroupID` = 2; + +-- Fishbot 5000 quests: only available when event 90 (Turn-ins) is active +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 19 AND `SourceEntry` IN (8225,8224,8221); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(19,0,8225,0,0,12,0,90,0,0,0,0,0,'','Fishing Extravaganza - Turn-ins active'), +(19,0,8224,0,0,12,0,90,0,0,0,0,0,'','Fishing Extravaganza - Turn-ins active'), +(19,0,8221,0,0,12,0,90,0,0,0,0,0,'','Fishing Extravaganza - Turn-ins active'); + +-- Jang quest: event 90 (Turn-ins) is active and event has a winner (world state id 198) +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`= 19 AND `SourceEntry`= 8194; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(19,0,8194,0,0,12,0,90,0,0,0,0,0,'','Fishing Extravaganza - Turn-ins active'), +(19,0,8194,0,0,11,0,198,1,0,0,0,0,'','Fishing Extravaganza - fishing event has a winner'); + +-- Riggle texts: zone wide announcement +UPDATE `creature_text` SET `TextRange` = 2 WHERE `CreatureID` = 15077 AND `GroupID` IN (0,1,2); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 73851d071..c6e79b5bc 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -2302,11 +2302,6 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) break; case CONDITION_WORLD_STATE: { - if (!sWorld->getWorldState(cond->ConditionValue1)) - { - LOG_ERROR("sql.sql", "World state condition has non existing world state in value1 ({}), skipped", cond->ConditionValue1); - return false; - } if (cond->ConditionValue3) LOG_ERROR("sql.sql", "World state condition has useless data in value3 ({})!", cond->ConditionValue3); break; diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index d06e81b68..7642d723f 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -207,19 +207,30 @@ public: } }; -enum riggleBassbait +/* + * Stranglethorn Vale Fishing Extravaganza World States + */ +enum FishingExtravaganzaWorldStates { - EVENT_RIGGLE_ANNOUNCE = 1, + STV_FISHING_PREV_WIN_TIME = 197, + STV_FISHING_HAS_WINNER = 198, + STV_FISHING_ANNOUNCE_EVENT_BEGIN = 199, + STV_FISHING_ANNOUNCE_POOLS_DESPAN = 200 +}; - RIGGLE_SAY_START = 0, - RIGGLE_SAY_WINNER = 1, - RIGGLE_SAY_END = 2, +enum RiggleBassbait +{ + RIGGLE_SAY_START = 0, + RIGGLE_SAY_POOLS_END = 1, + RIGGLE_SAY_WINNER = 2, - QUEST_MASTER_ANGLER = 8193, + QUEST_MASTER_ANGLER = 8193, - DATA_ANGLER_FINISHED = 1, + EVENT_FISHING_TURN_INS = 90, + EVENT_FISHING_POOLS = 15, - GAME_EVENT_FISHING = 62 + GOSSIP_EVENT_ACTIVE = 7614, + GOSSIP_EVENT_OVER = 7714 }; class npc_riggle_bassbait : public CreatureScript @@ -231,84 +242,95 @@ public: { npc_riggle_bassbaitAI(Creature* c) : ScriptedAI(c) { - events.Reset(); - events.ScheduleEvent(EVENT_RIGGLE_ANNOUNCE, 1000, 1, 0); - finished = sWorld->getWorldState(GAME_EVENT_FISHING) == 1; - startWarning = false; - finishWarning = false; - } - - EventMap events; - bool finished; - bool startWarning; - bool finishWarning; - - uint32 GetData(uint32 type) const override - { - if (type == DATA_ANGLER_FINISHED) - return (uint32)finished; - - return 0; - } - - void DoAction(int32 param) override - { - if (param == DATA_ANGLER_FINISHED) + m_uiTimer = 0; + auto prevWinTime = sWorld->getWorldState(STV_FISHING_PREV_WIN_TIME); + if (GameTime::GetGameTime().count() - prevWinTime > DAY) { - finished = true; - sWorld->setWorldState(GAME_EVENT_FISHING, 1); + // reset all after 1 day + sWorld->setWorldState(STV_FISHING_ANNOUNCE_EVENT_BEGIN, 1); + sWorld->setWorldState(STV_FISHING_ANNOUNCE_POOLS_DESPAN, 0); + sWorld->setWorldState(STV_FISHING_HAS_WINNER, 0); + } + } + + uint32 m_uiTimer; + + void CheckTournamentState() const + { + if (sGameEventMgr->IsActiveEvent(EVENT_FISHING_TURN_INS) && !sWorld->getWorldState(STV_FISHING_HAS_WINNER)) + { + if (!me->IsQuestGiver()) + { + me->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); + } + if (sWorld->getWorldState(STV_FISHING_ANNOUNCE_EVENT_BEGIN)) + { + me->Yell(RIGGLE_SAY_START); + sWorld->setWorldState(STV_FISHING_ANNOUNCE_EVENT_BEGIN, 0); + } + } + else + { + if (me->IsQuestGiver()) + { + me->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); + } + } + if (sGameEventMgr->IsActiveEvent(EVENT_FISHING_POOLS)) + { + // enable announcement: when pools despawn + sWorld->setWorldState(STV_FISHING_ANNOUNCE_POOLS_DESPAN, 1); + } + else + { + if (sWorld->getWorldState(STV_FISHING_ANNOUNCE_POOLS_DESPAN)) + { + me->Yell(RIGGLE_SAY_POOLS_END); + sWorld->setWorldState(STV_FISHING_ANNOUNCE_POOLS_DESPAN, 0); + } } } void UpdateAI(uint32 diff) override { - events.Update(diff); - switch (events.ExecuteEvent()) + if (m_uiTimer < diff) { - case EVENT_RIGGLE_ANNOUNCE: - { - tm strdate = Acore::Time::TimeBreakdown(); - - if (!startWarning && strdate.tm_hour == 14 && strdate.tm_min == 0) - { - sCreatureTextMgr->SendChat(me, RIGGLE_SAY_START, 0, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, TEXT_RANGE_ZONE); - startWarning = true; - } - - if (!finishWarning && strdate.tm_hour == 16 && strdate.tm_min == 0) - { - sCreatureTextMgr->SendChat(me, RIGGLE_SAY_END, 0, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, TEXT_RANGE_ZONE); - finishWarning = true; - // no one won - despawn - if (!finished) - { - me->DespawnOrUnsummon(); - break; - } - } - - events.RepeatEvent(1000); - break; - } + CheckTournamentState(); + m_uiTimer = 1000; + } + else + { + m_uiTimer -= diff; } } }; bool OnGossipHello(Player* player, Creature* creature) override { - if (!creature->AI()->GetData(DATA_ANGLER_FINISHED)) + if (creature->IsQuestGiver()) + { player->PrepareQuestMenu(creature->GetGUID()); + } - SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID()); + if (sWorld->getWorldState(STV_FISHING_HAS_WINNER)) + { + SendGossipMenuFor(player, GOSSIP_EVENT_OVER, creature->GetGUID()); + } + else + { + SendGossipMenuFor(player, GOSSIP_EVENT_ACTIVE, creature->GetGUID()); + } return true; } bool OnQuestReward(Player* player, Creature* creature, Quest const* quest, uint32 /*opt*/) override { - if (!creature->AI()->GetData(DATA_ANGLER_FINISHED) && quest->GetQuestId() == QUEST_MASTER_ANGLER) + if (quest->GetQuestId() == QUEST_MASTER_ANGLER) { - creature->AI()->DoAction(DATA_ANGLER_FINISHED); - sCreatureTextMgr->SendChat(creature, RIGGLE_SAY_WINNER, player, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, TEXT_RANGE_ZONE); + creature->RemoveNpcFlag(UNIT_NPC_FLAG_QUESTGIVER); + creature->Yell(RIGGLE_SAY_WINNER, player); + sWorld->setWorldState(STV_FISHING_PREV_WIN_TIME, GameTime::GetGameTime().count()); + sWorld->setWorldState(STV_FISHING_HAS_WINNER, 1); } return true; }