| '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); |