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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-08-18 13:06:07 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-08-18 13:06:07 +1000
commitc11d20894bf648e812144b2ff55d18548ab2ecaf (patch)
treebc8c624da7d5b67812ad6ae76741ad24d04699b1
parent90267c610530d8be1c14288fc742b73d3473050f (diff)
Item Drop Improvements
-rw-r--r--assets/opensb/itemdrop.config.patch8
-rw-r--r--assets/opensb/sfx/interface/item_pickup.oggbin0 -> 6399 bytes
-rw-r--r--source/game/StarItemDrop.cpp62
-rw-r--r--source/game/StarItemDrop.hpp14
-rw-r--r--source/game/StarPlayer.cpp2
5 files changed, 73 insertions, 13 deletions
diff --git a/assets/opensb/itemdrop.config.patch b/assets/opensb/itemdrop.config.patch
new file mode 100644
index 0000000..cd3d445
--- /dev/null
+++ b/assets/opensb/itemdrop.config.patch
@@ -0,0 +1,8 @@
+{
+ "directives" : "",
+ "pickupDistance" : 0.5,
+ "afterTakenLife" : 2.5,
+ "overheadTime" : 0.5,
+ "overheadApproach" : 2000,
+ "overheadRandomizedDistance" : 0.25
+} \ No newline at end of file
diff --git a/assets/opensb/sfx/interface/item_pickup.ogg b/assets/opensb/sfx/interface/item_pickup.ogg
new file mode 100644
index 0000000..9b72860
--- /dev/null
+++ b/assets/opensb/sfx/interface/item_pickup.ogg
Binary files differ
diff --git a/source/game/StarItemDrop.cpp b/source/game/StarItemDrop.cpp
index 7940e63..d600159 100644
--- a/source/game/StarItemDrop.cpp
+++ b/source/game/StarItemDrop.cpp
@@ -7,6 +7,7 @@
#include "StarEntityRendering.hpp"
#include "StarWorld.hpp"
#include "StarDataStreamExtra.hpp"
+#include "StarPlayer.hpp"
namespace Star {
@@ -179,13 +180,25 @@ RectF ItemDrop::collisionArea() const {
void ItemDrop::update(float dt, uint64_t) {
if (isMaster()) {
if (m_owningEntity.get() != NullEntityId) {
- auto owningEntity = world()->entity(m_owningEntity.get());
- if (owningEntity) {
+ if (auto owningEntity = world()->entity(m_owningEntity.get())) {
Vec2F position = m_movementController.position();
- Vec2F diff = world()->geometry().diff(owningEntity->position(), position);
+ bool overhead = m_dropAge.elapsedTime() < m_overheadTime;
+ Vec2F targetPosition = owningEntity->position();
+ if (overhead) {
+ targetPosition += m_overheadOffset;
+ auto rect = owningEntity->collisionArea();
+ if (!rect.isNull())
+ targetPosition[1] += rect.yMax() + 1.5;
+ else
+ targetPosition[1] += 1.5f;
+ }
+ Vec2F diff = world()->geometry().diff(targetPosition, position);
float magnitude = diff.magnitude();
- m_movementController.approachVelocity(diff.normalized() * m_config.getFloat("velocity"), m_config.getFloat("velocityApproach"));
- if (magnitude < m_config.getFloat("pickupDistance"))
+ Vec2F velocity = diff.normalized() * m_velocity * min(1.0f, magnitude);
+ if (auto playerEntity = as<Player>(owningEntity))
+ velocity += playerEntity->velocity();
+ m_movementController.approachVelocity(velocity, overhead ? m_overheadApproach : m_velocityApproach);
+ if (!overhead && magnitude < m_pickupDistance)
m_mode.set(Mode::Dead);
} else {
@@ -199,12 +212,12 @@ void ItemDrop::update(float dt, uint64_t) {
m_movementController.applyParameters(parameters);
} else {
// Rarely, check for other drops near us and combine with them if possible.
- if (canTake() && m_mode.get() == Mode::Available && Random::randf() < m_config.getFloat("combineChance")) {
- world()->findEntity(RectF::withCenter(position(), Vec2F::filled(m_config.getFloat("combineRadius"))), [&](EntityPtr const& entity) {
+ if (canTake() && m_mode.get() == Mode::Available && Random::randf() < m_combineChance) {
+ world()->findEntity(RectF::withCenter(position(), Vec2F::filled(m_combineRadius)), [&](EntityPtr const& entity) {
if (auto closeDrop = as<ItemDrop>(entity)) {
// Make sure not to try to merge with ourselves here.
if (closeDrop.get() != this && closeDrop->canTake()
- && vmag(position() - closeDrop->position()) < m_config.getFloat("combineRadius")) {
+ && vmag(position() - closeDrop->position()) < m_combineRadius) {
if (m_item->couldStack(closeDrop->item()) == closeDrop->item()->count()) {
m_item->stackWith(closeDrop->take());
m_dropAge.setElapsedTime(min(m_dropAge.elapsedTime(), closeDrop->m_dropAge.elapsedTime()));
@@ -240,10 +253,10 @@ void ItemDrop::update(float dt, uint64_t) {
m_mode.set(Mode::Available);
if (!m_eternal && m_mode.get() == Mode::Available && m_dropAge.elapsedTime() > m_item->timeToLive())
m_mode.set(Mode::Dead);
- if (m_mode.get() == Mode::Taken && m_dropAge.elapsedTime() > m_config.getFloat("afterTakenLife"))
+ if (m_mode.get() == Mode::Taken && m_dropAge.elapsedTime() > m_afterTakenLife)
m_mode.set(Mode::Dead);
- if (m_mode.get() <= Mode::Available && m_ageItemsTimer.elapsedTime() > m_config.getDouble("ageItemsEvery", 10)) {
+ if (m_mode.get() <= Mode::Available && m_ageItemsTimer.elapsedTime() > m_ageItemsEvery) {
Root::singleton().itemDatabase()->ageItem(m_item, m_ageItemsTimer.elapsedTime());
m_itemDescriptor.set(m_item->descriptor());
updateCollisionPoly();
@@ -261,9 +274,20 @@ bool ItemDrop::shouldDestroy() const {
}
void ItemDrop::render(RenderCallback* renderCallback) {
- for (auto& drawable : m_item->dropDrawables()) {
- drawable.translate(position());
- renderCallback->addDrawable(move(drawable), RenderLayerItemDrop);
+ if (!m_drawables) {
+ m_drawables = m_item->dropDrawables();
+ if (Directives dropDirectives = m_config.getString("directives", "")) {
+ for (auto& drawable : *m_drawables) {
+ if (drawable.isImage())
+ drawable.imagePart().addDirectives(dropDirectives, true);
+ }
+ }
+ }
+ EntityRenderLayer renderLayer = m_mode.get() == Mode::Taken ? RenderLayerForegroundTile : RenderLayerItemDrop;
+ Vec2F dropPosition = position();
+ for (auto& drawable : *m_drawables) {
+ drawable.position = dropPosition;
+ renderCallback->addDrawable(drawable, renderLayer);
}
}
@@ -339,6 +363,18 @@ ItemDrop::ItemDrop() {
m_netGroup.addNetElement(&m_movementController);
m_netGroup.addNetElement(&m_itemDescriptor);
+ m_afterTakenLife = m_config.getFloat("afterTakenLife");
+ m_overheadTime = m_config.getFloat("overheadTime");
+ m_pickupDistance = m_config.getFloat("pickupDistance");
+ m_velocity = m_config.getFloat("velocity");
+ m_velocityApproach = m_config.getFloat("velocityApproach");
+ m_overheadApproach = m_config.getFloat("overheadApproach");
+ m_overheadOffset = Vec2F(m_config.getFloat("overheadRandomizedDistance"), 0).rotate(Constants::pi * 2.0 * Random::randf());
+
+ m_combineChance = m_config.getFloat("combineChance");
+ m_combineRadius = m_config.getFloat("combineRadius");
+ m_ageItemsEvery = m_config.getDouble("ageItemsEvery", 10);
+
m_eternal = false;
}
diff --git a/source/game/StarItemDrop.hpp b/source/game/StarItemDrop.hpp
index 035a07d..25ea819 100644
--- a/source/game/StarItemDrop.hpp
+++ b/source/game/StarItemDrop.hpp
@@ -6,6 +6,7 @@
#include "StarItemDescriptor.hpp"
#include "StarGameTimers.hpp"
#include "StarEntity.hpp"
+#include "StarDrawable.hpp"
namespace Star {
@@ -96,6 +97,17 @@ private:
Json m_config;
ItemPtr m_item;
RectF m_boundBox;
+ float m_afterTakenLife;
+ float m_overheadTime;
+ float m_pickupDistance;
+ float m_velocity;
+ float m_velocityApproach;
+ float m_overheadApproach;
+ Vec2F m_overheadOffset;
+
+ float m_combineChance;
+ float m_combineRadius;
+ double m_ageItemsEvery;
NetElementTopGroup m_netGroup;
NetElementEnum<Mode> m_mode;
@@ -108,6 +120,8 @@ private:
EpochTimer m_dropAge;
GameTimer m_intangibleTimer;
EpochTimer m_ageItemsTimer;
+
+ Maybe<List<Drawable>> m_drawables;
};
}
diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp
index 5ee46c4..78bf250 100644
--- a/source/game/StarPlayer.cpp
+++ b/source/game/StarPlayer.cpp
@@ -1150,6 +1150,8 @@ ItemPtr Player::pickupItems(ItemPtr const& items) {
if (items->pickupSound().size()) {
m_effectsAnimator->setSoundPool("pickup", {items->pickupSound()});
+ float pitch = 1.f - ((float)items->count() / (float)items->maxStack()) * 0.5f;
+ m_effectsAnimator->setSoundPitchMultiplier("pickup", clamp(pitch * Random::randf(0.9f, 1.1f), 0.f, 2.f));
m_effectsAnimator->playSound("pickup");
}
auto itemDb = Root::singleton().itemDatabase();