Allow overriding placed collision kind ("""overground""") from world.placeMaterial

This commit is contained in:
Kae 2023-08-19 18:26:52 +10:00
parent f22eed8304
commit ec4f70340e
6 changed files with 71 additions and 14 deletions

View File

@ -18,6 +18,26 @@ enum class CollisionKind : uint8_t {
Block Block
}; };
enum class TileCollisionOverride : uint8_t {
None,
Empty,
Platform,
Dynamic
};
inline CollisionKind collisionKindFromOverride(TileCollisionOverride const& over) {
switch (over) {
case TileCollisionOverride::Empty:
return CollisionKind::None;
case TileCollisionOverride::Platform:
return CollisionKind::Platform;
case TileCollisionOverride::Dynamic:
return CollisionKind::Dynamic;
default:
return CollisionKind::Null;
}
}
class CollisionSet { class CollisionSet {
public: public:
CollisionSet(); CollisionSet();

View File

@ -4,7 +4,17 @@
namespace Star { namespace Star {
DataStream& operator>>(DataStream& ds, PlaceMaterial& tileMaterialPlacement) { DataStream& operator>>(DataStream& ds, PlaceMaterial& tileMaterialPlacement) {
ds.read(tileMaterialPlacement.layer); uint8_t layer;
ds.read(layer);
if (layer > 1) {
tileMaterialPlacement.layer = TileLayer::Foreground;
tileMaterialPlacement.collisionOverride = (TileCollisionOverride)(layer - 1);
}
else {
tileMaterialPlacement.layer = (TileLayer)layer;
tileMaterialPlacement.collisionOverride = TileCollisionOverride::None;
}
ds.read(tileMaterialPlacement.material); ds.read(tileMaterialPlacement.material);
ds.read(tileMaterialPlacement.materialHueShift); ds.read(tileMaterialPlacement.materialHueShift);
@ -12,7 +22,14 @@ DataStream& operator>>(DataStream& ds, PlaceMaterial& tileMaterialPlacement) {
} }
DataStream& operator<<(DataStream& ds, PlaceMaterial const& tileMaterialPlacement) { DataStream& operator<<(DataStream& ds, PlaceMaterial const& tileMaterialPlacement) {
ds.write(tileMaterialPlacement.layer); if (tileMaterialPlacement.collisionOverride != TileCollisionOverride::None
&& tileMaterialPlacement.layer == TileLayer::Foreground) {
uint8_t layer = (uint8_t)tileMaterialPlacement.collisionOverride;
ds.write(++layer);
}
else
ds.write(tileMaterialPlacement.layer);
ds.write(tileMaterialPlacement.material); ds.write(tileMaterialPlacement.material);
ds.write(tileMaterialPlacement.materialHueShift); ds.write(tileMaterialPlacement.materialHueShift);

View File

@ -4,16 +4,17 @@
#include "StarDataStream.hpp" #include "StarDataStream.hpp"
#include "StarVariant.hpp" #include "StarVariant.hpp"
#include "StarGameTypes.hpp" #include "StarGameTypes.hpp"
#include "StarCollisionBlock.hpp"
namespace Star { namespace Star {
struct PlaceMaterial { struct PlaceMaterial {
TileLayer layer; TileLayer layer;
MaterialId material; MaterialId material;
// If the material hue shift is not set it will get the natural hue shift for // If the material hue shift is not set it will get the natural hue shift for
// the environment. // the environment.
Maybe<MaterialHue> materialHueShift; Maybe<MaterialHue> materialHueShift;
TileCollisionOverride collisionOverride = TileCollisionOverride::None;
}; };
DataStream& operator>>(DataStream& ds, PlaceMaterial& tileMaterialPlacement); DataStream& operator>>(DataStream& ds, PlaceMaterial& tileMaterialPlacement);
DataStream& operator<<(DataStream& ds, PlaceMaterial const& tileMaterialPlacement); DataStream& operator<<(DataStream& ds, PlaceMaterial const& tileMaterialPlacement);

View File

@ -2224,7 +2224,10 @@ void WorldClient::informTilePrediction(Vec2I const& pos, TileModification const&
if (placeMaterial->layer == TileLayer::Foreground) { if (placeMaterial->layer == TileLayer::Foreground) {
p.foreground = placeMaterial->material; p.foreground = placeMaterial->material;
p.foregroundHueShift = placeMaterial->materialHueShift; p.foregroundHueShift = placeMaterial->materialHueShift;
p.collision = Root::singleton().materialDatabase()->materialCollisionKind(placeMaterial->material); if (placeMaterial->collisionOverride != TileCollisionOverride::None)
p.collision = collisionKindFromOverride(placeMaterial->collisionOverride);
else
p.collision = Root::singleton().materialDatabase()->materialCollisionKind(placeMaterial->material);
dirtyCollision(RectI::withSize(pos, { 1, 1 })); dirtyCollision(RectI::withSize(pos, { 1, 1 }));
} else { } else {
p.background = placeMaterial->material; p.background = placeMaterial->material;

View File

@ -1378,7 +1378,10 @@ TileModificationList WorldServer::doApplyTileModifications(TileModificationList
tile->foregroundHueShift = m_worldTemplate->biomeMaterialHueShift(tile->blockBiomeIndex, placeMaterial->material); tile->foregroundHueShift = m_worldTemplate->biomeMaterialHueShift(tile->blockBiomeIndex, placeMaterial->material);
tile->foregroundColorVariant = DefaultMaterialColorVariant; tile->foregroundColorVariant = DefaultMaterialColorVariant;
tile->updateCollision(materialDatabase->materialCollisionKind(tile->foreground)); if (placeMaterial->collisionOverride != TileCollisionOverride::None)
tile->updateCollision(collisionKindFromOverride(placeMaterial->collisionOverride));
else
tile->updateCollision(materialDatabase->materialCollisionKind(tile->foreground));
if (tile->foreground == EmptyMaterialId) { if (tile->foreground == EmptyMaterialId) {
// Remove the foreground mod if removing the foreground. // Remove the foreground mod if removing the foreground.
tile->foregroundMod = NoModId; tile->foregroundMod = NoModId;

View File

@ -1912,7 +1912,7 @@ namespace LuaBindings {
} else if (layerName == "background") { } else if (layerName == "background") {
layer = TileLayer::Background; layer = TileLayer::Background;
} else { } else {
throw StarException(strf("Unsupported damageTile layer {}", layerName)); throw StarException(strf("Unsupported tile layer {}", layerName));
} }
unsigned harvestLevel = 999; unsigned harvestLevel = 999;
@ -1942,15 +1942,28 @@ namespace LuaBindings {
PlaceMaterial placeMaterial; PlaceMaterial placeMaterial;
auto layerName = arg2; std::string layerName = arg2.utf8();
if (layerName == "foreground") { auto split = layerName.find_first_of('+');
placeMaterial.layer = TileLayer::Foreground; if (split != NPos) {
} else if (layerName == "background") { auto overrideName = layerName.substr(split + 1);
placeMaterial.layer = TileLayer::Background; layerName = layerName.substr(0, split);
} else { if (overrideName == "empty" || overrideName == "none")
throw StarException(strf("Unsupported damageTile layer {}", layerName)); placeMaterial.collisionOverride = TileCollisionOverride::Empty;
else if (overrideName == "dynamic" || overrideName == "block")
placeMaterial.collisionOverride = TileCollisionOverride::Dynamic;
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 materialName = arg3; auto materialName = arg3;
auto materialDatabase = Root::singleton().materialDatabase(); auto materialDatabase = Root::singleton().materialDatabase();
if (!materialDatabase->materialNames().contains(materialName)) if (!materialDatabase->materialNames().contains(materialName))
@ -1976,7 +1989,7 @@ namespace LuaBindings {
} else if (layerName == "background") { } else if (layerName == "background") {
placeMod.layer = TileLayer::Background; placeMod.layer = TileLayer::Background;
} else { } else {
throw StarException(strf("Unsupported damageTile layer {}", layerName)); throw StarException(strf("Unsupported tile layer {}", layerName));
} }
auto modName = arg3; auto modName = arg3;