1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 06:47:45 +00:00

First iteration of questbattle update logic

This commit is contained in:
Mordred 2019-04-17 00:10:32 +02:00
parent a8bb58e51c
commit 6c43c79af1
17 changed files with 180 additions and 21 deletions

View file

@ -576,7 +576,7 @@ namespace Sapphire::Network::Packets::Server
uint32_t u15; uint32_t u15;
uint32_t bNPCBase; uint32_t bNPCBase;
uint32_t bNPCName; uint32_t bNPCName;
uint32_t u18; uint32_t levelId;
uint32_t u19; uint32_t u19;
uint32_t directorId; uint32_t directorId;
uint32_t spawnerId; uint32_t spawnerId;

View file

@ -27,9 +27,14 @@ private:
static constexpr auto CUT_SCENE_01 = 54; static constexpr auto CUT_SCENE_01 = 54;
static constexpr auto HOW_TO_QIB = 79; static constexpr auto HOW_TO_QIB = 79;
enum vars
{
SET_1_SPAWNED,
SET_2_SPAWNED
};
public: public:
ChasingShadows() : Sapphire::ScriptAPI::QuestBattleScript( 11 ) ChasingShadows() : Sapphire::ScriptAPI::QuestBattleScript( 11 ) {}
{ }
void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player ) void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player )
{ {
@ -40,25 +45,35 @@ public:
void onInit( QuestBattle& instance ) override void onInit( QuestBattle& instance ) override
{ {
instance.registerEObj( "unknown_0", 2005192, 5760474, 4, { -51.493111f, 0.309087f, 71.436897f }, 1.000000f, -0.000006f ); instance.registerEObj( "unknown_0", 2005192, 5760474, 4, { -51.493111f, 0.309087f, 71.436897f }, 1.000000f, -0.000006f );
auto a1 = instance.createBNpcFromLevelEntry( INIT_POP_BOSS, 12, 0, 21141, 939,
instance.getDirectorId(), Common::BNpcType::Enemy );
auto a2 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_01, 10, 0, 1440, 938,
instance.getDirectorId(), Common::BNpcType::Enemy );
auto a3 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_02, 10, 0, 1440, 938,
instance.getDirectorId(), Common::BNpcType::Enemy );
instance.pushActor( a1 );
instance.pushActor( a2 );
instance.pushActor( a3 );
auto a4 = instance.createBNpcFromLevelEntry( INIT_P_POP_IDA, 50, 0, 27780, 1375,
instance.getDirectorId(), Common::BNpcType::Friendly );
auto a5 = instance.createBNpcFromLevelEntry( INIT_P_POP_PAPARIMO, 50, 0, 27780, 1376,
instance.getDirectorId(), Common::BNpcType::Friendly );
instance.pushActor( a4 );
instance.pushActor( a5 );
} }
void onUpdate( QuestBattle& instance, uint64_t tickCount ) override void onUpdate( QuestBattle& instance, uint64_t tickCount ) override
{ {
auto pair1Spawnd = instance.getCustomVar( SET_1_SPAWNED );
auto boss = instance.getActiveBNpcByLevelId( INIT_POP_BOSS );
if( !boss )
return;
if( pair1Spawnd == 0 && boss->getHpPercent() <= 90 )
{
instance.setCustomVar( SET_1_SPAWNED, 1 );
auto a2 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_03, 10, 0, 1440, 938,
instance.getDirectorId(), Common::BNpcType::Enemy );
auto a3 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_04, 10, 0, 1440, 938,
instance.getDirectorId(), Common::BNpcType::Enemy );
instance.pushActor( a2 );
instance.pushActor( a3 );
auto pPlayer = instance.getPlayerPtr();
a2->hateListAdd( pPlayer, 1 );
pPlayer->hateListAdd( a2 );
a3->hateListAdd( pPlayer, 1 );
pPlayer->hateListAdd( a3 );
}
} }
@ -71,6 +86,7 @@ public:
DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR | DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR |
// todo: wtf is 0x00100000 // todo: wtf is 0x00100000
DISABLE_CANCEL_EMOTE, 0 ); DISABLE_CANCEL_EMOTE, 0 );
} }
void onDutyComplete( QuestBattle& instance, Entity::Player& player ) override void onDutyComplete( QuestBattle& instance, Entity::Player& player ) override
@ -78,6 +94,47 @@ public:
player.updateQuest( instance.getQuestId(), 2 ); player.updateQuest( instance.getQuestId(), 2 );
} }
void onDutyCommence( QuestBattle& instance, Entity::Player& player ) override
{
auto a1 = instance.createBNpcFromLevelEntry( INIT_POP_BOSS, 12, 0, 21141, 939,
instance.getDirectorId(), Common::BNpcType::Enemy );
auto a2 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_01, 10, 0, 1440, 938,
instance.getDirectorId(), Common::BNpcType::Enemy );
auto a3 = instance.createBNpcFromLevelEntry( INIT_POP_ENEMY_B_02, 10, 0, 1440, 938,
instance.getDirectorId(), Common::BNpcType::Enemy );
auto a4 = instance.createBNpcFromLevelEntry( INIT_P_POP_IDA, 50, 0, 27780, 1375,
instance.getDirectorId(), Common::BNpcType::Friendly );
auto a5 = instance.createBNpcFromLevelEntry( INIT_P_POP_PAPARIMO, 50, 0, 27780, 1376,
instance.getDirectorId(), Common::BNpcType::Friendly );
instance.pushActor( a1 );
instance.pushActor( a2 );
instance.pushActor( a3 );
instance.pushActor( a4 );
instance.pushActor( a5 );
a1->hateListAdd( a4, 10000 );
a1->hateListAdd( a5, 10000 );
a2->hateListAdd( a4, 10000 );
a2->hateListAdd( a5, 10000 );
a2->hateListAdd( player.getAsPlayer(), 1 );
player.hateListAdd( a2 );
a3->hateListAdd( a4, 10000 );
a3->hateListAdd( a5, 10000 );
a3->hateListAdd( player.getAsPlayer(), 1 );
player.hateListAdd( a3 );
a4->hateListAdd( a1, 10000 );
a4->hateListAdd( a2, 9999 );
a4->hateListAdd( a3, 9999 );
a5->hateListAdd( a1, 10000 );
a5->hateListAdd( a2, 9999 );
a5->hateListAdd( a3, 9999 );
}
}; };
EXPOSE_SCRIPT( ChasingShadows ); EXPOSE_SCRIPT( ChasingShadows );

