fix(Scripts/HowlingFjord): Harrowmeiser and Petrov Gossips (#26875)
This commit is contained in:
@@ -36,6 +36,7 @@ enum ZeppelinEvent
|
||||
EVENT_UC_TO_OG_DEPARTURE = 15321,
|
||||
EVENT_UC_TO_GROMGOL_DEPARTURE = 15313,
|
||||
EVENT_GROMGOL_TO_UC_DEPARTURE = 15315,
|
||||
EVENT_WK_DEPARTURE = 15430,
|
||||
};
|
||||
|
||||
enum ZeppelinMaster
|
||||
@@ -55,6 +56,11 @@ enum ZeppelinMaster
|
||||
NPC_KRENDLE_BIGPOCKETS = 34766,
|
||||
};
|
||||
|
||||
enum ZeppelinTransport
|
||||
{
|
||||
GO_WESTGUARD_ZEPPELIN = 186371,
|
||||
};
|
||||
|
||||
const float SEARCH_RANGE_ZEPPELIN_MASTER = 32.0f;
|
||||
|
||||
enum ZeppelinPassenger
|
||||
|
||||
@@ -15,8 +15,15 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CreatureScript.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameObjectScript.h"
|
||||
#include "Map.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "Transport.h"
|
||||
#include "TransportMgr.h"
|
||||
#include "WorldState.h"
|
||||
#include "transport_zeppelin.h"
|
||||
|
||||
@@ -101,9 +108,166 @@ struct go_transport_the_purple_princess : GameObjectAI
|
||||
}
|
||||
};
|
||||
|
||||
// 186371 Zeppelin - Westguard Keep to Shattered Straits
|
||||
struct go_transport_westguard_zeppelin : GameObjectAI
|
||||
{
|
||||
go_transport_westguard_zeppelin(GameObject* object) : GameObjectAI(object) { };
|
||||
|
||||
void EventInform(uint32 eventId) override
|
||||
{
|
||||
if (eventId != EVENT_WK_ARRIVAL)
|
||||
return;
|
||||
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_HARROWMEISER, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(0);
|
||||
|
||||
// the dock is covered by two stop frames of 60s each, so EVENT_WK_DEPARTURE
|
||||
// only fires two minutes later - warn one minute before it does
|
||||
_scheduler.Schedule(1min, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (Creature* creature = me->FindNearestCreature(NPC_HARROWMEISER, SEARCH_RANGE_ZEPPELIN_MASTER))
|
||||
creature->AI()->Talk(1);
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
enum WestguardZeppelinGossip
|
||||
{
|
||||
GOSSIP_TEXT_PETROV_EN_ROUTE = 11322,
|
||||
GOSSIP_TEXT_PETROV_ARRIVING = 11324,
|
||||
GOSSIP_TEXT_HARROWMEISER_DOCKED = 11328,
|
||||
GOSSIP_TEXT_HARROWMEISER_ARRIVING = 11330,
|
||||
GOSSIP_TEXT_HARROWMEISER_EN_ROUTE = 11332,
|
||||
};
|
||||
|
||||
// The two "en route" texts above read "in less than $3078w minutes". The client
|
||||
// substitutes that token with the world state below, so it renders 0 unless a value
|
||||
// has been pushed to the player first.
|
||||
enum WestguardZeppelinWorldState
|
||||
{
|
||||
WORLD_STATE_ZEPPELIN_ETA = 3078,
|
||||
};
|
||||
|
||||
enum WestguardZeppelinState
|
||||
{
|
||||
ZEPPELIN_STATE_EN_ROUTE,
|
||||
ZEPPELIN_STATE_ARRIVING,
|
||||
ZEPPELIN_STATE_DOCKED,
|
||||
};
|
||||
|
||||
// Reports where the Westguard Keep zeppelin is in its path. While it is still touring the
|
||||
// bay the remaining minutes are pushed to the player as WORLD_STATE_ZEPPELIN_ETA.
|
||||
WestguardZeppelinState GetWestguardZeppelinState(Player* player, Map* map)
|
||||
{
|
||||
MotionTransport const* zeppelin = nullptr;
|
||||
for (Transport* transport : map->GetAllTransports())
|
||||
if (transport->GetEntry() == GO_WESTGUARD_ZEPPELIN)
|
||||
{
|
||||
zeppelin = transport->ToMotionTransport();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!zeppelin || !zeppelin->GetPeriod())
|
||||
return ZEPPELIN_STATE_EN_ROUTE;
|
||||
|
||||
uint32 dockArriveTime = 0;
|
||||
uint32 dockDepartTime = 0;
|
||||
for (KeyFrame const& frame : zeppelin->GetKeyFrames())
|
||||
{
|
||||
if (frame.Node->arrivalEventID == EVENT_WK_ARRIVAL)
|
||||
dockArriveTime = frame.ArriveTime;
|
||||
else if (frame.Node->departureEventID == EVENT_WK_DEPARTURE)
|
||||
dockDepartTime = frame.DepartureTime;
|
||||
}
|
||||
|
||||
if (!dockArriveTime)
|
||||
return ZEPPELIN_STATE_EN_ROUTE;
|
||||
|
||||
uint32 const period = zeppelin->GetPeriod();
|
||||
uint32 const timer = zeppelin->GetPathProgress() % period;
|
||||
|
||||
// the dock is covered by the last and the first stop frame of the path, so the docked
|
||||
// window normally wraps the end of one period into the start of the next
|
||||
bool const docked = dockArriveTime > dockDepartTime
|
||||
? timer >= dockArriveTime || timer < dockDepartTime
|
||||
: timer >= dockArriveTime && timer < dockDepartTime;
|
||||
|
||||
if (docked)
|
||||
return ZEPPELIN_STATE_DOCKED;
|
||||
|
||||
// modular so it stays correct whichever way around the two stop frames sit
|
||||
uint32 const msUntilArrival = (dockArriveTime + period - timer) % period;
|
||||
if (msUntilArrival <= MINUTE * IN_MILLISECONDS)
|
||||
return ZEPPELIN_STATE_ARRIVING;
|
||||
|
||||
// the texts read "less than X minutes", so round up
|
||||
player->SendUpdateWorldState(WORLD_STATE_ZEPPELIN_ETA,
|
||||
(msUntilArrival + MINUTE * IN_MILLISECONDS - 1) / (MINUTE * IN_MILLISECONDS));
|
||||
|
||||
return ZEPPELIN_STATE_EN_ROUTE;
|
||||
}
|
||||
|
||||
// 23823 Harrowmeiser
|
||||
class npc_harrowmeiser : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_harrowmeiser() : CreatureScript("npc_harrowmeiser") { }
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature) override
|
||||
{
|
||||
uint32 textId = GOSSIP_TEXT_HARROWMEISER_EN_ROUTE;
|
||||
switch (GetWestguardZeppelinState(player, creature->GetMap()))
|
||||
{
|
||||
case ZEPPELIN_STATE_DOCKED:
|
||||
textId = GOSSIP_TEXT_HARROWMEISER_DOCKED;
|
||||
break;
|
||||
case ZEPPELIN_STATE_ARRIVING:
|
||||
textId = GOSSIP_TEXT_HARROWMEISER_ARRIVING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SendGossipMenuFor(player, textId, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// 23895 Bombardier Petrov
|
||||
class npc_bombardier_petrov : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_bombardier_petrov() : CreatureScript("npc_bombardier_petrov") { }
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature) override
|
||||
{
|
||||
if (creature->IsQuestGiver())
|
||||
player->PrepareQuestMenu(creature->GetGUID());
|
||||
|
||||
// he has no docked text of his own, "she's almost here" covers being at the dock too
|
||||
uint32 const textId = GetWestguardZeppelinState(player, creature->GetMap()) == ZEPPELIN_STATE_EN_ROUTE
|
||||
? GOSSIP_TEXT_PETROV_EN_ROUTE
|
||||
: GOSSIP_TEXT_PETROV_ARRIVING;
|
||||
|
||||
SendGossipMenuFor(player, textId, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_transport_zeppelins()
|
||||
{
|
||||
RegisterGameObjectAI(go_transport_the_iron_eagle);
|
||||
RegisterGameObjectAI(go_transport_the_thundercaller);
|
||||
RegisterGameObjectAI(go_transport_the_purple_princess);
|
||||
RegisterGameObjectAI(go_transport_westguard_zeppelin);
|
||||
new npc_harrowmeiser();
|
||||
new npc_bombardier_petrov();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user