'src/DefaultWorldGen.cc', | 'src/DefaultWorldGen.cc', | ||||
'src/entities/PlayerEntity.cc', | 'src/entities/PlayerEntity.cc', | ||||
'src/entities/ItemStackEntity.cc', | 'src/entities/ItemStackEntity.cc', | ||||
'src/world/tree.cc', | |||||
name_prefix: '', | name_prefix: '', | ||||
name_suffix: 'so', | name_suffix: 'so', | ||||
install: true, | install: true, |
#include "DefaultWorldGen.h" | #include "DefaultWorldGen.h" | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cstdint> | |||||
#include "entities/PlayerEntity.h" | #include "entities/PlayerEntity.h" | ||||
if (pos.y > grassLevel + 7 && perlin_.noise(pos.x / 43.37, pos.y / 16.37) > 0.2) | if (pos.y > grassLevel + 7 && perlin_.noise(pos.x / 43.37, pos.y / 16.37) > 0.2) | ||||
return tAir_; | return tAir_; | ||||
// Trees | |||||
if (pos.y == grassLevel - 1) { | |||||
constexpr int treeProb = 4; | |||||
bool spawnTree = Swan::random(pos.x) % treeProb == 0; | |||||
if (spawnTree) { | |||||
// Avoid trees which are too close | |||||
for (int rx = 1; rx <= 5; ++rx) { | |||||
if (Swan::random(pos.x + rx) % treeProb == 0) { | |||||
spawnTree = false; | |||||
break; | |||||
} | |||||
} | |||||
if (spawnTree) { | |||||
return tTreeSeeder_; | |||||
} | |||||
} | |||||
} | |||||
if (pos.y > stoneLevel) | if (pos.y > stoneLevel) | ||||
return tStone_; | return tStone_; | ||||
else if (pos.y > grassLevel) | else if (pos.y > grassLevel) |
tGrass_(world.getTileID("core::grass")), | tGrass_(world.getTileID("core::grass")), | ||||
tDirt_(world.getTileID("core::dirt")), | tDirt_(world.getTileID("core::dirt")), | ||||
tStone_(world.getTileID("core::stone")), | tStone_(world.getTileID("core::stone")), | ||||
tTreeSeeder_(world.getTileID("core::tree-seeder")), | |||||
tAir_(world.getTileID("@::air")), | tAir_(world.getTileID("@::air")), | ||||
tTreeTrunk_(world.getTileID("core::tree-trunk")), | |||||
tLeaves_(world.getTileID("core::leaves")), | |||||
bgCave_(world.getSprite("core::misc/background-cave")) {} | bgCave_(world.getSprite("core::misc/background-cave")) {} | ||||
void drawBackground( | void drawBackground( | ||||
private: | private: | ||||
Swan::Tile::ID genTile(Swan::TilePos pos); | Swan::Tile::ID genTile(Swan::TilePos pos); | ||||
Swan::Tile::ID tGrass_, tDirt_, tStone_, tAir_, tTreeTrunk_, tLeaves_; | |||||
const uint32_t seed_ = 100; | |||||
Swan::Tile::ID tGrass_, tDirt_, tStone_, tTreeSeeder_, tAir_; | |||||
Cygnet::RenderSprite bgCave_; | Cygnet::RenderSprite bgCave_; | ||||
siv::PerlinNoise perlin_ = siv::PerlinNoise(100); | |||||
siv::PerlinNoise perlin_{seed_}; | |||||
}; | }; |
#include "DefaultWorldGen.h" | #include "DefaultWorldGen.h" | ||||
#include "entities/PlayerEntity.h" | #include "entities/PlayerEntity.h" | ||||
#include "entities/ItemStackEntity.h" | #include "entities/ItemStackEntity.h" | ||||
#include "world/tree.h" | |||||
#include <functional> | #include <functional> | ||||
registerTile({ | registerTile({ | ||||
.name = "tree-trunk", | .name = "tree-trunk", | ||||
.image = "core::tile/tree-trunk", | .image = "core::tile/tree-trunk", | ||||
.isSolid = false, | |||||
.droppedItem = "core::tree-trunk", | .droppedItem = "core::tree-trunk", | ||||
}); | }); | ||||
registerTile({ | registerTile({ | ||||
.name = "leaves", | |||||
.name = "tree-leaves", | |||||
.image = "core::tile/leaves", | |||||
.isSolid = false, | |||||
}); | |||||
registerTile({ | |||||
.name = "tree-seeder", | |||||
.image = "core::tile/leaves", | .image = "core::tile/leaves", | ||||
.onSpawn = spawnTree, | |||||
}); | }); | ||||
registerTile({ | registerTile({ | ||||
.name = "torch", | .name = "torch", |
#include "tree.h" | |||||
#include <algorithm> | |||||
void spawnTree(const Swan::Context &ctx, Swan::TilePos pos) { | |||||
Swan::Tile::ID logID = ctx.world.getTileID("core::tree-trunk"); | |||||
Swan::Tile::ID leavesID = ctx.world.getTileID("core::tree-leaves"); | |||||
int height = 4 + Swan::random(pos.x) % 3; | |||||
for (int y = pos.y; y >= pos.y - height; --y) { | |||||
ctx.plane.setTileID({pos.x, y}, logID); | |||||
} | |||||
int radius = 2 + Swan::random(pos.x) % 2; | |||||
int radius2 = radius * radius; | |||||
Swan::TilePos top = pos - Swan::Vec2i{0, height}; | |||||
for (int ry = -radius; ry <= radius + 2; ++ry) { | |||||
for (int rx = -radius; rx <= radius; ++rx) { | |||||
if (rx == 0 && ry <= -radius / 2) { | |||||
continue; | |||||
} | |||||
int d2 = std::max( | |||||
ry * ry + rx * rx, | |||||
(ry + 1) * (ry + 1) + rx * rx); | |||||
if (d2 <= radius2) { | |||||
ctx.plane.setTileID(top - Swan::Vec2i{rx, ry}, leavesID); | |||||
} | |||||
} | |||||
} | |||||
} |
#pragma once | |||||
#include "swan/swan.h" | |||||
void spawnTree(const Swan::Context &ctx, Swan::TilePos pos); |