mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-30 08:07:46 +00:00
Merge pull request #276 from NotAdam/actor_rewrite
instance player binding done, minor refactoring
This commit is contained in:
commit
f2684f6c7d
8 changed files with 108 additions and 57 deletions
|
@ -614,7 +614,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
|
|||
uint32_t unknownC;
|
||||
uint32_t charId;
|
||||
uint32_t restedExp;
|
||||
uint16_t unknown18;
|
||||
uint16_t currentLevel;
|
||||
uint8_t maxLevel;
|
||||
uint8_t expansion;
|
||||
uint8_t unknown1A;
|
||||
|
@ -730,8 +730,8 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
|
|||
uint16_t pvpFrontlineWeekly2nd;
|
||||
uint16_t pvpFrontlineWeekly3rd;
|
||||
uint8_t unknown61E;
|
||||
uint8_t unknown61F[32];
|
||||
uint8_t unknown63F[22];
|
||||
uint8_t centurioSealHunts[32];
|
||||
uint8_t alliedSealHunts[22];
|
||||
uint8_t tripleTriadCards[28];
|
||||
uint8_t unknown671[11];
|
||||
uint8_t unknownMask67C[22];
|
||||
|
@ -739,12 +739,12 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
|
|||
uint8_t orchestrionMask[40];
|
||||
uint8_t hallOfNoviceCompleteMask[3];
|
||||
uint8_t unknownMask6C0[11];
|
||||
uint8_t unknownMask6CB[16];
|
||||
uint8_t animaRelicMask[16]; // [2] = anima glass key item, [1] = ulan's note key item
|
||||
uint8_t unknown6DB[14];
|
||||
uint8_t unlockedRaids[28];
|
||||
uint8_t unlockedDungeons[18];
|
||||
uint8_t unlockedGuildhests[10];
|
||||
uint8_t unlockedTrails[7];
|
||||
uint8_t unlockedTrials[7];
|
||||
uint8_t unlockedPvp[5];
|
||||
uint8_t unknownMask72D[28];
|
||||
uint8_t unknownMask749[18];
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <Exd/ExdDataGenerated.h>
|
||||
|
||||
#include "Zone/TerritoryMgr.h"
|
||||
#include "Zone/Zone.h"
|
||||
#include "Zone/InstanceContent.h"
|
||||
|
||||
#include "Network/GameConnection.h"
|
||||
#include "Network/PacketWrappers/ServerNoticePacket.h"
|
||||
|
@ -54,19 +54,25 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
|
|||
{
|
||||
auto pTeriMgr = g_fw.get< TerritoryMgr >();
|
||||
auto pExdData = g_fw.get< Data::ExdDataGenerated >();
|
||||
// TODO use for loop for this
|
||||
auto contentId1 = inPacket.getValAt< uint16_t >( 0x2E );
|
||||
auto contentId2 = inPacket.getValAt< uint16_t >( 0x30 );
|
||||
auto contentId3 = inPacket.getValAt< uint16_t >( 0x32 );
|
||||
auto contentId4 = inPacket.getValAt< uint16_t >( 0x34 );
|
||||
auto contentId5 = inPacket.getValAt< uint16_t >( 0x36 );
|
||||
|
||||
player.sendDebug( "Duty register request");
|
||||
player.sendDebug( "ContentId1: " + std::to_string( contentId1 ) );
|
||||
player.sendDebug( "ContentId2: " + std::to_string( contentId2 ) );
|
||||
player.sendDebug( "ContentId3: " + std::to_string( contentId3 ) );
|
||||
player.sendDebug( "ContentId4: " + std::to_string( contentId4 ) );
|
||||
player.sendDebug( "ContentId5: " + std::to_string( contentId5 ) );
|
||||
std::vector< uint16_t > selectedContent;
|
||||
|
||||
for( uint32_t offset = 0x2E; offset <= 0x36; offset += 0x2 )
|
||||
{
|
||||
auto id = inPacket.getValAt< uint16_t >( offset );
|
||||
if( id == 0 )
|
||||
break;
|
||||
|
||||
player.sendDebug( "got contentId: " + std::to_string( id ) );
|
||||
|
||||
selectedContent.push_back( id );
|
||||
}
|
||||
|
||||
// todo: rand bias problem, will do for now tho
|
||||
auto index = std::rand() % selectedContent.size();
|
||||
auto contentId = selectedContent.at( index );
|
||||
|
||||
player.sendDebug( "Duty register request for contentid: " + std::to_string( contentId ) );
|
||||
|
||||
// let's cancel it because otherwise you can't register it again
|
||||
ZoneChannelPacket< FFXIVIpcCFNotify > cfCancelPacket( player.getId() );
|
||||
|
@ -74,7 +80,7 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
|
|||
cfCancelPacket.data().state2 = 1; // Your registration is withdrawn.
|
||||
queueOutPacket( cfCancelPacket );
|
||||
|
||||
auto cfCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentId1 );
|
||||
auto cfCondition = pExdData->get< Core::Data::ContentFinderCondition >( contentId );
|
||||
if( !cfCondition )
|
||||
return;
|
||||
|
||||
|
@ -82,6 +88,9 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
|
|||
if( !instance )
|
||||
return;
|
||||
|
||||
auto pInstance = instance->getAsInstanceContent();
|
||||
pInstance->bindPlayer( player.getId() );
|
||||
|
||||
player.sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) );
|
||||
|
||||
player.setInstance( instance );
|
||||
|
@ -90,6 +99,11 @@ void Core::Network::GameConnection::cfRegisterDuty( const Packets::GamePacket& i
|
|||
void Core::Network::GameConnection::cfRegisterRoulette( const Packets::GamePacket& inPacket,
|
||||
Entity::Player& player)
|
||||
{
|
||||
ZoneChannelPacket< FFXIVIpcCFNotify > cfCancelPacket( player.getId() );
|
||||
cfCancelPacket.data().state1 = 3;
|
||||
cfCancelPacket.data().state2 = 1; // Your registration is withdrawn.
|
||||
queueOutPacket( cfCancelPacket );
|
||||
|
||||
player.sendDebug( "Roulette register" );
|
||||
}
|
||||
|
||||
|
|
|
@ -418,7 +418,9 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
|||
|
||||
// if the zone is an instanceContent instance, make sure the player is actually bound to it
|
||||
auto pInstance = instance->getAsInstanceContent();
|
||||
if( !pInstance->isPlayerBound( player.getId() ) )
|
||||
|
||||
// pInstance will be nullptr if you're accessing a normal zone via its allocated instance id rather than its zoneid
|
||||
if( pInstance && !pInstance->isPlayerBound( player.getId() ) )
|
||||
{
|
||||
player.sendUrgent( "Not able to join instance: " + std::to_string( param1 ) );
|
||||
player.sendUrgent( "Player not bound! ( run !instance bind <instanceId> first ) " + std::to_string( param1 ) );
|
||||
|
|
|
@ -38,6 +38,7 @@ private:
|
|||
m_data.gender = player.getLookAt( Common::CharaLook::Gender );
|
||||
m_data.currentClass = static_cast< uint8_t >( player.getClass() );
|
||||
m_data.currentJob = static_cast< uint8_t >( player.getClass() );
|
||||
m_data.currentLevel = player.getLevel();
|
||||
m_data.deity = static_cast< uint8_t >( player.getGuardianDeity() );
|
||||
m_data.namedayMonth = player.getBirthMonth();
|
||||
m_data.namedayDay = player.getBirthDay();
|
||||
|
@ -74,6 +75,17 @@ private:
|
|||
m_data.maxLevel = 0x46;
|
||||
m_data.expansion = 2;
|
||||
|
||||
// df stuff
|
||||
// todo: actually do this properly
|
||||
m_data.unknown70[4] = 1; // enable df
|
||||
|
||||
// enable all raids/guildhests/dungeons
|
||||
memset( m_data.unlockedDungeons, 0xFF, sizeof( m_data.unlockedDungeons ) );
|
||||
memset( m_data.unlockedGuildhests, 0xFF, sizeof( m_data.unlockedGuildhests ) );
|
||||
memset( m_data.unlockedPvp, 0xFF, sizeof( m_data.unlockedPvp ) );
|
||||
memset( m_data.unlockedRaids, 0xFF, sizeof( m_data.unlockedRaids ) );
|
||||
memset( m_data.unlockedTrials, 0xFF, sizeof( m_data.unlockedTrials ) );
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -27,19 +27,19 @@ using namespace Core::Common;
|
|||
using namespace Core::Network::Packets;
|
||||
using namespace Core::Network::Packets::Server;
|
||||
|
||||
Core::InstanceContent::InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceContent,
|
||||
Core::InstanceContent::InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceConfiguration,
|
||||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
uint32_t instanceContentId )
|
||||
: Zone( static_cast< uint16_t >( pInstanceContent->territoryType ), guId, internalName, contentName ),
|
||||
: Zone( static_cast< uint16_t >( pInstanceConfiguration->territoryType ), guId, internalName, contentName ),
|
||||
Director( Event::Director::InstanceContent, instanceContentId ),
|
||||
m_instanceContentInfo( pInstanceContent ),
|
||||
m_instanceConfiguration( pInstanceConfiguration ),
|
||||
m_instanceContentId( instanceContentId ),
|
||||
m_state( Created ),
|
||||
m_pEntranceEObj( nullptr ),
|
||||
m_instanceCommenceTime( 0 ),
|
||||
m_currentBgm( pInstanceContent->bGM )
|
||||
m_currentBgm( pInstanceConfiguration->bGM )
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -63,15 +63,15 @@ uint32_t Core::InstanceContent::getInstanceContentId() const
|
|||
return m_instanceContentId;
|
||||
}
|
||||
|
||||
Core::Data::ExdDataGenerated::InstanceContentPtr Core::InstanceContent::getInstanceContentInfo() const
|
||||
Core::Data::ExdDataGenerated::InstanceContentPtr Core::InstanceContent::getInstanceConfiguration() const
|
||||
{
|
||||
return m_instanceContentInfo;
|
||||
return m_instanceConfiguration;
|
||||
}
|
||||
|
||||
void Core::InstanceContent::onPlayerZoneIn( Entity::Player& player )
|
||||
{
|
||||
auto pLog = g_fw.get< Logger >();
|
||||
pLog->debug( "InstanceContent::onEnterTerritory: Zone#" + std::to_string( getGuId() ) + "|"
|
||||
pLog->debug( "InstanceContent::onPlayerZoneIn: Zone#" + std::to_string( getGuId() ) + "|"
|
||||
+ std::to_string( getInstanceContentId() ) +
|
||||
+ ", Entity#" + std::to_string( player.getId() ) );
|
||||
|
||||
|
@ -100,26 +100,28 @@ void Core::InstanceContent::onLeaveTerritory( Entity::Player& player )
|
|||
|
||||
void Core::InstanceContent::onUpdate( uint32_t currTime )
|
||||
{
|
||||
|
||||
|
||||
// TODO: check all players if still bound, if not, remove
|
||||
// needs to happen regardless of state
|
||||
|
||||
switch( m_state )
|
||||
{
|
||||
case Created:
|
||||
{
|
||||
// temporary handling for instance state progression
|
||||
if( m_playerMap.size() < 1 )
|
||||
if( m_boundPlayerIds.size() == 0 )
|
||||
return;
|
||||
|
||||
// TODO: 1. check all bound players instead of just players in instance at the time
|
||||
for( const auto playerId : m_boundPlayerIds )
|
||||
{
|
||||
auto it = m_playerMap.find( playerId );
|
||||
if( it == m_playerMap.end() )
|
||||
return;
|
||||
}
|
||||
|
||||
for( const auto& playerIt : m_playerMap )
|
||||
{
|
||||
if( !playerIt.second->isLoadingComplete() ||
|
||||
!playerIt.second->isDirectorInitialized() ||
|
||||
!playerIt.second->isOnEnterEventDone() ||
|
||||
playerIt.second->hasStateFlag( PlayerStateFlag::WatchingCutscene ) )
|
||||
const auto& player = playerIt.second;
|
||||
|
||||
if( !player->isLoadingComplete() ||
|
||||
!player->isDirectorInitialized() ||
|
||||
!player->isOnEnterEventDone() ||
|
||||
player->hasStateFlag( PlayerStateFlag::WatchingCutscene ) )
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -136,13 +138,13 @@ void Core::InstanceContent::onUpdate( uint32_t currTime )
|
|||
auto pPlayer = playerIt.second;
|
||||
pPlayer->queuePacket(
|
||||
ActorControlPacket143( pPlayer->getId(), DirectorUpdate,
|
||||
getDirectorId(), 0x40000001, m_instanceContentInfo->timeLimitmin * 60u ) );
|
||||
getDirectorId(), 0x40000001, m_instanceConfiguration->timeLimitmin * 60u ) );
|
||||
}
|
||||
|
||||
if( m_pEntranceEObj )
|
||||
m_pEntranceEObj->setState( 7 );
|
||||
m_state = DutyInProgress;
|
||||
m_instanceExpireTime = Util::getTimeSeconds() + ( m_instanceContentInfo->timeLimitmin * 60u );
|
||||
m_instanceExpireTime = Util::getTimeSeconds() + ( m_instanceConfiguration->timeLimitmin * 60u );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -159,9 +161,9 @@ void Core::InstanceContent::onUpdate( uint32_t currTime )
|
|||
case DutyFinished:
|
||||
break;
|
||||
}
|
||||
|
||||
auto pScriptMgr = g_fw.get< Scripting::ScriptMgr >();
|
||||
pScriptMgr->onInstanceUpdate( getAsInstanceContent(), currTime );
|
||||
|
||||
}
|
||||
|
||||
void Core::InstanceContent::onFinishLoading( Entity::Player& player )
|
||||
|
@ -338,6 +340,10 @@ Core::InstanceContent::InstanceContentState Core::InstanceContent::getState() co
|
|||
|
||||
void Core::InstanceContent::onBeforePlayerZoneIn( Core::Entity::Player& player )
|
||||
{
|
||||
// remove any players from the instance who aren't bound on zone in
|
||||
if( !isPlayerBound( player.getId() ) )
|
||||
player.exitInstance();
|
||||
|
||||
// if a player has already spawned once inside this instance, don't move them if they happen to zone in again
|
||||
if( !hasPlayerPreviouslySpawned( player ) )
|
||||
{
|
||||
|
@ -411,6 +417,11 @@ void Core::InstanceContent::setCurrentBGM( uint16_t bgmIndex )
|
|||
}
|
||||
}
|
||||
|
||||
void Core::InstanceContent::setPlayerBGM( Core::Entity::Player& player, uint16_t bgmId )
|
||||
{
|
||||
player.queuePacket( ActorControlPacket143( player.getId(), DirectorUpdate, getDirectorId(), 0x80000001, bgmId ) );
|
||||
}
|
||||
|
||||
uint16_t Core::InstanceContent::getCurrentBGM() const
|
||||
{
|
||||
return m_currentBgm;
|
||||
|
@ -438,4 +449,8 @@ bool Core::InstanceContent::isPlayerBound( uint32_t playerId ) const
|
|||
void Core::InstanceContent::unbindPlayer( uint32_t playerId )
|
||||
{
|
||||
m_boundPlayerIds.erase( playerId );
|
||||
|
||||
auto it = m_playerMap.find( playerId );
|
||||
if( it != m_playerMap.end() )
|
||||
it->second->exitInstance();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
DutyFinished
|
||||
};
|
||||
|
||||
InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceContent,
|
||||
InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceConfiguration,
|
||||
uint32_t guId,
|
||||
const std::string& internalName,
|
||||
const std::string& contentName,
|
||||
|
@ -51,14 +51,16 @@ public:
|
|||
void endEventCutscene();
|
||||
|
||||
/*! set the current bgm index (inside bgm.exd) */
|
||||
void setCurrentBGM( uint16_t bgmIndex );
|
||||
void setCurrentBGM( uint16_t bgmId );
|
||||
/*! set the current bgm for a specific player */
|
||||
void setPlayerBGM( Entity::Player& player, uint16_t bgmId );
|
||||
/*! get the currently playing bgm index */
|
||||
uint16_t getCurrentBGM() const;
|
||||
|
||||
bool hasPlayerPreviouslySpawned( Entity::Player &player ) const;
|
||||
bool hasPlayerPreviouslySpawned( Entity::Player& player ) const;
|
||||
InstanceContentState getState() const;
|
||||
|
||||
boost::shared_ptr< Core::Data::InstanceContent > getInstanceContentInfo() const;
|
||||
boost::shared_ptr< Core::Data::InstanceContent > getInstanceConfiguration() const;
|
||||
|
||||
uint32_t getInstanceContentId() const;
|
||||
|
||||
|
@ -77,7 +79,7 @@ public:
|
|||
const uint32_t instanceStartDelay = 1250;
|
||||
|
||||
private:
|
||||
boost::shared_ptr< Core::Data::InstanceContent > m_instanceContentInfo;
|
||||
boost::shared_ptr< Core::Data::InstanceContent > m_instanceConfiguration;
|
||||
uint32_t m_instanceContentId;
|
||||
InstanceContentState m_state;
|
||||
uint16_t m_currentBgm;
|
||||
|
|
|
@ -70,15 +70,18 @@ bool Core::TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId )
|
|||
if( !pTeri )
|
||||
return false;
|
||||
|
||||
return pTeri->territoryIntendedUse == TerritoryIntendedUse::AllianceRaid ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::BeforeTrialDung ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Trial ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Dungeon ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpenWorldInstanceBattle ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::PalaceOfTheDead ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::RaidFights ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Raids ||
|
||||
pTeri->territoryIntendedUse == TerritoryIntendedUse::TreasureMapInstance;
|
||||
auto intendedUse = pTeri->territoryIntendedUse;
|
||||
|
||||
return intendedUse == TerritoryIntendedUse::AllianceRaid ||
|
||||
intendedUse == TerritoryIntendedUse::BeforeTrialDung ||
|
||||
intendedUse == TerritoryIntendedUse::Trial ||
|
||||
intendedUse == TerritoryIntendedUse::Dungeon ||
|
||||
intendedUse == TerritoryIntendedUse::OpenWorldInstanceBattle ||
|
||||
intendedUse == TerritoryIntendedUse::PalaceOfTheDead ||
|
||||
intendedUse == TerritoryIntendedUse::RaidFights ||
|
||||
intendedUse == TerritoryIntendedUse::Raids ||
|
||||
intendedUse == TerritoryIntendedUse::TreasureMapInstance ||
|
||||
intendedUse == TerritoryIntendedUse::EventTrial;
|
||||
}
|
||||
|
||||
bool Core::TerritoryMgr::isPrivateTerritory( uint32_t territoryTypeId ) const
|
||||
|
|
|
@ -53,7 +53,10 @@ namespace Core
|
|||
FreeCompanyGarrison = 30,
|
||||
PalaceOfTheDead = 31,
|
||||
TreasureMapInstance = 33,
|
||||
EventArea = 40,
|
||||
EventTrial = 36,
|
||||
TheFeastArea = 37,
|
||||
PrivateEventArea = 40,
|
||||
//Eureka = 41, // wat
|
||||
};
|
||||
|
||||
TerritoryMgr();
|
||||
|
|
Loading…
Add table
Reference in a new issue