Tile placement improvements

Placing materials is now done in a line to fix gaps at low framerates
This commit is contained in:
Kae 2023-07-31 16:00:19 +10:00
parent df83b02f1d
commit 830d4deb7b
4 changed files with 64 additions and 20 deletions

View File

@ -0,0 +1,3 @@
{
"materialItems" : { "cooldown" : 0 } // tile prediction makes a cooldown pointless
}

View File

@ -322,16 +322,23 @@ TileModificationList WorldClient::applyTileModifications(TileModificationList co
if (!inWorld())
return {};
auto result = WorldImpl::splitTileModifications(m_entityMap, modificationList, allowEntityOverlap, m_tileGetterFunction, [this](Vec2I pos, TileModification) {
auto extraCheck = [this](Vec2I pos, TileModification) {
return !isTileProtected(pos);
});
};
// thanks to new prediction: do it aggressively until no changes occur
auto result = WorldImpl::splitTileModifications(m_entityMap, modificationList, allowEntityOverlap, m_tileGetterFunction, extraCheck);
while (true) {
if (!result.first.empty()) {
informTilePredictions(result.first);
m_outgoingPackets.append(make_shared<ModifyTileListPacket>(result.first, true));
}
auto list = move(result.second);
result = WorldImpl::splitTileModifications(m_entityMap, list, allowEntityOverlap, m_tileGetterFunction, extraCheck);
}
else
return result.second;
}
}
float WorldClient::gravity(Vec2F const& pos) const {

View File

@ -27,9 +27,10 @@ MaterialItem::MaterialItem(Json const& config, String const& directory, Json con
setTwoHanded(config.getBool("twoHanded", true));
setCooldownTime(Root::singleton().assets()->json("/items/defaultParameters.config:materialItems.cooldown").toFloat());
m_blockRadius = Root::singleton().assets()->json("/items/defaultParameters.config:blockRadius").toFloat();
m_altBlockRadius = Root::singleton().assets()->json("/items/defaultParameters.config:altBlockRadius").toFloat();
auto defaultParameters = Root::singleton().assets()->json("/items/defaultParameters.config");
setCooldownTime(config.queryFloat("materialItems.cooldown", defaultParameters.queryFloat("materialItems.cooldown")));
m_blockRadius = config.getFloat("blockRadius", defaultParameters.getFloat("blockRadius"));
m_altBlockRadius = config.getFloat("altBlockRadius", defaultParameters.getFloat("altBlockRadius"));
m_multiplace = config.getBool("allowMultiplace", BlockCollisionSet.contains(Root::singleton().materialDatabase()->materialCollisionKind(m_material)));
m_shifting = false;
@ -75,17 +76,48 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
if (!multiplaceEnabled())
radius = 1;
for (auto pos : tileAreaBrush(radius, owner()->aimPosition(), true))
modifications.append({pos, PlaceMaterial{layer, materialId(), placementHueShift(pos)}});
auto geo = world()->geometry();
auto aimPosition = owner()->aimPosition();
if (!m_lastAimPosition)
m_lastAimPosition = aimPosition;
unsigned steps = 1;
Vec2F diff = {};
if (*m_lastAimPosition != aimPosition) {
diff = geo.diff(*m_lastAimPosition, aimPosition);
float magnitude = diff.magnitude();
if (magnitude > 32) {
m_lastAimPosition = aimPosition + diff.normalized() * 32;
magnitude = 32;
}
steps = (int)ceil(magnitude);
}
bool fail = true;
for (int i = 0; i != steps; ++i) {
auto placementOrigin = aimPosition + diff * ((float)i / steps);
for (Vec2I pos : tileAreaBrush(radius, placementOrigin, true))
modifications.append({ pos, PlaceMaterial{layer, materialId(), placementHueShift(pos)} });
// Make sure not to make any more modifications than we have consumables.
if (modifications.size() > count())
modifications.resize(count());
size_t failed = world()->applyTileModifications(modifications, false).size();
if (failed < modifications.size()) {
FireableItem::fire(mode, shifting, edgeTriggered);
fail = false;
consume(modifications.size() - failed);
}
}
if (!fail)
FireableItem::fire(mode, shifting, edgeTriggered);
m_lastAimPosition = aimPosition;
}
void MaterialItem::endFire(FireMode mode, bool shifting) {
m_lastAimPosition.reset();
}
MaterialId MaterialItem::materialId() const {

View File

@ -23,6 +23,7 @@ public:
List<Drawable> nonRotatedDrawables() const override;
void fire(FireMode mode, bool shifting, bool edgeTriggered) override;
void endFire(FireMode mode, bool shifting) override;
MaterialId materialId() const;
MaterialHue materialHueShift() const;
@ -43,6 +44,7 @@ private:
float m_altBlockRadius;
bool m_shifting;
bool m_multiplace;
Maybe<Vec2F> m_lastAimPosition;
};
}