From 1b7d11bb43b07ce07e97a42a287a56470d03806e Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 00:15:26 +1000 Subject: [PATCH 01/12] addItem is way less retarded now, stacks are automagically filled first --- src/common/Exd/ExdDataGenerated.cpp | 1 + src/common/Exd/ExdDataGenerated.h | 1 + .../Scripts/opening/OpeningGridania.cpp | 2 +- src/servers/Scripts/opening/OpeningLimsa.cpp | 2 +- src/servers/Scripts/opening/OpeningUldah.cpp | 2 +- src/servers/sapphire_api/PlayerMinimal.h | 2 +- src/servers/sapphire_zone/Actor/Player.h | 6 +- .../sapphire_zone/Actor/PlayerInventory.cpp | 121 ++++++++++-------- .../sapphire_zone/Actor/PlayerQuest.cpp | 4 +- .../sapphire_zone/Inventory/ItemUtil.cpp | 5 +- .../Network/Handlers/GMCommandHandlers.cpp | 2 +- 11 files changed, 83 insertions(+), 65 deletions(-) diff --git a/src/common/Exd/ExdDataGenerated.cpp b/src/common/Exd/ExdDataGenerated.cpp index b058341e..9d364919 100644 --- a/src/common/Exd/ExdDataGenerated.cpp +++ b/src/common/Exd/ExdDataGenerated.cpp @@ -2314,6 +2314,7 @@ Core::Data::Item::Item( uint32_t row_id, Core::Data::ExdDataGenerated* exdData ) isUnique = exdData->getField< bool >( row, 20 ); isUntradable = exdData->getField< bool >( row, 21 ); isIndisposable = exdData->getField< bool >( row, 22 ); + isEquippable = exdData->getField< bool >( row, 23 ); priceMid = exdData->getField< uint32_t >( row, 24 ); priceLow = exdData->getField< uint32_t >( row, 25 ); canBeHq = exdData->getField< bool >( row, 26 ); diff --git a/src/common/Exd/ExdDataGenerated.h b/src/common/Exd/ExdDataGenerated.h index c0f9d8e4..62642872 100644 --- a/src/common/Exd/ExdDataGenerated.h +++ b/src/common/Exd/ExdDataGenerated.h @@ -2406,6 +2406,7 @@ struct Item bool isUnique; bool isUntradable; bool isIndisposable; + bool isEquippable; uint32_t priceMid; uint32_t priceLow; bool canBeHq; diff --git a/src/servers/Scripts/opening/OpeningGridania.cpp b/src/servers/Scripts/opening/OpeningGridania.cpp index 25ce7e31..77f23678 100644 --- a/src/servers/Scripts/opening/OpeningGridania.cpp +++ b/src/servers/Scripts/opening/OpeningGridania.cpp @@ -42,7 +42,7 @@ private: default: itemId = 4426; break; } - auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true ); + auto item = player.addItem( itemId, 1, false, true ); if( item ) player.equipItem( Common::EquipSlot::Ring2, item, true ); diff --git a/src/servers/Scripts/opening/OpeningLimsa.cpp b/src/servers/Scripts/opening/OpeningLimsa.cpp index 71983122..b5e6a50b 100644 --- a/src/servers/Scripts/opening/OpeningLimsa.cpp +++ b/src/servers/Scripts/opening/OpeningLimsa.cpp @@ -57,7 +57,7 @@ private: default: itemId = 4426; break; } - auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true ); + auto item = player.addItem( itemId, 1, false, true ); if( item ) player.equipItem( Common::EquipSlot::Ring2, item, true ); diff --git a/src/servers/Scripts/opening/OpeningUldah.cpp b/src/servers/Scripts/opening/OpeningUldah.cpp index 7c3529ea..3711eebd 100644 --- a/src/servers/Scripts/opening/OpeningUldah.cpp +++ b/src/servers/Scripts/opening/OpeningUldah.cpp @@ -43,7 +43,7 @@ private: default: itemId = 4426; break; } - auto item = player.addItem( Common::InventoryType::ArmoryRing, -1, itemId, 1, false, true ); + auto item = player.addItem( itemId, 1, false, true ); if( item ) player.equipItem( Common::EquipSlot::Ring2, item, true ); diff --git a/src/servers/sapphire_api/PlayerMinimal.h b/src/servers/sapphire_api/PlayerMinimal.h index e6e74df5..e2af647d 100644 --- a/src/servers/sapphire_api/PlayerMinimal.h +++ b/src/servers/sapphire_api/PlayerMinimal.h @@ -155,7 +155,7 @@ namespace Core { return m_gmInvis; } - bool setGmInvis( bool invis ) + void setGmInvis( bool invis ) { m_gmInvis = invis; } diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 0d3393a3..48526f17 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -222,10 +222,6 @@ public: // Inventory / Item / Currency ////////////////////////////////////////////////////////////////////////////////////////////////////// - /*! add an item to the first free slot in one of the 4 main containers */ - bool tryAddItem( uint16_t catalogId, uint32_t quantity ); - /*! add an item to a given container */ -// bool addItem( uint16_t containerId, uint16_t catalogId, uint32_t quantity ); /*! equip an item to a specified slot */ void equipItem( Common::EquipSlot equipSlotId, ItemPtr pItem, bool sendModel ); /*! remove an item from an equipment slot */ @@ -612,7 +608,7 @@ public: bool loadInventory(); InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId ); InvSlotPair getFreeBagSlot(); - Core::ItemPtr addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity = 1, bool isHq = false, bool slient = false ); + Core::ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool slient = false ); void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot ); void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot ); void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId ); diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index 44ec57ab..8013f5f4 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -320,17 +320,6 @@ void Core::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t amo queuePacket( invUpdate ); } -bool Core::Entity::Player::tryAddItem( uint16_t catalogId, uint32_t quantity ) -{ - - for( uint16_t i = 0; i < 4; i++ ) - { - if( addItem( i, -1, catalogId, quantity ) ) - return true; - } - return false; -} - void Core::Entity::Player::sendInventory() { InventoryMap::iterator it; @@ -495,7 +484,7 @@ bool Core::Entity::Player::isObtainable( uint32_t catalogId, uint8_t quantity ) } -Core::ItemPtr Core::Entity::Player::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity, bool isHq, bool silent ) +Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quantity, bool isHq, bool silent ) { auto pDb = g_fw.get< Db::DbWorkerPool< Db::CharaDbConnection > >(); auto pExdData = g_fw.get< Data::ExdDataGenerated >(); @@ -507,57 +496,87 @@ Core::ItemPtr Core::Entity::Player::addItem( uint16_t inventoryId, int8_t slotId return nullptr; } - int8_t rSlotId = -1; + if( itemInfo->isEquippable ) + quantity = 1; - //if( itemInfo->stack_size > 1 ) - //{ - // auto itemList = this->getSlotsOfItemsInInventory( catalogId ); - // // TODO: this is a stacked item so we need to see if the item is already in inventory and - // // check how much free space we have on existing stacks before looking for empty slots. - //} - //else + // used for item obtain notification + uint32_t originalQuantity = quantity; + + // todo: for now we're just going to add any items to main inv + + std::pair< uint8_t, uint8_t > freeBagSlot; + bool foundFreeSlot = false; + + for( auto bag : { Bag0, Bag1, Bag2, Bag3 } ) { - auto freeSlot = getFreeBagSlot(); - inventoryId = freeSlot.first; - rSlotId = freeSlot.second; + auto storage = m_storageMap[bag]; - if( rSlotId == -1 ) - return nullptr; + for( uint8_t slot = 0; slot < storage->getMaxSize(); slot++ ) + { + auto item = storage->getItem( slot ); + + // add any items that are stackable + if( item && !itemInfo->isEquippable && item->getId() == catalogId ) + { + uint32_t count = item->getStackSize(); + uint32_t maxStack = item->getMaxStackSize(); + + // if slot is full, skip it + if( count >= maxStack ) + continue; + + // update stack + uint32_t newStackSize = count + quantity; + uint32_t overflow = 0; + + if( newStackSize > maxStack ) + { + overflow = newStackSize - item->getMaxStackSize(); + newStackSize = maxStack; + } + + item->setStackSize( newStackSize ); + + auto slotUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), slot, bag, *item ); + queuePacket( slotUpdate ); + + quantity = overflow; + + // return existing stack if we have no overflow - items fit into a preexisting stack + if( quantity == 0 ) + return item; + } + else if( !item && !foundFreeSlot ) + { + freeBagSlot = { bag, slot }; + foundFreeSlot = true; + + break; + } + } } - auto item = createItem( catalogId, quantity ); + // couldn't find a free slot and we still have some quantity of items left, shits fucked + if( !foundFreeSlot ) + return nullptr; + auto item = createItem( catalogId, quantity ); item->setHq( isHq ); - if( rSlotId != -1 ) + auto storage = m_storageMap[freeBagSlot.first]; + storage->setItem( freeBagSlot.second, item ); + + writeInventory( static_cast< InventoryType >( freeBagSlot.first ) ); + + if( !silent ) { + auto invUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), freeBagSlot.second, freeBagSlot.first, *item ); + queuePacket( invUpdate ); - auto storage = m_storageMap[inventoryId]; - storage->setItem( rSlotId, item ); - - pDb->execute( "UPDATE " + storage->getTableName() + " SET container_" + - std::to_string( rSlotId ) + " = " + std::to_string( item->getUId() ) + - " WHERE storageId = " + std::to_string( inventoryId ) + - " AND CharacterId = " + std::to_string( getId() ) ); - - if( !silent ) - { - auto invUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), - rSlotId, - inventoryId, - *item ); - - queuePacket( invUpdate ); - - queuePacket( boost::make_shared< ActorControlPacket143 >( getId(), ItemObtainIcon, - catalogId, item->getStackSize() ) ); - } - - + queuePacket( boost::make_shared< ActorControlPacket143 >( getId(), ItemObtainIcon, catalogId, originalQuantity ) ); } return item; - } void Core::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot ) @@ -641,7 +660,7 @@ void Core::Entity::Player::splitItem( uint16_t fromInventoryId, uint8_t fromSlot // todo: correct invalid move? again, not sure what retail does here return; - auto newItem = addItem( toInventoryId, toSlot, fromItem->getId(), itemCount, fromItem->isHq(), true ); + auto newItem = addItem( fromItem->getId(), itemCount, fromItem->isHq(), true ); if( !newItem ) return; diff --git a/src/servers/sapphire_zone/Actor/PlayerQuest.cpp b/src/servers/sapphire_zone/Actor/PlayerQuest.cpp index b8c9d1f8..c7e1a77c 100644 --- a/src/servers/sapphire_zone/Actor/PlayerQuest.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerQuest.cpp @@ -1059,14 +1059,14 @@ bool Core::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t optional { for( uint32_t i = 0; i < questInfo->itemReward0.size(); i++ ) { - addItem( -1, questInfo->itemReward0.at( i ), questInfo->itemCountReward0.at( i ) ); + addItem( questInfo->itemCountReward0.at( i ) ); } } if( optionalItemCount > 0 ) { auto itemId = questInfo->itemReward1.at( optionalChoice ); - addItem( -1, itemId, questInfo->itemCountReward1.at( optionalChoice ) ); + addItem( questInfo->itemCountReward1.at( optionalChoice ) ); } if( gilReward > 0 ) diff --git a/src/servers/sapphire_zone/Inventory/ItemUtil.cpp b/src/servers/sapphire_zone/Inventory/ItemUtil.cpp index 340dd7dc..b830f2c7 100644 --- a/src/servers/sapphire_zone/Inventory/ItemUtil.cpp +++ b/src/servers/sapphire_zone/Inventory/ItemUtil.cpp @@ -62,9 +62,10 @@ uint16_t Core::Items::Util::getArmoryToEquipSlot( uint8_t slotId ) case Common::Wrist: return Common::ArmoryWrist; - } - return 0; + default: + return 0; + } } diff --git a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp index 0a81a927..bac41fb1 100644 --- a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp @@ -323,7 +323,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::FFXIVARR_PACKET_R return; } - if( !targetPlayer->addItem( -1, param1, quantity ) ) + if( !targetPlayer->addItem( param1, quantity ) ) player.sendUrgent( "Item " + std::to_string( param1 ) + " could not be added to inventory." ); break; } From 84c51913776314dd82288731accdccc964bbac77 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 00:37:21 +1000 Subject: [PATCH 02/12] correctly update items and select slot --- src/servers/sapphire_zone/Actor/PlayerInventory.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index 8013f5f4..2eb5d6f4 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -536,6 +536,7 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti } item->setStackSize( newStackSize ); + writeItem( item ); auto slotUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), slot, bag, *item ); queuePacket( slotUpdate ); @@ -544,14 +545,17 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti // return existing stack if we have no overflow - items fit into a preexisting stack if( quantity == 0 ) + { + queuePacket( boost::make_shared< ActorControlPacket143 >( getId(), ItemObtainIcon, catalogId, originalQuantity ) ); + return item; + } + } else if( !item && !foundFreeSlot ) { freeBagSlot = { bag, slot }; foundFreeSlot = true; - - break; } } } From ae282c7030945d473f95da249fcda715b5fb66e8 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 19:27:38 +1000 Subject: [PATCH 03/12] correctly preserve hq/lq stacks & cap quantity correctly --- src/servers/sapphire_zone/Actor/PlayerInventory.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index 2eb5d6f4..166412cf 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -496,8 +496,7 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti return nullptr; } - if( itemInfo->isEquippable ) - quantity = 1; + quantity = std::min< uint32_t >( quantity, itemInfo->stackSize ); // used for item obtain notification uint32_t originalQuantity = quantity; @@ -525,6 +524,10 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti if( count >= maxStack ) continue; + // check slot is same quality + if( item->isHq() != isHq ) + continue; + // update stack uint32_t newStackSize = count + quantity; uint32_t overflow = 0; From d1568c75f901a4bd532316632b3d7d2c44e9370c Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 20:48:27 +1000 Subject: [PATCH 04/12] update submodule --- src/libraries | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries b/src/libraries index 61712f8f..3e907dc9 160000 --- a/src/libraries +++ b/src/libraries @@ -1 +1 @@ -Subproject commit 61712f8f11892d12ad6878a80b9b89b318908558 +Subproject commit 3e907dc9e2cce6f137dd067bb740c714a7b26300 From a86fc2794b118c5b16a4d07ebbcdb5b3fe838b80 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 20:52:20 +1000 Subject: [PATCH 05/12] cleanup stack calc code --- src/servers/sapphire_zone/Actor/PlayerInventory.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index 166412cf..578a07b5 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -530,11 +530,9 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti // update stack uint32_t newStackSize = count + quantity; - uint32_t overflow = 0; - if( newStackSize > maxStack ) { - overflow = newStackSize - item->getMaxStackSize(); + quantity = newStackSize - maxStack; newStackSize = maxStack; } @@ -544,8 +542,6 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti auto slotUpdate = boost::make_shared< UpdateInventorySlotPacket >( getId(), slot, bag, *item ); queuePacket( slotUpdate ); - quantity = overflow; - // return existing stack if we have no overflow - items fit into a preexisting stack if( quantity == 0 ) { From 4cab50f77c8556109cef6a22a3eb1b3190d962a0 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 22:38:07 +1000 Subject: [PATCH 06/12] correctly store items in armory/inventory based on client flag --- src/common/Common.h | 46 +++++++++++++++++-- src/servers/sapphire_api/PlayerMinimal.cpp | 2 +- .../sapphire_zone/Actor/PlayerInventory.cpp | 20 ++++++-- .../sapphire_zone/Inventory/ItemUtil.cpp | 44 ++++++++++++------ .../sapphire_zone/Inventory/ItemUtil.h | 2 +- 5 files changed, 92 insertions(+), 22 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index cfdad245..d49b3b53 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -62,6 +62,46 @@ namespace Common { SoulCrystal = 13, }; + enum EquipSlotCategory : uint8_t + { + Unequippbale = 0, + + // main slots + + CharaMainHand = 1, + CharaOffHand = 2, + CharaHead = 3, + CharaBody = 4, + CharaHands = 5, + CharaWaist = 6, + CharaLegs = 7, + CharaFeet = 8, + CharaEars = 9, + CharaNeck = 10, + CharaWrist = 11, + CharaRing = 12, + CharaSoulCrystal = 17, + + // specials + + /*! Cannot equip gear to offhand slot */ + MainTwoHandedWeapon = 13, + /*! Can be equipped in either main or offhand slot */ + MainOrOffHand = 14, // unused + /*! Cannot equip gear to head */ + BodyAndHead = 15, + /*! Cannot equip gear to hands, legs and feet slots */ + BodyDisallowHandsLegsFeet = 16, + /*! Cannot equip gear to feet slot */ + LegsDisallowFeet = 18, + /*! Cannot equp gear to head, hands, legs, feet slots */ + BodyDisallowAll = 19, + /*! Cannot equip gear to hands slot */ + BodyDisallowHands = 20, + /*! Cannot equip gear to legs & feet slots */ + BodyDisallowLegsFeet = 21, + }; + enum InventoryType : uint16_t { Bag0 = 0, @@ -87,7 +127,7 @@ namespace Common { ArmoryWaist = 3204, ArmoryLegs = 3205, ArmoryFeet = 3206, - ArmotyNeck = 3207, + ArmoryNeck = 3207, ArmoryEar = 3208, ArmoryWrist = 3209, ArmoryRing = 3300, @@ -600,8 +640,8 @@ namespace Common { HideWeapon = 0x2, HideLegacyMark = 0x4, - StoreNewItemsInArmouryChest = 0x5, - StoreCraftedItemsInInventory = 0x6, + StoreNewItemsInArmouryChest = 0x10, + StoreCraftedItemsInInventory = 0x20, Visor = 0x40, }; diff --git a/src/servers/sapphire_api/PlayerMinimal.cpp b/src/servers/sapphire_api/PlayerMinimal.cpp index 55648afa..db4d010d 100644 --- a/src/servers/sapphire_api/PlayerMinimal.cpp +++ b/src/servers/sapphire_api/PlayerMinimal.cpp @@ -289,7 +289,7 @@ namespace Core { createInvDbContainer( InventoryType::ArmoryLegs ); createInvDbContainer( InventoryType::ArmoryFeet ); - createInvDbContainer( InventoryType::ArmotyNeck ); + createInvDbContainer( InventoryType::ArmoryNeck ); createInvDbContainer( InventoryType::ArmoryEar ); createInvDbContainer( InventoryType::ArmoryWrist ); createInvDbContainer( InventoryType::ArmoryRing ); diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index 578a07b5..d35a0baa 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -88,7 +88,7 @@ void Core::Entity::Player::initInventory() setupContainer( ArmoryFeet, 34, "charaiteminventory", true ); //neck - setupContainer( ArmotyNeck, 34, "charaiteminventory", true ); + setupContainer( ArmoryNeck, 34, "charaiteminventory", true ); //earring setupContainer( ArmoryEar, 34, "charaiteminventory", true ); @@ -503,10 +503,22 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti // todo: for now we're just going to add any items to main inv - std::pair< uint8_t, uint8_t > freeBagSlot; + std::pair< uint16_t, uint8_t > freeBagSlot; bool foundFreeSlot = false; - for( auto bag : { Bag0, Bag1, Bag2, Bag3 } ) + std::vector< uint16_t > bags = { Bag0, Bag1, Bag2, Bag3 }; + + // add the related armoury bag to the applicable bags and try and fill a free slot there before falling back to regular inventory + if( itemInfo->isEquippable && getEquipDisplayFlags() & StoreNewItemsInArmouryChest ) + { + auto bag = Items::Util::getCharaEquipSlotCategoryToArmoryId( itemInfo->equipSlotCategory ); + + sendDebug( "Got bag: " + std::to_string( bag ) + " for cat: " + std::to_string( itemInfo->equipSlotCategory ) ); + + bags.insert( bags.begin(), bag ); + } + + for( auto bag : bags ) { auto storage = m_storageMap[bag]; @@ -727,7 +739,7 @@ void Core::Entity::Player::swapItem( uint16_t fromInventoryId, uint8_t fromSlotI && !Items::Util::isArmory( fromInventoryId ) ) { updateContainer( fromInventoryId, fromSlotId, nullptr ); - fromInventoryId = Items::Util::getArmoryToEquipSlot( toSlot ); + fromInventoryId = Items::Util::getCharaEquipSlotCategoryToArmoryId( toSlot ); fromSlotId = static_cast < uint8_t >( m_storageMap[fromInventoryId]->getFreeSlot() ); } diff --git a/src/servers/sapphire_zone/Inventory/ItemUtil.cpp b/src/servers/sapphire_zone/Inventory/ItemUtil.cpp index b830f2c7..2a6df5fc 100644 --- a/src/servers/sapphire_zone/Inventory/ItemUtil.cpp +++ b/src/servers/sapphire_zone/Inventory/ItemUtil.cpp @@ -25,44 +25,62 @@ bool Core::Items::Util::isArmory( uint16_t containerId ) containerId == Common::ArmoryOff || containerId == Common::ArmoryRing || containerId == Common::ArmoryWaist || - containerId == Common::ArmoryWrist; + containerId == Common::ArmoryWrist || + containerId == Common::ArmorySoulCrystal; } -uint16_t Core::Items::Util::getArmoryToEquipSlot( uint8_t slotId ) +uint16_t Core::Items::Util::getCharaEquipSlotCategoryToArmoryId( uint8_t slotId ) { + switch( slotId ) { - case Common::Body: + case Common::CharaHead: + return Common::ArmoryHead; + + case Common::CharaBody: + case Common::BodyAndHead: + case Common::BodyDisallowHandsLegsFeet: + case Common::BodyDisallowAll: + case Common::BodyDisallowHands: + case Common::BodyDisallowLegsFeet: return Common::ArmoryBody; - case Common::Ear: + case Common::CharaEars: return Common::ArmoryEar; - case Common::Feet: + case Common::CharaFeet: return Common::ArmoryFeet; - case Common::Hands: + case Common::CharaHands: return Common::ArmoryHand; - case Common::Legs: + case Common::CharaLegs: + case Common::LegsDisallowFeet: return Common::ArmoryLegs; - case Common::MainHand: + case Common::CharaMainHand: + case Common::MainTwoHandedWeapon: + case Common::MainOrOffHand: return Common::ArmoryMain; - case Common::OffHand: + case Common::CharaOffHand: return Common::ArmoryOff; - case Common::Ring2: - case Common::Ring1: + case Common::CharaRing: return Common::ArmoryRing; - case Common::Waist: + case Common::CharaWaist: return Common::ArmoryWaist; - case Common::Wrist: + case Common::CharaWrist: return Common::ArmoryWrist; + case Common::CharaNeck: + return Common::ArmoryNeck; + + case Common::CharaSoulCrystal: + return Common::ArmorySoulCrystal; + default: return 0; } diff --git a/src/servers/sapphire_zone/Inventory/ItemUtil.h b/src/servers/sapphire_zone/Inventory/ItemUtil.h index 9d0e401c..b0e63b61 100644 --- a/src/servers/sapphire_zone/Inventory/ItemUtil.h +++ b/src/servers/sapphire_zone/Inventory/ItemUtil.h @@ -15,7 +15,7 @@ namespace Util { bool isArmory( uint16_t containerId ); bool isEquipment( uint16_t containerId ); - uint16_t getArmoryToEquipSlot( uint8_t slotId ); + uint16_t getCharaEquipSlotCategoryToArmoryId( uint8_t slotId ); Common::ContainerType getContainerType( uint32_t containerId ); From 8a3b63d276a77698ee5d1c09d191790e45808d47 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 22:41:03 +1000 Subject: [PATCH 07/12] cleanup unnecessary debug output --- src/servers/sapphire_zone/Actor/PlayerInventory.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index d35a0baa..a01da9d1 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -513,8 +513,6 @@ Core::ItemPtr Core::Entity::Player::addItem( uint32_t catalogId, uint32_t quanti { auto bag = Items::Util::getCharaEquipSlotCategoryToArmoryId( itemInfo->equipSlotCategory ); - sendDebug( "Got bag: " + std::to_string( bag ) + " for cat: " + std::to_string( itemInfo->equipSlotCategory ) ); - bags.insert( bags.begin(), bag ); } From 7131c254ea60d89aef7722f4192ba632007a2389 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 22:56:46 +1000 Subject: [PATCH 08/12] EquipSlot -> GearSetSlot --- src/common/Common.h | 4 ++-- .../Scripts/opening/OpeningGridania.cpp | 2 +- src/servers/Scripts/opening/OpeningLimsa.cpp | 2 +- src/servers/Scripts/opening/OpeningUldah.cpp | 2 +- src/servers/sapphire_api/PlayerMinimal.cpp | 18 +++++++++--------- src/servers/sapphire_zone/Actor/Player.cpp | 8 ++++---- src/servers/sapphire_zone/Actor/Player.h | 8 ++++---- .../sapphire_zone/Actor/PlayerInventory.cpp | 18 +++++++++--------- src/servers/sapphire_zone/Actor/PlayerSql.cpp | 2 +- .../DebugCommand/DebugCommandHandler.cpp | 2 +- .../Network/PacketWrappers/ModelEquipPacket.h | 10 +++++----- .../Network/PacketWrappers/PlayerSpawnPacket.h | 12 ++++++------ 12 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index d49b3b53..161b4cff 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -44,7 +44,7 @@ namespace Common { French = 8 }; - enum EquipSlot : uint8_t + enum GearSetSlot : uint8_t { MainHand = 0, OffHand = 1, @@ -64,7 +64,7 @@ namespace Common { enum EquipSlotCategory : uint8_t { - Unequippbale = 0, + Unequippable = 0, // main slots diff --git a/src/servers/Scripts/opening/OpeningGridania.cpp b/src/servers/Scripts/opening/OpeningGridania.cpp index 77f23678..d8906905 100644 --- a/src/servers/Scripts/opening/OpeningGridania.cpp +++ b/src/servers/Scripts/opening/OpeningGridania.cpp @@ -45,7 +45,7 @@ private: auto item = player.addItem( itemId, 1, false, true ); if( item ) - player.equipItem( Common::EquipSlot::Ring2, item, true ); + player.equipItem( Common::GearSetSlot::Ring2, item, true ); player.setOpeningSequence( 1 ); Scene00001( player ); diff --git a/src/servers/Scripts/opening/OpeningLimsa.cpp b/src/servers/Scripts/opening/OpeningLimsa.cpp index b5e6a50b..c249f262 100644 --- a/src/servers/Scripts/opening/OpeningLimsa.cpp +++ b/src/servers/Scripts/opening/OpeningLimsa.cpp @@ -60,7 +60,7 @@ private: auto item = player.addItem( itemId, 1, false, true ); if( item ) - player.equipItem( Common::EquipSlot::Ring2, item, true ); + player.equipItem( Common::GearSetSlot::Ring2, item, true ); player.setOpeningSequence( 1 ); Scene00001( player ); diff --git a/src/servers/Scripts/opening/OpeningUldah.cpp b/src/servers/Scripts/opening/OpeningUldah.cpp index 3711eebd..b4513a25 100644 --- a/src/servers/Scripts/opening/OpeningUldah.cpp +++ b/src/servers/Scripts/opening/OpeningUldah.cpp @@ -46,7 +46,7 @@ private: auto item = player.addItem( itemId, 1, false, true ); if( item ) - player.equipItem( Common::EquipSlot::Ring2, item, true ); + player.equipItem( Common::GearSetSlot::Ring2, item, true ); player.setOpeningSequence( 1 ); Scene00001( player ); diff --git a/src/servers/sapphire_api/PlayerMinimal.cpp b/src/servers/sapphire_api/PlayerMinimal.cpp index db4d010d..8999ef80 100644 --- a/src/servers/sapphire_api/PlayerMinimal.cpp +++ b/src/servers/sapphire_api/PlayerMinimal.cpp @@ -353,15 +353,15 @@ namespace Core { insertDbGlobalItem( 15133, ringUid ); g_charaDb.execute( "INSERT INTO charaitemgearset (storageId, CharacterId, " - "container_" + std::to_string( EquipSlot::MainHand ) + ", " - "container_" + std::to_string( EquipSlot::Body ) + ", " - "container_" + std::to_string( EquipSlot::Hands ) + ", " - "container_" + std::to_string( EquipSlot::Legs ) + ", " - "container_" + std::to_string( EquipSlot::Feet ) + ", " - "container_" + std::to_string( EquipSlot::Neck ) + ", " - "container_" + std::to_string( EquipSlot::Ear ) + ", " - "container_" + std::to_string( EquipSlot::Wrist ) + ", " - "container_" + std::to_string( EquipSlot::Ring1 ) + ", " + "container_" + std::to_string( GearSetSlot::MainHand ) + ", " + "container_" + std::to_string( GearSetSlot::Body ) + ", " + "container_" + std::to_string( GearSetSlot::Hands ) + ", " + "container_" + std::to_string( GearSetSlot::Legs ) + ", " + "container_" + std::to_string( GearSetSlot::Feet ) + ", " + "container_" + std::to_string( GearSetSlot::Neck ) + ", " + "container_" + std::to_string( GearSetSlot::Ear ) + ", " + "container_" + std::to_string( GearSetSlot::Wrist ) + ", " + "container_" + std::to_string( GearSetSlot::Ring1 ) + ", " "UPDATE_DATE ) " "VALUES ( " + std::to_string( InventoryType::GearSet0 ) + ", " + std::to_string( m_id ) + ", " + std::to_string( uniqueId ) + ", " + diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index a36f6bd9..cffe9426 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -774,12 +774,12 @@ void Core::Entity::Player::sendModel() sendToInRangeSet( boost::make_shared< ModelEquipPacket >( *getAsPlayer() ), true ); } -uint32_t Core::Entity::Player::getModelForSlot( Common::EquipSlot slot ) +uint32_t Core::Entity::Player::getModelForSlot( Common::GearSetSlot slot ) { return m_modelEquip[slot]; } -void Core::Entity::Player::setModelForSlot( Common::EquipSlot slot, uint32_t val ) +void Core::Entity::Player::setModelForSlot( Common::GearSetSlot slot, uint32_t val ) { m_modelEquip[slot] = val; } @@ -1028,7 +1028,7 @@ void Core::Entity::Player::update( int64_t currTime ) { if( m_targetId && m_currentStance == Entity::Chara::Stance::Active && isAutoattackOn() ) { - auto mainWeap = getItemAt( Common::GearSet0, Common::EquipSlot::MainHand ); + auto mainWeap = getItemAt( Common::GearSet0, Common::GearSetSlot::MainHand ); // @TODO i dislike this, iterating over all in range actors when you already know the id of the actor you need... for( auto actor : m_inRangeActor ) @@ -1411,7 +1411,7 @@ uint32_t Core::Entity::Player::getPersistentEmote() const void Core::Entity::Player::autoAttack( CharaPtr pTarget ) { - auto mainWeap = getItemAt( Common::GearSet0, Common::EquipSlot::MainHand ); + auto mainWeap = getItemAt( Common::GearSet0, Common::GearSetSlot::MainHand ); pTarget->onActionHostile( *this ); //uint64_t tick = Util::getTimeMs(); diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 48526f17..56cd1f88 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -223,9 +223,9 @@ public: // Inventory / Item / Currency ////////////////////////////////////////////////////////////////////////////////////////////////////// /*! equip an item to a specified slot */ - void equipItem( Common::EquipSlot equipSlotId, ItemPtr pItem, bool sendModel ); + void equipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem, bool sendModel ); /*! remove an item from an equipment slot */ - void unequipItem( Common::EquipSlot equipSlotId, ItemPtr pItem ); + void unequipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem ); /*! equip a weapon, possibly forcing a job change */ void equipWeapon( ItemPtr pItem ); /*! get player ilvl */ @@ -241,9 +241,9 @@ public: /*! return a const pointer to the model array */ const uint32_t* getModelArray() const; /*! return the equipment model in a specified equipment slot */ - uint32_t getModelForSlot( Common::EquipSlot slot ); + uint32_t getModelForSlot( Common::GearSetSlot slot ); /*! set the equipment model in a specified equipment slot */ - void setModelForSlot( Common::EquipSlot slot, uint32_t val ); + void setModelForSlot( Common::GearSetSlot slot, uint32_t val ); /*! add amount to the currency of type */ void addCurrency( Common::CurrencyType type, uint32_t amount ); /*! remove amount from the currency of type */ diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index a01da9d1..b86cfebe 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -171,7 +171,7 @@ void Core::Entity::Player::equipWeapon( ItemPtr pItem ) } // equip an item -void Core::Entity::Player::equipItem( Common::EquipSlot equipSlotId, ItemPtr pItem, bool sendUpdate ) +void Core::Entity::Player::equipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem, bool sendUpdate ) { //g_framework.getLogger().debug( "Equipping into slot " + std::to_string( equipSlotId ) ); @@ -181,18 +181,18 @@ void Core::Entity::Player::equipItem( Common::EquipSlot equipSlotId, ItemPtr pIt switch( equipSlotId ) { - case Common::EquipSlot::MainHand: + case Common::GearSetSlot::MainHand: m_modelMainWeapon = model; m_modelSubWeapon = model2; // TODO: add job change upon changing weapon if needed // equipWeapon( pItem ); break; - case Common::EquipSlot::OffHand: + case Common::GearSetSlot::OffHand: m_modelSubWeapon = model; break; - case Common::EquipSlot::SoulCrystal: + case Common::GearSetSlot::SoulCrystal: // TODO: add Job change on equipping crystal // change job break; @@ -211,7 +211,7 @@ void Core::Entity::Player::equipItem( Common::EquipSlot equipSlotId, ItemPtr pIt } } -void Core::Entity::Player::unequipItem( Common::EquipSlot equipSlotId, ItemPtr pItem ) +void Core::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, ItemPtr pItem ) { m_modelEquip[static_cast< uint8_t >( equipSlotId )] = 0; sendModel(); @@ -611,10 +611,10 @@ void Core::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotI writeInventory( static_cast< InventoryType >( fromInventoryId ) ); if( static_cast< InventoryType >( toInventoryId ) == GearSet0 ) - equipItem( static_cast< EquipSlot >( toSlot ), tmpItem, true ); + equipItem( static_cast< GearSetSlot >( toSlot ), tmpItem, true ); if( static_cast< InventoryType >( fromInventoryId ) == GearSet0 ) - unequipItem( static_cast< EquipSlot >( fromSlotId ), tmpItem ); + unequipItem( static_cast< GearSetSlot >( fromSlotId ), tmpItem ); } @@ -638,9 +638,9 @@ bool Core::Entity::Player::updateContainer( uint16_t storageId, uint8_t slotId, case GearSet: { if( pItem ) - equipItem( static_cast< EquipSlot >( slotId ), pItem, true ); + equipItem( static_cast< GearSetSlot >( slotId ), pItem, true ); else - unequipItem( static_cast< EquipSlot >( slotId ), pItem ); + unequipItem( static_cast< GearSetSlot >( slotId ), pItem ); writeInventory( static_cast< InventoryType >( storageId ) ); break; diff --git a/src/servers/sapphire_zone/Actor/PlayerSql.cpp b/src/servers/sapphire_zone/Actor/PlayerSql.cpp index f87a2fc5..13b0d4dd 100644 --- a/src/servers/sapphire_zone/Actor/PlayerSql.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerSql.cpp @@ -617,7 +617,7 @@ bool Core::Entity::Player::loadInventory() continue; m_storageMap[storageId]->getItemMap()[i - 1] = pItem; - equipItem( static_cast< EquipSlot >( i - 1 ), pItem, false ); + equipItem( static_cast< GearSetSlot >( i - 1 ), pItem, false ); } } diff --git a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp index 9c93527f..04befe62 100644 --- a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp @@ -267,7 +267,7 @@ void Core::DebugCommandHandler::set( char * data, Entity::Player& player, boost: uint32_t val; sscanf( params.c_str(), "%d %d", &slot, &val ); - player.setModelForSlot( static_cast< Common::EquipSlot >( slot ), val ); + player.setModelForSlot( static_cast< Common::GearSetSlot >( slot ), val ); player.sendModel(); player.sendDebug( "Model updated" ); } diff --git a/src/servers/sapphire_zone/Network/PacketWrappers/ModelEquipPacket.h b/src/servers/sapphire_zone/Network/PacketWrappers/ModelEquipPacket.h index 6d52668e..324e54a5 100644 --- a/src/servers/sapphire_zone/Network/PacketWrappers/ModelEquipPacket.h +++ b/src/servers/sapphire_zone/Network/PacketWrappers/ModelEquipPacket.h @@ -28,11 +28,11 @@ private: { m_data.mainWeapon = player.getModelMainWeapon(); m_data.offWeapon = player.getModelSubWeapon(); - m_data.models[0] = player.getModelForSlot( Common::EquipSlot::Head ); - m_data.models[1] = player.getModelForSlot( Common::EquipSlot::Body ); - m_data.models[2] = player.getModelForSlot( Common::EquipSlot::Hands ); - m_data.models[3] = player.getModelForSlot( Common::EquipSlot::Legs ); - m_data.models[4] = player.getModelForSlot( Common::EquipSlot::Feet ); + m_data.models[0] = player.getModelForSlot( Common::GearSetSlot::Head ); + m_data.models[1] = player.getModelForSlot( Common::GearSetSlot::Body ); + m_data.models[2] = player.getModelForSlot( Common::GearSetSlot::Hands ); + m_data.models[3] = player.getModelForSlot( Common::GearSetSlot::Legs ); + m_data.models[4] = player.getModelForSlot( Common::GearSetSlot::Feet ); }; }; diff --git a/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h b/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h index b41282de..0bb69151 100644 --- a/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h +++ b/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h @@ -49,16 +49,16 @@ namespace Server { memcpy( m_data.look, player.getLookArray(), 26 ); - auto item = player.getItemAt( Common::GearSet0, Common::EquipSlot::MainHand ); + auto item = player.getItemAt( Common::GearSet0, Common::GearSetSlot::MainHand ); if( item ) m_data.mainWeaponModel = item->getModelId1(); m_data.secWeaponModel = player.getModelSubWeapon(); - m_data.models[0] = player.getModelForSlot( Common::EquipSlot::Head ); - m_data.models[1] = player.getModelForSlot( Common::EquipSlot::Body ); - m_data.models[2] = player.getModelForSlot( Common::EquipSlot::Hands ); - m_data.models[3] = player.getModelForSlot( Common::EquipSlot::Legs ); - m_data.models[4] = player.getModelForSlot( Common::EquipSlot::Feet ); + m_data.models[0] = player.getModelForSlot( Common::GearSetSlot::Head ); + m_data.models[1] = player.getModelForSlot( Common::GearSetSlot::Body ); + m_data.models[2] = player.getModelForSlot( Common::GearSetSlot::Hands ); + m_data.models[3] = player.getModelForSlot( Common::GearSetSlot::Legs ); + m_data.models[4] = player.getModelForSlot( Common::GearSetSlot::Feet ); strcpy( m_data.name, player.getName().c_str() ); m_data.pos.x = player.getPos().x; From 78ddbb36729472880a54c23318ed33f94c4a02d5 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sat, 25 Aug 2018 22:58:13 +1000 Subject: [PATCH 09/12] more consistent enum naming --- src/common/Common.h | 2 +- src/servers/sapphire_zone/Inventory/ItemUtil.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 161b4cff..9cdffed8 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -89,7 +89,7 @@ namespace Common { /*! Can be equipped in either main or offhand slot */ MainOrOffHand = 14, // unused /*! Cannot equip gear to head */ - BodyAndHead = 15, + BodyDisallowHead = 15, /*! Cannot equip gear to hands, legs and feet slots */ BodyDisallowHandsLegsFeet = 16, /*! Cannot equip gear to feet slot */ diff --git a/src/servers/sapphire_zone/Inventory/ItemUtil.cpp b/src/servers/sapphire_zone/Inventory/ItemUtil.cpp index 2a6df5fc..f02bdcc5 100644 --- a/src/servers/sapphire_zone/Inventory/ItemUtil.cpp +++ b/src/servers/sapphire_zone/Inventory/ItemUtil.cpp @@ -38,7 +38,7 @@ uint16_t Core::Items::Util::getCharaEquipSlotCategoryToArmoryId( uint8_t slotId return Common::ArmoryHead; case Common::CharaBody: - case Common::BodyAndHead: + case Common::BodyDisallowHead: case Common::BodyDisallowHandsLegsFeet: case Common::BodyDisallowAll: case Common::BodyDisallowHands: From e68b302f42c10cbc524f992404d20cb79aa9a0b9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 26 Aug 2018 16:19:05 +1000 Subject: [PATCH 10/12] fix db storage for classjobs, improve switching between classes --- sql/characlass.sql | 2 +- sql/update.sql | 4 +- src/servers/sapphire_zone/Actor/Player.cpp | 6 ++ src/servers/sapphire_zone/Actor/Player.h | 2 + .../sapphire_zone/Actor/PlayerInventory.cpp | 65 +++++-------------- .../Network/Handlers/GMCommandHandlers.cpp | 2 +- 6 files changed, 28 insertions(+), 53 deletions(-) diff --git a/sql/characlass.sql b/sql/characlass.sql index a1966375..1dcbaad0 100644 --- a/sql/characlass.sql +++ b/sql/characlass.sql @@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS `characlass` ( `ClassIdx` int(3) DEFAULT '0', `Exp` int(10) DEFAULT '0', `Lvl` int(5) DEFAULT '0', - PRIMARY KEY (`CharacterId`) + INDEX `CharacterId` (`CharacterId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- Dumping data for table sapphire.characlass: 0 rows diff --git a/sql/update.sql b/sql/update.sql index 239bb5a4..bd8873d2 100644 --- a/sql/update.sql +++ b/sql/update.sql @@ -48,4 +48,6 @@ ALTER TABLE `charainfo` CHANGE `Orchestrion` `Orchestrion` BINARY(40) NULL DEFAU ALTER TABLE `charainfo` CHANGE `Minions` `Minions` BINARY(37) NULL DEFAULT NULL; ALTER TABLE `charainfo` CHANGE `QuestCompleteFlags` `QuestCompleteFlags` VARBINARY(396) NULL DEFAULT NULL; ALTER TABLE `charainfo` ADD COLUMN `EquipDisplayFlags` INT(3) NULL DEFAULT '0' AFTER `GMRank`; -ALTER TABLE `charainfo` ADD COLUMN `Pose` INT(3) NULL DEFAULT '0' AFTER `EquipDisplayFlags`; \ No newline at end of file +ALTER TABLE `charainfo` ADD COLUMN `Pose` INT(3) NULL DEFAULT '0' AFTER `EquipDisplayFlags`; + +ALTER TABLE `characlass` DROP PRIMARY KEY, ADD INDEX `CharacterId` (`CharacterId`); \ No newline at end of file diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index cffe9426..095b4990 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -704,6 +704,12 @@ uint8_t Core::Entity::Player::getLevelForClass( Common::ClassJob pClass ) const return static_cast< uint8_t >( m_classArray[classJobIndex] ); } +bool Core::Entity::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 + return getLevelForClass( classJob ) != 0; +} + uint32_t Core::Entity::Player::getExp() const { auto pExdData = g_fw.get< Data::ExdDataGenerated >(); diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 56cd1f88..02720bab 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -257,6 +257,8 @@ public: uint8_t getLevel() const override; /*! returns the level of the provided class / job */ uint8_t getLevelForClass( Common::ClassJob pClass ) const; + /*! returns if the classjob is unlocked */ + bool isClassJobUnlocked( Common::ClassJob classJob ) const; /*! returns the exp of the currently active class / job */ uint32_t getExp() const; /*! sets the exp of the currently active class / job */ diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index b86cfebe..1305fcf2 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -115,59 +115,24 @@ void Core::Entity::Player::sendItemLevel() queuePacket( boost::make_shared< ActorControlPacket142 >( getId(), SetItemLevel, getItemLevel(), 0 ) ); } -// TODO: This has to be redone and simplified void Core::Entity::Player::equipWeapon( ItemPtr pItem ) { - ClassJob currentClass = static_cast< ClassJob >( getClass() ); + auto exdData = g_fw.get< Core::Data::ExdDataGenerated >(); + if( !exdData ) + return; - switch( pItem->getCategory() ) - { - case ItemUICategory::PugilistsArm: - if( currentClass != ClassJob::Pugilist && - currentClass != ClassJob::Monk ) - setClassJob( ClassJob::Pugilist ); - break; - case ItemUICategory::GladiatorsArm: - if( currentClass != ClassJob::Gladiator && - currentClass != ClassJob::Paladin ) - setClassJob( ClassJob::Gladiator ); - break; - case ItemUICategory::MaraudersArm: - if( currentClass != ClassJob::Marauder && - currentClass != ClassJob::Warrior ) - setClassJob( ClassJob::Marauder ); - break; - case ItemUICategory::ArchersArm: - if( currentClass != ClassJob::Archer && - currentClass != ClassJob::Bard ) - setClassJob( ClassJob::Archer ); - break; - case ItemUICategory::LancersArm: - if( currentClass != ClassJob::Lancer && - currentClass != ClassJob::Dragoon ) - setClassJob( ClassJob::Lancer ); - break; - case ItemUICategory::OnehandedThaumaturgesArm: - case ItemUICategory::TwohandedThaumaturgesArm: - if( currentClass != ClassJob::Thaumaturge && - currentClass != ClassJob::Blackmage ) - setClassJob( ClassJob::Thaumaturge ); - break; - case ItemUICategory::OnehandedConjurersArm: - case ItemUICategory::TwohandedConjurersArm: - if( currentClass != ClassJob::Conjurer && - currentClass != ClassJob::Whitemage ) - setClassJob( ClassJob::Conjurer ); - break; - case ItemUICategory::ArcanistsGrimoire: - if( currentClass != ClassJob::Arcanist && - currentClass != ClassJob::Summoner && - currentClass != ClassJob::Scholar ) - setClassJob( ClassJob::Arcanist ); - break; - default: - break; - } + auto itemInfo = exdData->get< Core::Data::Item >( pItem->getId() ); + auto itemClassJob = itemInfo->classJobUse; + + auto currentClass = getClass(); + auto newClassJob = static_cast< ClassJob >( itemClassJob ); + + if( isClassJobUnlocked( newClassJob ) ) + return; + + // todo: check if soul crystal is equipped and use job instead + + setClassJob( newClassJob ); } // equip an item diff --git a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp index bac41fb1..ab58ab39 100644 --- a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp @@ -113,7 +113,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::FFXIVARR_PACKET_R else { auto inRange = player.getInRangeActors(); - for( auto actor : inRange ) + for( auto& actor : inRange ) { if( actor->getId() == param3 ) targetActor = actor; From abbff07e770e4e7054682d8faf85bd30c269b2d3 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 26 Aug 2018 18:48:45 +1000 Subject: [PATCH 11/12] minor fixes --- src/servers/sapphire_api/PlayerMinimal.cpp | 3 +++ src/servers/sapphire_zone/Inventory/ItemContainer.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/servers/sapphire_api/PlayerMinimal.cpp b/src/servers/sapphire_api/PlayerMinimal.cpp index 8999ef80..704d49a3 100644 --- a/src/servers/sapphire_api/PlayerMinimal.cpp +++ b/src/servers/sapphire_api/PlayerMinimal.cpp @@ -217,6 +217,9 @@ namespace Core { startTown = 3; startZone = 182; break; + + default: + break; } // "(AccountId, CharacterId, ContentId, Name, Hp, Mp, " diff --git a/src/servers/sapphire_zone/Inventory/ItemContainer.cpp b/src/servers/sapphire_zone/Inventory/ItemContainer.cpp index 88b81425..c02d17f1 100644 --- a/src/servers/sapphire_zone/Inventory/ItemContainer.cpp +++ b/src/servers/sapphire_zone/Inventory/ItemContainer.cpp @@ -82,7 +82,7 @@ int8_t Core::ItemContainer::getFreeSlot() Core::ItemPtr Core::ItemContainer::getItem( uint8_t slotId ) { - if( ( slotId > m_size ) || ( slotId == -1 ) ) + if( ( slotId > m_size ) ) { auto pLog = g_fw.get< Logger >(); pLog->error( "Slot out of range " + std::to_string( slotId ) ); @@ -94,7 +94,7 @@ Core::ItemPtr Core::ItemContainer::getItem( uint8_t slotId ) void Core::ItemContainer::setItem( uint8_t slotId, ItemPtr pItem ) { - if( ( slotId > m_size ) ) + if( slotId > m_size ) return; m_itemMap[slotId] = pItem; From ceefd5e53169838018c3f437e529449366cdc981 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 26 Aug 2018 18:55:21 +1000 Subject: [PATCH 12/12] update submodule --- src/libraries | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries b/src/libraries index 3e907dc9..8c260396 160000 --- a/src/libraries +++ b/src/libraries @@ -1 +1 @@ -Subproject commit 3e907dc9e2cce6f137dd067bb740c714a7b26300 +Subproject commit 8c260396dde22977cbee4af537757427d2049ee2