View file

@ -68,6 +68,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX
m_level = level; m_level = level;
m_invincibilityType = InvincibilityNone; m_invincibilityType = InvincibilityNone;
m_currentStance = Common::Stance::Passive; m_currentStance = Common::Stance::Passive;
m_levelId = 0;
m_pCurrentZone = pZone; m_pCurrentZone = pZone;
@ -157,6 +158,7 @@ uint32_t Sapphire::Entity::BNpc::getBNpcNameId() const
void Sapphire::Entity::BNpc::spawn( PlayerPtr pTarget ) void Sapphire::Entity::BNpc::spawn( PlayerPtr pTarget )
{ {
m_lastRoamTargetReached = Util::getTimeSeconds();
pTarget->queuePacket( std::make_shared< NpcSpawnPacket >( *this, *pTarget ) ); pTarget->queuePacket( std::make_shared< NpcSpawnPacket >( *this, *pTarget ) );
} }
@ -393,11 +395,11 @@ void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::CharaPtr pChara )
m_state = BNpcState::Combat; m_state = BNpcState::Combat;
sendToInRangeSet( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 1, 1, 0 ) ); sendToInRangeSet( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 1, 1, 0 ) );
sendToInRangeSet( makeActorControl142( getId(), ActorControlType::ToggleAggro, 1, 0, 0 ) );
if( pChara->isPlayer() ) if( pChara->isPlayer() )
{ {
PlayerPtr tmpPlayer = pChara->getAsPlayer(); PlayerPtr tmpPlayer = pChara->getAsPlayer();
sendToInRangeSet( makeActorControl142( getId(), ActorControlType::ToggleAggro, 1, 0, 0 ) );
tmpPlayer->onMobAggro( getAsBNpc() ); tmpPlayer->onMobAggro( getAsBNpc() );
} }
@ -472,6 +474,10 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
case BNpcState::Idle: case BNpcState::Idle:
{ {
auto pHatedActor = hateListGetHighest();
if( pHatedActor )
aggro( pHatedActor );
if( Util::getTimeSeconds() - m_lastRoamTargetReached > roamTick ) if( Util::getTimeSeconds() - m_lastRoamTargetReached > roamTick )
{ {
auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >();
@ -690,3 +696,13 @@ void Sapphire::Entity::BNpc::setOwner( Sapphire::Entity::CharaPtr m_pChara )
sendToInRangeSet( setOwnerPacket ); sendToInRangeSet( setOwnerPacket );
} }
} }
void Sapphire::Entity::BNpc::setLevelId( uint32_t levelId )
{
m_levelId = levelId;
}
uint32_t Sapphire::Entity::BNpc::getLevelId() const
{
return m_levelId;
}

