Added Sand, Water, Lava Tiles physics.
This commit is contained in:
@@ -29,7 +29,6 @@ namespace CaveGame::Core
|
||||
|
||||
~Chunk()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// Constructs a chunk with empty (air) tiles, located at the given chunk-cell.
|
||||
@@ -53,7 +52,18 @@ namespace CaveGame::Core
|
||||
}
|
||||
|
||||
TileID GetTile(int x, int y) const;
|
||||
void SetTile(int x, int y, TileID t);
|
||||
void SetTile(int x, int y, TileID t, bool trigger_tile_updates = true);
|
||||
|
||||
void SetTileSilent(int x, int y, TileID t)
|
||||
{ SetTile(x, y, t, false); }
|
||||
|
||||
bool GetTileUpdateFlag(int x, int y) const {
|
||||
return tagged_for_update[x][y];
|
||||
}
|
||||
|
||||
void SetTileUpdateFlag(int x, int y, bool flag = true) {
|
||||
tagged_for_update[x][y] = flag;
|
||||
}
|
||||
|
||||
[[nodiscard]] Vector2 GetChunkCell() const;
|
||||
[[nodiscard]] Vector2 GetChunkRealCoordinates() const;
|
||||
@@ -101,6 +111,7 @@ namespace CaveGame::Core
|
||||
protected:
|
||||
Vector2 cell;
|
||||
TileID tiles[ChunkSize][ChunkSize];
|
||||
bool tagged_for_update[ChunkSize][ChunkSize];
|
||||
|
||||
};
|
||||
}
|
@@ -12,21 +12,15 @@ namespace CaveGame::Core
|
||||
public:
|
||||
virtual TileID GetTile(int x, int y) const = 0;
|
||||
virtual void SetTile(int x, int y, TileID tile) = 0;
|
||||
|
||||
virtual bool GetTileUpdateFlag(int x, int y) = 0;
|
||||
virtual void SetTileUpdateFlag(int x, int y, bool flag = true) = 0;
|
||||
virtual TileState GetTileState(int x, int y) const = 0;
|
||||
virtual void SetTileState(int x, int y, TileState state) = 0;
|
||||
|
||||
bool GrassSpreadable(int x, int y) const;
|
||||
|
||||
bool IsNonSolidTile(int x, int y) const;
|
||||
|
||||
bool GrassShouldSuffocate(int x, int y) const;
|
||||
|
||||
|
||||
bool IsSolidTile(int x, int y) const;
|
||||
|
||||
bool HasAdjacentOrDiagonalAirBlock(int x, int y) const;
|
||||
|
||||
bool HasAdjacentAirBlock(int x, int y) const;
|
||||
};
|
||||
}
|
@@ -135,6 +135,7 @@ namespace CaveGame::Core
|
||||
[[nodiscard]] std::string MnemonicID() const;
|
||||
std::string Name() const { return mnemonic_id; }
|
||||
virtual bool DoesRandomTicc() const { return false; }
|
||||
virtual bool DoesForcedTicc() const { return false;}
|
||||
virtual bool Solid() const { return false;}
|
||||
virtual void ForcedTicc(ITileMap* world, TileState state, int x, int y) {}
|
||||
virtual void RandomTicc(ITileMap* world, TileState state, int x, int y) {}
|
||||
@@ -152,6 +153,39 @@ namespace CaveGame::Core
|
||||
LiquidTile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet);
|
||||
LiquidTile(TileID numeric, const std::string& name, Color4 color);
|
||||
bool Solid() const override { return true;}
|
||||
bool DoesForcedTicc() const override { return true;}
|
||||
void ForcedTicc(ITileMap *world, TileState state, int x, int y) override {
|
||||
if (world->GetTile(x, y+1) == TileID::AIR) {
|
||||
world->SetTile(x, y+1, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->GetTile(x+1, y+1) == TileID::AIR) {
|
||||
world->SetTile(x+1, y+1, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->GetTile(x-1, y+1) == TileID::AIR) {
|
||||
world->SetTile(x-1, y+1, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->GetTile(x-1, y) == TileID::AIR) {
|
||||
world->SetTile(x-1, y, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->GetTile(x+1, y) == TileID::AIR) {
|
||||
world->SetTile(x+1, y, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class SoilTile : public Tile
|
||||
@@ -181,9 +215,7 @@ namespace CaveGame::Core
|
||||
class MossyTile : public SoilTile {
|
||||
public:
|
||||
MossyTile();
|
||||
|
||||
MossyTile(TileID id, const std::string& name, const Color4& color, TileID decays_target);
|
||||
MossyTile(TileID numeric, const std::string &name, Color4 color, TileID decays_target);
|
||||
MossyTile(TileID id, const std::string &name, const Color4 &color, const std::vector<Color4> &pallet);
|
||||
MossyTile(TileID numeric, const std::string &name, Color4 color);
|
||||
void RandomTicc(ITileMap *world, TileState state, int x, int y) override;
|
||||
@@ -192,21 +224,46 @@ namespace CaveGame::Core
|
||||
class VineTile : public Tile {
|
||||
public:
|
||||
VineTile();
|
||||
|
||||
VineTile(TileID id, const std::string& name, const Color4& color);
|
||||
|
||||
VineTile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet);
|
||||
|
||||
bool Solid() const override { return true;}
|
||||
bool DoesRandomTicc() const override { return true; }
|
||||
void ForcedTicc(ITileMap* world, TileState state, int x, int y) override;
|
||||
|
||||
void RandomTicc(ITileMap* world, TileState state, int x, int y) override;
|
||||
bool DecayCheck(ITileMap* world, TileState state, int x, int y, TileID decays_to) override;
|
||||
bool ShouldSpread(ITileMap* world, int x, int y, TileID spreads_to) const override;
|
||||
bool SpreadCheck(ITileMap* world, TileState state, int x, int y, TileID spreads_to) override;
|
||||
};
|
||||
|
||||
class GravityTile : public Tile {
|
||||
public:
|
||||
GravityTile();
|
||||
GravityTile(TileID id, const std::string& name, const Color4& color);
|
||||
GravityTile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet);
|
||||
|
||||
bool DoesForcedTicc() const override { return true;}
|
||||
void ForcedTicc(ITileMap *world, TileState state, int x, int y) override {
|
||||
if (world->GetTile(x, y+1) == TileID::AIR) {
|
||||
world->SetTile(x, y+1, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->GetTile(x+1, y+2) == TileID::AIR) {
|
||||
world->SetTile(x+1, y+2, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (world->GetTile(x-1, y+2) == TileID::AIR) {
|
||||
world->SetTile(x-1, y+2, numeric_id);
|
||||
world->SetTile(x, y, TileID::AIR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SaplingTile : public Tile {
|
||||
public:
|
||||
|
||||
@@ -234,10 +291,10 @@ namespace CaveGame::Core
|
||||
static const Tile Limestone {ID::LIMESTONE, "Limestone", Colors::Yellows::PaleGoldenrod};
|
||||
static const Tile Basalt {ID::BASALT, "Basalt", Colors::Grays::DimGray};
|
||||
static const Tile Cobblestone {ID::COBBLESTONE, "Cobblestone", Colors::Grays::Gainsboro};
|
||||
static const SoilTile RedMoss {ID::RED_MOSS, "Red Moss ", Colors::Reds::Crimson, ID::STONE};
|
||||
static const SoilTile BrownMoss {ID::BROWN_MOSS, "Brown Moss", Colors::Browns::Brown, ID::STONE};
|
||||
static const SoilTile GreenMoss {ID::GREEN_MOSS, "Green Moss", Colors::Greens::LimeGreen, ID::STONE};
|
||||
static const SoilTile LavaMoss {ID::LAVA_MOSS, "Lava Moss", Colors::Reds::LightCoral, ID::STONE};
|
||||
static const MossyTile RedMoss {ID::RED_MOSS, "Red Moss ", Colors::Reds::Crimson, ID::STONE};
|
||||
static const MossyTile BrownMoss {ID::BROWN_MOSS, "Brown Moss", Colors::Browns::Brown, ID::STONE};
|
||||
static const MossyTile GreenMoss {ID::GREEN_MOSS, "Green Moss", Colors::Greens::LimeGreen, ID::STONE};
|
||||
static const MossyTile LavaMoss {ID::LAVA_MOSS, "Lava Moss", Colors::Reds::LightCoral, ID::STONE};
|
||||
static const Tile Granite {ID::GRANITE, "Granite", Colors::Whites::AntiqueWhite};
|
||||
static const Tile Marble {ID::MARBLE, "Marble", Colors::Whites::GhostWhite};
|
||||
static const GrassyTile Grass {ID::GRASS, "Grass", Colors::Greens::LawnGreen,
|
||||
@@ -246,7 +303,7 @@ namespace CaveGame::Core
|
||||
|
||||
static const VineTile Vine {ID::VINE, "Vine", Colors::Greens::ForestGreen};
|
||||
|
||||
static const Tile Sand {ID::SAND, "Sand", Colors::Yellows::PaleGoldenrod, {{238, 232, 170}, {232, 238, 160}, {218, 212, 175}}};
|
||||
static const GravityTile Sand {ID::SAND, "Sand", Colors::Yellows::PaleGoldenrod, {{238, 232, 170}, {232, 238, 160}, {218, 212, 175}}};
|
||||
|
||||
static const Tile WhiteSand {ID::WHITE_SAND, "White Sand", Colors::Whites::SeaShell};
|
||||
static const Tile RedSand {ID::RED_SAND, "Red Sand", Colors::Reds::Firebrick};
|
||||
|
@@ -47,7 +47,11 @@ namespace CaveGame::Core
|
||||
|
||||
TileState GetTileState(int x, int y) const override { return 0; /* TODO: Implement tile state field */ }
|
||||
|
||||
void SetTileState(int x, int y, TileState state) { /* TODO: Implement tile state field */ }
|
||||
void SetTileState(int x, int y, TileState state) override { /* TODO: Implement tile state field */ }
|
||||
|
||||
void SetTileUpdateFlag(int x, int y, bool flag) override;
|
||||
|
||||
bool GetTileUpdateFlag(int x, int y) override;
|
||||
|
||||
// TODO: Doesn't really belong here.
|
||||
Vector2 ToUnitDirection(float rotation);
|
||||
@@ -62,6 +66,8 @@ namespace CaveGame::Core
|
||||
|
||||
virtual void RefreshAll();
|
||||
|
||||
void DoForcedTileTicks();
|
||||
|
||||
virtual void AutoSaveAsync() { }
|
||||
|
||||
virtual void AutoSave();
|
||||
|
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
void Chunk::SetTile(int x, int y, TileID t) {
|
||||
void Chunk::SetTile(int x, int y, TileID t, bool trigger_tile_updates) {
|
||||
if (!(0 <= x && x < ChunkSize && 0 <= y && y < ChunkSize))
|
||||
assert("Out of bounds!");
|
||||
|
||||
@@ -14,6 +14,10 @@ namespace CaveGame::Core
|
||||
{
|
||||
tiles[x][y] = t;
|
||||
touched = true;
|
||||
|
||||
if (trigger_tile_updates)
|
||||
SetTileUpdateFlag(x, y);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -138,10 +138,7 @@ namespace CaveGame::Core
|
||||
MossyTile::MossyTile(): SoilTile()
|
||||
{}
|
||||
|
||||
MossyTile::MossyTile(TileID id, const std::string& name, const Color4& color, TileID decays_target): SoilTile(id, name, color, decays_target)
|
||||
{}
|
||||
|
||||
MossyTile::MossyTile(TileID numeric, const std::string &name, Color4 color, TileID decays_target): SoilTile(numeric, name, color, decays_target) { }
|
||||
MossyTile::MossyTile(TileID id, const std::string& name, const Color4& color, TileID decays_target): SoilTile(id, name, color, decays_target) { }
|
||||
|
||||
MossyTile::MossyTile(TileID id, const std::string &name, const Color4 &color, const std::vector<Color4> &pallet): SoilTile(id,name, color,pallet, TileID::STONE) { }
|
||||
|
||||
@@ -157,9 +154,24 @@ namespace CaveGame::Core
|
||||
|
||||
}
|
||||
|
||||
GravityTile::GravityTile(): Tile()
|
||||
{
|
||||
//does_forced_ticc = true;
|
||||
}
|
||||
|
||||
GravityTile::GravityTile(TileID id, const std::string& name, const Color4& color): Tile(id, name, color)
|
||||
{
|
||||
//does_forced_ticc = true;
|
||||
}
|
||||
|
||||
GravityTile::GravityTile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet):Tile(id, name, color, pallet)
|
||||
{
|
||||
//does_forced_ticc = true;
|
||||
}
|
||||
|
||||
VineTile::VineTile(): Tile()
|
||||
{
|
||||
does_random_ticc = true;
|
||||
//does_forced_ticc = true;
|
||||
}
|
||||
|
||||
VineTile::VineTile(TileID id, const std::string& name, const Color4& color): Tile(id, name, color)
|
||||
|
@@ -25,6 +25,7 @@ namespace CaveGame::Core
|
||||
}
|
||||
|
||||
DoRandomTileTicks();
|
||||
DoForcedTileTicks();
|
||||
|
||||
for (auto* entity : entities) {
|
||||
entity->Update(elapsed);
|
||||
@@ -98,6 +99,46 @@ namespace CaveGame::Core
|
||||
|
||||
std::unordered_map<Vector2, Chunk> World::GetChunkList() { return loaded_chunks; }
|
||||
|
||||
void World::SetTileUpdateFlag(int x, int y, bool flag) {
|
||||
float chunkX = Math::Floor((float)x / Chunk::ChunkSize);
|
||||
float chunkY = Math::Floor((float)y / Chunk::ChunkSize);
|
||||
|
||||
float tileX = Math::Mod(x, Chunk::ChunkSize);
|
||||
float tileY = Math::Mod(y, Chunk::ChunkSize);
|
||||
|
||||
if (tileX < 0)
|
||||
tileX = Chunk::ChunkSize + tileX;
|
||||
if (tileY < 0)
|
||||
tileY = Chunk::ChunkSize + tileY;
|
||||
|
||||
|
||||
const Vector2 coords = Vector2(chunkX, chunkY);
|
||||
|
||||
if (HasChunkAtCell(coords))
|
||||
loaded_chunks.at(coords).SetTileUpdateFlag(tileX, tileY, flag);
|
||||
}
|
||||
|
||||
bool World::GetTileUpdateFlag(int x, int y) {
|
||||
float chunkX = Math::Floor((float)x / Chunk::ChunkSize);
|
||||
float chunkY = Math::Floor((float)y / Chunk::ChunkSize);
|
||||
|
||||
float tileX = Math::Mod(x, Chunk::ChunkSize);
|
||||
float tileY = Math::Mod(y, Chunk::ChunkSize);
|
||||
|
||||
if (tileX < 0)
|
||||
tileX = Chunk::ChunkSize + tileX;
|
||||
if (tileY < 0)
|
||||
tileY = Chunk::ChunkSize + tileY;
|
||||
|
||||
Vector2 coords = Vector2(chunkX, chunkY);
|
||||
|
||||
|
||||
if (HasChunkAtCell(coords))
|
||||
return loaded_chunks.at(coords).GetTileUpdateFlag(tileX, tileY);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector2 World::ToUnitDirection(float rotation) {
|
||||
return {std::cos(rotation), std::cos(rotation)};
|
||||
}
|
||||
@@ -210,6 +251,37 @@ namespace CaveGame::Core
|
||||
}
|
||||
|
||||
|
||||
void World::DoForcedTileTicks() {
|
||||
Tile* tile = nullptr;
|
||||
|
||||
for (auto [coords, chunk] : loaded_chunks) {
|
||||
for (int x = 0; x < Core::Chunk::ChunkSize; x++) {
|
||||
for (int y = 0; y < Core::Chunk::ChunkSize; y++) {
|
||||
int wx = coords.x*Chunk::ChunkSize + x;
|
||||
int wy = coords.y*Chunk::ChunkSize + y;
|
||||
|
||||
if (!chunk.GetTileUpdateFlag(x, y))
|
||||
continue;
|
||||
|
||||
TileID at = chunk.GetTile(x, y);
|
||||
|
||||
if (at == TileID::AIR)
|
||||
continue;
|
||||
|
||||
tile = GetByNumeric(at);
|
||||
|
||||
if (tile != nullptr) {
|
||||
if (tile->DoesForcedTicc()) {
|
||||
tile->ForcedTicc(this, 0, wx, wy);
|
||||
chunk.SetTileUpdateFlag(x, y, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void World::DoRandomTileTicks() {
|
||||
// Every frame, In each loaded chunk, perform a RandomTileTick on N tiles.
|
||||
|
Reference in New Issue
Block a user