diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index ce984909..bb17af0a 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -326,6 +326,12 @@ public: /*! equip a weapon, possibly forcing a job change */ void equipWeapon( ItemPtr pItem, bool updateClass ); + /*! equip a soul crystal, possibly forcing a job change*/ + void equipSoulCrystal( ItemPtr pItem, bool updateClass ); + + /*! unequip a soul crystal, returning to the base class*/ + void unequipSoulCrystal( ItemPtr pItem ); + /*! get player ilvl */ uint16_t getItemLevel() const; diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index f8aef788..521b11e4 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -135,6 +135,20 @@ void Core::Entity::Player::equipWeapon( ItemPtr pItem, bool updateClass ) } } +void Core::Entity::Player::equipSoulCrystal( ItemPtr pItem, bool updateJob ) +{ + auto exdData = g_fw.get< Core::Data::ExdDataGenerated >(); + if ( !exdData ) + return; + + auto itemInfo = exdData->get< Core::Data::Item >( pItem->getId() ); + auto itemClassJob = itemInfo->classJobUse; + auto newClassJob = static_cast< ClassJob >( itemClassJob ); + + if ( isClassJobUnlocked( newClassJob ) && updateJob ) + setClassJob( newClassJob ); +} + // equip an item void Core::Entity::Player::equipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem, bool sendUpdate ) { @@ -169,8 +183,7 @@ void Core::Entity::Player::updateModels( GearSetSlot equipSlotId, const Core::It break; case SoulCrystal: - // TODO: add Job change on equipping crystal - // change job + equipSoulCrystal( pItem, updateClass ); break; case Waist: @@ -228,6 +241,20 @@ void Core::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, ItemPtr m_itemLevel = calculateEquippedGearItemLevel(); sendItemLevel(); + + if ( equipSlotId == SoulCrystal ) + unequipSoulCrystal( pItem ); +} + +void Core::Entity::Player::unequipSoulCrystal( ItemPtr pItem ) +{ + auto exdData = g_fw.get< Core::Data::ExdDataGenerated >(); + if ( !exdData ) + return; + + auto currentClassJob = exdData->get< Core::Data::ClassJob >( static_cast< uint32_t >( getClass() ) ); + auto parentClass = static_cast< ClassJob >( currentClassJob->classJobParent ); + setClassJob ( parentClass ); } // TODO: these next functions are so similar that they could likely be simplified