View file

@ -102,6 +102,9 @@ namespace Sapphire::Entity
void setOwner( CharaPtr m_pChara ); void setOwner( CharaPtr m_pChara );
void setLevelId( uint32_t levelId );
uint32_t getLevelId() const;
private: private:
uint32_t m_bNpcBaseId; uint32_t m_bNpcBaseId;
uint32_t m_bNpcNameId; uint32_t m_bNpcNameId;
@ -114,6 +117,7 @@ namespace Sapphire::Entity
uint16_t m_modelChara; uint16_t m_modelChara;
uint32_t m_displayFlags; uint32_t m_displayFlags;
uint8_t m_level; uint8_t m_level;
uint32_t m_levelId;
float m_scale; float m_scale;
float m_naviTargetReachedDistance; float m_naviTargetReachedDistance;

View file

@ -81,6 +81,11 @@ uint32_t Sapphire::Entity::Chara::getHp() const
return m_hp; return m_hp;
} }
uint32_t Sapphire::Entity::Chara::getHpPercent() const
{
return ( m_hp * 100 ) / m_maxHp;
}
/*! \return current MP */ /*! \return current MP */
uint32_t Sapphire::Entity::Chara::getMp() const uint32_t Sapphire::Entity::Chara::getMp() const
{ {

View file

@ -187,6 +187,8 @@ namespace Sapphire::Entity
uint32_t getHp() const; uint32_t getHp() const;
uint32_t getHpPercent() const;
uint32_t getMp() const; uint32_t getMp() const;
uint16_t getTp() const; uint16_t getTp() const;

View file

@ -182,3 +182,16 @@ void Sapphire::Event::Director::setDirectorSequence( uint8_t value )
{ {
m_sequence = value; m_sequence = value;
} }
void Sapphire::Event::Director::setCustomVar( uint32_t varId, uint32_t value )
{
m_customVarMap[ varId ] = value;
}
uint32_t Sapphire::Event::Director::getCustomVar( uint32_t varId )
{
auto it = m_customVarMap.find( varId );
if( it != m_customVarMap.end() )
return it->second;
return 0;
}

View file

@ -102,6 +102,9 @@ namespace Sapphire::Event
void setDirectorBranch( uint8_t value ); void setDirectorBranch( uint8_t value );
void setCustomVar( uint32_t varId, uint32_t value );
uint32_t getCustomVar( uint32_t varId );
private: private:
/*! Id of the content of the director */ /*! Id of the content of the director */
uint16_t m_contentId; uint16_t m_contentId;
@ -178,6 +181,7 @@ namespace Sapphire::Event
uint32_t m_elapsedTime; uint32_t m_elapsedTime;
std::unordered_map< uint32_t, uint32_t > m_customVarMap;
}; };

