mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-26 22:37:45 +00:00
First iteration of questbattle update logic
This commit is contained in:
parent
a8bb58e51c
commit
6c43c79af1
17 changed files with 180 additions and 21 deletions
|
@ -576,7 +576,7 @@ namespace Sapphire::Network::Packets::Server
|
|||
uint32_t u15;
|
||||
uint32_t bNPCBase;
|
||||
uint32_t bNPCName;
|
||||
uint32_t u18;
|
||||
uint32_t levelId;
|
||||
uint32_t u19;
|
||||
uint32_t directorId;
|
||||
uint32_t spawnerId;
|
||||
|
|
|
@ -27,9 +27,14 @@ private:
|
|||
static constexpr auto CUT_SCENE_01 = 54;
|
||||
static constexpr auto HOW_TO_QIB = 79;
|
||||
|
||||
enum vars
|
||||
{
|
||||
SET_1_SPAWNED,
|
||||
SET_2_SPAWNED
|
||||
};
|
||||
|
||||
public:
|
||||
ChasingShadows() : Sapphire::ScriptAPI::QuestBattleScript( 11 )
|
||||
{ }
|
||||
ChasingShadows() : Sapphire::ScriptAPI::QuestBattleScript( 11 ) {}
|
||||
|
||||
void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player )
|
||||
{
|
||||
|
@ -40,25 +45,35 @@ public:
|
|||
void onInit( QuestBattle& instance ) override
|
||||
{
|
||||
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
|
||||
{
|
||||
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 |
|
||||
// todo: wtf is 0x00100000
|
||||
DISABLE_CANCEL_EMOTE, 0 );
|
||||
|
||||
}
|
||||
|
||||
void onDutyComplete( QuestBattle& instance, Entity::Player& player ) override
|
||||
|
@ -78,6 +94,47 @@ public:
|
|||
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 );
|
|
@ -68,6 +68,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX
|
|||
m_level = level;
|
||||
m_invincibilityType = InvincibilityNone;
|
||||
m_currentStance = Common::Stance::Passive;
|
||||
m_levelId = 0;
|
||||
|
||||
m_pCurrentZone = pZone;
|
||||
|
||||
|
@ -157,6 +158,7 @@ uint32_t Sapphire::Entity::BNpc::getBNpcNameId() const
|
|||
|
||||
void Sapphire::Entity::BNpc::spawn( PlayerPtr pTarget )
|
||||
{
|
||||
m_lastRoamTargetReached = Util::getTimeSeconds();
|
||||
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;
|
||||
|
||||
sendToInRangeSet( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 1, 1, 0 ) );
|
||||
sendToInRangeSet( makeActorControl142( getId(), ActorControlType::ToggleAggro, 1, 0, 0 ) );
|
||||
|
||||
if( pChara->isPlayer() )
|
||||
{
|
||||
PlayerPtr tmpPlayer = pChara->getAsPlayer();
|
||||
sendToInRangeSet( makeActorControl142( getId(), ActorControlType::ToggleAggro, 1, 0, 0 ) );
|
||||
tmpPlayer->onMobAggro( getAsBNpc() );
|
||||
}
|
||||
|
||||
|
@ -472,6 +474,10 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
|
|||
|
||||
case BNpcState::Idle:
|
||||
{
|
||||
auto pHatedActor = hateListGetHighest();
|
||||
if( pHatedActor )
|
||||
aggro( pHatedActor );
|
||||
|
||||
if( Util::getTimeSeconds() - m_lastRoamTargetReached > roamTick )
|
||||
{
|
||||
auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >();
|
||||
|
@ -690,3 +696,13 @@ void Sapphire::Entity::BNpc::setOwner( Sapphire::Entity::CharaPtr m_pChara )
|
|||
sendToInRangeSet( setOwnerPacket );
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::Entity::BNpc::setLevelId( uint32_t levelId )
|
||||
{
|
||||
m_levelId = levelId;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Entity::BNpc::getLevelId() const
|
||||
{
|
||||
return m_levelId;
|
||||
}
|
|
@ -102,6 +102,9 @@ namespace Sapphire::Entity
|
|||
|
||||
void setOwner( CharaPtr m_pChara );
|
||||
|
||||
void setLevelId( uint32_t levelId );
|
||||
uint32_t getLevelId() const;
|
||||
|
||||
private:
|
||||
uint32_t m_bNpcBaseId;
|
||||
uint32_t m_bNpcNameId;
|
||||
|
@ -114,6 +117,7 @@ namespace Sapphire::Entity
|
|||
uint16_t m_modelChara;
|
||||
uint32_t m_displayFlags;
|
||||
uint8_t m_level;
|
||||
uint32_t m_levelId;
|
||||
|
||||
float m_scale;
|
||||
float m_naviTargetReachedDistance;
|
||||
|
|
|
@ -81,6 +81,11 @@ uint32_t Sapphire::Entity::Chara::getHp() const
|
|||
return m_hp;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Entity::Chara::getHpPercent() const
|
||||
{
|
||||
return ( m_hp * 100 ) / m_maxHp;
|
||||
}
|
||||
|
||||
/*! \return current MP */
|
||||
uint32_t Sapphire::Entity::Chara::getMp() const
|
||||
{
|
||||
|
|
|
@ -187,6 +187,8 @@ namespace Sapphire::Entity
|
|||
|
||||
uint32_t getHp() const;
|
||||
|
||||
uint32_t getHpPercent() const;
|
||||
|
||||
uint32_t getMp() const;
|
||||
|
||||
uint16_t getTp() const;
|
||||
|
|
|
@ -182,3 +182,16 @@ void Sapphire::Event::Director::setDirectorSequence( uint8_t 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;
|
||||
}
|
|
@ -102,6 +102,9 @@ namespace Sapphire::Event
|
|||
|
||||
void setDirectorBranch( uint8_t value );
|
||||
|
||||
void setCustomVar( uint32_t varId, uint32_t value );
|
||||
uint32_t getCustomVar( uint32_t varId );
|
||||
|
||||
private:
|
||||
/*! Id of the content of the director */
|
||||
uint16_t m_contentId;
|
||||
|
@ -178,6 +181,7 @@ namespace Sapphire::Event
|
|||
|
||||
uint32_t m_elapsedTime;
|
||||
|
||||
std::unordered_map< uint32_t, uint32_t > m_customVarMap;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace Sapphire::Network::Packets::Server
|
|||
m_data.pos.y = bnpc.getPos().y;
|
||||
m_data.pos.z = bnpc.getPos().z;
|
||||
m_data.rotation = Util::floatToUInt16Rot( bnpc.getRot() );
|
||||
m_data.levelId = bnpc.getLevelId();
|
||||
|
||||
m_data.enemyType = bnpc.getEnemyType();
|
||||
m_data.mainWeaponModel = bnpc.getWeaponMain();
|
||||
|
|
|
@ -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,
|
||||
uint16_t param1, uint16_t param2 )
|
||||
{
|
||||
|
|
|
@ -241,6 +241,8 @@ namespace Sapphire::ScriptAPI
|
|||
|
||||
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 onInit( Sapphire::QuestBattle& instance );
|
||||
|
|
|
@ -499,6 +499,20 @@ bool Sapphire::Scripting::ScriptMgr::onInstanceUpdate( QuestBattlePtr instance,
|
|||
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,
|
||||
uint32_t eventId, uint16_t param1, uint16_t param2 )
|
||||
{
|
||||
|
|
|
@ -106,6 +106,8 @@ namespace Sapphire::Scripting
|
|||
|
||||
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,
|
||||
uint16_t param2 );
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ void Sapphire::InstanceContent::onUpdate( uint64_t tickCount )
|
|||
|
||||
case DutyInProgress:
|
||||
{
|
||||
updateBNpcs( tickCount );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,8 @@ void Sapphire::QuestBattle::onUpdate( uint64_t tickCount )
|
|||
return;
|
||||
|
||||
onEnterSceneFinish( *m_pPlayer );
|
||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||
pScriptMgr->onDutyCommence( *this, *m_pPlayer );
|
||||
|
||||
m_state = DutyInProgress;
|
||||
m_instanceExpireTime = Util::getTimeSeconds() + ( m_pBattleDetails->timeLimit * 60u );
|
||||
|
@ -129,6 +131,7 @@ void Sapphire::QuestBattle::onUpdate( uint64_t tickCount )
|
|||
break;
|
||||
|
||||
case DutyInProgress:
|
||||
updateBNpcs( tickCount );
|
||||
break;
|
||||
|
||||
case DutyFinished:
|
||||
|
@ -464,5 +467,32 @@ Sapphire::Entity::BNpcPtr
|
|||
levelData->yaw, level, hp, shared_from_this(), m_pFw );
|
||||
|
||||
bnpc->setDirectorId( directorId );
|
||||
bnpc->setLevelId( levelId );
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,9 @@ namespace Sapphire
|
|||
void fail();
|
||||
void success();
|
||||
|
||||
Entity::BNpcPtr getActiveBNpcByLevelId( uint32_t levelId );
|
||||
uint32_t getCountEnemyBNpc();
|
||||
|
||||
void clearDirector( Entity::Player& player );
|
||||
|
||||
Event::Director::DirectorState getState() const;
|
||||
|
@ -83,6 +86,8 @@ namespace Sapphire
|
|||
uint32_t hp, uint16_t nameId, uint32_t directorId,
|
||||
uint8_t bnpcType );
|
||||
|
||||
Entity::PlayerPtr getPlayerPtr();
|
||||
|
||||
private:
|
||||
std::shared_ptr< Sapphire::Data::QuestBattle > m_pBattleDetails;
|
||||
uint32_t m_questBattleId;
|
||||
|
|
|
@ -451,7 +451,6 @@ bool Sapphire::Zone::update( uint64_t tickCount )
|
|||
bool changedWeather = checkWeather();
|
||||
|
||||
updateSessions( tickCount, changedWeather );
|
||||
updateBNpcs( tickCount );
|
||||
onUpdate( tickCount );
|
||||
|
||||
updateSpawnPoints();
|
||||
|
@ -708,7 +707,7 @@ void Sapphire::Zone::onLeaveTerritory( Entity::Player& player )
|
|||
|
||||
void Sapphire::Zone::onUpdate( uint64_t tickCount )
|
||||
{
|
||||
|
||||
updateBNpcs( tickCount );
|
||||
}
|
||||
|
||||
void Sapphire::Zone::onFinishLoading( Entity::Player& player )
|
||||
|
|
Loading…
Add table
Reference in a new issue