oops: Fix sub-step material placement

This commit is contained in:
Kae 2023-08-19 21:35:56 +10:00
parent 2fb2616384
commit 3805db7722
3 changed files with 14 additions and 13 deletions

View File

@ -351,6 +351,7 @@ TileModificationList WorldClient::applyTileModifications(TileModificationList co
} }
if (yay) { if (yay) {
list = &(temp = move(failures)); list = &(temp = move(failures));
failures = {};
continue; continue;
} }
else break; else break;

View File

@ -99,7 +99,7 @@ void MaterialItem::render(RenderCallback* renderCallback, EntityRenderLayer rend
auto indicator = Drawable::makeImage(path, 1.0f / TilePixels, true, basePosition); auto indicator = Drawable::makeImage(path, 1.0f / TilePixels, true, basePosition);
indicator.fullbright = true; indicator.fullbright = true;
indicator.color = color; indicator.color = color;
for (auto& tilePos : tileArea(calcRadius(m_shifting))) { for (auto& tilePos : tileArea(calcRadius(m_shifting), owner()->aimPosition())) {
indicator.position = basePosition + Vec2F(tilePos); indicator.position = basePosition + Vec2F(tilePos);
renderCallback->addDrawable(indicator, RenderLayerForegroundTile); renderCallback->addDrawable(indicator, RenderLayerForegroundTile);
} }
@ -129,7 +129,6 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
auto geo = world()->geometry(); auto geo = world()->geometry();
auto aimPosition = owner()->aimPosition(); auto aimPosition = owner()->aimPosition();
auto& tilePositions = tileArea(radius);
if (!m_lastAimPosition) if (!m_lastAimPosition)
m_lastAimPosition = aimPosition; m_lastAimPosition = aimPosition;
@ -145,14 +144,14 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
magnitude = limit; magnitude = limit;
} }
steps = (int)ceil(magnitude * (Constants::pi / 2)); steps = (unsigned)ceil(magnitude * (Constants::pi / 2));
} }
size_t total = 0; size_t total = 0;
for (int i = 0; i != steps; ++i) { for (int i = 0; i != steps; ++i) {
auto placementOrigin = aimPosition + diff * (1.0f - ((float)i / steps)); auto placementOrigin = aimPosition + diff * (1.0f - ((float)i / steps));
for (Vec2I& pos : tilePositions) for (Vec2I& pos : tileArea(radius, placementOrigin))
modifications.append({ pos, PlaceMaterial{layer, materialId(), placementHueShift(pos), m_collisionOverride} }); modifications.emplaceAppend(pos, PlaceMaterial{layer, materialId(), placementHueShift(pos), m_collisionOverride});
// Make sure not to make any more modifications than we have consumables. // Make sure not to make any more modifications than we have consumables.
if (modifications.size() > count()) if (modifications.size() > count())
@ -166,7 +165,7 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
} }
if (total) { 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)); 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); FireableItem::fire(mode, shifting, edgeTriggered);
} }
@ -189,11 +188,11 @@ float MaterialItem::calcRadius(bool shifting) const {
return !shifting ? m_blockRadius : m_altBlockRadius; return !shifting ? m_blockRadius : m_altBlockRadius;
} }
List<Vec2I>& MaterialItem::tileArea(float radius) const { List<Vec2I>& MaterialItem::tileArea(float radius, Vec2F const& position) const {
auto aimPosition = owner()->aimPosition(); if (m_lastTileAreaOriginCache != position || m_lastTileAreaRadiusCache != radius) {
if (!m_lastAimPosition || *m_lastAimPosition != aimPosition || m_lastTileAreaRadiusCache != radius) { m_lastTileAreaOriginCache = position;
m_lastTileAreaRadiusCache = radius; m_lastTileAreaRadiusCache = radius;
m_tileAreasCache = tileAreaBrush(radius, owner()->aimPosition(), true); m_tileAreasCache = tileAreaBrush(radius, position, true);
} }
return m_tileAreasCache; return m_tileAreasCache;
} }
@ -208,7 +207,7 @@ bool MaterialItem::canPlace(bool shifting) const {
float radius = calcRadius(shifting); float radius = calcRadius(shifting);
for (auto& pos : tileArea(radius)) { for (auto& pos : tileArea(radius, owner()->aimPosition())) {
MaterialHue hueShift = placementHueShift(pos); MaterialHue hueShift = placementHueShift(pos);
if (world()->canModifyTile(pos, PlaceMaterial{TileLayer::Foreground, material, hueShift}, false) if (world()->canModifyTile(pos, PlaceMaterial{TileLayer::Foreground, material, hueShift}, false)
|| world()->canModifyTile(pos, PlaceMaterial{TileLayer::Background, material, hueShift}, false)) || world()->canModifyTile(pos, PlaceMaterial{TileLayer::Background, material, hueShift}, false))
@ -244,7 +243,7 @@ List<PreviewTile> MaterialItem::preview(bool shifting) const {
auto color = DefaultMaterialColorVariant; auto color = DefaultMaterialColorVariant;
size_t c = 0; size_t c = 0;
for (auto& pos : tileArea(calcRadius(shifting))) { for (auto& pos : tileArea(calcRadius(shifting), owner()->aimPosition())) {
MaterialHue hueShift = placementHueShift(pos); MaterialHue hueShift = placementHueShift(pos);
if (c >= count()) if (c >= count())
break; break;

View File

@ -43,7 +43,7 @@ public:
List<PreviewTile> preview(bool shifting) const override; List<PreviewTile> preview(bool shifting) const override;
private: private:
float calcRadius(bool shifting) const; float calcRadius(bool shifting) const;
List<Vec2I>& tileArea(float radius) const; List<Vec2I>& tileArea(float radius, Vec2F const& position) const;
MaterialHue placementHueShift(Vec2I const& position) const; MaterialHue placementHueShift(Vec2I const& position) const;
MaterialId m_material; MaterialId m_material;
@ -57,6 +57,7 @@ private:
Maybe<Vec2F> m_lastAimPosition; Maybe<Vec2F> m_lastAimPosition;
TileCollisionOverride m_collisionOverride; TileCollisionOverride m_collisionOverride;
mutable Vec2F m_lastTileAreaOriginCache;
mutable float m_lastTileAreaRadiusCache; mutable float m_lastTileAreaRadiusCache;
mutable List<Vec2I> m_tileAreasCache; mutable List<Vec2I> m_tileAreasCache;
}; };