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

summaryrefslogtreecommitdiff
path: root/source/game
diff options
context:
space:
mode:
authorchililisoup <rebot333gaming@gmail.com>2025-03-23 18:23:11 -0600
committerchililisoup <rebot333gaming@gmail.com>2025-03-23 18:23:11 -0600
commit83f090f0ca79c4006ef2f1fca2d6b6876661e08c (patch)
treeb3d615195d2b973a98ec489c1516f3421634e4b8 /source/game
parent2b4c762b6b1da745cabe6810187fc34cb546e0cb (diff)
more block swap fixes
Diffstat (limited to 'source/game')
-rw-r--r--source/game/StarNetPackets.cpp8
-rw-r--r--source/game/StarNetPackets.hpp3
-rw-r--r--source/game/StarWorldClient.cpp4
-rw-r--r--source/game/StarWorldClient.hpp2
-rw-r--r--source/game/StarWorldServer.cpp46
-rw-r--r--source/game/StarWorldServer.hpp2
-rw-r--r--source/game/interfaces/StarWorld.hpp2
-rw-r--r--source/game/items/StarMaterialItem.cpp108
-rw-r--r--source/game/items/StarMaterialItem.hpp2
9 files changed, 107 insertions, 70 deletions
diff --git a/source/game/StarNetPackets.cpp b/source/game/StarNetPackets.cpp
index dfe3ff1..4b16ce8 100644
--- a/source/game/StarNetPackets.cpp
+++ b/source/game/StarNetPackets.cpp
@@ -750,19 +750,21 @@ void ModifyTileListPacket::write(DataStream& ds) const {
ds.write(allowEntityOverlap);
}
-ReplaceTileListPacket::ReplaceTileListPacket() {}
+ReplaceTileListPacket::ReplaceTileListPacket() : applyDamage() {}
-ReplaceTileListPacket::ReplaceTileListPacket(TileModificationList modifications, TileDamage tileDamage)
- : modifications(modifications), tileDamage(std::move(tileDamage)) {}
+ReplaceTileListPacket::ReplaceTileListPacket(TileModificationList modifications, TileDamage tileDamage, bool applyDamage)
+ : modifications(modifications), tileDamage(std::move(tileDamage)), applyDamage(applyDamage) {}
void ReplaceTileListPacket::read(DataStream& ds) {
ds.readContainer(modifications);
ds.read(tileDamage);
+ ds.read(applyDamage);
}
void ReplaceTileListPacket::write(DataStream& ds) const {
ds.writeContainer(modifications);
ds.write(tileDamage);
+ ds.write(applyDamage);
}
DamageTileGroupPacket::DamageTileGroupPacket() : layer(TileLayer::Foreground) {}
diff --git a/source/game/StarNetPackets.hpp b/source/game/StarNetPackets.hpp
index 349191f..8db5c03 100644
--- a/source/game/StarNetPackets.hpp
+++ b/source/game/StarNetPackets.hpp
@@ -632,13 +632,14 @@ struct ModifyTileListPacket : PacketBase<PacketType::ModifyTileList> {
struct ReplaceTileListPacket : PacketBase<PacketType::ReplaceTileList> {
ReplaceTileListPacket();
- ReplaceTileListPacket(TileModificationList modifications, TileDamage tileDamage);
+ ReplaceTileListPacket(TileModificationList modifications, TileDamage tileDamage, bool applyDamage);
void read(DataStream& ds) override;
void write(DataStream& ds) const override;
TileModificationList modifications;
TileDamage tileDamage;
+ bool applyDamage;
};
struct DamageTileGroupPacket : PacketBase<PacketType::DamageTileGroup> {
diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp
index 80d84c7..51fe883 100644
--- a/source/game/StarWorldClient.cpp
+++ b/source/game/StarWorldClient.cpp
@@ -375,7 +375,7 @@ TileModificationList WorldClient::applyTileModifications(TileModificationList co
return failures;
}
-TileModificationList WorldClient::replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage) {
+TileModificationList WorldClient::replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage, bool applyDamage) {
if (!inWorld())
return {};
@@ -392,7 +392,7 @@ TileModificationList WorldClient::replaceTiles(TileModificationList const& modif
failures.append(pair);
}
- m_outgoingPackets.append(make_shared<ReplaceTileListPacket>(std::move(success), tileDamage));
+ m_outgoingPackets.append(make_shared<ReplaceTileListPacket>(std::move(success), tileDamage, applyDamage));
return failures;
}
diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp
index 195a95c..5ce3997 100644
--- a/source/game/StarWorldClient.hpp
+++ b/source/game/StarWorldClient.hpp
@@ -53,7 +53,7 @@ public:
LiquidLevel liquidLevel(RectF const& region) const override;
TileModificationList validTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) const override;
TileModificationList applyTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) override;
- TileModificationList replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage) override;
+ TileModificationList replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage, bool applyDamage = false) override;
bool damageWouldDestroy(Vec2I const& pos, TileLayer layer, TileDamage const& tileDamage) const override;
EntityPtr entity(EntityId entityId) const override;
void addEntity(EntityPtr const& entity, EntityId entityId = NullEntityId) override;
diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp
index b58c41d..5796b65 100644
--- a/source/game/StarWorldServer.cpp
+++ b/source/game/StarWorldServer.cpp
@@ -374,7 +374,7 @@ void WorldServer::handleIncomingPackets(ConnectionId clientId, List<PacketPtr> c
clientInfo->outgoingPackets.append(make_shared<TileModificationFailurePacket>(unappliedModifications));
} else if (auto rtpacket = as<ReplaceTileListPacket>(packet)) {
- auto unappliedModifications = replaceTiles(rtpacket->modifications, rtpacket->tileDamage);
+ auto unappliedModifications = replaceTiles(rtpacket->modifications, rtpacket->tileDamage, rtpacket->applyDamage);
if (!unappliedModifications.empty())
clientInfo->outgoingPackets.append(make_shared<TileModificationFailurePacket>(unappliedModifications));
@@ -907,14 +907,48 @@ bool WorldServer::replaceTile(Vec2I const& pos, TileModification const& modifica
return false;
}
-TileModificationList WorldServer::replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage) {
+TileModificationList WorldServer::replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage, bool applyDamage) {
TileModificationList success, failures;
- for (auto pair : modificationList) {
- if (replaceTile(pair.first, pair.second, tileDamage))
- success.append(pair);
- else
+ if (applyDamage) {
+ List<Vec2I> toDamage;
+ TileLayer layer;
+
+ for (auto pair : modificationList) {
+ if (auto placeMaterial = pair.second.ptr<PlaceMaterial>()) {
+ layer = placeMaterial->layer;
+
+ if (placeMaterial->material == material(pair.first, layer)) {
+ failures.append(pair);
+ continue;
+ }
+
+ if (damageWouldDestroy(pair.first, layer, tileDamage)) {
+ if (replaceTile(pair.first, pair.second, tileDamage))
+ success.append(pair);
+ else
+ failures.append(pair);
+ continue;
+ }
+
+ toDamage.append(pair.first);
+ success.append(pair);
+ continue;
+ }
+
failures.append(pair);
+ }
+
+ if (!toDamage.empty())
+ damageTiles(toDamage, layer, Vec2F(), tileDamage, Maybe<EntityId>());
+
+ } else {
+ for (auto pair : modificationList) {
+ if (replaceTile(pair.first, pair.second, tileDamage))
+ success.append(pair);
+ else
+ failures.append(pair);
+ }
}
failures.appendAll(doApplyTileModifications(success, true, false, false));
diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp
index 2e6d6a8..4a0e87a 100644
--- a/source/game/StarWorldServer.hpp
+++ b/source/game/StarWorldServer.hpp
@@ -136,7 +136,7 @@ public:
TileModificationList validTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) const override;
TileModificationList applyTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) override;
bool replaceTile(Vec2I const& pos, TileModification const& modification, TileDamage const& tileDamage);
- TileModificationList replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage) override;
+ TileModificationList replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage, bool applyDamage = false) override;
bool damageWouldDestroy(Vec2I const& pos, TileLayer layer, TileDamage const& tileDamage) const override;
EntityPtr entity(EntityId entityId) const override;
void addEntity(EntityPtr const& entity, EntityId entityId = NullEntityId) override;
diff --git a/source/game/interfaces/StarWorld.hpp b/source/game/interfaces/StarWorld.hpp
index f2db119..5d97db1 100644
--- a/source/game/interfaces/StarWorld.hpp
+++ b/source/game/interfaces/StarWorld.hpp
@@ -48,7 +48,7 @@ public:
virtual TileModificationList applyTileModifications(TileModificationList const& modificationList, bool allowEntityOverlap) = 0;
// Swap existing tiles for ones defined in the modification list,
// and returns the modifications that could not be applied.
- virtual TileModificationList replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage) = 0;
+ virtual TileModificationList replaceTiles(TileModificationList const& modificationList, TileDamage const& tileDamage, bool applyDamage = false) = 0;
// If an applied damage would destroy a tile
virtual bool damageWouldDestroy(Vec2I const& pos, TileLayer layer, TileDamage const& tileDamage) const = 0;
diff --git a/source/game/items/StarMaterialItem.cpp b/source/game/items/StarMaterialItem.cpp
index a46fa98..41c09f3 100644
--- a/source/game/items/StarMaterialItem.cpp
+++ b/source/game/items/StarMaterialItem.cpp
@@ -10,7 +10,6 @@
#include "StarInput.hpp"
#include "StarTileDrawer.hpp"
#include "StarPlayer.hpp"
-#include "StarTools.hpp"
namespace Star {
@@ -211,10 +210,11 @@ void MaterialItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
? collisionKindFromOverride(m_collisionOverride)
: Root::singleton().materialDatabase()->materialCollisionKind(m_material);
+ size_t total = 0;
+
if (m_blockSwap && owner()->inToolRange(aimPosition))
- blockSwap(radius, layer);
+ total += blockSwap(radius, layer);
- size_t total = 0;
for (unsigned i = 0; i != steps; ++i) {
auto placementOrigin = aimPosition + diff * (1.0f - (static_cast<float>(i) / steps));
if (!owner()->inToolRange(placementOrigin))
@@ -247,20 +247,17 @@ void MaterialItem::endFire(FireMode, bool) {
m_lastAimPosition.reset();
}
-void MaterialItem::blockSwap(float radius, TileLayer layer) {
+size_t MaterialItem::blockSwap(float radius, TileLayer layer) {
Player* player = as<Player>(owner());
if (!player)
- return;
+ return 0;
ItemPtr beamAxePtr = player->essentialItem(EssentialItem::BeamAxe);
if (!beamAxePtr)
- return;
+ return 0;
Item* beamAxe = beamAxePtr.get();
- BeamMiningTool* tool = as<BeamMiningTool>(beamAxe);
- if (!tool)
- return;
-
+
List<Vec2I> swapPositions;
for (Vec2I& pos : tileArea(radius, owner()->aimPosition())) {
if (!world()->isTileConnectable(pos, layer, true))
@@ -273,19 +270,53 @@ void MaterialItem::blockSwap(float radius, TileLayer layer) {
}
if (swapPositions.empty())
- return;
+ return 0;
+ if (swapPositions.size() > count())
+ swapPositions.resize(count());
+
+ TileDamage damage;
+ damage.type = TileDamageType::Beamish;
+ damage.amount = beamAxe->instanceValue("tileDamage", beamAxe->instanceValue("primaryAbility.tileDamage", 1.0f)).toFloat();
+ damage.harvestLevel = beamAxe->instanceValue("harvestLevel", beamAxe->instanceValue("primaryAbility.harvestLevel", 1)).toUInt();
+
+ TileModificationList toSwap;
+ List<Vec2I> willDamage;
+ for (auto pos : swapPositions) {
+ toSwap.emplaceAppend(pos, PlaceMaterial{layer, materialId(), placementHueShift(pos), m_collisionOverride});
+ if (!world()->damageWouldDestroy(pos, layer, damage))
+ willDamage.append(pos);
+ }
+ size_t success;
+ size_t failed = world()->replaceTiles(toSwap, damage, true).size();
+
+ if (failed < toSwap.size()) {
+ success = toSwap.size() - failed;
+ consume(success);
+ } else {
+ List<Vec2I> toDamage;
+
+ for (auto pair : toSwap)
+ toDamage.append(pair.first);
+
+ world()->damageTiles(toDamage, layer, owner()->position(), damage, owner()->entityId());
+ }
+
+ if (willDamage.empty())
+ return success;
+
auto materialDatabase = Root::singleton().materialDatabase();
auto assets = Root::singleton().assets();
String blockSound;
- for (auto pos : swapPositions) {
+ for (auto pos : willDamage) {
blockSound = materialDatabase->miningSound(world()->material(pos, layer), world()->mod(pos, layer));
if (!blockSound.empty())
break;
}
+
if (blockSound.empty()) {
- for (auto pos : swapPositions) {
+ for (auto pos : willDamage) {
blockSound = materialDatabase->footstepSound(world()->material(pos, layer), world()->mod(pos, layer));
if (!blockSound.empty()
&& blockSound != assets->json("/client.config:defaultFootstepSound").toString())
@@ -293,51 +324,20 @@ void MaterialItem::blockSwap(float radius, TileLayer layer) {
}
}
- TileDamage damage;
- damage.type = TileDamageType::Beamish;
- damage.amount = beamAxe->instanceValue("tileDamage", 1.0f).toFloat();
- damage.harvestLevel = beamAxe->instanceValue("harvestLevel", 1).toUInt();
+ owner()->addSound(blockSound, assets->json("/sfx.config:miningBlockVolume").toFloat());
- TileModificationList toSwap;
- List<Vec2I> toDamage;
- for (auto pos : swapPositions) {
- if (world()->damageWouldDestroy(pos, layer, damage))
- toSwap.emplaceAppend(pos, PlaceMaterial{layer, materialId(), placementHueShift(pos), m_collisionOverride});
- else
- toDamage.append(pos);
+ auto strikeSounds = beamAxe->instanceValue("strikeSounds");
+ if (!strikeSounds.isNull()) {
+ owner()->addSound(
+ Random::randValueFrom(jsonToStringList(strikeSounds)),
+ assets->json("/sfx.config:miningToolVolume").toFloat()
+ );
}
- if (toSwap.size() > count())
- toSwap.resize(count());
- if (toDamage.size() + toSwap.size() > count())
- toDamage.resize(count() - toSwap.size());
+ if (FireableItem* item = as<FireableItem>(beamAxe))
+ setFireTimer(item->windupTime() + item->cooldownTime());
- if (!toSwap.empty()) {
- size_t failed = world()->replaceTiles(toSwap, damage).size();
-
- if (failed < toSwap.size())
- consume(toSwap.size() - failed);
- else {
- for (auto pair : toSwap)
- toDamage.append(pair.first);
- if (toDamage.size() > count())
- toDamage.resize(count());
- }
- }
-
- if (!toDamage.empty()) {
- auto damageResult = world()->damageTiles(toDamage, layer, owner()->position(), damage, owner()->entityId());
- if (damageResult == TileDamageResult::Protected) {
- blockSound = assets->json("/client.config:defaultDingSound").toString();
- }
- }
-
- owner()->addSound(
- Random::randValueFrom(jsonToStringList(beamAxe->instanceValue("strikeSounds"))),
- assets->json("/sfx.config:miningToolVolume").toFloat()
- );
- owner()->addSound(blockSound, assets->json("/sfx.config:miningBlockVolume").toFloat());
- setFireTimer(tool->windupTime() + tool->cooldownTime());
+ return success;
}
MaterialId MaterialItem::materialId() const {
diff --git a/source/game/items/StarMaterialItem.hpp b/source/game/items/StarMaterialItem.hpp
index cb423be..77ff473 100644
--- a/source/game/items/StarMaterialItem.hpp
+++ b/source/game/items/StarMaterialItem.hpp
@@ -46,7 +46,7 @@ public:
List<PreviewTile> previewTiles(bool shifting) const override;
List<Drawable> const& generatedPreview(Vec2I position = {}) const;
private:
- void blockSwap(float radius, TileLayer layer);
+ size_t blockSwap(float radius, TileLayer layer);
void updatePropertiesFromPlayer(Player* player);
float calcRadius(bool shifting) const;
List<Vec2I>& tileArea(float radius, Vec2F const& position) const;