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

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchililisoup <rebot333gaming@gmail.com>2025-03-23 14:11:21 -0600
committerchililisoup <rebot333gaming@gmail.com>2025-03-23 14:11:21 -0600
commit2b4c762b6b1da745cabe6810187fc34cb546e0cb (patch)
tree3553abb3423320dc5879f7e12d58a11c67593f46
parentc484b1a67230f938493de16026ca3a2dd7269a2c (diff)
block swapping lua support
-rw-r--r--doc/lua/openstarbound/world.md12
-rw-r--r--source/game/StarWorldServer.cpp2
-rw-r--r--source/game/scripting/StarWorldLuaBindings.cpp72
-rw-r--r--source/game/scripting/StarWorldLuaBindings.hpp2
4 files changed, 87 insertions, 1 deletions
diff --git a/doc/lua/openstarbound/world.md b/doc/lua/openstarbound/world.md
index 281fd70..8e0fef3 100644
--- a/doc/lua/openstarbound/world.md
+++ b/doc/lua/openstarbound/world.md
@@ -65,3 +65,15 @@ Calls a function in the specified world script context.
?
---
+
+#### `bool` world.replaceMaterials(`List<Vec2I>` positions, `String` layerName, `String` materialName, [`int` hueShift], [`bool` enableDrops])
+
+Attempts to replace existing materials with the specified material in the specified positions and layer. Positions with no preexisting material will be skipped. Returns `true` if the placement succeeds and `false` otherwise.
+
+---
+
+#### `bool` world.replaceMaterialArea(`Vec2F` center, `float` radius, `String` layerName, `String` materialName, [`int` hueShift], [`bool` enableDrops])
+
+Identical to world.replaceMaterials but applies to tiles in a circular radius around the specified center point.
+
+---
diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp
index 9d53d54..b58c41d 100644
--- a/source/game/StarWorldServer.cpp
+++ b/source/game/StarWorldServer.cpp
@@ -893,7 +893,7 @@ bool WorldServer::replaceTile(Vec2I const& pos, TileModification const& modifica
if (auto tile = m_tileArray->modifyTile(pos)) {
auto damageParameters = WorldImpl::tileDamageParameters(tile, placeMaterial->layer, tileDamage);
- bool harvested = tileDamage.harvestLevel >= damageParameters.requiredHarvestLevel();
+ bool harvested = tileDamage.amount >= 0 && tileDamage.harvestLevel >= damageParameters.requiredHarvestLevel();
auto damage = placeMaterial->layer == TileLayer::Foreground ? tile->foregroundDamage : tile->backgroundDamage;
Vec2F dropPosition = centerOfTile(pos);
diff --git a/source/game/scripting/StarWorldLuaBindings.cpp b/source/game/scripting/StarWorldLuaBindings.cpp
index f5d9172..b2c94a4 100644
--- a/source/game/scripting/StarWorldLuaBindings.cpp
+++ b/source/game/scripting/StarWorldLuaBindings.cpp
@@ -599,6 +599,8 @@ namespace LuaBindings {
callbacks.registerCallbackWithSignature<bool, List<Vec2I>, String, Vec2F, String, float, Maybe<unsigned>, Maybe<EntityId>>("damageTiles", bind(WorldEnvironmentCallbacks::damageTiles, world, _1, _2, _3, _4, _5, _6, _7));
callbacks.registerCallbackWithSignature<bool, Vec2F, float, String, Vec2F, String, float, Maybe<unsigned>, Maybe<EntityId>>("damageTileArea", bind(WorldEnvironmentCallbacks::damageTileArea, world, _1, _2, _3, _4, _5, _6, _7, _8));
callbacks.registerCallbackWithSignature<bool, Vec2I, String, String, Maybe<int>, bool>("placeMaterial", bind(WorldEnvironmentCallbacks::placeMaterial, world, _1, _2, _3, _4, _5));
+ callbacks.registerCallbackWithSignature<bool, List<Vec2I>, String, String, Maybe<int>, bool>("replaceMaterials", bind(WorldEnvironmentCallbacks::replaceMaterials, world, _1, _2, _3, _4, _5));
+ callbacks.registerCallbackWithSignature<bool, Vec2F, float, String, String, Maybe<int>, bool>("replaceMaterialArea", bind(WorldEnvironmentCallbacks::replaceMaterialArea, world, _1, _2, _3, _4, _5, _6));
callbacks.registerCallbackWithSignature<bool, Vec2I, String, String, Maybe<int>, bool>("placeMod", bind(WorldEnvironmentCallbacks::placeMod, world, _1, _2, _3, _4, _5));
callbacks.registerCallback("radialTileQuery", [world](Vec2F center, float radius, String layerName) -> List<Vec2I> {
@@ -2019,6 +2021,76 @@ namespace LuaBindings {
return world->modifyTile(tilePosition, placeMaterial, allowOverlap);
}
+ bool WorldEnvironmentCallbacks::replaceMaterials(World* world,
+ List<Vec2I> const& tilePositions,
+ String const& layer,
+ String const& materialName,
+ Maybe<int> const& hueShift,
+ bool enableDrops) {
+ PlaceMaterial placeMaterial;
+
+ std::string layerName = layer.utf8();
+ auto split = layerName.find_first_of('+');
+ if (split != NPos) {
+ auto overrideName = layerName.substr(split + 1);
+ layerName = layerName.substr(0, split);
+ if (overrideName == "empty" || overrideName == "none")
+ placeMaterial.collisionOverride = TileCollisionOverride::Empty;
+ else if (overrideName == "block")
+ placeMaterial.collisionOverride = TileCollisionOverride::Block;
+ else if (overrideName == "platform")
+ placeMaterial.collisionOverride = TileCollisionOverride::Platform;
+ else
+ throw StarException(strf("Unsupported collision override {}", overrideName));
+ }
+
+ if (layerName == "foreground")
+ placeMaterial.layer = TileLayer::Foreground;
+ else if (layerName == "background")
+ placeMaterial.layer = TileLayer::Background;
+ else
+ throw StarException(strf("Unsupported tile layer {}", layerName));
+
+ auto materialDatabase = Root::singleton().materialDatabase();
+ if (!materialDatabase->materialNames().contains(materialName))
+ throw StarException(strf("Unknown material name {}", materialName));
+ placeMaterial.material = materialDatabase->materialId(materialName);
+
+ if (hueShift)
+ placeMaterial.materialHueShift = (MaterialHue)*hueShift;
+
+ TileModificationList modifications;
+ for (auto pos : tilePositions) {
+ if (!world->isTileConnectable(pos, placeMaterial.layer, true))
+ continue;
+ modifications.emplaceAppend(pos, placeMaterial);
+ }
+
+ if (modifications.empty())
+ return true;
+
+ TileDamage damage;
+ if (enableDrops) {
+ damage.amount = 1.0f;
+ damage.harvestLevel = 999;
+ } else {
+ damage.amount = -1.0f;
+ }
+
+ return world->replaceTiles(modifications, damage).empty();;
+ }
+
+ bool WorldEnvironmentCallbacks::replaceMaterialArea(World* world,
+ Vec2F center,
+ float radius,
+ String const& layer,
+ String const& materialName,
+ Maybe<int> const& hueShift,
+ bool enableDrops) {
+ auto tiles = tileAreaBrush(radius, center, false);
+ return replaceMaterials(world, tiles, layer, materialName, hueShift, enableDrops);
+ }
+
bool WorldEnvironmentCallbacks::placeMod(World* world, Vec2I const& arg1, String const& arg2, String const& arg3, Maybe<int> const& arg4, bool arg5) {
auto tilePosition = arg1;
diff --git a/source/game/scripting/StarWorldLuaBindings.hpp b/source/game/scripting/StarWorldLuaBindings.hpp
index 3cb8c72..3f08a77 100644
--- a/source/game/scripting/StarWorldLuaBindings.hpp
+++ b/source/game/scripting/StarWorldLuaBindings.hpp
@@ -178,6 +178,8 @@ namespace LuaBindings {
bool damageTiles(World* world, List<Vec2I> const& arg1, String const& arg2, Vec2F const& arg3, String const& arg4, float arg5, Maybe<unsigned> const& arg6, Maybe<EntityId> sourceEntity);
bool damageTileArea(World* world, Vec2F center, float radius, String layer, Vec2F sourcePosition, String damageType, float damage, Maybe<unsigned> const& harvestLevel, Maybe<EntityId> sourceEntity);
bool placeMaterial(World* world, Vec2I const& arg1, String const& arg2, String const& arg3, Maybe<int> const& arg4, bool arg5);
+ bool replaceMaterials(World* world, List<Vec2I> const& tilePositions, String const& layer, String const& materialName, Maybe<int> const& hueShift, bool enableDrops);
+ bool replaceMaterialArea(World* world, Vec2F center, float radius, String const& layer, String const& materialName, Maybe<int> const& hueShift, bool enableDrops);
bool placeMod(World* world, Vec2I const& arg1, String const& arg2, String const& arg3, Maybe<int> const& arg4, bool arg5);
}
}