diff options
author | chililisoup <rebot333gaming@gmail.com> | 2025-03-23 18:23:11 -0600 |
---|---|---|
committer | chililisoup <rebot333gaming@gmail.com> | 2025-03-23 18:23:11 -0600 |
commit | 83f090f0ca79c4006ef2f1fca2d6b6876661e08c (patch) | |
tree | b3d615195d2b973a98ec489c1516f3421634e4b8 /source/game | |
parent | 2b4c762b6b1da745cabe6810187fc34cb546e0cb (diff) |
more block swap fixes
Diffstat (limited to 'source/game')
-rw-r--r-- | source/game/StarNetPackets.cpp | 8 | ||||
-rw-r--r-- | source/game/StarNetPackets.hpp | 3 | ||||
-rw-r--r-- | source/game/StarWorldClient.cpp | 4 | ||||
-rw-r--r-- | source/game/StarWorldClient.hpp | 2 | ||||
-rw-r--r-- | source/game/StarWorldServer.cpp | 46 | ||||
-rw-r--r-- | source/game/StarWorldServer.hpp | 2 | ||||
-rw-r--r-- | source/game/interfaces/StarWorld.hpp | 2 | ||||
-rw-r--r-- | source/game/items/StarMaterialItem.cpp | 108 | ||||
-rw-r--r-- | source/game/items/StarMaterialItem.hpp | 2 |
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; |