mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-29 07:37:45 +00:00
correctly process hatevalues to table; update players with value/rate of their respective table entry;
This commit is contained in:
parent
56545371a3
commit
83333690a0
8 changed files with 103 additions and 14 deletions
|
@ -890,6 +890,11 @@ void Action::Action::setActionKind( uint8_t actionKind )
|
|||
m_actionKind = actionKind;
|
||||
}
|
||||
|
||||
void Action::Action::setAggroMultiplier( float aggroMultiplier )
|
||||
{
|
||||
m_aggroMultiplier = aggroMultiplier;
|
||||
}
|
||||
|
||||
uint64_t Action::Action::getCastTimeRest() const
|
||||
{
|
||||
return m_castTimeRestMs;
|
||||
|
|
|
@ -49,6 +49,8 @@ namespace Sapphire::World::Action
|
|||
uint8_t getActionKind() const;
|
||||
void setActionKind( uint8_t actionKind );
|
||||
|
||||
void setAggroMultiplier( float aggroMultiplier );
|
||||
|
||||
uint64_t getCastTimeRest() const;
|
||||
|
||||
/*!
|
||||
|
@ -174,6 +176,8 @@ namespace Sapphire::World::Action
|
|||
Common::ActionPrimaryCostType m_primaryCostType;
|
||||
uint16_t m_primaryCost{};
|
||||
|
||||
float m_aggroMultiplier{ 1.f };
|
||||
|
||||
uint64_t m_startTime{};
|
||||
uint64_t m_castTimeRestMs{};
|
||||
uint32_t m_castTimeMs{};
|
||||
|
|
|
@ -448,6 +448,40 @@ void Sapphire::Entity::BNpc::hateListClear()
|
|||
m_hateList.clear();
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Entity::BNpc::hateListGetValue( const Sapphire::Entity::CharaPtr& pChara )
|
||||
{
|
||||
for( const auto& listEntry : m_hateList )
|
||||
{
|
||||
if( listEntry->m_pChara == pChara )
|
||||
{
|
||||
return listEntry->m_hateAmount;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Entity::BNpc::hateListGetHighestValue()
|
||||
{
|
||||
auto it = m_hateList.begin();
|
||||
uint32_t maxHate = 0;
|
||||
std::shared_ptr< HateListEntry > entry;
|
||||
for( ; it != m_hateList.end(); ++it )
|
||||
{
|
||||
if( ( *it )->m_hateAmount > maxHate )
|
||||
{
|
||||
maxHate = ( *it )->m_hateAmount;
|
||||
entry = *it;
|
||||
}
|
||||
}
|
||||
|
||||
if( entry && maxHate != 0 )
|
||||
return entry->m_hateAmount;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Sapphire::Entity::CharaPtr Sapphire::Entity::BNpc::hateListGetHighest()
|
||||
{
|
||||
auto it = m_hateList.begin();
|
||||
|
@ -491,29 +525,45 @@ void Sapphire::Entity::BNpc::hateListAddDelayed( const Sapphire::Entity::CharaPt
|
|||
|
||||
void Sapphire::Entity::BNpc::hateListUpdate( const Sapphire::Entity::CharaPtr& pChara, int32_t hateAmount )
|
||||
{
|
||||
bool hasEntry = false;
|
||||
|
||||
for( const auto& listEntry : m_hateList )
|
||||
{
|
||||
if( listEntry->m_pChara == pChara )
|
||||
{
|
||||
listEntry->m_hateAmount += static_cast< uint32_t >( hateAmount );
|
||||
return;
|
||||
hasEntry = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !hasEntry )
|
||||
{
|
||||
auto hateEntry = std::make_shared< HateListEntry >();
|
||||
hateEntry->m_hateAmount = static_cast< uint32_t >( hateAmount );
|
||||
hateEntry->m_pChara = pChara;
|
||||
m_hateList.insert( hateEntry );
|
||||
}
|
||||
|
||||
for( const auto& listEntry : m_hateList )
|
||||
{
|
||||
// update entire hatelist for all players who are on aggro with this bnpc
|
||||
if( pChara->isPlayer() )
|
||||
{
|
||||
auto pPlayer = pChara->getAsPlayer();
|
||||
Service< World::Manager::PlayerMgr >::ref().onHateListChanged( *pPlayer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::Entity::BNpc::hateListRemove( const Sapphire::Entity::CharaPtr& pChara )
|
||||
{
|
||||
for( const auto& listEntry : m_hateList )
|
||||
{
|
||||
if( listEntry->m_pChara == pChara )
|
||||
{
|
||||
|
||||
m_hateList.erase( listEntry );
|
||||
|
||||
if( pChara->isPlayer() )
|
||||
{
|
||||
PlayerPtr tmpPlayer = pChara->getAsPlayer();
|
||||
|
@ -547,7 +597,6 @@ void Sapphire::Entity::BNpc::aggro( const Sapphire::Entity::CharaPtr& pChara )
|
|||
auto variation = static_cast< uint32_t >( pRNGMgr.getRandGenerator< float >( 500, 1000 ).next() );
|
||||
|
||||
m_lastAttack = Util::getTimeMs() + variation;
|
||||
hateListUpdate( pChara, 1 );
|
||||
|
||||
setStance( Stance::Active );
|
||||
m_state = BNpcState::Combat;
|
||||
|
@ -773,6 +822,8 @@ void Sapphire::Entity::BNpc::onActionHostile( Sapphire::Entity::CharaPtr pSource
|
|||
if( !hateListGetHighest() )
|
||||
aggro( pSource );
|
||||
|
||||
hateListUpdate( pSource, 1 );
|
||||
|
||||
if( !m_pOwner )
|
||||
setOwner( pSource );
|
||||
}
|
||||
|
|
|
@ -103,6 +103,8 @@ namespace Sapphire::Entity
|
|||
void setState( BNpcState state );
|
||||
|
||||
void hateListClear();
|
||||
uint32_t hateListGetValue( const Sapphire::Entity::CharaPtr& pChara );
|
||||
uint32_t hateListGetHighestValue();
|
||||
CharaPtr hateListGetHighest();
|
||||
void hateListAdd( const CharaPtr& pChara, int32_t hateAmount );
|
||||
void hateListAddDelayed( const CharaPtr& pChara, int32_t hateAmount );
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "Network/PacketWrappers/HudParamPacket.h"
|
||||
|
||||
#include <Actor/Player.h>
|
||||
#include <Actor/BNpc.h>
|
||||
#include "Territory/InstanceObjectCache.h"
|
||||
|
||||
using namespace Sapphire;
|
||||
|
@ -212,6 +213,7 @@ void PlayerMgr::onMobKill( Entity::Player& player, uint16_t nameId, uint32_t lay
|
|||
void PlayerMgr::onHateListChanged( Entity::Player& player )
|
||||
{
|
||||
auto& server = Common::Service< World::WorldServer >::ref();
|
||||
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
|
||||
|
||||
auto hateListPacket = makeZonePacket< FFXIVIpcHateList >( player.getId() );
|
||||
auto hateRankPacket = makeZonePacket< FFXIVIpcHaterList >( player.getId() );
|
||||
|
@ -222,14 +224,28 @@ void PlayerMgr::onHateListChanged( Entity::Player& player )
|
|||
|
||||
hateRankPacket->data().Count = static_cast< uint8_t >( actorIdToHateSlotMap.size() );
|
||||
auto it = actorIdToHateSlotMap.begin();
|
||||
for( int32_t i = 0; it != actorIdToHateSlotMap.end(); ++it, i++ )
|
||||
|
||||
auto zone = teriMgr.getTerritoryByGuId( player.getTerritoryId() );
|
||||
if( !zone )
|
||||
return;
|
||||
|
||||
for( int32_t i = 0; it != actorIdToHateSlotMap.end(); ++it, ++i )
|
||||
{
|
||||
// TODO: get actual hate values for these
|
||||
auto pBNpc = zone->getActiveBNpcByEntityId( it->first );
|
||||
if( !pBNpc )
|
||||
continue;
|
||||
|
||||
auto hateValue = pBNpc->hateListGetValue( player.getAsChara() );
|
||||
if( hateValue == 0 )
|
||||
continue;
|
||||
|
||||
auto hatePercent = ( hateValue / static_cast< float >( pBNpc->hateListGetHighestValue() ) ) * 100.f;
|
||||
|
||||
hateListPacket->data().List[ i ].Id = player.getId();
|
||||
hateListPacket->data().List[ i ].Value = 6;
|
||||
hateListPacket->data().List[ i ].Value = hateValue;
|
||||
|
||||
hateRankPacket->data().List[ i ].Id = it->first;
|
||||
hateRankPacket->data().List[ i ].Rate = 100;
|
||||
hateRankPacket->data().List[ i ].Rate = static_cast< uint8_t >( hatePercent );
|
||||
}
|
||||
|
||||
server.queueForPlayer( player.getCharacterId(), { hateListPacket, hateRankPacket } );
|
||||
|
|
|
@ -840,6 +840,15 @@ Sapphire::Entity::BNpcPtr Sapphire::Territory::createBNpcFromInstanceId( uint32_
|
|||
return pBNpc;
|
||||
}
|
||||
|
||||
Sapphire::Entity::BNpcPtr Sapphire::Territory::getActiveBNpcByEntityId( uint32_t entityId )
|
||||
{
|
||||
auto it = m_bNpcMap.find( entityId );
|
||||
if( it == m_bNpcMap.end() )
|
||||
return nullptr;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Sapphire::Entity::BNpcPtr Sapphire::Territory::getActiveBNpcByInstanceId( uint32_t instanceId )
|
||||
{
|
||||
for( const auto& bnpcIt : m_bNpcMap )
|
||||
|
|
|
@ -175,6 +175,8 @@ namespace Sapphire
|
|||
|
||||
Entity::BNpcPtr createBNpcFromInstanceId( uint32_t levelId, uint32_t hp, Common::BNpcType bnpcType, uint32_t triggerOwnerId = 0 );
|
||||
|
||||
Entity::BNpcPtr getActiveBNpcByEntityId( uint32_t entityId );
|
||||
|
||||
Entity::BNpcPtr getActiveBNpcByInstanceId( uint32_t instanceId );
|
||||
|
||||
Entity::BNpcPtr getActiveBNpcByInstanceIdAndTriggerOwner( uint32_t instanceId, uint32_t triggerOwnerId );
|
||||
|
|
Loading…
Add table
Reference in a new issue