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

summaryrefslogtreecommitdiff
path: root/source/game
diff options
context:
space:
mode:
Diffstat (limited to 'source/game')
-rw-r--r--source/game/StarHumanoid.cpp55
-rw-r--r--source/game/StarHumanoid.hpp7
-rw-r--r--source/game/StarPlayer.cpp40
3 files changed, 90 insertions, 12 deletions
diff --git a/source/game/StarHumanoid.cpp b/source/game/StarHumanoid.cpp
index c71e161..8f39abe 100644
--- a/source/game/StarHumanoid.cpp
+++ b/source/game/StarHumanoid.cpp
@@ -242,6 +242,14 @@ EnumMap<Humanoid::State> const Humanoid::StateNames{
{Humanoid::State::Lay, "lay"},
};
+// gross, but I don't want to make config calls more than I need to
+bool& Humanoid::globalHeadRotation(Maybe<bool> default) {
+ static Maybe<bool> s_headRotation;
+ if (!s_headRotation)
+ s_headRotation = Root::singleton().configuration()->get("humanoidHeadRotation").optBool().value(true);
+ return *s_headRotation;
+};
+
Humanoid::Humanoid(Json const& config) {
loadConfig(config);
@@ -252,7 +260,7 @@ Humanoid::Humanoid(Json const& config) {
m_movingBackwards = false;
m_altHand.angle = 0;
m_facingDirection = Direction::Left;
- m_rotation = 0;
+ m_headRotationTarget = m_headRotation = m_rotation = 0;
m_scale = Vec2F::filled(1.f);
m_drawVaporTrail = false;
m_state = State::Idle;
@@ -412,6 +420,10 @@ void Humanoid::setMovingBackwards(bool movingBackwards) {
m_movingBackwards = movingBackwards;
}
+void Humanoid::setHeadRotation(float headRotation) {
+ m_headRotationTarget = headRotation;
+}
+
void Humanoid::setRotation(float rotation) {
m_rotation = rotation;
}
@@ -476,6 +488,10 @@ void Humanoid::setPrimaryHandNonRotatedDrawables(List<Drawable> drawables) {
m_primaryHand.nonRotatedDrawables = std::move(drawables);
}
+bool Humanoid::primaryHandHoldingItem() const {
+ return m_primaryHand.holdingItem;
+}
+
void Humanoid::setAltHandParameters(bool holdingItem, float angle, float itemAngle, bool recoil,
bool outsideOfHand) {
m_altHand.holdingItem = holdingItem;
@@ -498,16 +514,24 @@ void Humanoid::setAltHandNonRotatedDrawables(List<Drawable> drawables) {
m_altHand.nonRotatedDrawables = std::move(drawables);
}
+bool Humanoid::altHandHoldingItem() const {
+ return m_altHand.holdingItem;
+}
+
void Humanoid::animate(float dt) {
m_animationTimer += dt;
m_emoteAnimationTimer += dt;
m_danceTimer += dt;
+ float headRotationTarget = globalHeadRotation() ? m_headRotationTarget : 0.f;
+ float diff = angleDiff(m_headRotation, headRotationTarget);
+ m_headRotation = (headRotationTarget - (headRotationTarget - m_headRotation) * powf(.333333f, dt * 60.f));
}
void Humanoid::resetAnimation() {
m_animationTimer = 0.0f;
m_emoteAnimationTimer = 0.0f;
m_danceTimer = 0.0f;
+ m_headRotation = globalHeadRotation() ? 0.f : m_headRotationTarget;
}
List<Drawable> Humanoid::render(bool withItems, bool withRotationAndScale) {
@@ -641,11 +665,28 @@ List<Drawable> Humanoid::render(bool withItems, bool withRotationAndScale) {
else if (m_state == Lay)
headPosition += m_headLayOffset;
+ auto addHeadDrawable = [&](Drawable drawable, bool forceFullbright = false) {
+ if (m_facingDirection == Direction::Left)
+ drawable.scale(Vec2F(-1, 1));
+ drawable.fullbright |= forceFullbright;
+ if (m_headRotation != 0.f) {
+ float dir = numericalDirection(m_facingDirection);
+ Vec2F rotationPoint = headPosition;
+ rotationPoint[0] *= dir;
+ rotationPoint[1] -= .25f;
+ float headX = (m_headRotation / ((float)Constants::pi * 2.f));
+ drawable.rotate(m_headRotation, rotationPoint);
+ drawable.position[0] -= state() == State::Run ? (fmaxf(headX * dir, 0.f) * 2.f) * dir : headX;
+ drawable.position[1] -= fabsf(m_headRotation / ((float)Constants::pi * 4.f));
+ }
+ drawables.append(std::move(drawable));
+ };
+
if (!m_headFrameset.empty() && !m_bodyHidden) {
String image = strf("{}:normal", m_headFrameset);
auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition);
drawable.imagePart().addDirectives(getBodyDirectives(), true);
- addDrawable(std::move(drawable), m_bodyFullbright);
+ addHeadDrawable(std::move(drawable), m_bodyFullbright);
}
if (!m_emoteFrameset.empty() && !m_bodyHidden) {
@@ -653,14 +694,14 @@ List<Drawable> Humanoid::render(bool withItems, bool withRotationAndScale) {
String image = strf("{}:{}.{}{}", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq, emoteDirectives.prefix());
auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition);
drawable.imagePart().addDirectives(emoteDirectives, true);
- addDrawable(std::move(drawable), m_bodyFullbright);
+ addHeadDrawable(std::move(drawable), m_bodyFullbright);
}
if (!m_hairFrameset.empty() && !m_bodyHidden) {
String image = strf("{}:normal", m_hairFrameset);
auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition);
drawable.imagePart().addDirectives(getHairDirectives(), true).addDirectives(getHelmetMaskDirectives(), true);
- addDrawable(std::move(drawable), m_bodyFullbright);
+ addHeadDrawable(std::move(drawable), m_bodyFullbright);
}
if (!m_bodyFrameset.empty() && !m_bodyHidden) {
@@ -719,21 +760,21 @@ List<Drawable> Humanoid::render(bool withItems, bool withRotationAndScale) {
String image = strf("{}:normal", m_facialHairFrameset);
auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition);
drawable.imagePart().addDirectives(getFacialHairDirectives(), true).addDirectives(getHelmetMaskDirectives(), true);
- addDrawable(std::move(drawable), m_bodyFullbright);
+ addHeadDrawable(std::move(drawable), m_bodyFullbright);
}
if (!m_facialMaskFrameset.empty() && !m_bodyHidden) {
String image = strf("{}:normal", m_facialMaskFrameset);
auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition);
drawable.imagePart().addDirectives(getFacialMaskDirectives(), true).addDirectives(getHelmetMaskDirectives(), true);
- addDrawable(std::move(drawable));
+ addHeadDrawable(std::move(drawable));
}
if (!m_headArmorFrameset.empty()) {
String image = strf("{}:normal{}", m_headArmorFrameset, m_headArmorDirectives.prefix());
auto drawable = Drawable::makeImage(std::move(image), 1.0f / TilePixels, true, headPosition);
drawable.imagePart().addDirectives(getHeadDirectives(), true);
- addDrawable(std::move(drawable));
+ addHeadDrawable(std::move(drawable));
}
auto frontArmDrawable = [&](String const& frameSet, Directives const& directives) -> Drawable {
diff --git a/source/game/StarHumanoid.hpp b/source/game/StarHumanoid.hpp
index c83ddb5..6fd1cbe 100644
--- a/source/game/StarHumanoid.hpp
+++ b/source/game/StarHumanoid.hpp
@@ -100,6 +100,8 @@ public:
};
static EnumMap<State> const StateNames;
+ static bool& globalHeadRotation(Maybe<bool> default = {});
+
Humanoid(Json const& config);
Humanoid(HumanoidIdentity const& identity);
Humanoid(Humanoid const&) = default;
@@ -163,6 +165,7 @@ public:
void setDance(Maybe<String> const& dance);
void setFacingDirection(Direction facingDirection);
void setMovingBackwards(bool movingBackwards);
+ void setHeadRotation(float headRotation);
void setRotation(float rotation);
void setScale(Vec2F scale);
@@ -183,6 +186,7 @@ public:
void setPrimaryHandFrameOverrides(String backFrameOverride, String frontFrameOverride);
void setPrimaryHandDrawables(List<Drawable> drawables);
void setPrimaryHandNonRotatedDrawables(List<Drawable> drawables);
+ bool primaryHandHoldingItem() const;
// Same as primary hand.
void setAltHandParameters(bool holdingItem, float angle, float itemAngle, bool recoil,
@@ -190,6 +194,7 @@ public:
void setAltHandFrameOverrides(String backFrameOverride, String frontFrameOverride);
void setAltHandDrawables(List<Drawable> drawables);
void setAltHandNonRotatedDrawables(List<Drawable> drawables);
+ bool altHandHoldingItem() const;
// Updates the animation based on whatever the current animation state is,
// wrapping or clamping animation time as appropriate.
@@ -355,6 +360,8 @@ private:
Maybe<String> m_dance;
Direction m_facingDirection;
bool m_movingBackwards;
+ float m_headRotation;
+ float m_headRotationTarget;
float m_rotation;
Vec2F m_scale;
bool m_drawVaporTrail;
diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp
index 2f89ff3..24a3c16 100644
--- a/source/game/StarPlayer.cpp
+++ b/source/game/StarPlayer.cpp
@@ -1021,16 +1021,16 @@ void Player::update(float dt, uint64_t) {
|| m_humanoid->danceCyclicOrEnded() || m_movementController->running())
m_humanoid->setDance({});
- bool isClient = world()->isClient();
- if (isClient)
- m_armor->setupHumanoidClothingDrawables(*m_humanoid, forceNude());
-
m_tools->suppressItems(suppressedItems);
m_tools->tick(dt, m_shifting, m_pendingMoves);
-
+
if (auto overrideFacingDirection = m_tools->setupHumanoidHandItems(*m_humanoid, position(), aimPosition()))
m_movementController->controlFace(*overrideFacingDirection);
+ bool isClient = world()->isClient();
+ if (isClient)
+ m_armor->setupHumanoidClothingDrawables(*m_humanoid, forceNude());
+
m_effectsAnimator->resetTransformationGroup("flip");
if (m_movementController->facingDirection() == Direction::Left)
m_effectsAnimator->scaleTransformationGroup("flip", Vec2F(-1, 1));
@@ -1075,6 +1075,35 @@ void Player::update(float dt, uint64_t) {
m_effectEmitter->tick(dt, *entityMode());
+ if (isClient) {
+ bool calculateHeadRotation = isMaster();
+ if (!calculateHeadRotation) {
+ auto headRotationProperty = getSecretProperty("humanoid.headRotation");
+ if (headRotationProperty.isType(Json::Type::Float)) {
+ m_humanoid->setHeadRotation(headRotationProperty.toFloat());
+ } else
+ calculateHeadRotation = true;
+ }
+ if (calculateHeadRotation) { // master or not an OpenStarbound player
+ float headRotation = 0.f;
+ if (m_humanoid->primaryHandHoldingItem() || m_humanoid->altHandHoldingItem()) {
+ auto primary = m_tools->primaryHandItem();
+ auto alt = m_tools->altHandItem();
+ String const disableFlag = "disableHeadRotation";
+ auto statusFlag = m_statusController->statusProperty(disableFlag);
+ if (!(statusFlag.isType(Json::Type::Bool) && statusFlag.toBool())
+ && !(primary && primary->instanceValue(disableFlag))
+ && !(alt && alt->instanceValue(disableFlag))) {
+ auto diff = world()->geometry().diff(aimPosition(), mouthPosition());
+ diff.setX(fabsf(diff.x()));
+ headRotation = diff.angle() * .25f * numericalDirection(m_humanoid->facingDirection());
+ }
+ }
+ m_humanoid->setHeadRotation(headRotation);
+ setSecretProperty("humanoid.headRotation", headRotation);
+ }
+ }
+
m_humanoid->setFacingDirection(m_movementController->facingDirection());
m_humanoid->setMovingBackwards(m_movementController->facingDirection() != m_movementController->movingDirection());
@@ -2610,6 +2639,7 @@ Maybe<StringView> Player::getSecretPropertyView(String const& name) const {
return {};
}
+
Json Player::getSecretProperty(String const& name, Json defaultValue) const {
if (auto tag = m_effectsAnimator->globalTagPtr(secretProprefix + name)) {
DataStreamExternalBuffer buffer(tag->utf8Ptr(), tag->utf8Size());