1
Fork 0
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:
Mordred 2018-03-16 19:34:08 +01:00 committed by GitHub
commit f2684f6c7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 108 additions and 57 deletions

View file

@ -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];

View file

@ -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" );
}

View file

@ -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 ) );

View file

@ -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 ) );
};
};

View file

@ -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();
}

View file

@ -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;
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;

View file

@ -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

View file

@ -53,7 +53,10 @@ namespace Core
FreeCompanyGarrison = 30,
PalaceOfTheDead = 31,
TreasureMapInstance = 33,
EventArea = 40,
EventTrial = 36,
TheFeastArea = 37,
PrivateEventArea = 40,
//Eureka = 41, // wat
};
TerritoryMgr();