mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-02 16:57:47 +00:00
myerge squashy;
This commit is contained in:
parent
ee72f2e447
commit
f2805e951c
37 changed files with 498 additions and 343 deletions
|
@ -18,28 +18,39 @@ if( UNIX )
|
|||
"preferred path to MySQL (mysql_config)"
|
||||
)
|
||||
|
||||
find_program(MYSQL_CONFIG mysql_config
|
||||
# try mariadb first
|
||||
find_program(MYSQL_CONFIG mariadb_config
|
||||
${MYSQL_CONFIG_PREFER_PATH}
|
||||
/usr/local/mysql/bin/
|
||||
/usr/local/bin/
|
||||
/usr/bin/
|
||||
)
|
||||
|
||||
if( NOT MYSQL_CONFIG )
|
||||
# fallback to mysql
|
||||
find_program(MYSQL_CONFIG mysql_config
|
||||
${MYSQL_CONFIG_PREFER_PATH}
|
||||
/usr/local/mysql/bin/
|
||||
/usr/local/bin/
|
||||
/usr/bin/
|
||||
)
|
||||
endif()
|
||||
|
||||
if( MYSQL_CONFIG )
|
||||
message(STATUS "Using mysql-config: ${MYSQL_CONFIG}")
|
||||
# set INCLUDE_DIR
|
||||
exec_program(${MYSQL_CONFIG}
|
||||
ARGS --include
|
||||
execute_process(COMMAND ${MYSQL_CONFIG} --include
|
||||
OUTPUT_VARIABLE MY_TMP
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
string(REGEX REPLACE "-I([^ ]*)( .*)?" "\\1" MY_TMP "${MY_TMP}")
|
||||
set(MYSQL_ADD_INCLUDE_PATH ${MY_TMP} CACHE FILEPATH INTERNAL)
|
||||
#message("[DEBUG] MYSQL ADD_INCLUDE_PATH : ${MYSQL_ADD_INCLUDE_PATH}")
|
||||
# set LIBRARY_DIR
|
||||
exec_program(${MYSQL_CONFIG}
|
||||
ARGS --libs_r
|
||||
execute_process(COMMAND ${MYSQL_CONFIG} --libs_r
|
||||
OUTPUT_VARIABLE MY_TMP
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
set(MYSQL_ADD_LIBRARIES "")
|
||||
string(REGEX MATCHALL "-l[^ ]*" MYSQL_LIB_LIST "${MY_TMP}")
|
||||
|
|
6
deps/watchdog/Watchdog.h
vendored
6
deps/watchdog/Watchdog.h
vendored
|
@ -32,14 +32,8 @@
|
|||
|
||||
#include <functional>
|
||||
|
||||
// fucking filesystem
|
||||
#if _MSC_VER >= 1925
|
||||
#include <filesystem>
|
||||
namespace ci { namespace fs = std::filesystem; }
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace ci { namespace fs = std::experimental::filesystem; }
|
||||
#endif
|
||||
|
||||
//! Exception for when Watchdog can't locate a file or parse the wildcard
|
||||
class WatchedFileSystemExc : public std::exception {
|
||||
|
|
|
@ -31,14 +31,8 @@
|
|||
#include <Util/CrashHandler.h>
|
||||
|
||||
|
||||
// fucking filesystem
|
||||
#if _MSC_VER >= 1925
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
|
||||
Sapphire::Common::Util::CrashHandler crashHandler;
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace Sapphire::Common
|
|||
const uint16_t ARRSIZE_ORCHESTRION = 40u;
|
||||
const uint16_t ARRSIZE_MONSTERNOTE = 12u;
|
||||
const uint16_t ARRSIZE_BORROWACTION = 10u;
|
||||
const uint16_t ARRSIZE_CONDITION = 12u;
|
||||
|
||||
const uint8_t TOWN_COUNT = 6;
|
||||
|
||||
|
|
|
@ -2,13 +2,8 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#if _MSC_VER >= 1925
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
using namespace Sapphire;
|
||||
using namespace Sapphire::Common;
|
||||
|
|
|
@ -8,13 +8,8 @@
|
|||
#include <spdlog/sinks/daily_file_sink.h>
|
||||
|
||||
// #include <iostream>
|
||||
#if _MSC_VER >= 1925
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
|
||||
void Sapphire::Logger::init( const std::string& logPath )
|
||||
|
|
|
@ -184,3 +184,23 @@ float Util::trunc( float value, uint8_t digitsToRemain )
|
|||
|
||||
return std::floor( value * factor ) / factor;
|
||||
}
|
||||
|
||||
float Util::length( const FFXIVARR_POSITION3& vec ) {
|
||||
return std::sqrt( vec.x * vec.x + vec.y * vec.y + vec.z * vec.z );
|
||||
}
|
||||
|
||||
FFXIVARR_POSITION3 Util::normalize( const FFXIVARR_POSITION3& vec ) {
|
||||
float len = length( vec );
|
||||
if( len == 0 ) return FFXIVARR_POSITION3();
|
||||
return FFXIVARR_POSITION3{ vec.x / len, vec.y / len, vec.z / len };
|
||||
}
|
||||
|
||||
float Util::dot( const FFXIVARR_POSITION3& vec1, const FFXIVARR_POSITION3& vec2 )
|
||||
{
|
||||
return vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
|
||||
}
|
||||
|
||||
FFXIVARR_POSITION3 Util::projectY( const FFXIVARR_POSITION3& vec )
|
||||
{
|
||||
return FFXIVARR_POSITION3{ vec.x, 0, vec.z };
|
||||
}
|
|
@ -48,6 +48,14 @@ namespace Sapphire::Common::Util
|
|||
FFXIVARR_POSITION3 transform( const FFXIVARR_POSITION3& vector, const Matrix33& matrix );
|
||||
|
||||
float eulerToDirection( const FFXIVARR_POSITION3& euler );
|
||||
|
||||
float length( const FFXIVARR_POSITION3& vec );
|
||||
|
||||
FFXIVARR_POSITION3 normalize( const FFXIVARR_POSITION3& vec );
|
||||
|
||||
float dot( const FFXIVARR_POSITION3& vec1, const FFXIVARR_POSITION3& vec2 );
|
||||
|
||||
FFXIVARR_POSITION3 projectY( const FFXIVARR_POSITION3& vec );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,12 +7,17 @@ inline bool FFXIVARR_POSITION3::operator == ( const FFXIVARR_POSITION3& target )
|
|||
return x == target.x && y == target.y && z == target.z;
|
||||
}
|
||||
|
||||
inline bool Vector3::operator == ( const Vector3& target ) const
|
||||
FFXIVARR_POSITION3 FFXIVARR_POSITION3::operator - ( const FFXIVARR_POSITION3& target ) const
|
||||
{
|
||||
return x == target.x && y == target.y && z == target.z;
|
||||
return FFXIVARR_POSITION3{ x - target.x, y - target.y, z - target.z };
|
||||
}
|
||||
|
||||
inline bool Vector3::operator == ( const FFXIVARR_POSITION3& target ) const
|
||||
inline bool Vector3::operator == ( const Vector3& target ) const
|
||||
{
|
||||
return x == target.x && y == target.y && z == target.z;
|
||||
return x == target.x && y == target.y && z == target.z && reserve == target.reserve;
|
||||
}
|
||||
|
||||
Vector3 Vector3::operator - ( const Vector3& target ) const
|
||||
{
|
||||
return Vector3{ x - target.x, y - target.y, z - target.z };
|
||||
}
|
|
@ -9,6 +9,7 @@ namespace Sapphire::Common
|
|||
float y;
|
||||
float z;
|
||||
inline bool operator == ( const FFXIVARR_POSITION3& target ) const;
|
||||
FFXIVARR_POSITION3 operator - ( const FFXIVARR_POSITION3& target ) const;
|
||||
};
|
||||
|
||||
struct Vector3
|
||||
|
@ -16,8 +17,10 @@ namespace Sapphire::Common
|
|||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float reserve;
|
||||
inline bool operator == ( const Vector3& target ) const;
|
||||
inline bool operator == ( const FFXIVARR_POSITION3& target ) const;
|
||||
Vector3 operator - ( const Vector3& target ) const;
|
||||
};
|
||||
|
||||
struct Matrix33
|
||||
|
|
|
@ -11,14 +11,8 @@
|
|||
using namespace Sapphire;
|
||||
using namespace Sapphire::Common;
|
||||
|
||||
// fucking filesystem
|
||||
#if _MSC_VER >= 1925
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
|
||||
DbManager::DbManager( const std::string& host, const std::string& database, const std::string& user, const std::string& pw, uint16_t port ) :
|
||||
|
|
|
@ -9,14 +9,8 @@
|
|||
|
||||
Sapphire::Common::Util::CrashHandler crashHandler;
|
||||
|
||||
// fucking filesystem
|
||||
#if _MSC_VER >= 1925
|
||||
#include <filesystem>
|
||||
namespace filesys = std::filesystem;
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace filesys = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
eventMgr().playScene( player, eventId, 1, 0, [this, eobj]( Entity::Player& player, const Event::SceneResult& result )
|
||||
{
|
||||
if( result.getResult( 0 ) != 1 )
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -823,7 +823,7 @@ private:
|
|||
quest.setSeq( Seq6 );
|
||||
eventMgr().sendEventNotice( player, getId(), 4, 0 );
|
||||
playerMgr().sendUrgent( player, "QuestBattle Unimplemented, skipping..." );
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
travelToPoprange( player, Poprange3, false );
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <Logging/Logger.h>
|
||||
|
||||
using namespace Sapphire;
|
||||
using namespace Sapphire::World::Action;
|
||||
|
@ -138,6 +139,10 @@ bool ActionLutData::cacheActions()
|
|||
{
|
||||
auto id = std::stoi( i.key() );
|
||||
auto action = i.value().get< ActionEntry >();
|
||||
|
||||
if( ActionLut::m_actionLut.count( id ) > 0 )
|
||||
throw std::runtime_error( fmt::format( "Action with ID {} cannot be defined more than once (defined again in {})", i.key(), p.path().string() ) );
|
||||
|
||||
ActionLut::m_actionLut.try_emplace( id, action );
|
||||
}
|
||||
|
||||
|
|
|
@ -171,6 +171,7 @@ std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket
|
|||
break;
|
||||
}
|
||||
|
||||
m_actorResultsMap.clear();
|
||||
return actionResult;
|
||||
}
|
||||
else // use Effect for single target
|
||||
|
|
|
@ -115,6 +115,6 @@ void ItemAction::handleSongItem()
|
|||
{
|
||||
auto player = getSourceChara()->getAsPlayer();
|
||||
|
||||
player->learnSong( m_itemAction->data().Calcu0Arg[ 0 ], m_id );
|
||||
playerMgr().onSongLearned( *player, m_itemAction->data().Calcu0Arg[ 0 ], m_id );
|
||||
player->dropInventoryItem( static_cast< Common::InventoryType >( m_itemSourceContainer ), static_cast< uint8_t >( m_itemSourceSlot ) );
|
||||
}
|
|
@ -712,7 +712,7 @@ void BNpc::onDeath()
|
|||
if( pPlayer )
|
||||
{
|
||||
playerMgr.onMobKill( *pPlayer, *this );
|
||||
pPlayer->gainExp( paramGrowthInfo->data().BaseExp );
|
||||
playerMgr.onGainExp( *pPlayer, paramGrowthInfo->data().BaseExp );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -834,6 +834,26 @@ float Chara::getModifier( Common::ParamModifier paramModifier ) const
|
|||
return result;
|
||||
}
|
||||
|
||||
// Compute forward direction based on rotation angle (assuming rotation around Z axis)
|
||||
FFXIVARR_POSITION3 Chara::getForwardVector() const {
|
||||
return Common::Util::normalize( FFXIVARR_POSITION3{ std::sin( getRot() ), 0, std::cos( getRot() ) } );
|
||||
}
|
||||
|
||||
// Function to check if actor is facing target
|
||||
bool Chara::isFacingTarget( const Chara& other, float threshold )
|
||||
{
|
||||
auto toActor = Common::Util::normalize( Common::Util::projectY( other.getPos() - getPos() ) );
|
||||
|
||||
auto forward = getForwardVector();
|
||||
|
||||
float dot = Common::Util::dot( forward, toActor );
|
||||
|
||||
// The threshold is used to determine how closely the actors need to be facing each other
|
||||
// 1.0 means they need to be perfectly facing each other
|
||||
// Lower values allow for some deviation
|
||||
return dot >= threshold;
|
||||
}
|
||||
|
||||
void Chara::onTick()
|
||||
{
|
||||
uint32_t thisTickDmg = 0;
|
||||
|
|
|
@ -265,6 +265,10 @@ namespace Sapphire::Entity
|
|||
|
||||
virtual void update( uint64_t tickCount );
|
||||
|
||||
Common::FFXIVARR_POSITION3 getForwardVector() const;
|
||||
|
||||
bool isFacingTarget( const Chara& other, float threshold = 0.95f );
|
||||
|
||||
World::Action::ActionPtr getCurrentAction() const;
|
||||
|
||||
void setCurrentAction( World::Action::ActionPtr pAction );
|
||||
|
|
|
@ -397,18 +397,6 @@ bool Player::isAutoattackOn() const
|
|||
return m_bAutoattack;
|
||||
}
|
||||
|
||||
bool Player::exitInstance()
|
||||
{
|
||||
auto& warpMgr = Common::Service< WarpMgr >::ref();
|
||||
|
||||
resetHp();
|
||||
resetMp();
|
||||
|
||||
warpMgr.requestMoveTerritory( *this, WarpType::WARP_TYPE_CONTENT_END_RETURN, getPrevTerritoryId(), getPrevPos(), getPrevRot() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t Player::getPlayTime() const
|
||||
{
|
||||
return m_playTime;
|
||||
|
@ -474,60 +462,6 @@ Player::Discovery& Player::getDiscoveryBitmask()
|
|||
return m_discovery;
|
||||
}
|
||||
|
||||
void Player::discover( int16_t mapId, int16_t subId )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
int32_t offset;
|
||||
|
||||
auto info = exdData.getRow< Excel::Map >( mapId );
|
||||
if( !info )
|
||||
{
|
||||
PlayerMgr::sendDebug( *this, "discover(): Could not obtain map data for map_id == {0}", mapId );
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mapData = info->data();
|
||||
|
||||
if( mapData.IsUint16Discovery )
|
||||
offset = 2 * mapData.DiscoveryIndex;
|
||||
else
|
||||
offset = 320 + 4 * mapData.DiscoveryIndex;
|
||||
|
||||
uint16_t index;
|
||||
uint8_t value;
|
||||
Util::valueToFlagByteIndexValue( subId, value, index );
|
||||
|
||||
m_discovery[ offset + index ] |= value;
|
||||
|
||||
uint16_t level = getLevel();
|
||||
|
||||
uint32_t exp = ( exdData.getRow< Excel::ParamGrow >( level )->data().NextExp * 5 / 100 );
|
||||
gainExp( exp );
|
||||
|
||||
// gain 10x additional EXP if entire map is completed
|
||||
uint32_t mask = mapData.DiscoveryFlag;
|
||||
uint32_t discoveredAreas;
|
||||
if( info->data().IsUint16Discovery )
|
||||
{
|
||||
discoveredAreas = ( m_discovery[ offset + 1 ] << 8 ) | m_discovery[ offset ];
|
||||
}
|
||||
else
|
||||
{
|
||||
discoveredAreas = ( m_discovery[ offset + 3 ] << 24 ) |
|
||||
( m_discovery[ offset + 2 ] << 16 ) |
|
||||
( m_discovery[ offset + 1 ] << 8 ) |
|
||||
m_discovery[ offset ];
|
||||
}
|
||||
|
||||
bool allDiscovered = ( ( discoveredAreas & mask ) == mask );
|
||||
|
||||
if( allDiscovered )
|
||||
{
|
||||
gainExp( exp * 10 );
|
||||
}
|
||||
}
|
||||
|
||||
bool Player::isNewAdventurer() const
|
||||
{
|
||||
return m_bNewAdventurer;
|
||||
|
@ -563,6 +497,11 @@ void Player::setRewardFlag( Common::UnlockEntry unlockId )
|
|||
Network::Util::Packet::sendActorControlSelf( *this, getId(), SetRewardFlag, unlock, 1 );
|
||||
}
|
||||
|
||||
void Player::fillRewardFlags()
|
||||
{
|
||||
memset( m_unlocks.data(), 0xFF, m_unlocks.size() );
|
||||
}
|
||||
|
||||
void Player::setBorrowAction( uint8_t slot, uint32_t action )
|
||||
{
|
||||
if( slot > Common::ARRSIZE_BORROWACTION )
|
||||
|
@ -586,8 +525,6 @@ void Player::learnSong( uint8_t songId, uint32_t itemId )
|
|||
Util::valueToFlagByteIndexValue( songId, value, index );
|
||||
|
||||
m_orchestrion[ index ] |= value;
|
||||
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), ToggleOrchestrionUnlock, songId, 1, itemId );
|
||||
}
|
||||
|
||||
bool Player::hasReward( Common::UnlockEntry unlockId ) const
|
||||
|
@ -614,52 +551,6 @@ bool Player::hasMount( uint32_t mountId ) const
|
|||
return m_mountGuide[ index ] & value;
|
||||
}
|
||||
|
||||
void Player::gainExp( uint32_t amount )
|
||||
{
|
||||
uint32_t currentExp = getExp();
|
||||
uint16_t level = getLevel();
|
||||
auto currentClass = static_cast< uint8_t >( getClass() );
|
||||
|
||||
if( level >= Common::MAX_PLAYER_LEVEL )
|
||||
{
|
||||
setExp( 0 );
|
||||
if( currentExp != 0 )
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), UpdateUiExp, currentClass, 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
uint32_t neededExpToLevel = exdData.getRow< Excel::ParamGrow >( level )->data().NextExp;
|
||||
uint32_t neededExpToLevelPlus1 = exdData.getRow< Excel::ParamGrow >( level + 1 )->data().NextExp;
|
||||
|
||||
if( ( currentExp + amount ) >= neededExpToLevel )
|
||||
{
|
||||
// levelup
|
||||
amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelPlus1 ? neededExpToLevelPlus1 - 1 : ( currentExp + amount - neededExpToLevel );
|
||||
|
||||
if( level + 1 >= Common::MAX_PLAYER_LEVEL )
|
||||
amount = 0;
|
||||
|
||||
setExp( amount );
|
||||
levelUp();
|
||||
}
|
||||
else
|
||||
setExp( currentExp + amount );
|
||||
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), GainExpMsg, currentClass, amount );
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), UpdateUiExp, currentClass, getExp() );
|
||||
}
|
||||
|
||||
void Player::levelUp()
|
||||
{
|
||||
m_hp = getMaxHp();
|
||||
m_mp = getMaxMp();
|
||||
|
||||
setLevel( getLevel() + 1 );
|
||||
}
|
||||
|
||||
uint8_t Player::getLevel() const
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
@ -691,14 +582,14 @@ bool Player::isClassJobUnlocked( Common::ClassJob classJob ) const
|
|||
return getLevelForClass( classJob ) != 0;
|
||||
}
|
||||
|
||||
uint32_t Player::getExp() const
|
||||
uint32_t Player::getCurrentExp() const
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( getClass() ) )->data().WorkIndex;
|
||||
return m_expArray[ classJobIndex ];
|
||||
}
|
||||
|
||||
void Player::setExp( uint32_t amount )
|
||||
void Player::setCurrentExp( uint32_t amount )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( getClass() ) )->data().WorkIndex;
|
||||
|
@ -719,20 +610,6 @@ void Player::setInCombat( bool mode )
|
|||
void Player::setClassJob( Common::ClassJob classJob )
|
||||
{
|
||||
m_class = classJob;
|
||||
|
||||
if( getHp() > getMaxHp() )
|
||||
m_hp = getMaxHp();
|
||||
|
||||
if( getMp() > getMaxMp() )
|
||||
m_mp = getMaxMp();
|
||||
|
||||
m_tp = 0;
|
||||
|
||||
Network::Util::Packet::sendChangeClass( *this );
|
||||
Network::Util::Packet::sendStatusUpdate( *this );
|
||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), ClassJobChange, 4 );
|
||||
Network::Util::Packet::sendHudParam( *this );
|
||||
Service< World::Manager::MapMgr >::ref().updateQuests( *this );
|
||||
}
|
||||
|
||||
void Player::setLevel( uint8_t level )
|
||||
|
@ -740,16 +617,6 @@ void Player::setLevel( uint8_t level )
|
|||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( getClass() ) )->data().WorkIndex;
|
||||
m_classArray[ classJobIndex ] = level;
|
||||
|
||||
calculateStats();
|
||||
Network::Util::Packet::sendBaseParams( *this );
|
||||
Network::Util::Packet::sendHudParam( *this );
|
||||
Network::Util::Packet::sendStatusUpdate( *this );
|
||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), LevelUpEffect, static_cast< uint8_t >( getClass() ), getLevel(), getLevel() - 1 );
|
||||
|
||||
auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref();
|
||||
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( *this, static_cast< uint32_t >( getClass() ) );
|
||||
Service< World::Manager::MapMgr >::ref().updateQuests( *this );
|
||||
}
|
||||
|
||||
void Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
|
||||
|
@ -1586,77 +1453,6 @@ Sapphire::Common::HuntingLogEntry& Player::getHuntingLogEntry( uint8_t index )
|
|||
return m_huntingLogEntries[ index ];
|
||||
}
|
||||
|
||||
void Player::updateHuntingLog( uint16_t id )
|
||||
{
|
||||
std::vector< uint32_t > rankRewards{ 2500, 10000, 20000, 30000, 40000 };
|
||||
const auto maxRank = 4;
|
||||
auto& pExdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
// make sure we get the matching base-class if a job is being used
|
||||
auto classJobInfo = pExdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( getClass() ) );
|
||||
if( !classJobInfo )
|
||||
return;
|
||||
|
||||
auto currentClassId = classJobInfo->data().MonsterNote;
|
||||
if( currentClassId == -1 || currentClassId == 127 )
|
||||
return;
|
||||
|
||||
auto& logEntry = m_huntingLogEntries[ currentClassId ];
|
||||
|
||||
bool logChanged = false;
|
||||
|
||||
|
||||
bool allSectionsComplete = true;
|
||||
for( int i = 1; i <= 10; ++i )
|
||||
{
|
||||
bool sectionComplete = true;
|
||||
bool sectionChanged = false;
|
||||
auto monsterNoteId = static_cast< uint32_t >( classJobInfo->data().MainClass * 10000 + logEntry.rank * 10 + i );
|
||||
auto note = pExdData.getRow< Excel::MonsterNote >( monsterNoteId );
|
||||
|
||||
// for classes that don't have entries, if the first fails the rest will fail
|
||||
if( !note )
|
||||
break;
|
||||
|
||||
for( auto x = 0; x < 4; ++x )
|
||||
{
|
||||
auto note1 = pExdData.getRow< Excel::MonsterNoteTarget >( note->data().Target[ x ] );
|
||||
if( note1->data().Monster == id && logEntry.entries[ i - 1 ][ x ] < note->data().NeededKills[ x ] )
|
||||
{
|
||||
logEntry.entries[ i - 1 ][ x ]++;
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogEntryUpdate, monsterNoteId, x, logEntry.entries[ i - 1 ][ x ] );
|
||||
logChanged = true;
|
||||
sectionChanged = true;
|
||||
}
|
||||
if( logEntry.entries[ i - 1 ][ x ] != note->data().NeededKills[ x ] )
|
||||
sectionComplete = false;
|
||||
}
|
||||
if( logChanged && sectionComplete && sectionChanged )
|
||||
{
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogSectionFinish, monsterNoteId, i, 0 );
|
||||
gainExp( note->data().RewardExp );
|
||||
}
|
||||
if( !sectionComplete )
|
||||
{
|
||||
allSectionsComplete = false;
|
||||
}
|
||||
}
|
||||
if( logChanged && allSectionsComplete )
|
||||
{
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogRankFinish, 4 );
|
||||
gainExp( rankRewards[ logEntry.rank ] );
|
||||
if( logEntry.rank < 4 )
|
||||
{
|
||||
logEntry.rank++;
|
||||
memset( logEntry.entries, 0, 40 );
|
||||
Network::Util::Packet::sendActorControlSelf( *this, getId(), HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( logChanged )
|
||||
Network::Util::Packet::sendHuntingLog( *this );
|
||||
}
|
||||
|
||||
void Player::setActiveLand( uint8_t land, uint8_t ward )
|
||||
{
|
||||
m_activeLand.plot = land;
|
||||
|
@ -1817,6 +1613,9 @@ void Player::setFalling( bool state, const Common::FFXIVARR_POSITION3& pos, bool
|
|||
takeDamage( damage );
|
||||
}
|
||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), SetFallDamage, damage );
|
||||
// todo: this used to work without refreshing the entire UI state
|
||||
// does 3.x use some sort of fall integrity?
|
||||
Network::Util::Packet::sendHudParam( *this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Sapphire::Entity
|
|||
using AetheryteList = std::array< uint8_t, Common::ARRSIZE_AETHERYTES >;
|
||||
using UnlockList = std::array< uint8_t, Common::ARRSIZE_UNLOCKS >;
|
||||
using OrchestrionList = std::array< uint8_t, Common::ARRSIZE_ORCHESTRION >;
|
||||
using Condition = std::array< uint8_t, 12 >;
|
||||
using Condition = std::array< uint8_t, Common::ARRSIZE_CONDITION >;
|
||||
|
||||
using ClassList = std::array< uint16_t, Common::ARRSIZE_CLASSJOB >;
|
||||
using ExpList = std::array< uint32_t, Common::ARRSIZE_CLASSJOB >;
|
||||
|
@ -215,16 +215,10 @@ namespace Sapphire::Entity
|
|||
bool isClassJobUnlocked( Common::ClassJob classJob ) const;
|
||||
|
||||
/*! returns the exp of the currently active class / job */
|
||||
uint32_t getExp() const;
|
||||
uint32_t getCurrentExp() const;
|
||||
|
||||
/*! sets the exp of the currently active class / job */
|
||||
void setExp( uint32_t amount );
|
||||
|
||||
/*! adds exp to the currently active class / job */
|
||||
void gainExp( uint32_t amount );
|
||||
|
||||
/*! gain a level on the currently active class / job */
|
||||
void levelUp();
|
||||
void setCurrentExp( uint32_t amount );
|
||||
|
||||
/*! set level on the currently active class / job to given level */
|
||||
void setLevel( uint8_t level );
|
||||
|
@ -294,9 +288,6 @@ namespace Sapphire::Entity
|
|||
/*! return current online status depending on current state / activity */
|
||||
Common::OnlineStatus getOnlineStatus() const;
|
||||
|
||||
/*! returns the player to their position before zoning into an instance */
|
||||
bool exitInstance();
|
||||
|
||||
/*! gets the players territoryTypeId */
|
||||
uint32_t getPrevTerritoryTypeId() const;
|
||||
|
||||
|
@ -423,9 +414,6 @@ namespace Sapphire::Entity
|
|||
/*! get homepoint */
|
||||
uint8_t getHomepoint() const;
|
||||
|
||||
/*! discover subarea subid fo map map_id, also send udpate packet */
|
||||
void discover( int16_t mapId, int16_t subId );
|
||||
|
||||
/*! return a reference to the discovery bitmask array */
|
||||
Discovery& getDiscoveryBitmask();
|
||||
|
||||
|
@ -441,6 +429,9 @@ namespace Sapphire::Entity
|
|||
/*! learn an action / update the unlock bitmask. */
|
||||
void setRewardFlag( Common::UnlockEntry unlockId );
|
||||
|
||||
/*! helper/debug function to fill unlock bitmask */
|
||||
void fillRewardFlags();
|
||||
|
||||
void setBorrowAction( uint8_t slot, uint32_t action );
|
||||
|
||||
BorrowAction& getBorrowAction();
|
||||
|
@ -778,8 +769,6 @@ namespace Sapphire::Entity
|
|||
|
||||
Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index );
|
||||
|
||||
void updateHuntingLog( uint16_t id );
|
||||
|
||||
uint64_t getPartyId() const;
|
||||
void setPartyId( uint64_t partyId );
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ void Player::equipWeapon( const Item& item )
|
|||
|
||||
if( ( isClassJobUnlocked( newClassJob ) ) && ( currentParentClass != newClassJob ) )
|
||||
{
|
||||
setClassJob( newClassJob );
|
||||
playerMgr().onClassJobChanged( *this, newClassJob );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ void Player::equipSoulCrystal( const Item& item )
|
|||
auto newClassJob = static_cast< ClassJob >( itemClassJob );
|
||||
|
||||
if( isClassJobUnlocked( newClassJob ) )
|
||||
setClassJob( newClassJob );
|
||||
playerMgr().onClassJobChanged( *this, newClassJob );
|
||||
}
|
||||
|
||||
void Player::updateModels( GearSetSlot equipSlotId, const Sapphire::Item& item )
|
||||
|
@ -263,7 +263,7 @@ void Player::unequipSoulCrystal()
|
|||
|
||||
auto currentClassJob = exdData.getRow< Excel::ClassJob >( static_cast< uint32_t >( getClass() ) );
|
||||
auto parentClass = static_cast< ClassJob >( currentClassJob->data().MainClass );
|
||||
setClassJob( parentClass );
|
||||
playerMgr().onClassJobChanged( *this, parentClass );
|
||||
}
|
||||
|
||||
uint32_t Player::currencyTypeToItem( Common::CurrencyType type ) const
|
||||
|
|
|
@ -493,7 +493,7 @@ void Player::updateDbClass() const
|
|||
|
||||
//Exp = ?, Lvl = ?, BorrowAction = ? WHERE CharacterId = ? AND ClassIdx = ?
|
||||
auto stmtS = db.getPreparedStatement( Db::CHARA_CLASS_UP );
|
||||
stmtS->setInt( 1, getExp() );
|
||||
stmtS->setInt( 1, getCurrentExp() );
|
||||
stmtS->setInt( 2, getLevel() );
|
||||
|
||||
std::vector< uint8_t > borrowActionVec( borrowAction.size() * 4 );
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <Database/DatabaseDef.h>
|
||||
#include <cmath>
|
||||
#include <Network/PacketWrappers/EffectPacket.h>
|
||||
#include <Network/Util/PacketUtil.h>
|
||||
#include <Service.h>
|
||||
|
||||
#include "DebugCommand/DebugCommand.h"
|
||||
|
@ -84,6 +85,7 @@ DebugCommandMgr::DebugCommandMgr()
|
|||
registerCommand( "cf", &DebugCommandMgr::contentFinder, "Content-Finder", 1 );
|
||||
registerCommand( "ew", &DebugCommandMgr::easyWarp, "Easy warping", 1 );
|
||||
registerCommand( "reload", &DebugCommandMgr::hotReload, "Reloads a resource", 1 );
|
||||
registerCommand( "facing", &DebugCommandMgr::facing, "Checks if you are facing an actor", 1 );
|
||||
registerCommand( "cbt", &DebugCommandMgr::cbt, "Create, bind and teleport to an instance", 1 );
|
||||
}
|
||||
|
||||
|
@ -163,6 +165,7 @@ void DebugCommandMgr::help( char* data, Entity::Player& player, std::shared_ptr<
|
|||
void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
||||
{
|
||||
auto& server = Sapphire::Common::Service< Sapphire::World::WorldServer >::ref();
|
||||
auto& playerMgr = Common::Service< PlayerMgr >::ref();
|
||||
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
||||
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
|
||||
|
||||
|
@ -237,7 +240,8 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr<
|
|||
else if( subCommand == "discovery_reset" )
|
||||
{
|
||||
player.resetDiscovery();
|
||||
server.queueForPlayer( player.getCharacterId(), std::make_shared< PlayerSetupPacket >( player ) );
|
||||
player.setIsLogin( true );
|
||||
playerMgr.onMoveZone( player );
|
||||
}
|
||||
else if( subCommand == "classjob" )
|
||||
{
|
||||
|
@ -248,10 +252,9 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr<
|
|||
if( player.getLevelForClass( static_cast< Common::ClassJob > ( id ) ) == 0 )
|
||||
{
|
||||
player.setLevelForClass( 1, static_cast< Common::ClassJob > ( id ) );
|
||||
player.setClassJob( static_cast< Common::ClassJob > ( id ) );
|
||||
}
|
||||
else
|
||||
player.setClassJob( static_cast< Common::ClassJob > ( id ) );
|
||||
|
||||
playerMgr.onClassJobChanged( player, static_cast< Common::ClassJob > ( id ) );
|
||||
}
|
||||
else if( subCommand == "cfpenalty" )
|
||||
{
|
||||
|
@ -389,6 +392,7 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr<
|
|||
void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
||||
{
|
||||
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
|
||||
auto& playerMgr = Common::Service< PlayerMgr >::ref();
|
||||
auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() );
|
||||
|
||||
std::string subCommand;
|
||||
|
@ -529,6 +533,13 @@ void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr<
|
|||
sscanf( params.c_str(), "%d", &id );
|
||||
player.setRewardFlag( static_cast< Common::UnlockEntry >( id ) );
|
||||
}
|
||||
else if( subCommand == "unlockall" )
|
||||
{
|
||||
player.fillRewardFlags();
|
||||
|
||||
player.setIsLogin( true );
|
||||
playerMgr.onMoveZone( player );
|
||||
}
|
||||
else if( subCommand == "effect" )
|
||||
{
|
||||
uint16_t param1;
|
||||
|
@ -969,7 +980,7 @@ void DebugCommandMgr::instance( char* data, Entity::Player& player, std::shared_
|
|||
}
|
||||
else if( subCommand == "return" || subCommand == "ret" )
|
||||
{
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
}
|
||||
else if( subCommand == "stringendomode" || subCommand == "sm" )
|
||||
{
|
||||
|
@ -1219,7 +1230,7 @@ void DebugCommandMgr::questBattle( char* data, Entity::Player& player, std::shar
|
|||
}
|
||||
else if( subCommand == "return" || subCommand == "ret" )
|
||||
{
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
}
|
||||
else if( subCommand == "set" )
|
||||
{
|
||||
|
@ -1600,3 +1611,42 @@ void DebugCommandMgr::hotReload( char* data, Sapphire::Entity::Player& player, s
|
|||
PlayerMgr::sendDebug( player, "Unknown sub command." );
|
||||
}
|
||||
}
|
||||
|
||||
void DebugCommandMgr::facing( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command )
|
||||
{
|
||||
std::string subCommand;
|
||||
std::string params = "";
|
||||
|
||||
// check if the command has parameters
|
||||
std::string tmpCommand = std::string( data + command->getName().length() + 1 );
|
||||
|
||||
std::size_t pos = tmpCommand.find_first_of( ' ' );
|
||||
|
||||
if( pos != std::string::npos )
|
||||
// command has parameters, grab the first part
|
||||
subCommand = tmpCommand.substr( 0, pos );
|
||||
else
|
||||
// no subcommand given
|
||||
subCommand = tmpCommand;
|
||||
|
||||
if( command->getName().length() + 1 + pos + 1 < strlen( data ) )
|
||||
params = std::string( data + command->getName().length() + 1 + pos + 1 );
|
||||
|
||||
Logger::debug( "[{0}] subCommand: {1} params: {2}", player.getId(), subCommand, params );
|
||||
|
||||
float threshold = 0.95f;
|
||||
sscanf( params.c_str(), "%f", &threshold );
|
||||
|
||||
if( player.getTargetId() != 0 )
|
||||
{
|
||||
auto target = player.lookupTargetById( player.getTargetId() );
|
||||
|
||||
if( !target )
|
||||
return;
|
||||
|
||||
if( auto bnpc = target->getAsBNpc() )
|
||||
{
|
||||
PlayerMgr::sendDebug( player, "Player facing target {0}: {1}", bnpc->getLayoutId(), player.isFacingTarget( *bnpc->getAsChara(), threshold ) );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,6 +67,8 @@ namespace Sapphire::World::Manager
|
|||
|
||||
void hotReload( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command );
|
||||
|
||||
void facing( char* data, Sapphire::Entity::Player& player, std::shared_ptr< DebugCommand > command );
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -35,11 +35,24 @@ using namespace Sapphire::World::Manager;
|
|||
bool MapMgr::loadQuests()
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
auto questList = exdData.getRows< Excel::Quest >();
|
||||
auto eNpcList = exdData.getRows< Excel::ENpcBase >();
|
||||
auto eObjList = exdData.getRows< Excel::EObj >();
|
||||
|
||||
for( auto& [ id, questExdData ] : questList )
|
||||
{
|
||||
m_quests.emplace( id, std::move( questExdData ) );
|
||||
m_questCacheMap.emplace( id, std::move( questExdData ) );
|
||||
}
|
||||
|
||||
for( auto& [ id, eNpcExdData ] : eNpcList )
|
||||
{
|
||||
m_eNpcCacheMap.emplace( id, std::move( eNpcExdData ) );
|
||||
}
|
||||
|
||||
for( auto& [ id, eObjExdData ] : eObjList )
|
||||
{
|
||||
m_eObjCacheMap.emplace( id, std::move( eObjExdData ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -58,12 +71,12 @@ void MapMgr::updateAll( Entity::Player& player )
|
|||
|
||||
for( const auto& eventNpc : *eventNpcs )
|
||||
{
|
||||
auto eNpc = exdData.getRow< Excel::ENpcBase >( eventNpc.second->data.enpcId );
|
||||
if( !eNpc )
|
||||
auto eNpcIt = m_eNpcCacheMap.find( eventNpc.second->data.enpcId );
|
||||
if( eNpcIt == std::end( m_eNpcCacheMap ) )
|
||||
continue;
|
||||
|
||||
auto eNpcData = eNpc->data().EventHandler;
|
||||
for( int npcEvent = 0; npcEvent < 32; npcEvent++ )
|
||||
auto eNpcData = eNpcIt->second->data().EventHandler;
|
||||
for( auto npcEvent = 0; npcEvent < 32; ++npcEvent )
|
||||
{
|
||||
auto npcData = eNpcData[ npcEvent ].EventHandler;
|
||||
|
||||
|
@ -80,7 +93,7 @@ void MapMgr::updateAll( Entity::Player& player )
|
|||
{
|
||||
case EventHandler::EventHandlerType::Quest:
|
||||
{
|
||||
auto& quest = m_quests[ npcData ]->data();
|
||||
auto& quest = m_questCacheMap[ npcData ]->data();
|
||||
|
||||
if( quest.Client == eventNpc.second->data.enpcId )
|
||||
{
|
||||
|
@ -102,7 +115,7 @@ void MapMgr::updateAll( Entity::Player& player )
|
|||
{
|
||||
if( guildLeve.NeedGrandCompanyRank > 0 && player.getGc() != 0 )
|
||||
{
|
||||
for( int8_t i = 0; i < 3; i++ )
|
||||
for( int8_t i = 0; i < 3; ++i )
|
||||
{
|
||||
if( player.getGcRankArray()[ i ] >= guildLeve.NeedGrandCompanyRank )
|
||||
{
|
||||
|
@ -162,11 +175,11 @@ void MapMgr::updateAll( Entity::Player& player )
|
|||
|
||||
for( const auto& eventObj : *eventObjs )
|
||||
{
|
||||
auto eObj = exdData.getRow< Excel::EObj >( eventObj.second->data.BaseId );
|
||||
if( !eObj )
|
||||
return;
|
||||
auto eObjIt = m_eObjCacheMap.find( eventObj.second->data.BaseId );
|
||||
if( eObjIt == std::end( m_eObjCacheMap ) )
|
||||
continue;
|
||||
|
||||
auto eObjData = eObj->data();
|
||||
auto eObjData = eObjIt->second->data();
|
||||
EventData eventData;
|
||||
eventData.handlerId = eObjData.EventHandler;
|
||||
eventData.layoutId = eventObj.first;
|
||||
|
@ -175,7 +188,7 @@ void MapMgr::updateAll( Entity::Player& player )
|
|||
|
||||
if( eventHandlerType == EventHandler::EventHandlerType::Quest )
|
||||
{
|
||||
auto& quest = m_quests[ eObjData.EventHandler ]->data();
|
||||
auto& quest = m_questCacheMap[ eObjData.EventHandler ]->data();
|
||||
|
||||
if( quest.Client == eventObj.second->data.BaseId )
|
||||
{
|
||||
|
@ -200,13 +213,13 @@ void MapMgr::updateQuests( Entity::Player& player )
|
|||
|
||||
for( const auto& eventNpc : *eventNpcs )
|
||||
{
|
||||
auto eNpc = exdData.getRow< Excel::ENpcBase >( eventNpc.second->data.enpcId );
|
||||
if( !eNpc )
|
||||
auto eNpcIt = m_eNpcCacheMap.find( eventNpc.second->data.enpcId );
|
||||
if( eNpcIt == std::end( m_eNpcCacheMap ) )
|
||||
continue;
|
||||
|
||||
auto eNpcData = eNpc->data().EventHandler;
|
||||
auto eNpcData = eNpcIt->second->data().EventHandler;
|
||||
|
||||
for( int npcEvent = 0; npcEvent < 32; npcEvent++ )
|
||||
for( auto npcEvent = 0; npcEvent < 32; ++npcEvent )
|
||||
{
|
||||
auto npcData = eNpcData[ npcEvent ].EventHandler;
|
||||
|
||||
|
@ -221,7 +234,7 @@ void MapMgr::updateQuests( Entity::Player& player )
|
|||
|
||||
if( eventHandlerType == EventHandler::EventHandlerType::Quest )
|
||||
{
|
||||
auto& quest = m_quests[ npcData ]->data();
|
||||
auto& quest = m_questCacheMap[ npcData ]->data();
|
||||
|
||||
if( quest.Client == eventNpc.second->data.enpcId )
|
||||
{
|
||||
|
@ -237,11 +250,11 @@ void MapMgr::updateQuests( Entity::Player& player )
|
|||
|
||||
for( const auto& eventObj : *eventObjs )
|
||||
{
|
||||
auto eObj = exdData.getRow< Excel::EObj >( eventObj.second->data.BaseId );
|
||||
if( !eObj )
|
||||
return;
|
||||
auto eObjIt = m_eObjCacheMap.find( eventObj.second->data.BaseId );
|
||||
if( eObjIt == std::end( m_eObjCacheMap ) )
|
||||
continue;
|
||||
|
||||
auto eObjData = eObj->data();
|
||||
auto eObjData = eObjIt->second->data();
|
||||
EventData eventData;
|
||||
eventData.handlerId = eObjData.EventHandler;
|
||||
eventData.layoutId = eventObj.first;
|
||||
|
@ -250,7 +263,7 @@ void MapMgr::updateQuests( Entity::Player& player )
|
|||
|
||||
if( eventHandlerType == EventHandler::EventHandlerType::Quest )
|
||||
{
|
||||
auto& quest = m_quests[ eObjData.EventHandler ]->data();
|
||||
auto& quest = m_questCacheMap[ eObjData.EventHandler ]->data();
|
||||
|
||||
if( quest.Client == eventObj.second->data.BaseId )
|
||||
{
|
||||
|
@ -267,7 +280,7 @@ void MapMgr::insertQuest( Entity::Player& player, uint32_t questId, uint32_t lay
|
|||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
|
||||
auto& quest = m_quests[ questId ]->data();
|
||||
auto& quest = m_questCacheMap[ questId ]->data();
|
||||
|
||||
if( isQuestVisible( player, questId, quest ) )
|
||||
{
|
||||
|
@ -307,7 +320,7 @@ bool MapMgr::isQuestAvailable( Entity::Player& player, uint32_t questId, Excel::
|
|||
|
||||
if( quest.InstanceContentOperator == 1 )
|
||||
{
|
||||
for( int32_t i = 0; i < 3; i++ )
|
||||
for( int32_t i = 0; i < 3; ++i )
|
||||
{
|
||||
if( quest.InstanceContent[ i ] == 0 )
|
||||
continue;
|
||||
|
@ -319,7 +332,7 @@ bool MapMgr::isQuestAvailable( Entity::Player& player, uint32_t questId, Excel::
|
|||
}
|
||||
else if( quest.InstanceContentOperator == 2 )
|
||||
{
|
||||
for( int32_t i = 0; i < 3; i++ )
|
||||
for( int32_t i = 0; i < 3; ++i )
|
||||
{
|
||||
if( quest.InstanceContent[ i ] == 0 )
|
||||
continue;
|
||||
|
@ -396,7 +409,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
|
|||
|
||||
if( quest.PrevQuestOperator == 1 )
|
||||
{
|
||||
for( int32_t i = 0; i < 3; i++ )
|
||||
for( auto i = 0; i < 3; ++i )
|
||||
{
|
||||
if( quest.PrevQuest[ i ] == 0 )
|
||||
continue;
|
||||
|
@ -419,7 +432,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
|
|||
}
|
||||
else if( quest.PrevQuestOperator == 2 )
|
||||
{
|
||||
for( int32_t i = 0; i < 3; i++ )
|
||||
for( auto i = 0; i < 3; ++i )
|
||||
{
|
||||
if( quest.PrevQuest[ i ] == 0 )
|
||||
continue;
|
||||
|
@ -434,7 +447,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
|
|||
|
||||
if( quest.ExcludeQuestOperator == 1 )
|
||||
{
|
||||
for( int32_t i = 0; i < 2; i++ )
|
||||
for( auto i = 0; i < 2; ++i )
|
||||
{
|
||||
if( quest.ExcludeQuest[ i ] == 0 )
|
||||
continue;
|
||||
|
@ -448,7 +461,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
|
|||
}
|
||||
else if( quest.ExcludeQuestOperator == 2 )
|
||||
{
|
||||
for( int32_t i = 0; i < 2; i++ )
|
||||
for( auto i = 0; i < 2; ++i )
|
||||
{
|
||||
if( quest.ExcludeQuest[ i ] == 0 )
|
||||
continue;
|
||||
|
@ -475,7 +488,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
|
|||
{
|
||||
auto classJobCategory = exdData.getRow< Excel::ClassJobCategory >( quest.ClassJob )->data().ClassJob;
|
||||
|
||||
for( int32_t i = 1; i <= Common::CLASSJOB_TOTAL; i++ )
|
||||
for( auto i = 1; i <= Common::CLASSJOB_TOTAL; ++i )
|
||||
{
|
||||
if( i == Common::CLASSJOB_TOTAL )
|
||||
return false;
|
||||
|
@ -494,13 +507,14 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu
|
|||
}
|
||||
|
||||
// TODO: I think this changed in 3.x to be for all relics, more research is needed.
|
||||
for( int32_t i = 0; i < Common::CLASSJOB_TOTAL; i++ )
|
||||
// todo: fix this inner j loop
|
||||
for( auto i = 0; i < Common::CLASSJOB_TOTAL; ++i )
|
||||
{
|
||||
auto classJob = exdData.getRow< Excel::ClassJob >( i );
|
||||
|
||||
if( classJob->data().ARRRelicQuestId == questId )
|
||||
{
|
||||
for( int32_t j = 0; i < Common::CLASSJOB_TOTAL; i++ )
|
||||
for( auto j = 0; i < Common::CLASSJOB_TOTAL; ++i )
|
||||
{
|
||||
classJob = exdData.getRow< Excel::ClassJob >( i );
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
namespace Sapphire::World::Manager
|
||||
{
|
||||
using QuestMap = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::Quest > > >;
|
||||
using EObjDataCache = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::EObj > > >;
|
||||
using ENpcDataCache = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::ENpcBase > > >;
|
||||
|
||||
class MapMgr
|
||||
{
|
||||
|
@ -65,7 +67,10 @@ namespace Sapphire::World::Manager
|
|||
|
||||
using EventSet = std::multiset< EventData, less >;
|
||||
|
||||
QuestMap m_quests;
|
||||
|
||||
QuestMap m_questCacheMap;
|
||||
ENpcDataCache m_eNpcCacheMap;
|
||||
EObjDataCache m_eObjCacheMap;
|
||||
|
||||
void insertQuest( Entity::Player& player, uint32_t questId, uint32_t layoutId, EventSet& mapData );
|
||||
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
#include <Service.h>
|
||||
|
||||
#include <Exd/ExdData.h>
|
||||
|
||||
#include <Util/Util.h>
|
||||
#include <Territory/Land.h>
|
||||
|
||||
#include <Manager/AchievementMgr.h>
|
||||
#include <Manager/TerritoryMgr.h>
|
||||
#include <Manager/HousingMgr.h>
|
||||
#include <Manager/QuestMgr.h>
|
||||
#include <Manager/WarpMgr.h>
|
||||
#include <Manager/MapMgr.h>
|
||||
|
||||
#include <Script/ScriptMgr.h>
|
||||
#include <Common.h>
|
||||
|
@ -204,7 +207,7 @@ void PlayerMgr::onMobKill( Entity::Player& player, Entity::BNpc& bnpc )
|
|||
scriptMgr.onBNpcKill( player, bnpc );
|
||||
|
||||
if( player.hasReward( Common::UnlockEntry::HuntingLog ) )
|
||||
player.updateHuntingLog( bnpc.getBNpcNameId() );
|
||||
onUpdateHuntingLog( player, bnpc.getBNpcNameId() );
|
||||
}
|
||||
|
||||
void PlayerMgr::sendLoginMessage( Entity::Player& player )
|
||||
|
@ -339,6 +342,101 @@ void PlayerMgr::checkAutoAttack( Entity::Player& player, uint64_t tickCount ) co
|
|||
|
||||
}
|
||||
|
||||
void PlayerMgr::onGainExp( Entity::Player& player, uint32_t exp )
|
||||
{
|
||||
uint32_t currentExp = player.getCurrentExp();
|
||||
uint16_t level = player.getLevel();
|
||||
auto currentClass = static_cast< uint8_t >( player.getClass() );
|
||||
|
||||
if( level >= Common::MAX_PLAYER_LEVEL )
|
||||
{
|
||||
player.setCurrentExp( 0 );
|
||||
if( currentExp != 0 )
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), UpdateUiExp, currentClass, 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
uint32_t neededExpToLevel = exdData.getRow< Excel::ParamGrow >( level )->data().NextExp;
|
||||
uint32_t neededExpToLevelPlus1 = exdData.getRow< Excel::ParamGrow >( level + 1 )->data().NextExp;
|
||||
|
||||
if( ( currentExp + exp ) >= neededExpToLevel )
|
||||
{
|
||||
// levelup
|
||||
exp = ( currentExp + exp - neededExpToLevel ) > neededExpToLevelPlus1 ? neededExpToLevelPlus1 - 1 : ( currentExp + exp - neededExpToLevel );
|
||||
|
||||
if( level + 1 >= Common::MAX_PLAYER_LEVEL )
|
||||
exp = 0;
|
||||
else
|
||||
onLevelChanged( player, level + 1 );
|
||||
|
||||
player.setCurrentExp( exp );
|
||||
|
||||
}
|
||||
else
|
||||
player.setCurrentExp( currentExp + exp );
|
||||
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), GainExpMsg, currentClass, exp );
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), UpdateUiExp, currentClass, player.getCurrentExp() );
|
||||
}
|
||||
|
||||
void PlayerMgr::onDiscoverArea( Entity::Player& player, int16_t mapId, int16_t subId )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
int32_t offset;
|
||||
|
||||
auto info = exdData.getRow< Excel::Map >( mapId );
|
||||
if( !info )
|
||||
{
|
||||
sendDebug( player, "discover(): Could not obtain map data for map_id == {0}", mapId );
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& mapData = info->data();
|
||||
|
||||
if( mapData.IsUint16Discovery )
|
||||
offset = 2 * mapData.DiscoveryIndex;
|
||||
else
|
||||
offset = 320 + 4 * mapData.DiscoveryIndex;
|
||||
|
||||
uint16_t index;
|
||||
uint8_t value;
|
||||
Common::Util::valueToFlagByteIndexValue( subId, value, index );
|
||||
|
||||
auto& discovery = player.getDiscoveryBitmask();
|
||||
|
||||
discovery[ offset + index ] |= value;
|
||||
|
||||
uint16_t level = player.getLevel();
|
||||
|
||||
uint32_t exp = ( exdData.getRow< Excel::ParamGrow >( level )->data().NextExp * 5 / 100 );
|
||||
onGainExp( player, exp );
|
||||
|
||||
// gain 10x additional EXP if entire map is completed
|
||||
uint32_t mask = mapData.DiscoveryFlag;
|
||||
uint32_t discoveredAreas;
|
||||
if( info->data().IsUint16Discovery )
|
||||
{
|
||||
discoveredAreas = ( discovery[ offset + 1 ] << 8 ) | discovery[ offset ];
|
||||
}
|
||||
else
|
||||
{
|
||||
discoveredAreas = ( discovery[ offset + 3 ] << 24 ) |
|
||||
( discovery[ offset + 2 ] << 16 ) |
|
||||
( discovery[ offset + 1 ] << 8 ) |
|
||||
discovery[ offset ];
|
||||
}
|
||||
|
||||
bool allDiscovered = ( ( discoveredAreas & mask ) == mask );
|
||||
|
||||
if( allDiscovered )
|
||||
{
|
||||
onGainExp( player, exp * 10 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////// Helper ///////////
|
||||
|
||||
|
@ -371,3 +469,129 @@ void PlayerMgr::sendBattleTalk( Sapphire::Entity::Player& player, uint32_t battl
|
|||
Network::Util::Packet::sendBattleTalk( player, battleTalkId, handlerId, kind, nameId, talkerId,
|
||||
param1, param2, param3, param4, param5, param6, param7, param8 );
|
||||
}
|
||||
|
||||
void PlayerMgr::onUpdateHuntingLog( Entity::Player& player, uint8_t id )
|
||||
{
|
||||
std::vector< uint32_t > rankRewards{ 2500, 10000, 20000, 30000, 40000 };
|
||||
const auto maxRank = 4;
|
||||
auto& pExdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
// make sure we get the matching base-class if a job is being used
|
||||
auto classJobInfo = pExdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( player.getClass() ) );
|
||||
if( !classJobInfo )
|
||||
return;
|
||||
|
||||
auto currentClassId = classJobInfo->data().MonsterNote;
|
||||
if( currentClassId == -1 || currentClassId == 127 )
|
||||
return;
|
||||
|
||||
auto& logEntry = player.getHuntingLogEntry( currentClassId );
|
||||
|
||||
bool logChanged = false;
|
||||
|
||||
bool allSectionsComplete = true;
|
||||
for( int i = 1; i <= 10; ++i )
|
||||
{
|
||||
bool sectionComplete = true;
|
||||
bool sectionChanged = false;
|
||||
auto monsterNoteId = static_cast< uint32_t >( classJobInfo->data().MainClass * 10000 + logEntry.rank * 10 + i );
|
||||
auto note = pExdData.getRow< Excel::MonsterNote >( monsterNoteId );
|
||||
|
||||
// for classes that don't have entries, if the first fails the rest will fail
|
||||
if( !note )
|
||||
break;
|
||||
|
||||
for( auto x = 0; x < 4; ++x )
|
||||
{
|
||||
auto note1 = pExdData.getRow< Excel::MonsterNoteTarget >( note->data().Target[ x ] );
|
||||
if( note1->data().Monster == id && logEntry.entries[ i - 1 ][ x ] < note->data().NeededKills[ x ] )
|
||||
{
|
||||
logEntry.entries[ i - 1 ][ x ]++;
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), HuntingLogEntryUpdate, monsterNoteId, x, logEntry.entries[ i - 1 ][ x ] );
|
||||
logChanged = true;
|
||||
sectionChanged = true;
|
||||
}
|
||||
if( logEntry.entries[ i - 1 ][ x ] != note->data().NeededKills[ x ] )
|
||||
sectionComplete = false;
|
||||
}
|
||||
if( logChanged && sectionComplete && sectionChanged )
|
||||
{
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), HuntingLogSectionFinish, monsterNoteId, i, 0 );
|
||||
onGainExp( player, note->data().RewardExp );
|
||||
}
|
||||
if( !sectionComplete )
|
||||
{
|
||||
allSectionsComplete = false;
|
||||
}
|
||||
}
|
||||
if( logChanged && allSectionsComplete )
|
||||
{
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), HuntingLogRankFinish, 4 );
|
||||
onGainExp( player, rankRewards[ logEntry.rank ] );
|
||||
if( logEntry.rank < 4 )
|
||||
{
|
||||
logEntry.rank++;
|
||||
memset( logEntry.entries, 0, 40 );
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( logChanged )
|
||||
Network::Util::Packet::sendHuntingLog( player );
|
||||
}
|
||||
|
||||
void PlayerMgr::onExitInstance( Entity::Player& player )
|
||||
{
|
||||
auto& warpMgr = Common::Service< WarpMgr >::ref();
|
||||
|
||||
player.resetHp();
|
||||
player.resetMp();
|
||||
|
||||
warpMgr.requestMoveTerritory( player, Common::WarpType::WARP_TYPE_CONTENT_END_RETURN,
|
||||
player.getPrevTerritoryId(), player.getPrevPos(), player.getPrevRot() );
|
||||
|
||||
}
|
||||
|
||||
void PlayerMgr::onClassJobChanged( Entity::Player& player, Common::ClassJob classJob )
|
||||
{
|
||||
player.setClassJob( classJob );
|
||||
if( player.getHp() > player.getMaxHp() )
|
||||
player.setHp( player.getMaxHp() );
|
||||
|
||||
if( player.getMp() > player.getMaxMp() )
|
||||
player.setMp( player.getMaxMp() );
|
||||
|
||||
player.setTp( 0 );
|
||||
|
||||
Network::Util::Packet::sendChangeClass( player );
|
||||
Network::Util::Packet::sendStatusUpdate( player );
|
||||
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds( true ), player.getId(), ClassJobChange, 4 );
|
||||
Network::Util::Packet::sendHudParam( player );
|
||||
Common::Service< World::Manager::MapMgr >::ref().updateQuests( player );
|
||||
}
|
||||
|
||||
void PlayerMgr::onLevelChanged( Entity::Player& player, uint8_t level )
|
||||
{
|
||||
player.setLevel( level );
|
||||
player.calculateStats();
|
||||
|
||||
player.setHp( player.getMaxHp() );
|
||||
player.setMp( player.getMaxMp() );
|
||||
Network::Util::Packet::sendBaseParams( player );
|
||||
Network::Util::Packet::sendHudParam( player );
|
||||
Network::Util::Packet::sendStatusUpdate( player );
|
||||
Network::Util::Packet::sendActorControl( player.getInRangePlayerIds( true ), player.getId(), LevelUpEffect, static_cast< uint8_t >( player.getClass() ), player.getLevel(), player.getLevel() - 1 );
|
||||
|
||||
auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref();
|
||||
achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( player, static_cast< uint32_t >( player.getClass() ) );
|
||||
Common::Service< World::Manager::MapMgr >::ref().updateQuests( player );
|
||||
}
|
||||
|
||||
void PlayerMgr::onSongLearned( Entity::Player& player, uint8_t songId, uint32_t itemId )
|
||||
{
|
||||
player.learnSong( songId, itemId );
|
||||
Network::Util::Packet::sendActorControlSelf( player, player.getId(), ToggleOrchestrionUnlock, songId, 1, itemId );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,20 @@ namespace Sapphire::World::Manager
|
|||
|
||||
void onUpdate( Sapphire::Entity::Player& player, uint64_t tickCount );
|
||||
|
||||
void onGainExp( Sapphire::Entity::Player& player, uint32_t exp );
|
||||
|
||||
void onDiscoverArea( Sapphire::Entity::Player& player, int16_t mapId, int16_t subId );
|
||||
|
||||
void onUpdateHuntingLog( Sapphire::Entity::Player& player, uint8_t id );
|
||||
|
||||
void onExitInstance( Sapphire::Entity::Player& player );
|
||||
|
||||
void onClassJobChanged( Sapphire::Entity::Player& player, Common::ClassJob classJob );
|
||||
|
||||
void onLevelChanged( Sapphire::Entity::Player& player, uint8_t level );
|
||||
|
||||
void onSongLearned( Sapphire::Entity::Player& player, uint8_t songId, uint32_t itemId );
|
||||
|
||||
//////////// Helpers
|
||||
|
||||
static void sendServerNotice( Sapphire::Entity::Player& player, const std::string& message );
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "Network/GameConnection.h"
|
||||
|
||||
#include <Manager/PlayerMgr.h>
|
||||
|
||||
#include "QuestMgr.h"
|
||||
#include "AchievementMgr.h"
|
||||
|
||||
|
@ -60,6 +62,7 @@ void QuestMgr::onRemoveQuest( Entity::Player &player, uint8_t questIndex )
|
|||
|
||||
bool QuestMgr::giveQuestRewards( Entity::Player& player, uint16_t questId, uint32_t optionalChoice )
|
||||
{
|
||||
auto& playerMgr = Common::Service< World::Manager::PlayerMgr >::ref();
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
auto questInfo = exdData.getRow< Excel::Quest >( static_cast< uint32_t >( Event::EventHandler::EventHandlerType::Quest ) << 16 | questId );
|
||||
|
||||
|
@ -71,7 +74,9 @@ bool QuestMgr::giveQuestRewards( Entity::Player& player, uint16_t questId, uint3
|
|||
|
||||
// TODO: check if there is room in inventory, else return false;
|
||||
if( exp > 0 )
|
||||
player.gainExp( exp );
|
||||
{
|
||||
playerMgr.onGainExp( player, exp );
|
||||
}
|
||||
|
||||
for( uint32_t i = 0; i < 6; i++ )
|
||||
{
|
||||
|
|
|
@ -225,7 +225,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
|||
targetPlayer->getTerritoryTypeId(),
|
||||
static_cast< uint8_t >( targetPlayer->getClass() ),
|
||||
targetPlayer->getLevel(),
|
||||
targetPlayer->getExp(),
|
||||
targetPlayer->getCurrentExp(),
|
||||
targetPlayer->getSearchMessage(),
|
||||
targetPlayer->getPlayTime() );
|
||||
break;
|
||||
|
@ -253,7 +253,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
|||
}
|
||||
case GmCommand::Kill:
|
||||
{
|
||||
targetActor->getAsChara()->takeDamage( 9999999 );
|
||||
targetActor->getAsChara()->takeDamage( 0xFFFFFFFF );
|
||||
PlayerMgr::sendServerNotice( player, "Killed {0}", targetActor->getId());
|
||||
break;
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
|||
}
|
||||
case GmCommand::Exp:
|
||||
{
|
||||
targetPlayer->gainExp( param1 );
|
||||
playerMgr().onGainExp( *targetPlayer, param1 );
|
||||
PlayerMgr::sendServerNotice( player, "{0} Exp was added to {1}", param1, targetPlayer->getName());
|
||||
break;
|
||||
}
|
||||
|
@ -328,7 +328,9 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
|||
if( param2 == 0 )
|
||||
{
|
||||
for( uint8_t i = 0; i < 255; i++ )
|
||||
targetPlayer->learnSong( i, 0 );
|
||||
{
|
||||
playerMgr().onSongLearned( *targetPlayer, i, 0 );
|
||||
}
|
||||
|
||||
PlayerMgr::sendServerNotice( player, "All Songs for {0} were turned on.", targetPlayer->getName() );
|
||||
}
|
||||
|
|
|
@ -319,7 +319,7 @@ void Sapphire::Network::GameConnection::newDiscoveryHandler( const Packets::FFXI
|
|||
discoveryPacket->data().mapId = tInfo->data().Map;
|
||||
discoveryPacket->data().mapPartId = pRefInfo->data.discoveryIndex;
|
||||
server().queueForPlayer( player.getCharacterId(), discoveryPacket );
|
||||
player.discover( tInfo->data().Map, pRefInfo->data.discoveryIndex );
|
||||
playerMgr().onDiscoverArea( player, tInfo->data().Map, pRefInfo->data.discoveryIndex );
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ void Util::Packet::sendStatusUpdate( Entity::Player& player )
|
|||
playerStatusUpdate->data().Lv = player.getLevel();
|
||||
playerStatusUpdate->data().Lv1 = player.getLevel();
|
||||
playerStatusUpdate->data().LvSync = 0; //player.getLevelSync();
|
||||
playerStatusUpdate->data().Exp = player.getExp();
|
||||
playerStatusUpdate->data().Exp = player.getCurrentExp();
|
||||
|
||||
server().queueForPlayer( player.getCharacterId(), playerStatusUpdate );
|
||||
}
|
||||
|
|
|
@ -57,13 +57,20 @@ Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPt
|
|||
Util::eraseAll( m_name, ')' );
|
||||
|
||||
m_flag |= entry->data().Category;
|
||||
m_flag |= static_cast< uint32_t >( entry->data().Forever ) << static_cast< uint32_t >( Common::StatusEffectFlag::Permanent );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().CanOff ) << static_cast< uint32_t >( Common::StatusEffectFlag::CanStatusOff );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotAction ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockActions );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotControl ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockControl );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotMove ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockMovement );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotLookAt ) << static_cast< uint32_t >( Common::StatusEffectFlag::IsGaze );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().FcAction ) << static_cast< uint32_t >( Common::StatusEffectFlag::FcBuff );
|
||||
if( entry->data().Forever )
|
||||
m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::Permanent );
|
||||
if( entry->data().CanOff )
|
||||
m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::CanStatusOff );
|
||||
if( entry->data().NotAction )
|
||||
m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::LockActions );
|
||||
if( entry->data().NotControl )
|
||||
m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::LockControl );
|
||||
if( entry->data().NotMove )
|
||||
m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::LockMovement );
|
||||
if( entry->data().NotLookAt )
|
||||
m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::IsGaze );
|
||||
if( entry->data().FcAction )
|
||||
m_flag |= static_cast< uint32_t >( Common::StatusEffectFlag::FcBuff );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ void Sapphire::InstanceContent::onPlayerZoneIn( Entity::Player& player )
|
|||
if( isTerminationReady() ) // wtf
|
||||
{
|
||||
Logger::warn( "Entity#{0} Appear for a terminated instance!", player.getId() );
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -281,7 +281,7 @@ void Sapphire::InstanceContent::onUpdate( uint64_t tickCount )
|
|||
return;
|
||||
|
||||
auto player = it->second;
|
||||
player->exitInstance();
|
||||
playerMgr().onExitInstance( *player );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ void Sapphire::InstanceContent::onEventHandlerOrder( Entity::Player& player, uin
|
|||
{
|
||||
case 0: // Leave content
|
||||
{
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
break;
|
||||
}
|
||||
case 1: // Force leave ( afk timer )
|
||||
|
@ -578,7 +578,7 @@ void Sapphire::InstanceContent::onBeforePlayerZoneIn( Sapphire::Entity::Player&
|
|||
{
|
||||
// remove any players from the instance who aren't bound on zone in
|
||||
if( !isPlayerBound( player.getId() ) )
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
|
||||
// if a player has already spawned once inside this instance, don't move them if they happen to zone in again
|
||||
if( !hasPlayerPreviouslySpawned( player ) )
|
||||
|
@ -713,7 +713,7 @@ void Sapphire::InstanceContent::unbindPlayer( uint32_t playerId )
|
|||
|
||||
auto it = m_playerMap.find( playerId );
|
||||
if( it != m_playerMap.end() )
|
||||
it->second->exitInstance();
|
||||
playerMgr().onExitInstance( *it->second );
|
||||
}
|
||||
|
||||
void Sapphire::InstanceContent::clearDirector( Entity::Player& player )
|
||||
|
|
|
@ -158,7 +158,7 @@ void Sapphire::QuestBattle::onUpdate( uint64_t tickCount )
|
|||
|
||||
if( ( static_cast< int64_t >( tickCount ) - static_cast< int64_t >( m_instanceFailTime ) ) > 6000 )
|
||||
{
|
||||
m_pPlayer->exitInstance();
|
||||
playerMgr().onExitInstance( *m_pPlayer );
|
||||
m_pPlayer.reset();
|
||||
}
|
||||
break;
|
||||
|
@ -322,7 +322,7 @@ void Sapphire::QuestBattle::success()
|
|||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||
scriptMgr.onDutyComplete( *this, *m_pPlayer );
|
||||
|
||||
player.exitInstance();
|
||||
playerMgr().onExitInstance( player );
|
||||
} );
|
||||
|
||||
} );
|
||||
|
|
Loading…
Add table
Reference in a new issue