diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index f6f25116..08edad4e 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -119,35 +119,39 @@ namespace Sapphire::Network::Packets PlayerSpawn = 0x0175, // updated 4.5 NpcSpawn = 0x0176, // updated 4.5 + NpcSpawn2 = 0x0177, // ( Bigger statuseffectlist? ) updated 4.5 ActorMove = 0x0178, // updated 4.5 + ActorSetPos = 0x017A, // updated 4.5 ActorCast = 0x017C, // updated 4.5 PartyList = 0x017E, // updated 4.5 - HateList = 0x017F, // updated 4.5 + HateList = 0x0180, // updated 4.5 ObjectSpawn = 0x0181, // updated 4.5 ObjectDespawn = 0x0182, // updated 4.5 - UpdateClassInfo = 0x0183, // updated 4.5 SilentSetClassJob = 0x0184, // updated 4.5 - seems to be the case, not sure if it's actually used for anything - InitUI = 0x0185, // updated 4.5 PlayerStats = 0x0186, // updated 4.5 ActorOwner = 0x0187, // updated 4.5 PlayerStateFlags = 0x0188, // updated 4.5 PlayerClassInfo = 0x0189, // updated 4.5 + ModelEquip = 0x018B, // updated 4.5 Examine = 0x018C, // updated 4.5 CharaNameReq = 0x018D, // updated 4.5 + SetLevelSync = 0x1186, // not updated for 4.4, not sure what it is anymore ItemInfo = 0x0196, // updated 4.5 ContainerInfo = 0x0197, // updated 4.5 InventoryTransactionFinish = 0x0198, // updated 4.5 InventoryTransaction = 0x0199, // updated 4.5 + CurrencyCrystalInfo = 0x019B, // updated 4.5 + InventoryActionAck = 0x019D, // updated 4.5 UpdateInventorySlot = 0x019E, // updated 4.5 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index c1c3cf93..ef70853c 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -698,8 +698,7 @@ struct FFXIVIpcActorSetPos : * Structural representation of the packet sent by the server * to start an actors casting */ -struct FFXIVIpcActorCast : - FFXIVIpcBasePacket< ActorCast > +struct FFXIVIpcActorCast : FFXIVIpcBasePacket< ActorCast > { uint16_t action_id; Common::SkillType skillType; @@ -715,11 +714,10 @@ struct FFXIVIpcActorCast : uint16_t unknown_3; }; -struct FFXIVIpcHateList : - FFXIVIpcBasePacket< HateList > +struct FFXIVIpcHateList : FFXIVIpcBasePacket< HateList > { uint32_t numEntries; - struct LsEntry + struct { uint32_t actorId; uint8_t hatePercent; @@ -729,8 +727,7 @@ struct FFXIVIpcHateList : uint32_t padding; }; -struct FFXIVIpcUpdateClassInfo : - FFXIVIpcBasePacket< UpdateClassInfo > +struct FFXIVIpcUpdateClassInfo : FFXIVIpcBasePacket< UpdateClassInfo > { uint8_t classId; uint8_t level1; diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index ae698688..17c4c02c 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -248,7 +248,7 @@ void Sapphire::Entity::BNpc::hateListRemove( Sapphire::Entity::CharaPtr pChara ) if( pChara->isPlayer() ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); - //tmpPlayer->onMobDeaggro( getAsBattleNpc() ); + tmpPlayer->onMobDeaggro( getAsBNpc() ); } return; } @@ -278,7 +278,7 @@ void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::CharaPtr pChara ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); tmpPlayer->queuePacket( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 0, 1, 1 ) ); - //tmpPlayer->onMobAggro( getAsBattleNpc() ); + tmpPlayer->onMobAggro( getAsBNpc() ); } } @@ -290,7 +290,7 @@ void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::CharaPtr pChara ) if( pChara->isPlayer() ) { PlayerPtr tmpPlayer = pChara->getAsPlayer(); - //tmpPlayer->onMobDeaggro( getAsBattleNpc() ); + tmpPlayer->onMobDeaggro( getAsBNpc() ); } } diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 991975e9..af148eb6 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -10,6 +10,7 @@ #include "Session.h" #include "Player.h" +#include "BNpc.h" #include "Manager/HousingMgr.h" #include "Manager/TerritoryMgr.h" @@ -1348,6 +1349,45 @@ void Sapphire::Entity::Player::initHateSlotQueue() m_freeHateSlotQueue.push( i ); } +void Sapphire::Entity::Player::hateListAdd( BNpcPtr pBNpc ) +{ + if( !m_freeHateSlotQueue.empty() ) + { + uint8_t hateId = m_freeHateSlotQueue.front(); + m_freeHateSlotQueue.pop(); + m_actorIdTohateSlotMap[ pBNpc->getId() ] = hateId; + sendHateList(); + } +} + +void Sapphire::Entity::Player::hateListRemove( BNpcPtr pBNpc ) +{ + + auto it = m_actorIdTohateSlotMap.begin(); + for( ; it != m_actorIdTohateSlotMap.end(); ++it ) + { + if( it->first == pBNpc->getId() ) + { + uint8_t hateSlot = it->second; + m_freeHateSlotQueue.push( hateSlot ); + m_actorIdTohateSlotMap.erase( it ); + sendHateList(); + + return; + } + } +} + +bool Sapphire::Entity::Player::hateListHasEntry( BNpcPtr pBNpc ) +{ + for( const auto& entry : m_actorIdTohateSlotMap ) + { + if( entry.first == pBNpc->getId() ) + return true; + } + return false; +} + void Sapphire::Entity::Player::sendHateList() { auto hateListPacket = makeZonePacket< FFXIVIpcHateList >( getId() ); @@ -1361,6 +1401,19 @@ void Sapphire::Entity::Player::sendHateList() queuePacket( hateListPacket ); } +void Sapphire::Entity::Player::onMobAggro( BNpcPtr pBNpc ) +{ + hateListAdd( pBNpc ); + queuePacket( makeActorControl142( getId(), ToggleAggro, 1 ) ); +} + +void Sapphire::Entity::Player::onMobDeaggro( BNpcPtr pBNpc ) +{ + hateListRemove( pBNpc ); + if( m_actorIdTohateSlotMap.empty() ) + queuePacket( makeActorControl142( getId(), ToggleAggro ) ); +} + bool Sapphire::Entity::Player::isLogin() const { return m_bIsLogin; diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 92a575e7..3c4382da 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -798,6 +798,11 @@ namespace Sapphire::Entity ////////////////////////////////////////////////////////////////////////////////////////////////////// void initHateSlotQueue(); + void hateListAdd( BNpcPtr pBNpc ); + void hateListRemove( BNpcPtr pBNpc ); + + bool hateListHasEntry( BNpcPtr pBNpc ); + void sendHateList(); bool actionHasCastTime( uint32_t actionId ); @@ -831,6 +836,9 @@ namespace Sapphire::Entity bool isAutoattackOn() const; + void onMobAggro( BNpcPtr pBNpc ); + void onMobDeaggro( BNpcPtr pBNpc ); + // Content Finder handling ////////////////////////////////////////////////////////////////////////////////////////////////////// /*! Get an unix time when the player can register into content finder again. */ diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index 3ad04d39..5f7702b7 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -802,7 +802,7 @@ bool Sapphire::Zone::loadSpawnGroups() float r = res->getFloat( 5 ); uint32_t gimmickId = res->getUInt( 6 ); - group.getSpawnPointList().push_back( std::make_shared< Entity::SpawnPoint >( x, y, z, r, gimmickId ) ); + group.getSpawnPointList().emplace_back( std::make_shared< Entity::SpawnPoint >( x, y, z, r, gimmickId ) ); Logger::debug( "id: {0}, x: {1}, y: {2}, z: {3}, gimmickId: {4}", id, x, y, z, gimmickId ); }