Tile placement improvements
Placing materials is now done in a line to fix gaps at low framerates
This commit is contained in:
parent
df83b02f1d
commit
830d4deb7b
3
assets/opensb/items/defaultParameters.config.patch
Normal file
3
assets/opensb/items/defaultParameters.config.patch
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"materialItems" : { "cooldown" : 0 } // tile prediction makes a cooldown pointless
|
||||||
|
}
|
@ -321,17 +321,24 @@ TileModificationList WorldClient::validTileModifications(TileModificationList co
|
|||||||
TileModificationList WorldClient::applyTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) {
|
TileModificationList WorldClient::applyTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) {
|
||||||
if (!inWorld())
|
if (!inWorld())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
auto extraCheck = [this](Vec2I pos, TileModification) {
|
||||||
|
return !isTileProtected(pos);
|
||||||
|
};
|
||||||
|
|
||||||
auto result = WorldImpl::splitTileModifications(m_entityMap, modificationList, allowEntityOverlap, m_tileGetterFunction, [this](Vec2I pos, TileModification) {
|
// thanks to new prediction: do it aggressively until no changes occur
|
||||||
return !isTileProtected(pos);
|
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));
|
||||||
|
|
||||||
if (!result.first.empty()) {
|
auto list = move(result.second);
|
||||||
informTilePredictions(result.first);
|
result = WorldImpl::splitTileModifications(m_entityMap, list, allowEntityOverlap, m_tileGetterFunction, extraCheck);
|
||||||
m_outgoingPackets.append(make_shared<ModifyTileListPacket>(result.first, true));
|
}
|
||||||
|
else
|
||||||
|
return result.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float WorldClient::gravity(Vec2F const& pos) const {
|
float WorldClient::gravity(Vec2F const& pos) const {
|
||||||
|
@ -27,9 +27,10 @@ MaterialItem::MaterialItem(Json const& config, String const& directory, Json con
|
|||||||
|
|
||||||
setTwoHanded(config.getBool("twoHanded", true));
|
setTwoHanded(config.getBool("twoHanded", true));
|
||||||
|
|
||||||
setCooldownTime(Root::singleton().assets()->json("/items/defaultParameters.config:materialItems.cooldown").toFloat());
|
auto defaultParameters = Root::singleton().assets()->json("/items/defaultParameters.config");
|
||||||
m_blockRadius = Root::singleton().assets()->json("/items/defaultParameters.config:blockRadius").toFloat();
|
setCooldownTime(config.queryFloat("materialItems.cooldown", defaultParameters.queryFloat("materialItems.cooldown")));
|
||||||
m_altBlockRadius = Root::singleton().assets()->json("/items/defaultParameters.config:altBlockRadius").toFloat();
|
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_multiplace = config.getBool("allowMultiplace", BlockCollisionSet.contains(Root::singleton().materialDatabase()->materialCollisionKind(m_material)));
|
||||||
|
|
||||||
m_shifting = false;
|
m_shifting = false;
|
||||||
@ -75,17 +76,48 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
|
|||||||
if (!multiplaceEnabled())
|
if (!multiplaceEnabled())
|
||||||
radius = 1;
|
radius = 1;
|
||||||
|
|
||||||
for (auto pos : tileAreaBrush(radius, owner()->aimPosition(), true))
|
auto geo = world()->geometry();
|
||||||
modifications.append({pos, PlaceMaterial{layer, materialId(), placementHueShift(pos)}});
|
auto aimPosition = owner()->aimPosition();
|
||||||
|
if (!m_lastAimPosition)
|
||||||
|
m_lastAimPosition = aimPosition;
|
||||||
|
|
||||||
// Make sure not to make any more modifications than we have consumables.
|
unsigned steps = 1;
|
||||||
if (modifications.size() > count())
|
Vec2F diff = {};
|
||||||
modifications.resize(count());
|
if (*m_lastAimPosition != aimPosition) {
|
||||||
size_t failed = world()->applyTileModifications(modifications, false).size();
|
diff = geo.diff(*m_lastAimPosition, aimPosition);
|
||||||
if (failed < modifications.size()) {
|
float magnitude = diff.magnitude();
|
||||||
FireableItem::fire(mode, shifting, edgeTriggered);
|
if (magnitude > 32) {
|
||||||
consume(modifications.size() - failed);
|
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()) {
|
||||||
|
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 {
|
MaterialId MaterialItem::materialId() const {
|
||||||
|
@ -23,6 +23,7 @@ public:
|
|||||||
List<Drawable> nonRotatedDrawables() const override;
|
List<Drawable> nonRotatedDrawables() const override;
|
||||||
|
|
||||||
void fire(FireMode mode, bool shifting, bool edgeTriggered) override;
|
void fire(FireMode mode, bool shifting, bool edgeTriggered) override;
|
||||||
|
void endFire(FireMode mode, bool shifting) override;
|
||||||
|
|
||||||
MaterialId materialId() const;
|
MaterialId materialId() const;
|
||||||
MaterialHue materialHueShift() const;
|
MaterialHue materialHueShift() const;
|
||||||
@ -43,6 +44,7 @@ private:
|
|||||||
float m_altBlockRadius;
|
float m_altBlockRadius;
|
||||||
bool m_shifting;
|
bool m_shifting;
|
||||||
bool m_multiplace;
|
bool m_multiplace;
|
||||||
|
Maybe<Vec2F> m_lastAimPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user