View file

@ -50,6 +50,7 @@ namespace Sapphire::Network::Packets::Server
m_data.pos.y = bnpc.getPos().y; m_data.pos.y = bnpc.getPos().y;
m_data.pos.z = bnpc.getPos().z; m_data.pos.z = bnpc.getPos().z;
m_data.rotation = Util::floatToUInt16Rot( bnpc.getRot() ); m_data.rotation = Util::floatToUInt16Rot( bnpc.getRot() );
m_data.levelId = bnpc.getLevelId();
m_data.enemyType = bnpc.getEnemyType(); m_data.enemyType = bnpc.getEnemyType();
m_data.mainWeaponModel = bnpc.getWeaponMain(); m_data.mainWeaponModel = bnpc.getWeaponMain();

View file

@ -218,6 +218,10 @@ namespace Sapphire::ScriptAPI
{ {
} }
void QuestBattleScript::onDutyCommence( QuestBattle& instance, Entity::Player& player )
{
}
void QuestBattleScript::onEnterTerritory( QuestBattle& instance, Entity::Player& player, uint32_t eventId, void QuestBattleScript::onEnterTerritory( QuestBattle& instance, Entity::Player& player, uint32_t eventId,
uint16_t param1, uint16_t param2 ) uint16_t param1, uint16_t param2 )
{ {

View file

@ -241,6 +241,8 @@ namespace Sapphire::ScriptAPI
virtual void onDutyComplete( Sapphire::QuestBattle& instance, Entity::Player& player ); virtual void onDutyComplete( Sapphire::QuestBattle& instance, Entity::Player& player );
virtual void onDutyCommence( QuestBattle& instance, Entity::Player& player );
virtual void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player ); virtual void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player );
virtual void onInit( Sapphire::QuestBattle& instance ); virtual void onInit( Sapphire::QuestBattle& instance );

View file

