From 3805db77226c1d46beb6e128dea796ab0bd94a63 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Sat, 19 Aug 2023 21:35:56 +1000 Subject: [PATCH] oops: Fix sub-step material placement --- source/game/StarWorldClient.cpp | 1 + source/game/items/StarMaterialItem.cpp | 23 +++++++++++------------ source/game/items/StarMaterialItem.hpp | 3 ++- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 789bafa..6359a12 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -351,6 +351,7 @@ TileModificationList WorldClient::applyTileModifications(TileModificationList co } if (yay) { list = &(temp = move(failures)); + failures = {}; continue; } else break; diff --git a/source/game/items/StarMaterialItem.cpp b/source/game/items/StarMaterialItem.cpp index acfe805..183b160 100644 --- a/source/game/items/StarMaterialItem.cpp +++ b/source/game/items/StarMaterialItem.cpp @@ -99,7 +99,7 @@ void MaterialItem::render(RenderCallback* renderCallback, EntityRenderLayer rend auto indicator = Drawable::makeImage(path, 1.0f / TilePixels, true, basePosition); indicator.fullbright = true; indicator.color = color; - for (auto& tilePos : tileArea(calcRadius(m_shifting))) { + for (auto& tilePos : tileArea(calcRadius(m_shifting), owner()->aimPosition())) { indicator.position = basePosition + Vec2F(tilePos); renderCallback->addDrawable(indicator, RenderLayerForegroundTile); } @@ -129,7 +129,6 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) { auto geo = world()->geometry(); auto aimPosition = owner()->aimPosition(); - auto& tilePositions = tileArea(radius); if (!m_lastAimPosition) m_lastAimPosition = aimPosition; @@ -145,14 +144,14 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) { magnitude = limit; } - steps = (int)ceil(magnitude * (Constants::pi / 2)); + steps = (unsigned)ceil(magnitude * (Constants::pi / 2)); } size_t total = 0; for (int i = 0; i != steps; ++i) { auto placementOrigin = aimPosition + diff * (1.0f - ((float)i / steps)); - for (Vec2I& pos : tilePositions) - modifications.append({ pos, PlaceMaterial{layer, materialId(), placementHueShift(pos), m_collisionOverride} }); + for (Vec2I& pos : tileArea(radius, placementOrigin)) + modifications.emplaceAppend(pos, PlaceMaterial{layer, materialId(), placementHueShift(pos), m_collisionOverride}); // Make sure not to make any more modifications than we have consumables. if (modifications.size() > count()) @@ -166,7 +165,7 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) { } if (total) { - float intensity = clamp((float)total / 96, 0.0f, 1.0f); + float intensity = clamp(sqrt((float)total) / 16, 0.0f, 1.0f); owner()->addSound(Random::randValueFrom(m_placeSounds), 1.0f + intensity, (1.125f - intensity * 0.75f) * Random::randf(0.9f, 1.1f)); FireableItem::fire(mode, shifting, edgeTriggered); } @@ -189,11 +188,11 @@ float MaterialItem::calcRadius(bool shifting) const { return !shifting ? m_blockRadius : m_altBlockRadius; } -List& MaterialItem::tileArea(float radius) const { - auto aimPosition = owner()->aimPosition(); - if (!m_lastAimPosition || *m_lastAimPosition != aimPosition || m_lastTileAreaRadiusCache != radius) { +List& MaterialItem::tileArea(float radius, Vec2F const& position) const { + if (m_lastTileAreaOriginCache != position || m_lastTileAreaRadiusCache != radius) { + m_lastTileAreaOriginCache = position; m_lastTileAreaRadiusCache = radius; - m_tileAreasCache = tileAreaBrush(radius, owner()->aimPosition(), true); + m_tileAreasCache = tileAreaBrush(radius, position, true); } return m_tileAreasCache; } @@ -208,7 +207,7 @@ bool MaterialItem::canPlace(bool shifting) const { float radius = calcRadius(shifting); - for (auto& pos : tileArea(radius)) { + for (auto& pos : tileArea(radius, owner()->aimPosition())) { MaterialHue hueShift = placementHueShift(pos); if (world()->canModifyTile(pos, PlaceMaterial{TileLayer::Foreground, material, hueShift}, false) || world()->canModifyTile(pos, PlaceMaterial{TileLayer::Background, material, hueShift}, false)) @@ -244,7 +243,7 @@ List MaterialItem::preview(bool shifting) const { auto color = DefaultMaterialColorVariant; size_t c = 0; - for (auto& pos : tileArea(calcRadius(shifting))) { + for (auto& pos : tileArea(calcRadius(shifting), owner()->aimPosition())) { MaterialHue hueShift = placementHueShift(pos); if (c >= count()) break; diff --git a/source/game/items/StarMaterialItem.hpp b/source/game/items/StarMaterialItem.hpp index e5b1f01..05f9e08 100644 --- a/source/game/items/StarMaterialItem.hpp +++ b/source/game/items/StarMaterialItem.hpp @@ -43,7 +43,7 @@ public: List preview(bool shifting) const override; private: float calcRadius(bool shifting) const; - List& tileArea(float radius) const; + List& tileArea(float radius, Vec2F const& position) const; MaterialHue placementHueShift(Vec2I const& position) const; MaterialId m_material; @@ -57,6 +57,7 @@ private: Maybe m_lastAimPosition; TileCollisionOverride m_collisionOverride; + mutable Vec2F m_lastTileAreaOriginCache; mutable float m_lastTileAreaRadiusCache; mutable List m_tileAreasCache; };