mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-07 03:07:45 +00:00
Merge pull request #837 from Skyliegirl33/feature-impl
[3.x] Fix a few issues, add SubSea005 QB
This commit is contained in:
commit
96249275f7
7 changed files with 166 additions and 23 deletions
|
@ -1,5 +1,8 @@
|
||||||
#include <ScriptObject.h>
|
#include <ScriptObject.h>
|
||||||
#include <Territory/QuestBattle.h>
|
#include <Territory/QuestBattle.h>
|
||||||
|
#include <Actor/Player.h>
|
||||||
|
#include <Actor/GameObject.h>
|
||||||
|
#include <Actor/BNpc.h>
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
|
|
||||||
|
@ -16,6 +19,14 @@ private:
|
||||||
static constexpr auto INIT_P_POP_01 = 4083622;
|
static constexpr auto INIT_P_POP_01 = 4083622;
|
||||||
static constexpr auto CUT_SCENE_01 = 133;
|
static constexpr auto CUT_SCENE_01 = 133;
|
||||||
static constexpr auto HOW_TO_QIB = 79;
|
static constexpr auto HOW_TO_QIB = 79;
|
||||||
|
static constexpr auto TEXT_YSHTOLA_BATTLETALK_01 = 82;
|
||||||
|
|
||||||
|
enum Variables : uint8_t
|
||||||
|
{
|
||||||
|
SET_1_SPAWNED,
|
||||||
|
SET_2_SPAWNED,
|
||||||
|
SUCCESS_CALLED
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LurkersintheGrotto() : Sapphire::ScriptAPI::QuestBattleScript( 35 )
|
LurkersintheGrotto() : Sapphire::ScriptAPI::QuestBattleScript( 35 )
|
||||||
|
@ -135,15 +146,106 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
player.setRot( 0 );
|
||||||
|
player.setPos( { -60, 25, -135 } );
|
||||||
|
}
|
||||||
|
|
||||||
void onUpdate( QuestBattle& instance, uint64_t tickCount ) override
|
void onUpdate( QuestBattle& instance, uint64_t tickCount ) override
|
||||||
{
|
{
|
||||||
|
auto set1Spawned = instance.getDirectorVar( Variables::SET_1_SPAWNED );
|
||||||
|
auto set2Spawned = instance.getDirectorVar( Variables::SET_2_SPAWNED );
|
||||||
|
auto successCalled = instance.getDirectorVar( Variables::SUCCESS_CALLED );
|
||||||
|
|
||||||
|
auto boss = instance.getActiveBNpcByLayoutId( INIT_POP_BOSS );
|
||||||
|
auto ysthola = instance.getActiveBNpcByLayoutId( INIT_P_POP_01 );
|
||||||
|
auto pPlayer = instance.getPlayerPtr();
|
||||||
|
|
||||||
|
auto bossHp = boss ? boss->getHpPercent() : 0;
|
||||||
|
|
||||||
|
if( pPlayer && !pPlayer->isAlive() )
|
||||||
|
{
|
||||||
|
instance.fail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !set1Spawned && bossHp <= 75 )
|
||||||
|
{
|
||||||
|
auto a1 = instance.createBNpcFromLayoutId( INIT_POP_01_01, 100, Common::BNpcType::Enemy );
|
||||||
|
auto a2 = instance.createBNpcFromLayoutId( INIT_POP_01_02, 100, Common::BNpcType::Enemy );
|
||||||
|
|
||||||
|
a1->setFlag( Entity::NoDeaggro );
|
||||||
|
a2->setFlag( Entity::NoDeaggro );
|
||||||
|
|
||||||
|
a1->hateListAdd( pPlayer, 1 );
|
||||||
|
a2->hateListAdd( pPlayer, 1 );
|
||||||
|
|
||||||
|
instance.setDirectorVar( Variables::SET_1_SPAWNED, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !set2Spawned && bossHp <= 25 )
|
||||||
|
{
|
||||||
|
auto a3 = instance.createBNpcFromLayoutId( INIT_POP_02_01, 150, Common::BNpcType::Enemy );
|
||||||
|
auto a4 = instance.createBNpcFromLayoutId( INIT_POP_02_02, 150, Common::BNpcType::Enemy );
|
||||||
|
auto a5 = instance.createBNpcFromLayoutId( INIT_POP_02_03, 100, Common::BNpcType::Enemy );
|
||||||
|
auto a6 = instance.createBNpcFromLayoutId( INIT_POP_02_04, 100, Common::BNpcType::Enemy );
|
||||||
|
|
||||||
|
a3->setFlag( Entity::NoDeaggro );
|
||||||
|
a4->setFlag( Entity::NoDeaggro );
|
||||||
|
a5->setFlag( Entity::NoDeaggro );
|
||||||
|
a6->setFlag( Entity::NoDeaggro );
|
||||||
|
|
||||||
|
a3->hateListAdd( pPlayer, 1 );
|
||||||
|
a4->hateListAdd( pPlayer, 1 );
|
||||||
|
a5->hateListAdd( pPlayer, 1 );
|
||||||
|
a6->hateListAdd( pPlayer, 1 );
|
||||||
|
|
||||||
|
instance.setDirectorVar( Variables::SET_2_SPAWNED, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !successCalled && instance.getCountEnemyBNpc() == 0 )
|
||||||
|
{
|
||||||
|
instance.setDirectorVar( Variables::SUCCESS_CALLED, true );
|
||||||
|
instance.success();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onEnterTerritory( QuestBattle& instance, Entity::Player& player, uint32_t eventId, uint16_t param1,
|
void onEnterTerritory( QuestBattle& instance, Entity::Player& player, uint32_t eventId, uint16_t param1,
|
||||||
uint16_t param2 ) override
|
uint16_t param2 ) override
|
||||||
{
|
{
|
||||||
|
eventMgr().playScene( player, instance.getDirectorId(), 1,
|
||||||
|
NO_DEFAULT_CAMERA | CONDITION_CUTSCENE | SILENT_ENTER_TERRI_ENV |
|
||||||
|
HIDE_HOTBAR | SILENT_ENTER_TERRI_BGM | SILENT_ENTER_TERRI_SE |
|
||||||
|
DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR |
|
||||||
|
// todo: wtf is 0x00100000
|
||||||
|
DISABLE_CANCEL_EMOTE, [ & ]( Entity::Player& player, const Event::SceneResult& result )
|
||||||
|
{
|
||||||
|
player.setOnEnterEventDone( true );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDutyComplete( QuestBattle& instance, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
auto idx = player.getQuestIndex( instance.getQuestId() );
|
||||||
|
if( idx == -1 )
|
||||||
|
return;
|
||||||
|
auto& quest = player.getQuestByIndex( idx );
|
||||||
|
quest.setSeq( 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDutyCommence( QuestBattle& instance, Entity::Player& player ) override
|
||||||
|
{
|
||||||
|
auto boss = instance.createBNpcFromLayoutId( INIT_POP_BOSS, 2000, Common::BNpcType::Enemy );
|
||||||
|
auto ysthola = instance.createBNpcFromLayoutId( INIT_P_POP_01, 27780, Common::BNpcType::Friendly );
|
||||||
|
|
||||||
|
boss->setFlag( Entity::NoDeaggro );
|
||||||
|
ysthola->setFlag( Entity::NoDeaggro );
|
||||||
|
|
||||||
|
boss->hateListAdd( ysthola, 10000 );
|
||||||
|
boss->hateListAdd( player.getAsPlayer(), 1 );
|
||||||
|
|
||||||
|
ysthola->hateListAdd( boss, 10000 );
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,5 +86,5 @@ void ItemAction::handleMountItem()
|
||||||
auto player = getSourceChara()->getAsPlayer();
|
auto player = getSourceChara()->getAsPlayer();
|
||||||
|
|
||||||
player->unlockMount( m_itemAction->data().Calcu0Arg[ 0 ] );
|
player->unlockMount( m_itemAction->data().Calcu0Arg[ 0 ] );
|
||||||
player->dropInventoryItem( static_cast< Common::InventoryType >( m_itemSourceContainer ), static_cast< uint8_t >( m_itemSourceSlot ) );
|
player->discardItem( m_itemSourceContainer, m_itemSourceSlot );
|
||||||
}
|
}
|
|
@ -1507,6 +1507,7 @@ void Player::sendZonePackets()
|
||||||
initPacket->data().playerActorId = getId();
|
initPacket->data().playerActorId = getId();
|
||||||
queuePacket( initPacket );
|
queuePacket( initPacket );
|
||||||
|
|
||||||
|
sendStatusUpdate();
|
||||||
sendInventory();
|
sendInventory();
|
||||||
|
|
||||||
if( isLogin() )
|
if( isLogin() )
|
||||||
|
|
|
@ -354,18 +354,62 @@ void EventMgr::handleReturnStringEventScene( Entity::Player& player, uint32_t ev
|
||||||
result.sceneId = sceneId;
|
result.sceneId = sceneId;
|
||||||
result.resultString = resultString;
|
result.resultString = resultString;
|
||||||
|
|
||||||
auto eventCallback = pEvent->getEventReturnCallback();
|
if( eventType == Event::EventHandler::EventHandlerType::Quest )
|
||||||
if( eventCallback )
|
|
||||||
{
|
{
|
||||||
eventCallback( player, result );
|
auto questId = static_cast< uint16_t >( eventId );
|
||||||
|
auto eventCallback = pEvent->getQuestEventReturnCallback();
|
||||||
|
if( eventCallback )
|
||||||
|
{
|
||||||
|
World::Quest preQ;
|
||||||
|
if( player.hasQuest( eventId ) )
|
||||||
|
{
|
||||||
|
auto questIdx = player.getQuestIndex( questId );
|
||||||
|
auto& quest = player.getQuestByIndex( questIdx );
|
||||||
|
preQ = quest;
|
||||||
|
eventCallback( quest, player, result );
|
||||||
|
if( quest != preQ )
|
||||||
|
player.updateQuest( quest );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto newQuest = World::Quest( questId, 0, 0 );
|
||||||
|
preQ = newQuest;
|
||||||
|
eventCallback( newQuest, player, result );
|
||||||
|
if( newQuest != preQ )
|
||||||
|
player.updateQuest( newQuest );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( auto chainCallback = pEvent->getQuestSceneChainCallback() )
|
||||||
|
{
|
||||||
|
if( player.hasQuest( eventId ) )
|
||||||
|
{
|
||||||
|
auto questIdx = player.getQuestIndex( questId );
|
||||||
|
auto& quest = player.getQuestByIndex( questIdx );
|
||||||
|
chainCallback( quest, player );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto newQuest = World::Quest( questId, 0, 0 );
|
||||||
|
chainCallback( newQuest, player );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto eventCallback = pEvent->getEventReturnCallback();
|
||||||
|
if( eventCallback )
|
||||||
|
{
|
||||||
|
eventCallback( player, result );
|
||||||
|
}
|
||||||
|
|
||||||
// we might have a scene chain callback instead so check for that too
|
// we might have a scene chain callback instead so check for that too
|
||||||
else if( auto chainCallback = pEvent->getSceneChainCallback() )
|
else if( auto chainCallback = pEvent->getSceneChainCallback() )
|
||||||
chainCallback( player );
|
chainCallback( player );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEvent( player, eventId );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventMgr::handleReturnIntAndStringEventScene( Entity::Player& player, uint32_t eventId, uint16_t sceneId, const std::string& resultString, uint64_t resultInt )
|
void EventMgr::handleReturnIntAndStringEventScene( Entity::Player& player, uint32_t eventId, uint16_t sceneId, const std::string& resultString, uint64_t resultInt )
|
||||||
|
|
|
@ -85,6 +85,7 @@ void WarpMgr::finishWarp( Entity::Player& player )
|
||||||
player.sendToInRangeSet( zoneInPacket );
|
player.sendToInRangeSet( zoneInPacket );
|
||||||
|
|
||||||
player.sendToInRangeSet( SetStatusPacket, true );
|
player.sendToInRangeSet( SetStatusPacket, true );
|
||||||
|
player.sendStatusUpdate();
|
||||||
|
|
||||||
auto& server = Common::Service< WorldServer >::ref();
|
auto& server = Common::Service< WorldServer >::ref();
|
||||||
server.queueForPlayer( player.getCharacterId(), zoneInPacket );
|
server.queueForPlayer( player.getCharacterId(), zoneInPacket );
|
||||||
|
|
|
@ -25,31 +25,31 @@ bool Sapphire::World::Quest::getBitFlag8( uint8_t index )
|
||||||
|
|
||||||
bool Sapphire::World::Quest::getBitFlag16( uint8_t index )
|
bool Sapphire::World::Quest::getBitFlag16( uint8_t index )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 16 - index;
|
||||||
return m_data.a.BitFlag16 & ( 1 << realIdx );
|
return m_data.a.BitFlag16 & ( 1 << realIdx );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::World::Quest::getBitFlag24( uint8_t index )
|
bool Sapphire::World::Quest::getBitFlag24( uint8_t index )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 24 - index;
|
||||||
return m_data.a.BitFlag24 & ( 1 << realIdx );
|
return m_data.a.BitFlag24 & ( 1 << realIdx );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::World::Quest::getBitFlag32( uint8_t index )
|
bool Sapphire::World::Quest::getBitFlag32( uint8_t index )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 32 - index;
|
||||||
return m_data.a.BitFlag32 & ( 1 << realIdx );
|
return m_data.a.BitFlag32 & ( 1 << realIdx );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::World::Quest::getBitFlag40( uint8_t index )
|
bool Sapphire::World::Quest::getBitFlag40( uint8_t index )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 40 - index;
|
||||||
return m_data.a.BitFlag40 & ( 1 << realIdx );
|
return m_data.a.BitFlag40 & ( 1 << realIdx );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::World::Quest::getBitFlag48( uint8_t index )
|
bool Sapphire::World::Quest::getBitFlag48( uint8_t index )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 48 - index;
|
||||||
return m_data.a.BitFlag48 & ( 1 << realIdx );
|
return m_data.a.BitFlag48 & ( 1 << realIdx );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +312,6 @@ void Sapphire::World::Quest::setUI32A( uint32_t val )
|
||||||
void Sapphire::World::Quest::setBitFlag8( uint8_t index, bool val )
|
void Sapphire::World::Quest::setBitFlag8( uint8_t index, bool val )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 8 - index;
|
||||||
|
|
||||||
if( val )
|
if( val )
|
||||||
m_data.a.BitFlag8 |= ( 1 << realIdx );
|
m_data.a.BitFlag8 |= ( 1 << realIdx );
|
||||||
else
|
else
|
||||||
|
@ -321,8 +320,7 @@ void Sapphire::World::Quest::setBitFlag8( uint8_t index, bool val )
|
||||||
|
|
||||||
void Sapphire::World::Quest::setBitFlag16( uint8_t index, bool val )
|
void Sapphire::World::Quest::setBitFlag16( uint8_t index, bool val )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 16 - index;
|
||||||
|
|
||||||
if( val )
|
if( val )
|
||||||
m_data.a.BitFlag16 |= ( 1 << realIdx );
|
m_data.a.BitFlag16 |= ( 1 << realIdx );
|
||||||
else
|
else
|
||||||
|
@ -331,8 +329,7 @@ void Sapphire::World::Quest::setBitFlag16( uint8_t index, bool val )
|
||||||
|
|
||||||
void Sapphire::World::Quest::setBitFlag24( uint8_t index, bool val )
|
void Sapphire::World::Quest::setBitFlag24( uint8_t index, bool val )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 24 - index;
|
||||||
|
|
||||||
if( val )
|
if( val )
|
||||||
m_data.a.BitFlag24 |= ( 1 << realIdx );
|
m_data.a.BitFlag24 |= ( 1 << realIdx );
|
||||||
else
|
else
|
||||||
|
@ -341,8 +338,7 @@ void Sapphire::World::Quest::setBitFlag24( uint8_t index, bool val )
|
||||||
|
|
||||||
void Sapphire::World::Quest::setBitFlag32( uint8_t index, bool val )
|
void Sapphire::World::Quest::setBitFlag32( uint8_t index, bool val )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 32 - index;
|
||||||
|
|
||||||
if( val )
|
if( val )
|
||||||
m_data.a.BitFlag32 |= ( 1 << realIdx );
|
m_data.a.BitFlag32 |= ( 1 << realIdx );
|
||||||
else
|
else
|
||||||
|
@ -351,8 +347,7 @@ void Sapphire::World::Quest::setBitFlag32( uint8_t index, bool val )
|
||||||
|
|
||||||
void Sapphire::World::Quest::setBitFlag40( uint8_t index, bool val )
|
void Sapphire::World::Quest::setBitFlag40( uint8_t index, bool val )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 40 - index;
|
||||||
|
|
||||||
if( val )
|
if( val )
|
||||||
m_data.a.BitFlag40 |= ( 1 << realIdx );
|
m_data.a.BitFlag40 |= ( 1 << realIdx );
|
||||||
else
|
else
|
||||||
|
@ -361,8 +356,7 @@ void Sapphire::World::Quest::setBitFlag40( uint8_t index, bool val )
|
||||||
|
|
||||||
void Sapphire::World::Quest::setBitFlag48( uint8_t index, bool val )
|
void Sapphire::World::Quest::setBitFlag48( uint8_t index, bool val )
|
||||||
{
|
{
|
||||||
uint8_t realIdx = 8 - index;
|
uint8_t realIdx = 48 - index;
|
||||||
|
|
||||||
if( val )
|
if( val )
|
||||||
m_data.a.BitFlag48 |= ( 1 << realIdx );
|
m_data.a.BitFlag48 |= ( 1 << realIdx );
|
||||||
else
|
else
|
||||||
|
|
|
@ -490,7 +490,8 @@ void Territory::updateSessions( uint64_t tickCount, bool changedWeather )
|
||||||
}
|
}
|
||||||
|
|
||||||
// this session is not linked to this area anymore, remove it from zone session list
|
// this session is not linked to this area anymore, remove it from zone session list
|
||||||
if( pPlayer->getTerritoryId() != m_guId )
|
// TODO: Retrieving the session is expensive, try to find a better method of removing invalid actors
|
||||||
|
if( pPlayer->getTerritoryId() != m_guId || !server.getSession( pPlayer->getId() ) )
|
||||||
{
|
{
|
||||||
Logger::debug( "[{}] removeActor( pPlayer );", pPlayer->getId() );
|
Logger::debug( "[{}] removeActor( pPlayer );", pPlayer->getId() );
|
||||||
removeActor( pPlayer );
|
removeActor( pPlayer );
|
||||||
|
|
Loading…
Add table
Reference in a new issue