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
};
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 {
public:
CollisionSet();

View File

@ -4,7 +4,17 @@
namespace Star {
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.materialHueShift);
@ -12,7 +22,14 @@ DataStream& operator>>(DataStream& ds, PlaceMaterial& 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.materialHueShift);

View File

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

View File

@ -1378,7 +1378,10 @@ TileModificationList WorldServer::doApplyTileModifications(TileModificationList
tile->foregroundHueShift = m_worldTemplate->biomeMaterialHueShift(tile->blockBiomeIndex, placeMaterial->material);
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) {
// Remove the foreground mod if removing the foreground.
tile->foregroundMod = NoModId;

View File

@ -1912,7 +1912,7 @@ namespace LuaBindings {
} else if (layerName == "background") {
layer = TileLayer::Background;
} else {
throw StarException(strf("Unsupported damageTile layer {}", layerName));
throw StarException(strf("Unsupported tile layer {}", layerName));
}
unsigned harvestLevel = 999;
@ -1942,15 +1942,28 @@ namespace LuaBindings {
PlaceMaterial placeMaterial;
auto layerName = arg2;
if (layerName == "foreground") {
placeMaterial.layer = TileLayer::Foreground;
} else if (layerName == "background") {
placeMaterial.layer = TileLayer::Background;
} else {
throw StarException(strf("Unsupported damageTile layer {}", layerName));
std::string layerName = arg2.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 == "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 materialDatabase = Root::singleton().materialDatabase();
if (!materialDatabase->materialNames().contains(materialName))
@ -1976,7 +1989,7 @@ namespace LuaBindings {
} else if (layerName == "background") {
placeMod.layer = TileLayer::Background;
} else {
throw StarException(strf("Unsupported damageTile layer {}", layerName));
throw StarException(strf("Unsupported tile layer {}", layerName));
}
auto modName = arg3;