diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 8ce809f..e57400a 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -1153,20 +1153,23 @@ uint64_t Player::itemsCanHold(ItemPtr const& items) const { return m_inventory->itemsCanFit(items); } -ItemPtr Player::pickupItems(ItemPtr const& items) { +ItemPtr Player::pickupItems(ItemPtr const& items, bool silent) { if (isDead() || !items || m_inventory->itemsCanFit(items) == 0) return items; triggerPickupEvents(items); - if (items->pickupSound().size()) { - m_effectsAnimator->setSoundPool("pickup", {items->pickupSound()}); - float pitch = 1.f - ((float)items->count() / (float)items->maxStack()) * 0.5f; - m_effectsAnimator->setSoundPitchMultiplier("pickup", clamp(pitch * Random::randf(0.8f, 1.2f), 0.f, 2.f)); - m_effectsAnimator->playSound("pickup"); + if (!silent) { + if (items->pickupSound().size()) { + m_effectsAnimator->setSoundPool("pickup", {items->pickupSound()}); + float pitch = 1.f - ((float)items->count() / (float)items->maxStack()) * 0.5f; + m_effectsAnimator->setSoundPitchMultiplier("pickup", clamp(pitch * Random::randf(0.8f, 1.2f), 0.f, 2.f)); + m_effectsAnimator->playSound("pickup"); + } + auto itemDb = Root::singleton().itemDatabase(); + queueItemPickupMessage(itemDb->itemShared(items->descriptor())); } - auto itemDb = Root::singleton().itemDatabase(); - queueItemPickupMessage(itemDb->itemShared(items->descriptor())); + return m_inventory->addItems(items); } diff --git a/source/game/StarPlayer.hpp b/source/game/StarPlayer.hpp index 766f16e..933f623 100644 --- a/source/game/StarPlayer.hpp +++ b/source/game/StarPlayer.hpp @@ -200,7 +200,7 @@ public: uint64_t itemsCanHold(ItemPtr const& items) const; // Adds items to the inventory, returning the overflow. // The items parameter is invalid after use. - ItemPtr pickupItems(ItemPtr const& items); + ItemPtr pickupItems(ItemPtr const& items, bool silent = false); // Pick up all of the given items as possible, dropping the overflow. // The item parameter is invalid after use. void giveItem(ItemPtr const& item); diff --git a/source/game/StarPlayerInventory.cpp b/source/game/StarPlayerInventory.cpp index dc8d8e4..bacd58d 100644 --- a/source/game/StarPlayerInventory.cpp +++ b/source/game/StarPlayerInventory.cpp @@ -214,6 +214,14 @@ ItemPtr PlayerInventory::addItems(ItemPtr items) { if (is(items) && !backArmor()) m_equipment[EquipmentSlot::Back] = items->take(1); + if (is(items)) { + if (auto primary = primaryHeldItem()) { + primary->stackWith(items); + if (items->empty()) + return {}; + } + } + // Then, finally the bags return addToBags(std::move(items)); } diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index ca99165..b60e2c2 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -573,23 +573,28 @@ void WorldClient::render(WorldRenderData& renderData, unsigned bufferTiles) { renderTile.liquidId = clientTile.liquid.liquid; renderTile.liquidLevel = floatToByte(clientTile.liquid.level); + }); - if (!m_predictedTiles.empty()) { - if (auto p = m_predictedTiles.ptr(position)) { - if (p->liquid) { - auto& liquid = *p->liquid; - if (liquid.liquid == renderTile.liquidId) - renderTile.liquidLevel = floatToByte(clientTile.liquid.level + liquid.level, true); - else { - renderTile.liquidId = liquid.liquid; - renderTile.liquidLevel = floatToByte(liquid.level, true); - } - } - - p->apply(renderTile); + for (auto& pair : m_predictedTiles) { + Vec2I tileArrayPos = m_geometry.diff(pair.first, renderData.tileMinPosition); + if (tileArrayPos[0] >= 0 && tileArrayPos[0] < (int)renderData.tiles.size(0) && tileArrayPos[1] >= 0 && tileArrayPos[1] < (int)renderData.tiles.size(1)) { + RenderTile& renderTile = renderData.tiles(tileArrayPos[0], tileArrayPos[1]); + PredictedTile& p = pair.second; + if (p.liquid) { + auto& liquid = *p.liquid; + if (liquid.liquid == renderTile.liquidId) { + uint8_t added = floatToByte(liquid.level, true); + renderTile.liquidLevel = (renderTile.liquidLevel > 255 - added) ? 255 : renderTile.liquidLevel + added; + } + else { + renderTile.liquidId = liquid.liquid; + renderTile.liquidLevel = floatToByte(liquid.level, true); } } - }); + + pair.second.apply(renderTile); + } + } for (auto const& previewTile : previewTiles) { Vec2I tileArrayPos = m_geometry.diff(previewTile.position, renderData.tileMinPosition); @@ -896,10 +901,10 @@ void WorldClient::handleIncomingPackets(List const& packets) { if (auto placeMaterial = modification.second.ptr()) { auto stack = materialDatabase->materialItemDrop(placeMaterial->material); - tryGiveMainPlayerItem(itemDatabase->item(stack)); + tryGiveMainPlayerItem(itemDatabase->item(stack), true); } else if (auto placeMod = modification.second.ptr()) { auto stack = materialDatabase->modItemDrop(placeMod->mod); - tryGiveMainPlayerItem(itemDatabase->item(stack)); + tryGiveMainPlayerItem(itemDatabase->item(stack), true); } } @@ -1799,8 +1804,8 @@ void WorldClient::clearWorld() { m_forceRegions.clear(); } -void WorldClient::tryGiveMainPlayerItem(ItemPtr item) { - if (auto spill = m_mainPlayer->pickupItems(item)) +void WorldClient::tryGiveMainPlayerItem(ItemPtr item, bool silent) { + if (auto spill = m_mainPlayer->pickupItems(item, silent)) addEntity(ItemDrop::createRandomizedDrop(spill->descriptor(), m_mainPlayer->position())); } diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp index 5bfb11c..56a24e5 100644 --- a/source/game/StarWorldClient.hpp +++ b/source/game/StarWorldClient.hpp @@ -213,7 +213,7 @@ private: void initWorld(WorldStartPacket const& packet); void clearWorld(); - void tryGiveMainPlayerItem(ItemPtr item); + void tryGiveMainPlayerItem(ItemPtr item, bool silent = false); void notifyEntityCreate(EntityPtr const& entity);