2023-03-08 11:59:45 -03:00
|
|
|
#include <Encounter/EncounterFight.h>
|
|
|
|
|
|
|
|
namespace Sapphire
|
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
class IfritEncounterFight : public EncounterFight
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
private:
|
|
|
|
static constexpr int NPC_IFRIT = 4126276;
|
|
|
|
static constexpr int VAL_IFRIT_HP = 13884;
|
|
|
|
static constexpr int ACT_HELLFIRE = 0;
|
2023-03-08 14:36:53 -03:00
|
|
|
|
2023-03-08 11:59:45 -03:00
|
|
|
public:
|
2023-03-24 11:21:09 -03:00
|
|
|
IfritEncounterFight( InstanceContentPtr pInstance ) : EncounterFight( pInstance )
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
};
|
2023-03-08 11:59:45 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
void init() override
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
m_status = EncounterFightStatus::IDLE;
|
|
|
|
m_startTime = 0;
|
2023-03-08 14:36:53 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
m_stateStack = std::make_shared< EncounterState::StateStack >();
|
2023-03-08 14:36:53 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
// todo: i don't like this
|
|
|
|
auto boss = m_pInstance->createBNpcFromLayoutId( NPC_IFRIT, VAL_IFRIT_HP, Common::BNpcType::Enemy );
|
2023-03-24 12:00:42 -03:00
|
|
|
boss->init();
|
2023-03-24 11:21:09 -03:00
|
|
|
addBNpc( boss );
|
2023-03-08 11:59:45 -03:00
|
|
|
}
|
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
void start() override
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
auto ifritInitState = makeIfritPhaseOneState();
|
2023-03-08 11:59:45 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
addState( ifritInitState );
|
2023-03-08 14:36:53 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
m_status = EncounterFightStatus::ACTIVE;
|
2023-03-08 11:59:45 -03:00
|
|
|
}
|
2023-03-24 11:21:09 -03:00
|
|
|
|
|
|
|
void reset() override
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
if( auto boss = m_pInstance->getActiveBNpcByLayoutId( NPC_IFRIT ); boss )
|
2023-03-08 14:36:53 -03:00
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
removeBNpc( NPC_IFRIT );
|
|
|
|
m_pInstance->removeActor( boss );
|
2023-03-08 14:36:53 -03:00
|
|
|
}
|
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
init();
|
2023-03-08 11:59:45 -03:00
|
|
|
}
|
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
EncounterStatePtr makeIfritPhaseOneState()
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
auto ifritInitState = std::make_shared< EncounterState >( shared_from_this() );
|
|
|
|
ifritInitState->setOnUpdateCallback( [ & ]( EncounterFightPtr pEncounter, EncounterState state )
|
|
|
|
{
|
|
|
|
auto timeElapsedMs = state.getElapsedTime();
|
|
|
|
|
|
|
|
auto pIfrit = pEncounter->getBNpc( NPC_IFRIT );
|
|
|
|
|
|
|
|
pIfrit->setRot( pIfrit->getRot() + .2f );
|
|
|
|
pIfrit->sendPositionUpdate();
|
|
|
|
|
|
|
|
// todo: use gambits+timelines for this
|
|
|
|
if( timeElapsedMs > 10000 )
|
|
|
|
{
|
|
|
|
state.setFinishFlag();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: use gambits+timelines for this
|
|
|
|
if( timeElapsedMs > 5000 )
|
|
|
|
{
|
|
|
|
auto ifritTwoState = makeIfritPhaseTwoState();
|
|
|
|
pEncounter->addState( ifritTwoState );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2023-03-08 14:36:53 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
ifritInitState->setOnFinishCallback( [ & ]( EncounterFightPtr pEncounter, EncounterState state )
|
|
|
|
{
|
|
|
|
Logger::info( "stage 1 finish - enrage" );
|
2023-03-08 11:59:45 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
auto pIfrit = pEncounter->getBNpc( NPC_IFRIT );
|
|
|
|
pIfrit->hateListGetHighest()->die();
|
|
|
|
}
|
|
|
|
);
|
2023-03-08 11:59:45 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
return ifritInitState;
|
|
|
|
}
|
2023-03-08 11:59:45 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
EncounterStatePtr makeIfritPhaseTwoState()
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
2023-03-24 11:21:09 -03:00
|
|
|
auto ifritTwoState = std::make_shared< EncounterState >( shared_from_this() );
|
|
|
|
ifritTwoState->setOnUpdateCallback( [ & ]( EncounterFightPtr pEncounter, EncounterState state ) {
|
|
|
|
auto timeElapsedMs = state.getElapsedTime();
|
2023-03-08 12:07:08 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
auto pIfrit = pEncounter->getBNpc( NPC_IFRIT );
|
2023-03-08 11:59:45 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
pIfrit->setRot( pIfrit->getRot() - .2f );
|
|
|
|
pIfrit->sendPositionUpdate();
|
2023-03-08 11:59:45 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
// todo: use gambits+timelines for this
|
|
|
|
if( timeElapsedMs > 5000 )
|
|
|
|
{
|
|
|
|
state.setFinishFlag();
|
|
|
|
}
|
|
|
|
} );
|
2023-03-08 12:07:08 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
return ifritTwoState;
|
2023-03-08 11:59:45 -03:00
|
|
|
}
|
|
|
|
|
2023-03-08 14:36:53 -03:00
|
|
|
void update( uint64_t deltaTime ) override
|
2023-03-08 11:59:45 -03:00
|
|
|
{
|
2023-03-08 14:15:13 -03:00
|
|
|
// todo: better way to start fights here..
|
2023-03-24 11:21:09 -03:00
|
|
|
// this probably doesn't need to be overriden either
|
2023-03-08 14:15:13 -03:00
|
|
|
|
2023-03-24 11:21:09 -03:00
|
|
|
auto ifrit = getBNpc( NPC_IFRIT );
|
2023-03-08 14:15:13 -03:00
|
|
|
|
|
|
|
if( ifrit; ifrit->hateListGetHighestValue() != 0 && m_status == EncounterFightStatus::IDLE )
|
|
|
|
{
|
2023-03-08 14:36:53 -03:00
|
|
|
m_startTime = deltaTime;
|
2023-03-08 14:15:13 -03:00
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_status == EncounterFightStatus::ACTIVE && ifrit && !ifrit->hateListGetHighest()->isAlive() )
|
|
|
|
{
|
|
|
|
m_status = EncounterFightStatus::FAIL;
|
|
|
|
}
|
2023-03-08 14:36:53 -03:00
|
|
|
|
2023-03-08 11:59:45 -03:00
|
|
|
if( m_stateStack; !m_stateStack->empty() )
|
|
|
|
{
|
|
|
|
if( m_stateStack->top()->shouldFinish() )
|
|
|
|
{
|
|
|
|
m_stateStack->top()->finish();
|
|
|
|
m_stateStack->pop();
|
|
|
|
}
|
2023-03-08 21:14:04 -03:00
|
|
|
|
|
|
|
if( !m_stateStack->empty() )
|
|
|
|
m_stateStack->top()->update( deltaTime );
|
2023-03-08 11:59:45 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|