@ -499,6 +499,20 @@ bool Sapphire::Scripting::ScriptMgr::onInstanceUpdate( QuestBattlePtr instance,
return false; return false;
} }
bool Sapphire::Scripting::ScriptMgr::onDutyCommence( QuestBattle& instance, Entity::Player& player )
{
auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::QuestBattleScript >( instance.getDirectorId() );
if( script )
{
script->onDutyCommence( instance, player );
return true;
}
return false;
}
bool Sapphire::Scripting::ScriptMgr::onInstanceEnterTerritory( QuestBattlePtr instance, Entity::Player& player, bool Sapphire::Scripting::ScriptMgr::onInstanceEnterTerritory( QuestBattlePtr instance, Entity::Player& player,
uint32_t eventId, uint16_t param1, uint16_t param2 ) uint32_t eventId, uint16_t param1, uint16_t param2 )
{ {

View file

@ -106,6 +106,8 @@ namespace Sapphire::Scripting
bool onInstanceUpdate( QuestBattlePtr instance, uint64_t tickCount ); bool onInstanceUpdate( QuestBattlePtr instance, uint64_t tickCount );
bool onDutyCommence( QuestBattle& instance, Entity::Player& player );
bool onInstanceEnterTerritory( QuestBattlePtr instance, Entity::Player& player, uint32_t eventId, uint16_t param1, bool onInstanceEnterTerritory( QuestBattlePtr instance, Entity::Player& player, uint32_t eventId, uint16_t param1,
uint16_t param2 ); uint16_t param2 );

View file

@ -145,6 +145,7 @@ void Sapphire::InstanceContent::onUpdate( uint64_t tickCount )
case DutyInProgress: case DutyInProgress:
{ {
updateBNpcs( tickCount );
break; break;
} }

View file

@ -119,6 +119,8 @@ void Sapphire::QuestBattle::onUpdate( uint64_t tickCount )
return; return;
onEnterSceneFinish( *m_pPlayer ); onEnterSceneFinish( *m_pPlayer );
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
pScriptMgr->onDutyCommence( *this, *m_pPlayer );
m_state = DutyInProgress; m_state = DutyInProgress;
m_instanceExpireTime = Util::getTimeSeconds() + ( m_pBattleDetails->timeLimit * 60u ); m_instanceExpireTime = Util::getTimeSeconds() + ( m_pBattleDetails->timeLimit * 60u );
@ -129,6 +131,7 @@ void Sapphire::QuestBattle::onUpdate( uint64_t tickCount )
break; break;
case DutyInProgress: case DutyInProgress:
updateBNpcs( tickCount );
break; break;
case DutyFinished: case DutyFinished:
@ -464,5 +467,32 @@ Sapphire::Entity::BNpcPtr
levelData->yaw, level, hp, shared_from_this(), m_pFw ); levelData->yaw, level, hp, shared_from_this(), m_pFw );
bnpc->setDirectorId( directorId ); bnpc->setDirectorId( directorId );
bnpc->setLevelId( levelId );
return bnpc; return bnpc;
} }
Sapphire::Entity::BNpcPtr Sapphire::QuestBattle::getActiveBNpcByLevelId( uint32_t levelId )
{
for( auto bnpcIt : m_bNpcMap )
{
if( bnpcIt.second->getLevelId() == levelId )
return bnpcIt.second;
}
return nullptr;
}
uint32_t Sapphire::QuestBattle::getCountEnemyBNpc()
{
uint32_t count = 0;
for( auto bnpcIt : m_bNpcMap )
{
if( bnpcIt.second->getEnemyType() == 4 )
count++;
}
return count;
}
Sapphire::Entity::PlayerPtr Sapphire::QuestBattle::getPlayerPtr()
{
return m_pPlayer;
}

View file

@ -66,6 +66,9 @@ namespace Sapphire
void fail(); void fail();
void success(); void success();
Entity::BNpcPtr getActiveBNpcByLevelId( uint32_t levelId );
uint32_t getCountEnemyBNpc();
void clearDirector( Entity::Player& player ); void clearDirector( Entity::Player& player );
Event::Director::DirectorState getState() const; Event::Director::DirectorState getState() const;
@ -83,6 +86,8 @@ namespace Sapphire
uint32_t hp, uint16_t nameId, uint32_t directorId, uint32_t hp, uint16_t nameId, uint32_t directorId,
uint8_t bnpcType ); uint8_t bnpcType );
Entity::PlayerPtr getPlayerPtr();
private: private:
std::shared_ptr< Sapphire::Data::QuestBattle > m_pBattleDetails; std::shared_ptr< Sapphire::Data::QuestBattle > m_pBattleDetails;
uint32_t m_questBattleId; uint32_t m_questBattleId;

View file

@ -451,7 +451,6 @@ bool Sapphire::Zone::update( uint64_t tickCount )
bool changedWeather = checkWeather(); bool changedWeather = checkWeather();
updateSessions( tickCount, changedWeather ); updateSessions( tickCount, changedWeather );
updateBNpcs( tickCount );
onUpdate( tickCount ); onUpdate( tickCount );
updateSpawnPoints(); updateSpawnPoints();
@ -708,7 +707,7 @@ void Sapphire::Zone::onLeaveTerritory( Entity::Player& player )
void Sapphire::Zone::onUpdate( uint64_t tickCount ) void Sapphire::Zone::onUpdate( uint64_t tickCount )
{ {
updateBNpcs( tickCount );
} }
void Sapphire::Zone::onFinishLoading( Entity::Player& player ) void Sapphire::Zone::onFinishLoading( Entity::Player& player )