Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2024-04-14 10:32:11 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2024-04-14 10:32:11 +1000
commited8b22c472b9159550ade374328092d15b575ade (patch)
tree1cc23095c36b83cf656f1d20ecee8b899666df37
parented3a3d90fb57a97e9e014526acea2811c54da467 (diff)
feat: nicer Humanoid ?scalenearest rendering
-rw-r--r--source/game/StarHumanoid.cpp31
-rw-r--r--source/game/StarHumanoid.hpp4
-rw-r--r--source/game/StarNpc.cpp11
-rw-r--r--source/game/StarPlayer.cpp18
4 files changed, 61 insertions, 3 deletions
diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp
index b19410a..418e88d 100644
--- a/source/game/StarHumanoid.cpp
+++ b/source/game/StarHumanoid.cpp
@@ -1374,4 +1374,35 @@ Json const& Humanoid::defaultMovementParameters() const {
return m_defaultMovementParameters;
}
+pair<Vec2F, Directives> Humanoid::extractScaleFromDirectives(Directives const& directives) {
+ if (!directives)
+ return make_pair(Vec2F::filled(1.f), Directives());
+
+ List<StringView> operations;
+ size_t totalLength = 0;
+ Maybe<Vec2F> scale;
+
+ for (auto& entry : directives.shared->entries) {
+ auto string = entry.string(*directives.shared);
+ const ScaleImageOperation* op = nullptr;
+ if (string.beginsWith("scalenearest") && string.utf8().find("skip") == NPos)
+ op = entry.loadOperation(*directives.shared).ptr<ScaleImageOperation>();
+
+ if (op)
+ scale = scale.value(Vec2F::filled(1.f)).piecewiseMultiply(op->scale);
+ else
+ totalLength += operations.emplace_back(string).utf8Size();
+ }
+
+ if (!scale)
+ return make_pair(Vec2F::filled(1.f), directives);
+
+ String mergedDirectives;
+ mergedDirectives.reserve(totalLength);
+ for (auto& directive : operations)
+ mergedDirectives.append(directive.utf8Ptr(), directive.utf8Size());
+
+ return make_pair(*scale, Directives(mergedDirectives));
+}
+
}
diff --git a/source/game/StarHumanoid.hpp b/source/game/StarHumanoid.hpp
index e6d89cb..3f8296b 100644
--- a/source/game/StarHumanoid.hpp
+++ b/source/game/StarHumanoid.hpp
@@ -240,6 +240,10 @@ public:
Json const& defaultMovementParameters() const;
+ // Extracts scalenearest from directives and returns the combined scale and
+ // a new Directives without those scalenearest directives.
+ static pair<Vec2F, Directives> extractScaleFromDirectives(Directives const& directives);
+
private:
struct HandDrawingInfo {
List<Drawable> itemDrawables;
diff --git a/source/game/StarNpc.cpp b/source/game/StarNpc.cpp
index 5450e6f..d45f416 100644
--- a/source/game/StarNpc.cpp
+++ b/source/game/StarNpc.cpp
@@ -475,10 +475,19 @@ void Npc::render(RenderCallback* renderCallback) {
renderLayer = loungeAnchor->loungeRenderLayer;
m_tools->setupHumanoidHandItemDrawables(m_humanoid);
+
+ DirectivesGroup humanoidDirectives;
+ Vec2F scale = Vec2F::filled(1.f);
+ for (auto& directives : m_statusController->parentDirectives().list()) {
+ auto result = Humanoid::extractScaleFromDirectives(directives);
+ scale = scale.piecewiseMultiply(result.first);
+ humanoidDirectives.append(result.second);
+ }
+
for (auto& drawable : m_humanoid.render()) {
drawable.translate(position());
if (drawable.isImage())
- drawable.imagePart().addDirectivesGroup(m_statusController->parentDirectives(), true);
+ drawable.imagePart().addDirectivesGroup(humanoidDirectives, true);
renderCallback->addDrawable(std::move(drawable), renderLayer);
}
diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp
index 7d751af..07196b6 100644
--- a/source/game/StarPlayer.cpp
+++ b/source/game/StarPlayer.cpp
@@ -373,11 +373,25 @@ List<Drawable> Player::drawables() const {
drawables.appendAll(m_techController->backDrawables());
if (!m_techController->parentHidden()) {
m_tools->setupHumanoidHandItemDrawables(*m_humanoid);
+
+ // Auto-detect any ?scalenearest and apply them as a direct scale on the Humanoid's drawables instead.
+ DirectivesGroup humanoidDirectives;
+ Vec2F scale = Vec2F::filled(1.f);
+ auto extractScale = [&](List<Directives> const& list) {
+ for (auto& directives : list) {
+ auto result = Humanoid::extractScaleFromDirectives(directives);
+ scale = scale.piecewiseMultiply(result.first);
+ humanoidDirectives.append(result.second);
+ }
+ };
+ extractScale(m_techController->parentDirectives().list());
+ extractScale(m_statusController->parentDirectives().list());
+
for (auto& drawable : m_humanoid->render()) {
+ drawable.scale(scale);
drawable.translate(position() + m_techController->parentOffset());
if (drawable.isImage()) {
- drawable.imagePart().addDirectivesGroup(m_techController->parentDirectives(), true);
- drawable.imagePart().addDirectivesGroup(m_statusController->parentDirectives(), true);
+ drawable.imagePart().addDirectivesGroup(humanoidDirectives, true);
if (auto anchor = as<LoungeAnchor>(m_movementController->entityAnchor())) {
if (auto& directives = anchor->directives)