diff --git a/src/api/PlayerMinimal.cpp b/src/api/PlayerMinimal.cpp index 41c0fa47..023a2e0a 100644 --- a/src/api/PlayerMinimal.cpp +++ b/src/api/PlayerMinimal.cpp @@ -35,7 +35,7 @@ void PlayerMinimal::load( uint64_t charId ) return; m_characterId = charId; - m_id = res->getUInt64( "EntityId" ); + m_id = res->getUInt( "EntityId" ); memset( m_name, 0, 32 ); diff --git a/src/api/SapphireApi.cpp b/src/api/SapphireApi.cpp index 21006093..1016c802 100644 --- a/src/api/SapphireApi.cpp +++ b/src/api/SapphireApi.cpp @@ -116,7 +116,7 @@ int SapphireApi::createCharacter( const uint32_t accountId, const std::string& n const char* ptr = infoJson.c_str() + 50; std::string lookPart( ptr ); - int32_t pos = lookPart.find_first_of( "]" ); + auto pos = lookPart.find_first_of( "]" ); if( pos != std::string::npos ) { lookPart = lookPart.substr( 0, pos + 1 ); @@ -188,7 +188,7 @@ void SapphireApi::deleteCharacter( std::string name, const uint32_t accountId ) } } - int32_t id = deletePlayer.getCharacterId(); + auto id = deletePlayer.getCharacterId(); g_charaDb.execute( "DELETE FROM charainfo WHERE CharacterId = " + std::to_string( id ) + ";" ); g_charaDb.execute( "DELETE FROM characlass WHERE CharacterId = " + std::to_string( id ) + ";" ); diff --git a/src/lobby/LobbyPacketContainer.cpp b/src/lobby/LobbyPacketContainer.cpp index fcd4e459..c396db1d 100644 --- a/src/lobby/LobbyPacketContainer.cpp +++ b/src/lobby/LobbyPacketContainer.cpp @@ -15,7 +15,7 @@ LobbyPacketContainer::LobbyPacketContainer( uint8_t* encKey ) m_encKey = encKey; - memset( m_dataBuf, 0, 0x1570 ); + memset( m_dataBuf.data(), 0, 0x1570 ); } LobbyPacketContainer::~LobbyPacketContainer() @@ -25,14 +25,14 @@ LobbyPacketContainer::~LobbyPacketContainer() void LobbyPacketContainer::addPacket( FFXIVPacketBasePtr pEntry ) { - memcpy( m_dataBuf + m_header.size, &pEntry->getData()[ 0 ], pEntry->getSize() ); + memcpy( m_dataBuf.data() + m_header.size, &pEntry->getData()[ 0 ], pEntry->getSize() ); // encryption key is set, we want to encrypt this packet if( m_encKey != nullptr ) { BlowFish blowfish; blowfish.initialize( m_encKey, 0x10 ); - blowfish.Encode( m_dataBuf + m_header.size + 0x10, m_dataBuf + m_header.size + 0x10, pEntry->getSize() - 0x10 ); + blowfish.Encode( m_dataBuf.data() + m_header.size + 0x10, m_dataBuf.data() + m_header.size + 0x10, pEntry->getSize() - 0x10 ); } m_header.size += pEntry->getSize(); @@ -51,6 +51,8 @@ uint8_t* LobbyPacketContainer::getRawData( bool addstuff ) m_header.unknown_0 = 0xff41a05252; m_header.timestamp = Common::Util::getTimeMs(); } - memcpy( m_dataBuf, &m_header, sizeof( Sapphire::Network::Packets::FFXIVARR_PACKET_HEADER ) ); - return m_dataBuf; + + memcpy( m_dataBuf.data(), &m_header, sizeof( Sapphire::Network::Packets::FFXIVARR_PACKET_HEADER ) ); + + return m_dataBuf.data(); } diff --git a/src/lobby/LobbyPacketContainer.h b/src/lobby/LobbyPacketContainer.h index 0ac3d0b5..57309b5f 100644 --- a/src/lobby/LobbyPacketContainer.h +++ b/src/lobby/LobbyPacketContainer.h @@ -1,6 +1,7 @@ #ifndef LOBBY_PACKET_CONTAINER_H_ #define LOBBY_PACKET_CONTAINER_H_ +#include #include #include @@ -34,7 +35,7 @@ namespace Sapphire::Network::Packets std::vector< FFXIVPacketBasePtr > m_entryList; - uint8_t m_dataBuf[0x2000]; + std::array< uint8_t, 0x2000 > m_dataBuf{ 0 }; }; diff --git a/src/lobby/RestConnector.cpp b/src/lobby/RestConnector.cpp index bef831b5..88330e4b 100644 --- a/src/lobby/RestConnector.cpp +++ b/src/lobby/RestConnector.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -66,7 +67,7 @@ Lobby::LobbySessionPtr Lobby::RestConnector::getSession( char* sId ) if( content.find( "invalid" ) == std::string::npos ) { - LobbySessionPtr pSession( new Lobby::LobbySession() ); + auto pSession = std::make_shared< Lobby::LobbySession >(); pSession->setAccountID( json["result"].get< uint32_t >() ); pSession->setSessionId( sId ); return pSession; diff --git a/src/tools/quest_parser/main.cpp b/src/tools/quest_parser/main.cpp index 5b769d83..1f2371ba 100644 --- a/src/tools/quest_parser/main.cpp +++ b/src/tools/quest_parser/main.cpp @@ -499,7 +499,7 @@ int main( int argc, char** argv ) Logger::info( "Export in progress" ); - uint32_t updateInterval = rows.size() / 20; + auto updateInterval = rows.size() / 20; uint32_t i = 0; for( const auto& row : rows ) { diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 80044b62..d5163fc8 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -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; diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index c5b73dca..d147f64b 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -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{}; diff --git a/src/world/Action/ItemAction.cpp b/src/world/Action/ItemAction.cpp index 992f46cf..5ca875f2 100644 --- a/src/world/Action/ItemAction.cpp +++ b/src/world/Action/ItemAction.cpp @@ -86,5 +86,5 @@ void ItemAction::handleMountItem() auto player = getSourceChara()->getAsPlayer(); player->unlockMount( m_itemAction->data().Calcu0Arg[ 0 ] ); - player->dropInventoryItem ( static_cast< Common::InventoryType >( m_itemSourceContainer ), m_itemSourceSlot ); + player->dropInventoryItem( static_cast< Common::InventoryType >( m_itemSourceContainer ), m_itemSourceSlot ); } \ No newline at end of file diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index f36eb7e6..e860bb5d 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -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,19 +525,35 @@ 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; } } - auto hateEntry = std::make_shared< HateListEntry >(); - hateEntry->m_hateAmount = static_cast< uint32_t >( hateAmount ); - hateEntry->m_pChara = pChara; - m_hateList.insert( hateEntry ); + 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 ) @@ -512,8 +562,8 @@ void Sapphire::Entity::BNpc::hateListRemove( const Sapphire::Entity::CharaPtr& p { 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 ); } diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index 3525f03c..c15aa6b3 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -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 ); diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index f0811f88..6808d6e6 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -2127,7 +2127,7 @@ void Sapphire::Entity::Player::setFalling( bool state, const Common::FFXIVARR_PO // get hp percentage starting from 0.1, increasing to 100% at max height float hpPer = std::min( 0.1f + ( deltaMax - 10.f ) / 20.f, 1.f ); - uint32_t damage = getMaxHp() * hpPer; + auto damage = static_cast< uint32_t >( getMaxHp() * hpPer ); // check if player has aggro - if not, player should "live" if( m_actorIdTohateSlotMap.empty() ) diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index ead73f71..fb32e16f 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -618,10 +618,10 @@ namespace Sapphire::Entity ////////////////////////////////////////////////////////////////////////////////////////////////////// void initHateSlotQueue(); - void hateListAdd( const BNpc &bnpc ); - void hateListRemove( const BNpc &bnpc ); + void hateListAdd( const BNpc& bnpc ); + void hateListRemove( const BNpc& bnpc ); - bool hateListHasEntry( const BNpc &bnpc ); + bool hateListHasEntry( const BNpc& bnpc ); const std::map< uint32_t, uint8_t >& getActorIdToHateSlotMap(); diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index f4733556..539515c6 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -90,7 +90,7 @@ bool HousingMgr::init() Logger::debug( "HousingMgr: Checking land counts" ); - uint32_t houseCount = 0; + size_t houseCount = 0; for( auto& landSet : m_landCache ) { auto count = landSet.second.size(); diff --git a/src/world/Manager/InventoryMgr.cpp b/src/world/Manager/InventoryMgr.cpp index e743300f..35df61f1 100644 --- a/src/world/Manager/InventoryMgr.cpp +++ b/src/world/Manager/InventoryMgr.cpp @@ -144,18 +144,23 @@ void InventoryMgr::updateHousingItemPosition( Inventory::HousingItemPtr item ) // ItemId, PosX, PosY, PosZ, Rotation, PosX, PosY, PosZ, Rotation auto pos = item->getPos(); - auto rot = item->getRot(); + + auto posX = static_cast< uint32_t >( pos.x ); + auto posY = static_cast< uint32_t >( pos.y ); + auto posZ = static_cast< uint32_t >( pos.z ); + + auto rot = static_cast< int32_t >( item->getRot() ); stmt->setUInt64( 1, item->getUId() ); - stmt->setUInt( 2, pos.x ); - stmt->setUInt( 3, pos.y ); - stmt->setUInt( 4, pos.z ); + stmt->setUInt( 2, posX ); + stmt->setUInt( 3, posY ); + stmt->setUInt( 4, posZ ); stmt->setInt( 5, rot ); - stmt->setUInt( 6, pos.x ); - stmt->setUInt( 7, pos.y ); - stmt->setUInt( 8, pos.z ); + stmt->setUInt( 6, posX ); + stmt->setUInt( 7, posY ); + stmt->setUInt( 8, posZ ); stmt->setInt( 9, rot ); db.execute( stmt ); diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index e1ba4a17..304d799f 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -29,6 +29,7 @@ #include "Network/PacketWrappers/HudParamPacket.h" #include +#include #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 } ); diff --git a/src/world/Network/Handlers/PacketCommandHandler.cpp b/src/world/Network/Handlers/PacketCommandHandler.cpp index f0749a17..0d843b4b 100644 --- a/src/world/Network/Handlers/PacketCommandHandler.cpp +++ b/src/world/Network/Handlers/PacketCommandHandler.cpp @@ -583,6 +583,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_ break; } + break; } case PacketCommand::FINISH_LOADING: // Finish zoning { @@ -637,7 +638,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_ case PacketCommand::HOUSING_LOCK_LAND_BY_BUILD: { auto hZone = std::dynamic_pointer_cast< HousingZone >( pZone ); - if (!hZone) + if( !hZone ) return; player.setActiveLand( static_cast< uint8_t >( param11 ), hZone->getWardNum() ); @@ -677,7 +678,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_ { auto& housingMgr = Service< HousingMgr >::ref(); auto hZone = std::dynamic_pointer_cast< HousingZone >( pZone ); - if (!hZone) + if( !hZone ) return; auto plot = static_cast< uint8_t >( param12 & 0xFF ); diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 7bff6c3d..2049145f 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -206,7 +206,7 @@ void Sapphire::HousingZone::sendLandSet( Entity::Player& player ) auto& parts = house->getHouseModels(); - for( auto ii = 0; ii != parts.size(); ii++ ) + for( auto ii = 0; ii != parts.size(); ++ii ) { landData.patternIds[ ii ] = parts[ ii ].first; landData.colors[ ii ] = parts[ ii ].second; @@ -245,7 +245,7 @@ void Sapphire::HousingZone::sendLandUpdate( uint8_t landId ) auto& parts = house->getHouseModels(); - for( auto i = 0; i != parts.size(); i++ ) + for( auto i = 0; i != parts.size(); ++i ) { landData.patternIds[ i ] = parts[ i ].first; landData.colors[ i ] = parts[ i ].second; diff --git a/src/world/Territory/Territory.cpp b/src/world/Territory/Territory.cpp index f9d3b771..928a7fd7 100644 --- a/src/world/Territory/Territory.cpp +++ b/src/world/Territory/Territory.cpp @@ -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 ) diff --git a/src/world/Territory/Territory.h b/src/world/Territory/Territory.h index 90f80416..9987d4a5 100644 --- a/src/world/Territory/Territory.h +++ b/src/world/Territory/Territory.h @@ -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 );