mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-03 09:17:47 +00:00
Merge pull request #889 from Skyliegirl33/master
[3.x] Implement glamours, set firstclass, fix tp not being set, log all params in packet cmds
This commit is contained in:
commit
81391f1ae1
15 changed files with 177 additions and 7 deletions
|
@ -275,7 +275,7 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
|
|||
CONNECTION_BOTH );
|
||||
|
||||
prepareStatement( CHARA_ITEMGLOBAL_UP,
|
||||
"UPDATE charaglobalitem SET stack = ?, durability = ?, stain = ? WHERE ItemId = ?;",
|
||||
"UPDATE charaglobalitem SET stack = ?, durability = ?, stain = ?, pattern = ? WHERE ItemId = ?;",
|
||||
CONNECTION_BOTH );
|
||||
|
||||
prepareStatement( CHARA_ITEMGLOBAL_DELETE,
|
||||
|
|
|
@ -549,6 +549,8 @@ namespace Sapphire::Network::ActorControl
|
|||
MOBHUNT_RECEIPT_ORDER = 0x1B3,
|
||||
MOBHUNT_BREAK_ORDER = 0x1B4,
|
||||
DYE_ITEM = 0x1B5,
|
||||
GLAMOUR_ITEM = 0x1BA,
|
||||
GLAMOUR_DISPEL = 0x1BB,
|
||||
EMOTE = 0x1F4,
|
||||
EMOTE_WITH_WARP = 0x1F5,
|
||||
EMOTE_CANCEL = 0x1F6,
|
||||
|
|
27
src/scripts/action/common/ActionGlamour2471.cpp
Normal file
27
src/scripts/action/common/ActionGlamour2471.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <ScriptObject.h>
|
||||
#include <Actor/Player.h>
|
||||
#include <Action/Action.h>
|
||||
#include <Inventory/Item.h>
|
||||
|
||||
class ActionGlamour2471 :
|
||||
public Sapphire::ScriptAPI::ActionScript
|
||||
{
|
||||
public:
|
||||
ActionGlamour2471() :
|
||||
Sapphire::ScriptAPI::ActionScript( 2471 )
|
||||
{
|
||||
}
|
||||
|
||||
void onExecute( Sapphire::World::Action::Action& action ) override
|
||||
{
|
||||
auto sourceChara = action.getSourceChara();
|
||||
|
||||
if( !sourceChara->isPlayer() )
|
||||
return;
|
||||
|
||||
//TODO: Effect
|
||||
sourceChara->getAsPlayer()->glamourItemFromGlamouringInfo();
|
||||
}
|
||||
};
|
||||
|
||||
EXPOSE_SCRIPT(ActionGlamour2471);
|
|
@ -690,6 +690,11 @@ uint8_t Player::getLevelForClass( Common::ClassJob pClass ) const
|
|||
return static_cast< uint8_t >( m_classArray[ classJobIndex ] );
|
||||
}
|
||||
|
||||
Common::ClassJob Player::getFirstClass() const
|
||||
{
|
||||
return m_firstClass;
|
||||
}
|
||||
|
||||
bool Player::isClassJobUnlocked( Common::ClassJob classJob ) const
|
||||
{
|
||||
// todo: need to properly check if a job is unlocked, at the moment we just check the class array which will return true for every job if the base class is unlocked
|
||||
|
@ -1505,6 +1510,68 @@ void Player::dyeItemFromDyeingInfo()
|
|||
queuePacket( dyePkt );
|
||||
}
|
||||
|
||||
void Player::setGlamouringInfo( uint32_t itemToGlamourContainer, uint32_t itemToGlamourSlot, uint32_t glamourBagContainer, uint32_t glamourBagSlot, bool shouldGlamour )
|
||||
{
|
||||
m_glamouringInfo.itemToGlamourContainer = itemToGlamourContainer;
|
||||
m_glamouringInfo.itemToGlamourSlot = itemToGlamourSlot;
|
||||
m_glamouringInfo.glamourBagContainer = glamourBagContainer;
|
||||
m_glamouringInfo.glamourBagSlot = glamourBagSlot;
|
||||
m_glamouringInfo.shouldGlamour = shouldGlamour;
|
||||
}
|
||||
|
||||
void Player::glamourItemFromGlamouringInfo()
|
||||
{
|
||||
auto& playerMgr = Service< World::Manager::PlayerMgr >::ref();
|
||||
|
||||
uint32_t itemToGlamourContainer = m_glamouringInfo.itemToGlamourContainer;
|
||||
uint32_t itemToGlamourSlot = m_glamouringInfo.itemToGlamourSlot;
|
||||
uint32_t glamourBagContainer = m_glamouringInfo.glamourBagContainer;
|
||||
uint32_t glamourBagSlot = m_glamouringInfo.glamourBagSlot;
|
||||
bool shouldGlamour = m_glamouringInfo.shouldGlamour;
|
||||
|
||||
playerMgr.onSendStateFlags( *this, true );
|
||||
|
||||
auto itemToGlamour = getItemAt( itemToGlamourContainer, itemToGlamourSlot );
|
||||
auto glamourToUse = getItemAt( glamourBagContainer, glamourBagSlot );
|
||||
//auto prismToUse = getItemAt( glamourBagContainer, glamourBagSlot );
|
||||
|
||||
if( !itemToGlamour )
|
||||
return;
|
||||
|
||||
//if( !removeItem( prismToUse->getId() ) )
|
||||
// return;
|
||||
|
||||
uint32_t patternID = itemToGlamour->getPattern();
|
||||
bool invalidateGearSet = shouldGlamour ? patternID != glamourToUse->getId() : true;
|
||||
|
||||
if( shouldGlamour )
|
||||
{
|
||||
itemToGlamour->setPattern( glamourToUse->getId() );
|
||||
itemToGlamour->setStain( glamourToUse->getStain() );
|
||||
}
|
||||
else
|
||||
{
|
||||
itemToGlamour->setPattern( 0 );
|
||||
itemToGlamour->setStain( 0 );
|
||||
}
|
||||
|
||||
itemToGlamour->setGlamModelIds();
|
||||
|
||||
insertInventoryItem( static_cast< Sapphire::Common::InventoryType >( itemToGlamourContainer ), static_cast< uint16_t >( itemToGlamourSlot ), itemToGlamour );
|
||||
writeItem( itemToGlamour );
|
||||
|
||||
if( shouldGlamour )
|
||||
{
|
||||
auto castGlamPkt = makeActorControlSelf( getId(), GlamourCastMsg, itemToGlamour->getId(), glamourToUse->getId(), invalidateGearSet );
|
||||
queuePacket( castGlamPkt );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto dispelGlamPkt = makeActorControlSelf( getId(), GlamourRemoveMsg, itemToGlamour->getId(), invalidateGearSet );
|
||||
queuePacket( dispelGlamPkt );
|
||||
}
|
||||
}
|
||||
|
||||
void Player::resetObjSpawnIndex()
|
||||
{
|
||||
m_objSpawnIndexAllocator.freeAllSpawnIndexes();
|
||||
|
|
|
@ -214,6 +214,9 @@ namespace Sapphire::Entity
|
|||
/*! returns the level of the provided class / job */
|
||||
uint8_t getLevelForClass( Common::ClassJob pClass ) const;
|
||||
|
||||
/*! \return the first class of the player */
|
||||
Common::ClassJob getFirstClass() const;
|
||||
|
||||
/*! returns if the classjob is unlocked */
|
||||
bool isClassJobUnlocked( Common::ClassJob classJob ) const;
|
||||
|
||||
|
@ -357,6 +360,9 @@ namespace Sapphire::Entity
|
|||
void setDyeingInfo( uint32_t itemToDyeContainer, uint32_t itemToDyeSlot, uint32_t dyeBagContainer, uint32_t dyeBagSlot );
|
||||
void dyeItemFromDyeingInfo();
|
||||
|
||||
void setGlamouringInfo( uint32_t itemToGlamourContainer, uint32_t itemToGlamourSlot, uint32_t glamourBagContainer, uint32_t glamourBagSlot, bool shouldGlamour );
|
||||
void glamourItemFromGlamouringInfo();
|
||||
|
||||
/*! get player's title list (available titles) */
|
||||
TitleList& getTitleList();
|
||||
|
||||
|
@ -898,6 +904,8 @@ namespace Sapphire::Entity
|
|||
ExpList m_expArray{};
|
||||
StateFlags m_stateFlags{};
|
||||
|
||||
Common::ClassJob m_firstClass{};
|
||||
|
||||
uint8_t m_homePoint;
|
||||
uint8_t m_startTown;
|
||||
uint16_t m_townWarpFstFlags;
|
||||
|
@ -968,6 +976,15 @@ namespace Sapphire::Entity
|
|||
uint32_t dyeBagSlot;
|
||||
} m_dyeingInfo{};
|
||||
|
||||
struct PlayerGlamouringInfo
|
||||
{
|
||||
uint32_t itemToGlamourContainer;
|
||||
uint32_t itemToGlamourSlot;
|
||||
uint32_t glamourBagContainer;
|
||||
uint32_t glamourBagSlot;
|
||||
bool shouldGlamour;
|
||||
} m_glamouringInfo{};
|
||||
|
||||
Common::Util::SpawnIndexAllocator< uint8_t > m_objSpawnIndexAllocator;
|
||||
Common::Util::SpawnIndexAllocator< uint8_t > m_actorSpawnIndexAllocator;
|
||||
|
||||
|
|
|
@ -529,8 +529,9 @@ void Sapphire::Entity::Player::writeItem( Sapphire::ItemPtr pItem ) const
|
|||
stmt->setInt( 1, pItem->getStackSize() );
|
||||
stmt->setInt( 2, pItem->getDurability() );
|
||||
stmt->setInt( 3, pItem->getStain() );
|
||||
stmt->setInt( 4, pItem->getPattern() );
|
||||
|
||||
stmt->setInt64( 4, pItem->getUId() );
|
||||
stmt->setInt64( 5, pItem->getUId() );
|
||||
|
||||
db.directExecute( stmt );
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ bool Sapphire::Entity::Player::loadFromDb( uint64_t characterId )
|
|||
|
||||
m_class = static_cast< ClassJob >( res->getUInt( "Class" ) );
|
||||
m_homePoint = res->getUInt8( "Homepoint" );
|
||||
m_firstClass = static_cast< ClassJob >( res->getUInt( "FirstClass" ) );
|
||||
|
||||
// Additional data
|
||||
m_voice = res->getUInt8( "Voice" );
|
||||
|
|
|
@ -132,6 +132,23 @@ Sapphire::Common::ItemUICategory Sapphire::Item::getCategory() const
|
|||
return m_category;
|
||||
}
|
||||
|
||||
void Sapphire::Item::setGlamModelIds()
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
|
||||
if( m_pattern != 0 )
|
||||
{
|
||||
auto itemInfo = exdData.getRow< Excel::Item >( m_pattern );
|
||||
m_glamModel1 = itemInfo->data().ModelId;
|
||||
m_glamModel2 = itemInfo->data().SubModelId;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_glamModel1 = 0;
|
||||
m_glamModel2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Sapphire::Item::setModelIds( uint64_t model1, uint64_t model2 )
|
||||
{
|
||||
m_model1 = model1;
|
||||
|
@ -140,12 +157,12 @@ void Sapphire::Item::setModelIds( uint64_t model1, uint64_t model2 )
|
|||
|
||||
uint64_t Sapphire::Item::getModelId1() const
|
||||
{
|
||||
return m_model1;
|
||||
return m_pattern != 0 ? m_glamModel1 : m_model1;
|
||||
}
|
||||
|
||||
uint64_t Sapphire::Item::getModelId2() const
|
||||
{
|
||||
return m_model2;
|
||||
return m_pattern != 0 ? m_glamModel2 : m_model2;
|
||||
}
|
||||
|
||||
bool Sapphire::Item::isHq() const
|
||||
|
@ -183,6 +200,16 @@ void Sapphire::Item::setStain( uint16_t stain )
|
|||
m_stain = stain;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Item::getPattern() const
|
||||
{
|
||||
return m_pattern;
|
||||
}
|
||||
|
||||
void Sapphire::Item::setPattern( uint32_t pattern )
|
||||
{
|
||||
m_pattern = pattern;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::Item::getAdditionalData() const
|
||||
{
|
||||
return m_additionalData;
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace Sapphire
|
|||
|
||||
Common::ItemUICategory getCategory() const;
|
||||
|
||||
void setGlamModelIds();
|
||||
|
||||
void setModelIds( uint64_t model1, uint64_t model2 );
|
||||
|
||||
uint64_t getModelId1() const;
|
||||
|
@ -75,6 +77,9 @@ namespace Sapphire
|
|||
uint16_t getStain() const;
|
||||
void setStain( uint16_t stain );
|
||||
|
||||
uint32_t getPattern() const;
|
||||
void setPattern( uint32_t pattern );
|
||||
|
||||
uint32_t getAdditionalData() const;
|
||||
|
||||
void setSpiritbond( uint16_t spiritbond );
|
||||
|
@ -99,6 +104,9 @@ namespace Sapphire
|
|||
uint64_t m_model1;
|
||||
uint64_t m_model2;
|
||||
|
||||
uint64_t m_glamModel1;
|
||||
uint64_t m_glamModel2;
|
||||
|
||||
bool m_isHq;
|
||||
|
||||
uint16_t m_delayMs;
|
||||
|
@ -110,6 +118,7 @@ namespace Sapphire
|
|||
uint8_t m_slot;
|
||||
uint16_t m_durability;
|
||||
uint16_t m_stain;
|
||||
uint32_t m_pattern;
|
||||
uint16_t m_spiritBond;
|
||||
uint32_t m_reservedFlag;
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ void InventoryMgr::sendInventoryContainer( Entity::Player& player, ItemContainer
|
|||
// todo: not sure if correct flag?
|
||||
itemInfoPacket->data().item.flags = static_cast< uint8_t >( itM.second->isHq() ? 1 : 0 );
|
||||
itemInfoPacket->data().item.stain = static_cast< uint8_t >( itM.second->getStain() );
|
||||
itemInfoPacket->data().item.pattern = itM.second->getPattern();
|
||||
|
||||
server.queueForPlayer( player.getCharacterId(), itemInfoPacket );
|
||||
}
|
||||
|
|
|
@ -141,7 +141,9 @@ ItemPtr ItemMgr::loadItem( uint64_t uId )
|
|||
|
||||
pItem->setStackSize( itemRes->getUInt( 2 ) );
|
||||
pItem->setStain( itemRes->getUInt16( 13 ) );
|
||||
pItem->setPattern( itemRes->getUInt( 14 ) );
|
||||
pItem->setDurability( itemRes->getInt16( 6 ) );
|
||||
pItem->setGlamModelIds();
|
||||
|
||||
return pItem;
|
||||
}
|
||||
|
|
|
@ -184,6 +184,10 @@ const char* packetCommandToString( uint16_t commandId )
|
|||
return "MOBHUNT_BREAK_ORDER";
|
||||
case DYE_ITEM:
|
||||
return "DYE_ITEM";
|
||||
case GLAMOUR_ITEM:
|
||||
return "GLAMOUR_ITEM";
|
||||
case GLAMOUR_DISPEL:
|
||||
return "GLAMOUR_DISPEL";
|
||||
case EMOTE:
|
||||
return "EMOTE";
|
||||
case EMOTE_WITH_WARP:
|
||||
|
@ -413,8 +417,8 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
|
|||
const auto param3 = packet.data().Target;
|
||||
|
||||
|
||||
Logger::debug( "\t\t {5} | {1:X} ( p1:{2:X} p2:{3:X} p3:{4:X} )",
|
||||
m_pSession->getId(), commandId, param1, param2, param3, packetCommandToString( commandId ) );
|
||||
Logger::debug( "\t\t {8} | {1:X} ( p1:{2:X} p11:{3:X} p12:{4:X} p2:{5:X} p3:{6:X} p4:{7:X} )",
|
||||
m_pSession->getId(), commandId, param1, param11, param12, param2, param3, param4, packetCommandToString( commandId ) );
|
||||
|
||||
//Logger::Log(LoggingSeverity::debug, "[" + std::to_string(m_pSession->getId()) + "] " + pInPacket->toString());
|
||||
|
||||
|
@ -635,6 +639,16 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
|
|||
player.setDyeingInfo( param11, param12, param2, param4 );
|
||||
break;
|
||||
}
|
||||
case PacketCommand::GLAMOUR_ITEM:
|
||||
{
|
||||
player.setGlamouringInfo( param11, param12, param2, param4, true );
|
||||
break;
|
||||
}
|
||||
case PacketCommand::GLAMOUR_DISPEL:
|
||||
{
|
||||
player.setGlamouringInfo( param11, param12, param2, param4, false );
|
||||
break;
|
||||
}
|
||||
case PacketCommand::DIRECTOR_INIT_RETURN: // Director init finish
|
||||
{
|
||||
pZone->onInitDirector( player );
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
|||
m_data.LvSync = 0; //player.getLevelSync();
|
||||
m_data.Hp = player.getHp();
|
||||
m_data.Mp = player.getMp();
|
||||
m_data.Tp = player.getTp();
|
||||
m_data.HpMax = player.getMaxHp();
|
||||
m_data.MpMax = player.getMaxMp();;
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
|||
m_data.Tribe = player.getLookAt( Common::CharaLook::Tribe );
|
||||
m_data.Sex = player.getLookAt( Common::CharaLook::Gender );
|
||||
m_data.ClassJob = static_cast< uint8_t >( player.getClass() );
|
||||
m_data.FirstClass = static_cast< uint8_t >( player.getClass() );
|
||||
m_data.FirstClass = static_cast< uint8_t >( player.getFirstClass() );
|
||||
//m_data.maxLevel = player.getLevel();
|
||||
m_data.GuardianDeity = static_cast< uint8_t >( player.getGuardianDeity() );
|
||||
m_data.BirthMonth = player.getBirthMonth();
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
|||
m_data.item.flags = static_cast< uint8_t >( item.isHq() ? 1 : 0 );
|
||||
m_data.item.refine = item.getSpiritbond();
|
||||
m_data.item.stain = static_cast< uint8_t >( item.getStain() );
|
||||
m_data.item.pattern = item.getPattern();
|
||||
m_data.item.durability = item.getDurability();
|
||||
m_data.item.signatureId = 0;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue