Coding in tile features.

This commit is contained in:
2024-12-16 22:08:32 -05:00
parent 232aed317a
commit fcd580cc3b
12 changed files with 503 additions and 387 deletions

View File

@@ -14,9 +14,6 @@ namespace CaveGame::Client
using Core::ConcurrentQueue;
using namespace std::chrono_literals;
class AsyncChunkRenderer : public ThreadPool
{
public:
@@ -45,6 +42,7 @@ namespace CaveGame::Client
protected:
std::unordered_map<Vector2, JGL::RenderTarget*> cached_chunk_sprites;
JGL::RenderTarget* canvas_render_target;
bool IsChunkCellWithinViewport(const Vector2& coords) const;

View File

@@ -128,48 +128,71 @@ namespace CaveGame::Client {
camera.ScaledViewport(), chunk_bounding_box);
}
RNG rng;
void LocalWorld::RenderChunkTexture(const Vector2 &coords, JGL::RenderTarget* destination, const Core::Chunk& chunk)
{
using CaveGame::Core::TileID;
std::vector<Vector2> stone_coords;
std::vector<Vector2> dirt_coords;
std::vector<Vector2> grass_coords;
std::vector<Vector2> clay_coords;
std::vector<Vector2> mud_coords;
TileID t_id;
Core::Tile* t_data;
Color4 t_color;
//std::vector<Vector2> stone_coords;
//std::vector<Vector2> dirt_coords;
//std::vector<Vector2> grass_coords;
//std::vector<Vector2> clay_coords;
//std::vector<Vector2> mud_coords;
JGL::J2D::Begin(destination, true);
for (int x = 0; x < Core::Chunk::ChunkSize; x++)
{
for (int y = 0; y < Core::Chunk::ChunkSize; y++)
{
TileID tile = chunk.GetTile(x, y);
t_id = chunk.GetTile(x, y);
Vector2 relative_tile_coords = Vector2(x, y);
Vector2 real_tile_coords = relative_tile_coords;
Vector2 tile_coords = relative_tile_coords;
if (tile == TileID::AIR) // Air
if (t_id == TileID::AIR) // Air
continue;
t_data = Core::GetByNumeric(t_id);
if (tile == TileID::STONE) // Stone
stone_coords.push_back(real_tile_coords);
if (t_data->has_color_pallet) {
uint rand = generator.ColorMap(t_data->color_pallet.size(), x, y);
t_color = t_data->color_pallet[rand];
} else {
t_color = t_data->base_color;
}
JGL::J2D::DrawPoint(t_color, tile_coords);
/*if (tile == TileID::STONE) // Stone
Core::Tiles::Stone::Draw(tile_coords);
//stone_coords.push_back(real_tile_coords);
else if (tile == TileID::DIRT) // Dirt
dirt_coords.push_back(real_tile_coords);
//dirt_coords.push_back(real_tile_coords);
else if (tile == TileID::GRASS) // Grass
grass_coords.push_back(real_tile_coords);
//grass_coords.push_back(real_tile_coords);
else if (tile == TileID::CLAY) // Ore
clay_coords.push_back(real_tile_coords);
//clay_coords.push_back(real_tile_coords);
else if (tile == TileID::MUD) // Water
mud_coords.push_back(real_tile_coords);
//mud_coords.push_back(real_tile_coords); */
}
}
JGL::J2D::Begin(destination, true);
JGL::J2D::DrawPoints(Colors::Gray, stone_coords.data(), stone_coords.size());
JGL::J2D::DrawPoints(Colors::Browns::Chocolate, dirt_coords.data(), dirt_coords.size());
JGL::J2D::DrawPoints(Colors::Green, grass_coords.data(), grass_coords.size());
JGL::J2D::DrawPoints(Colors::Reds::Firebrick, clay_coords.data(), clay_coords.size());
JGL::J2D::DrawPoints(Colors::Browns::BurlyWood, mud_coords.data(), mud_coords.size());
JGL::J2D::End();
//JGL::J2D::Begin(destination, true);
//JGL::J2D::Begin(destination, true);
// JGL::J2D::DrawPoints(Colors::Gray, stone_coords.data(), stone_coords.size());
// JGL::J2D::DrawPoints(Colors::Browns::Chocolate, dirt_coords.data(), dirt_coords.size());
// JGL::J2D::DrawPoints(Colors::Green, grass_coords.data(), grass_coords.size());
// JGL::J2D::DrawPoints(Colors::Reds::Firebrick, clay_coords.data(), clay_coords.size());
// JGL::J2D::DrawPoints(Colors::Browns::BurlyWood, mud_coords.data(), mud_coords.size());
//JGL::J2D::Begin(destination, true);
}
void LocalWorld::RenderChunk(const Vector2& coords, const Core::Chunk& chunk) {

View File

@@ -18,15 +18,14 @@ namespace CaveGame::Core
/// List of biomes.
namespace Biomes {
// The world is split into horizontal slices, each controlled by a higher-level "Elevation Biome"
/// The world is split into horizontal slices, each controlled by a higher-level "Elevation Biome"
#pragma region Elevation Biomes
BIOME Space;
BIOME Surface;
BIOME Subsurface;
BIOME Underground;
BIOME Deep;
BIOME Mantle;
BIOME Space; // -1000 < Y
BIOME Surface; // 1000 < Y <= -1000
BIOME Subsurface; // 2000 < Y <= 1000
BIOME Underground; // 10000 < T <= 2000
BIOME Deep; // 50000 < Y <= 10000
BIOME Mantle; // Y <= 50000
#pragma endregion
#pragma region Environmental Biomes

View File

@@ -12,11 +12,12 @@ namespace CaveGame::Core
AIR = 0,
STONE,
DIRT,
MUD,
DIRT, MUD,
GRASS,
MOSSY_STONE, LIMESTONE, BASALT, COBBLESTONE,
MOSSY_STONE,
LIMESTONE,
BASALT,
COBBLESTONE,
WET_CEMENT,
CEMENT,
CONCRETE,
@@ -32,20 +33,22 @@ namespace CaveGame::Core
GYPSUM,
PUMICE,
QUARTZ,
MARBLE,
BRIMSTONE,
OBSIDIAN,
HARDENED_CLAY, CLAY,
SILT, LOAM, QUAGMIRE, ASH,
GLOWY_GRASS, DRY_GRASS, DEAD_GRASS, GMO_GRASS, FAKE_GRASS,
MOSS,
GREEN_MOSS, RED_MOSS, BROWN_MOSS, LAVA_MOSS,
SNOW, PACKED_SNOW,
ICE, PACKED_ICE, ICE_BRICK, THIN_ICE,
SAND, WET_SAND, SANDSTONE, SAND_BRICK,
RED_SAND,
WHITE_SAND,
BLACK_SAND,
SAND, WET_SAND,
SANDSTONE, SAND_BRICK,
RED_SAND, RED_SANDSTONE, RED_SAND_BRICK,
WHITE_SAND, WHITE_SANDSTONE, WHITE_SAND_BRICK,
BLACK_SAND, BLACK_SANDSTONE, BLACK_SAND_BRICK,
GRAVEL,
DUST,
GLASS, CRACKED_GLASS,

View File

@@ -36,6 +36,8 @@ namespace CaveGame::Core
TileID ComputeTile(int wx, int wy);
void FirstPass(Chunk& chunk);
uint ColorMap(int range, int wx, int wy);
// TODO: Implement SecondPass, the catch is, it **may** need to load an arbitrary amount of adjacent chunks to correctly place structures.
// TODO: Expert Mode: How do we keep it threaded separately while still accomplishing the above?

View File

@@ -22,7 +22,6 @@ namespace CaveGame::Core
bool GrassShouldSuffocate(int x, int y) const;
void GrassRandomTicc(int wx, int wy);
bool IsSolidTile(int x, int y) const;

View File

@@ -8,7 +8,7 @@ namespace CaveGame::Core
/// This enum defines combinatorial category flags to items to enable smart sorting.
enum class ItemCategory: u8
{
ANY, TILE, ORE, TOOL, WEAPON, ARMOR, CLOTHING, FOOD, POTION, INGREDIENT, MEME, PLANT, METAL, ORGANIC, BUILDING_BLOCK,
ANY, TILE_ITEM, ORE, TOOL, WEAPON, ARMOR, CLOTHING, FOOD, POTION, INGREDIENT, MEME, PLANT, METAL, ORGANIC, BUILDING_BLOCK,
FLUID, SOIL, GAS, LIGHT_SOURCE, CRAFTING_STATION,
};

View File

@@ -105,250 +105,8 @@ namespace CaveGame::Core
class TileGroup {};
class Tile
{
public:
TileID numeric_id = TileID::VOID;
std::string mnemonic_id;
Color4 base_color;
std::vector<Color4> color_pallet;
bool collides;
bool does_random_ticc;
public:
class Tile;
constexpr Tile() = default;
Tile(TileID numeric, const std::string& name, Color4 color)
: numeric_id(numeric), mnemonic_id(name), base_color(color)
{}
virtual TileID NumericID() const { return numeric_id; };
virtual std::string MnemonicID() const { return mnemonic_id; };
bool DoesRandomTicc() const { return does_random_ticc; }
virtual Color4 ComputeColor(TileState state, int x, int y) {}
virtual void ForcedTicc(ITileMap* world, TileState state, int x, int y) {}
virtual void RandomTicc(ITileMap* world, TileState state, int x, int y) {}
template <TileID TDecaysTo>
void DecayTo(ITileMap *world, TileState state, int x, int y)
{
world->SetTile(x, y, TDecaysTo);
}
void DecayTo(ITileMap *world, TileState state, int x, int y, TileID TDecaysTo)
{
world->SetTile(x, y, TDecaysTo);
}
};
class SoilTile : public Tile
{
public:
TileID decays_to;
SoilTile(TileID numeric, const std::string& name, Color4 color, TileID decays_target)
: Tile(numeric, name, color)
{
decays_to = decays_target;
does_random_ticc = true;
}
void RandomTicc(ITileMap *world, TileState state, int x, int y) override
{
if (!world->HasAdjacentOrDiagonalAirBlock(x, y))
DecayTo(world, state, x, y, decays_to);
}
//void CanGrowGrass
};
class DirtTile : public SoilTile
{
};
class GrassyTile : public SoilTile
{
public:
GrassyTile(TileID numeric, const std::string& name, Color4 color)
: SoilTile(numeric, name, color, TileID::DIRT)
{
does_random_ticc = true;
}
void RandomTicc(ITileMap *world, TileState state, int x, int y) override
{
if (!world->HasAdjacentOrDiagonalAirBlock(x, y))
{
DecayTo(world, state, x, y, decays_to);
return;
}
world->GrassRandomTicc(x, y);
}
};
class GasTile : public Tile
{
};
#define TILE constexpr Tile
// TODO: Constexpr-qualify Color4
namespace Tiles {
using Core::TileID;
TILE Void {TileID::VOID, "Void", Colors::Transparent};
TILE Air {TileID::AIR, "Air", Colors::Transparent};
TILE Stone;
TILE Dirt;
TILE Mud;
TILE Limestone;
TILE Basalt;
TILE Cobblestone;
TILE MossyStone;
TILE RedMossyStone;
TILE BrownMossyStone;
TILE GreenMossyStone;
TILE LavaMossyStone;
TILE Granite;
TILE Marble;
TILE Grass;
TILE Bluegrass;
TILE Sand;
TILE WhiteSand;
TILE RedSand;
TILE BlackSand;
TILE Sandstone;
TILE WhiteSandstone;
TILE RedSandstone;
TILE BlackSandstone;
TILE Ash;
TILE Clay;
TILE Silt;
TILE Snow;
TILE Ice;
TILE Slush;
TILE Cactus;
TILE CactusFlower;
TILE CactusFruit;
TILE Bamboo;
TILE Sugarcane;
TILE Vine;
TILE VineFlower;
TILE FlowerStem;
TILE RedFlowerPetal;
TILE BlueFlowerPetal;
TILE YellowFlowerPetal;
TILE WhiteFlowerPetal;
TILE CopperWire;
TILE RedWire;
TILE GreenWire;
TILE YellowWire;
TILE BlueWire;
TILE LED;
TILE TNT;
TILE Cloud;
TILE ThinIce;
TILE RainCloud;
TILE Cobweb;
TILE Coal;
TILE CopperOre;
TILE TinOre;
TILE IronOre;
TILE LeadOre;
TILE SilverOre;
TILE TungstenOre;
TILE GoldOre;
TILE PlatinumOre;
TILE CobaltOre;
TILE TitaniumOre;
TILE UraniumOre;
TILE Diamond;
TILE Emerald;
TILE Amethyst;
TILE Topaz;
TILE Sapphire;
TILE Ruby;
TILE Amber;
TILE Obsidian;
TILE OakLog;
TILE OakPlank;
TILE OakPlatform;
TILE OakLeaf;
TILE AshLog;
TILE AshLeaf;
TILE AshPlank;
TILE PalmLog;
TILE PalmLeaf;
TILE PalmPlank;
TILE PineLog;
TILE PinePlank;
TILE PinePlatform;
TILE PineLeaf;
TILE RedwoodLog;
TILE RedwoodPlank;
TILE RedwoodPlatform;
TILE RedwoodLeaf;
TILE EbonyLog;
TILE EbonyPlank;
TILE EbonyPlatform;
TILE EbonyLeaf;
TILE MapleLog;
TILE MapleLeaf;
TILE MaplePlank;
TILE BirchLog;
TILE BirchLeaf;
TILE BirchPlank;
TILE Water;
TILE Blood;
TILE Sludge;
TILE Lava;
TILE MuddyWater;
TILE Ectoplasm;
TILE Oil;
TILE Honey;
TILE Milk;
TILE Rope;
}
void RegisterTile(Tile* data);
@@ -356,6 +114,286 @@ namespace CaveGame::Core
Tile* GetByName(const std::string& name);
class Tile
{
protected:
TileID numeric_id = TileID::VOID;
std::string mnemonic_id;
public:
Color4 base_color;
std::vector<Color4> color_pallet;
bool collides;
bool does_random_ticc;
bool has_color_pallet = false;
public:
Tile();
Tile(TileID id, const std::string& name, const Color4& color);
Tile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet);
[[nodiscard]] TileID NumericID() const;
[[nodiscard]] std::string MnemonicID() const;
virtual bool DoesRandomTicc() 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) {}
template <TileID TDecaysTo>
void DecayTo(ITileMap *world, TileState state, int x, int y)
{
DecayTo(world, state, x, y, TDecaysTo);
}
void DecayTo(ITileMap *world, TileState state, int x, int y, TileID TDecaysTo);
bool ShouldSpread(ITileMap* world, int x, int y, TileID spreads_to) const;
bool ShouldSuffocate(ITileMap* world, int x, int y) const;
bool DecayCheck(ITileMap* world, TileState state, int x, int y, TileID decays_to);
bool SpreadCheck(ITileMap* world, TileState state, int x, int y, TileID spreads_to);
};
class SoilTile : public Tile
{
public:
TileID decays_to;
SoilTile();
SoilTile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet, TileID decays_target);
SoilTile(TileID numeric, const std::string& name, Color4 color, TileID decays_target);
bool DoesRandomTicc() const override { return true; }
void RandomTicc(ITileMap *world, TileState state, int x, int y) override;
};
class GrassyTile : public SoilTile
{
public:
GrassyTile();
GrassyTile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet, TileID decays_target);
GrassyTile(TileID numeric, const std::string& name, Color4 color, TileID decays_target);
GrassyTile(TileID id, const std::string& name, const Color4& color, const std::vector<Color4>& pallet);
GrassyTile(TileID numeric, const std::string& name, Color4 color);
void RandomTicc(ITileMap *world, TileState state, int x, int y) override
{
if (DecayCheck(world, state, x, y, decays_to))
return;
if (SpreadCheck(world, state, x, y, decays_to))
return;
}
};
class MossyTile : public SoilTile {
public:
MossyTile() : SoilTile() {}
MossyTile(TileID id, const std::string& name, const Color4& color, TileID decays_target)
: SoilTile(id, name, color, 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
{
if (DecayCheck(world, state, x, y, decays_to))
return;
if (SpreadCheck(world, state, x, y, decays_to))
return;
}
};
class VineTile : public Tile {
public:
VineTile() : Tile()
{}
};
class GasTile : public Tile
{
};
void DoGrassRandomTicc(ITileMap *world, TileState state, int x, int y);
#define TILE static const Tile
namespace Tiles {
using ID = Core::TileID;
static const Tile Void {ID::VOID, "Void", Colors::Transparent};
static const Tile Air {ID::AIR, "Air", Colors::Transparent};
static const Tile Stone {ID::STONE, "Stone", Colors::Grays::SlateGray, {Colors::Grays::SlateGray, Colors::Grays::LightSlateGray}};
static const Tile Dirt {ID::DIRT, "Dirt", Colors::Browns::Chocolate, {Colors::Browns::Chocolate, {210, 125, 30},{195, 105, 40}}};
static const Tile Mud {ID::MUD, "Mud", Colors::Browns::SaddleBrown};
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 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,
{{126, 252, 5}, {124, 240, 0}, {124, 248, 8}}};
static const GrassyTile GlowyGrass {ID::GLOWY_GRASS, "Glowy Grass", Colors::Blues::PowderBlue};
static const VineTile Vine {ID::VINE, "Vine"};
static const Tile Sand {ID::SAND, "Sand", Colors::Yellows::PaleGoldenrod};
static const Tile WhiteSand {ID::WHITE_SAND, "White Sand", Colors::Whites::SeaShell};
static const Tile RedSand {ID::RED_SAND, "Red Sand", Colors::Reds::Firebrick};
static const Tile BlackSand {ID::BLACK_SAND, "Black Sand", Colors::Black};
static const Tile Sandstone {ID::SANDSTONE, "Sandstone", Colors::Yellows::PaleGoldenrod};
static const Tile WhiteSandstone {ID::WHITE_SANDSTONE, "White Sandstone", Colors::Whites::SeaShell};
static const Tile RedSandstone{ID::RED_SANDSTONE, "Red Sandstone", Colors::Reds::Firebrick};
static const Tile BlackSandstone {ID::BLACK_SANDSTONE, "Black Sandstone", Colors::Black};
static const Tile Ash {ID::ASH, "Ash", Colors::Grays::DarkSlateGray};
static const Tile Clay {ID::CLAY, "Clay", Colors::Browns::Brown};
static const Tile Silt;
static const Tile Snow;
static const Tile Ice;
static const Tile Slush;
static const Tile Cactus;
static const Tile CactusFlower;
static const Tile CactusFruit;
static const Tile Bamboo;
static const Tile Sugarcane;
static const Tile Vine;
static const Tile VineFlower;
static const Tile FlowerStem;
static const Tile RedFlowerPetal;
static const Tile BlueFlowerPetal;
static const Tile YellowFlowerPetal;
static const Tile WhiteFlowerPetal;
static const Tile CopperWire;
static const Tile RedWire;
static const Tile GreenWire;
static const Tile YellowWire;
static const Tile BlueWire;
static const Tile LED;
static const Tile TNT;
static const Tile Cloud;
static const Tile ThinIce;
static const Tile RainCloud;
static const Tile Cobweb;
static const Tile Coal;
static const Tile CopperOre;
static const Tile TinOre;
static const Tile IronOre;
static const Tile LeadOre;
static const Tile SilverOre;
static const Tile TungstenOre;
static const Tile GoldOre;
static const Tile PlatinumOre;
static const Tile CobaltOre;
static const Tile TitaniumOre;
static const Tile UraniumOre;
static const Tile Diamond;
static const Tile Emerald;
static const Tile Amethyst;
static const Tile Topaz;
static const Tile Sapphire;
static const Tile Ruby;
static const Tile Amber;
static const Tile Obsidian;
static const Tile OakLog;
static const Tile OakPlank;
static const Tile OakPlatform;
static const Tile OakLeaf;
static const Tile AshLog;
static const Tile AshLeaf;
static const Tile AshPlank;
static const Tile PalmLog;
static const Tile PalmLeaf;
static const Tile PalmPlank;
static const Tile PineLog;
static const Tile PinePlank;
static const Tile PinePlatform;
static const Tile PineLeaf;
static const Tile RedwoodLog;
static const Tile RedwoodPlank;
static const Tile RedwoodPlatform;
static const Tile RedwoodLeaf;
static const Tile EbonyLog;
static const Tile EbonyPlank;
static const Tile EbonyPlatform;
static const Tile EbonyLeaf;
static const Tile MapleLog;
static const Tile MapleLeaf;
static const Tile MaplePlank;
static const Tile BirchLog;
static const Tile BirchLeaf;
static const Tile BirchPlank;
static const Tile Water;
static const Tile Blood;
static const Tile Sludge;
static const Tile Lava;
static const Tile MuddyWater;
static const Tile Ectoplasm;
static const Tile Oil;
static const Tile Honey;
static const Tile Milk;
static const Tile Rope;
}
void DefineTiles();
}

View File

@@ -71,6 +71,8 @@ namespace CaveGame::Core
} else { return base; }*/
float cave_erosion = perlin.Noise(wx / CaveInputScale, wy / CaveInputScale, 0.f) * CaveOutputScale;
float cave_addition = perlin.Noise(wx / CaveAdditiveInputScale, wy / CaveAdditiveInputScale, 0.f)*CaveAdditiveOutputScale;
@@ -84,7 +86,22 @@ namespace CaveGame::Core
if (cave_erosion > -CaveErosionRange && CaveErosionRange > cave_erosion)
{
return TileID::AIR;
} else { return base; }
} else {
// Ore computation
float ore_map_1 = perlin.Noise(wx / 50, wy / 50, 0.f) * 3.f;
float ore_map_2 = perlin.Noise(wx / 500, wy / 500, 0.f) * 1.f;
float ore_map = ore_map_1 + ore_map_2;
if (ore_map > 0.4f) {
return TileID::CLAY;
}
return base;
}
}
@@ -102,6 +119,13 @@ namespace CaveGame::Core
}
}
uint Generator::ColorMap(int range, int wx, int wy) {
wx = ModInt(wx, PrecomputedWhiteNoiseResolution);
wy = ModInt(wy, PrecomputedWhiteNoiseResolution);
float norm = precomputed_white_noise_2D[wx][wy];
return norm*range;
}
float Generator::GetPrecomputedWhiteNoise2D(int x, int y) const {
x = ModInt(x, PrecomputedWhiteNoiseResolution);
y = ModInt(y, PrecomputedWhiteNoiseResolution);

View File

@@ -26,91 +26,4 @@ namespace CaveGame::Core
return true;
return false;
}
bool ITileMap::GrassSpreadable(int x, int y) const
{
if (GetTile(x, y) == TileID::DIRT)
{
if (HasAdjacentOrDiagonalAirBlock(x, y))
return true;
}
return false;
}
bool ITileMap::GrassShouldSuffocate(int x, int y) const
{
//if (IsSolidTile(x+1, y) && IsSolidTile(x-1, y) && IsSolidTile(x, y+1) && IsSolidTile(x, y-1) &&
//IsSolidTile(x+1, y+1) && IsSolidTile(x-1, y+1) && IsSolidTile(x+1, y-1) && IsSolidTile(x-1, y-1))
if (!HasAdjacentOrDiagonalAirBlock(x, y))
return true;
return false;
}
void ITileMap::GrassRandomTicc(int wx, int wy)
{
if (GrassShouldSuffocate(wx, wy))
{
SetTile(wx, wy, TileID::DIRT);
return;
}
// Check adjacent blocks
if (GrassSpreadable(wx, wy+1))
{
SetTile(wx, wy+1, TileID::GRASS);
return;
}
if (GrassSpreadable(wx, wy-1))
{
SetTile(wx, wy-1, TileID::GRASS);
return;
}
if (GrassSpreadable(wx+1, wy))
{
SetTile(wx+1, wy, TileID::GRASS);
return;
}
if (GrassSpreadable(wx-1, wy))
{
SetTile(wx-1, wy, TileID::GRASS);
return;
}
// Check diagonal blocks.
if (GrassSpreadable(wx+1, wy-1))
{
SetTile(wx+1, wy-1, TileID::GRASS);
return;
}
if (GrassSpreadable(wx-1, wy-1))
{
SetTile(wx-1, wy-1, TileID::GRASS);
return;
}
if (GrassSpreadable(wx+1, wy+1))
{
SetTile(wx+1, wy+1, TileID::GRASS);
return;
}
if (GrassSpreadable(wx-1, wy+1))
{
SetTile(wx-1, wy+1, TileID::GRASS);
return;
}
}
}

View File

@@ -5,24 +5,150 @@ namespace CaveGame::Core
std::array<Tile*, 65535> registered_tiles{};
void Tile::DecayTo(ITileMap *world, TileState state, int x, int y, TileID TDecaysTo) {
world->SetTile(x, y, TDecaysTo);
}
bool Tile::ShouldSpread(ITileMap *world, int x, int y, TileID spreads_to) const {
if (world->GetTile(x, y) == spreads_to)
{
if (world->HasAdjacentOrDiagonalAirBlock(x, y))
return true;
}
return false;
}
SoilTile::SoilTile(): Tile() {}
SoilTile::SoilTile(TileID id, const std::string &name, const Color4 &color, const std::vector<Color4> &pallet,
TileID decays_target): Tile(id,name, color,pallet) {
decays_to = decays_target;
does_random_ticc = true;
}
SoilTile::SoilTile(TileID numeric, const std::string &name, Color4 color, TileID decays_target): Tile(numeric, name, color) {
decays_to = decays_target;
does_random_ticc = true;
}
bool Tile::ShouldSuffocate(ITileMap *world, int x, int y) const {
if (!world->HasAdjacentOrDiagonalAirBlock(x, y))
return true;
return false;
}
bool Tile::DecayCheck(ITileMap *world, TileState state, int x, int y, TileID decays_to) {
if (ShouldSuffocate(world, x, y))
{
DecayTo(world, state, x, y, decays_to);
return true;
}
return false;
}
bool Tile::SpreadCheck(ITileMap *world, TileState state, int x, int y, TileID spreads_to) {
if (ShouldSpread(world, x, y+1, spreads_to)) {
world->SetTile(x, y+1, numeric_id);
return true;
}
if (ShouldSpread(world, x, y-1, spreads_to)) {
world->SetTile(x, y-1, numeric_id);
return true;
}
if (ShouldSpread(world, x+1, y, spreads_to)) {
world->SetTile(x+1, y, numeric_id);
return true;
}
if (ShouldSpread(world, x-1, y, spreads_to)) {
world->SetTile(x-1, y, numeric_id);
return true;
}
// Check diagonal blocks.
if (ShouldSpread(world, x+1, y-1, spreads_to))
{
world->SetTile(x+1, y-1, numeric_id);
return true;
}
if (ShouldSpread(world, x-1, y-1, spreads_to))
{
world->SetTile(x-1, y-1, numeric_id);
return true;
}
if (ShouldSpread(world, x+1, y+1, spreads_to))
{
world->SetTile(x+1, y+1, numeric_id);
return true;
}
if (ShouldSpread(world, x-1, y+1, spreads_to))
{
world->SetTile(x-1, y+1, numeric_id);
return true;
}
return false;
}
void SoilTile::RandomTicc(ITileMap *world, TileState state, int x, int y) {
if (!world->HasAdjacentOrDiagonalAirBlock(x, y))
DecayTo(world, state, x, y, decays_to);
}
GrassyTile::GrassyTile(): SoilTile() {}
GrassyTile::GrassyTile(TileID id, const std::string &name, const Color4 &color, const std::vector<Color4> &pallet,
TileID decays_target): SoilTile(id,name, color,pallet, decays_target) { }
GrassyTile::GrassyTile(TileID numeric, const std::string &name, Color4 color, TileID decays_target): SoilTile(numeric, name, color, decays_target) { }
GrassyTile::GrassyTile(TileID id, const std::string &name, const Color4 &color, const std::vector<Color4> &pallet): SoilTile(id,name, color,pallet, TileID::DIRT) { }
GrassyTile::GrassyTile(TileID numeric, const std::string &name, Color4 color): SoilTile(numeric, name, color, TileID::DIRT) { }
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, const std::vector<Color4> &pallet): SoilTile(id,name, color,pallet, TileID::STONE) { }
MossyTile::MossyTile(TileID numeric, const std::string &name, Color4 color): SoilTile(numeric, name, color, TileID::STONE) { }
void DefineTiles() {
RegisterTile(new Tile(TileID::AIR, "air", {0,0,0,0}));
/*RegisterTile(new Tile(TileID::AIR, "air", {0,0,0,0}));
RegisterTile(new SoilTile(TileID::DIRT, "dirt", Colors::Green, TileID::DIRT));
RegisterTile(new SoilTile(TileID::MUD, "mud", Colors::Green, TileID::MUD));
RegisterTile(new Tile(TileID::STONE, "stone", Colors::Green));
RegisterTile(new GrassyTile(TileID::GRASS, "grass", Colors::Green));
RegisterTile(new GrassyTile(TileID::GRASS, "grass", Colors::Green));*/
}
Tile *GetByName(const std::string &name) {
// TODO: Optimize with additional mapping!!
for(auto& tile : registered_tiles)
if (tile->mnemonic_id == name)
if (tile->MnemonicID() == name)
return tile;
throw std::runtime_error("Invalid mnemonic ID!");
}
Tile::Tile() {}
Tile::Tile(TileID id, const std::string &name, const Color4 &color): numeric_id(id), mnemonic_id(name), base_color(color),
has_color_pallet(false) {
RegisterTile(this);
}
Tile::Tile(TileID id, const std::string &name, const Color4 &color, const std::vector<Color4> &pallet): numeric_id(id), mnemonic_id(name), base_color(color), color_pallet(pallet),
has_color_pallet(true) {
RegisterTile(this);
}
TileID Tile::NumericID() const { return numeric_id; }
std::string Tile::MnemonicID() const { return mnemonic_id; }
Tile *GetByNumeric(TileID id) {
// TODO: Optimize with additional mapping!!
//if (registered_tiles.at((uint16_t)id))
@@ -35,7 +161,7 @@ namespace CaveGame::Core
}
void RegisterTile(Tile *data) {
uint16_t index = (uint16_t)data->numeric_id;
uint16_t index = (uint16_t)data->NumericID();
registered_tiles[index] = data;
}
}

View File

@@ -226,21 +226,12 @@ namespace CaveGame::Core
if (at == TileID::AIR)
continue;
bool slow_method = true;
// TODO: Unacceptably slow!!!
if (slow_method)
{
tile = GetByNumeric(at);
if (tile != nullptr)
if (tile->DoesRandomTicc())
tile->RandomTicc(this, 0, wx, wy);
} else {
// Fast method:
if (at == TileID::GRASS)
GrassRandomTicc(wx, wy);
}
}
}
}