Tweaked the MapGen class to begin adding half-generated chunks.WIP Trees
* Added turbulence to biome noises, and made their sampling 2D. * Added bees and ravens to test animation library. * Added TNT to test large scale world destruction (some work needs to be done).master
parent
8065520c71
commit
dbcfe5c822
|
@ -5,79 +5,90 @@
|
|||
//
|
||||
|
||||
#include "MapGen.h"
|
||||
#include "../../util/Timer.h"
|
||||
#include "NoiseSample.h"
|
||||
|
||||
MapGen::MapGen(unsigned int seed, DefinitionAtlas& atlas, BiomeAtlas& biomes) :
|
||||
seed(seed),
|
||||
atlas(atlas),
|
||||
biomes(biomes) {
|
||||
MapGen::MapGen(unsigned int seed, DefinitionAtlas& defs, BiomeAtlas& biomes) :
|
||||
seed(seed),
|
||||
defs(defs),
|
||||
biomes(biomes) {
|
||||
|
||||
temperatureBase.SetSeed(seed);
|
||||
temperatureBase.SetFrequency(0.02);
|
||||
temperatureBase.SetOctaveCount(4);
|
||||
// temperatureTurbulance.Set
|
||||
temperature.SetSourceModule(0, temperatureBase);
|
||||
temperatureTurbulence.SetSourceModule(0, temperatureBase);
|
||||
temperatureTurbulence.SetRoughness(4);
|
||||
temperatureTurbulence.SetFrequency(0.2);
|
||||
temperature.SetSourceModule(0, temperatureTurbulence);
|
||||
temperature.SetScale(0.35);
|
||||
temperature.SetBias(0.25);
|
||||
|
||||
humidityBase.SetSeed(seed + 5);
|
||||
humidityBase.SetFrequency(0.02);
|
||||
humidityBase.SetOctaveCount(4);
|
||||
humidity.SetSourceModule(0, humidityBase);
|
||||
humidityTurbulence.SetSourceModule(0, humidityBase);
|
||||
humidityTurbulence.SetRoughness(4);
|
||||
humidityTurbulence.SetFrequency(0.2);
|
||||
humidity.SetSourceModule(0, humidityTurbulence);
|
||||
humidity.SetScale(0.5);
|
||||
humidity.SetBias(0.5);
|
||||
|
||||
roughnessBase.SetSeed(seed + 10);
|
||||
roughnessBase.SetFrequency(0.02);
|
||||
roughnessBase.SetOctaveCount(4);
|
||||
roughness.SetSourceModule(0, roughnessBase);
|
||||
roughnessTurbulence.SetSourceModule(0, roughnessBase);
|
||||
roughnessTurbulence.SetRoughness(4);
|
||||
roughnessTurbulence.SetFrequency(0.2);
|
||||
roughness.SetSourceModule(0, roughnessTurbulence);
|
||||
roughness.SetScale(0.5);
|
||||
roughness.SetBias(0.5);
|
||||
|
||||
treeMap.SetFrequency(1.25);
|
||||
treeMap.SetOctaveCount(4);
|
||||
treeAbs.SetSourceModule(0, treeMap);
|
||||
}
|
||||
|
||||
std::vector<BlockChunk*> MapGen::generateMapBlock(glm::vec3 mbPos) {
|
||||
std::array<std::pair<MapGenJob*, BlockChunk*>, 64> chunks{};
|
||||
MapGen::chunk_partials_map MapGen::generateMapBlock(glm::ivec3 mbPos) {
|
||||
chunk_partials_map chunks {};
|
||||
|
||||
// Go top down
|
||||
for (short i = 3; i >= 0; i--) {
|
||||
for (short j = 0; j < 4; j++) {
|
||||
for (short k = 0; k < 4; k++) {
|
||||
glm::vec3 pos{ j, i, k };
|
||||
generateChunk(chunks, pos, pos + mbPos * 4.f);
|
||||
glm::ivec3 pos = glm::ivec3(j, i, k) + (mbPos * 4);
|
||||
generateChunk(chunks, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<BlockChunk*> returns{};
|
||||
returns.reserve(64);
|
||||
for (auto& pair : chunks) {
|
||||
returns.push_back(pair.second);
|
||||
for (auto& chunk : chunks) {
|
||||
// Delete MapGenJobs
|
||||
delete chunk.second.first;
|
||||
chunk.second.first = nullptr;
|
||||
}
|
||||
|
||||
return returns;
|
||||
return chunks;
|
||||
}
|
||||
|
||||
void MapGen::generateChunk(std::array<std::pair<MapGenJob*, BlockChunk*>, 64>& chunks, glm::vec3 localPos, glm::vec3 worldPos) {
|
||||
unsigned short index = localPos.x + 4 * (localPos.y + 4 * localPos.z);
|
||||
auto& chunk = chunks[index];
|
||||
chunk.first = new MapGenJob();
|
||||
chunk.second = new BlockChunk();
|
||||
void MapGen::generateChunk(chunk_partials_map& chunks, glm::ivec3 worldPos) {
|
||||
if (chunks.count(worldPos) == 0) chunks.insert(std::pair<glm::ivec3, chunk_partial>{worldPos, {new MapGenJob(), new BlockChunk()}});
|
||||
auto& chunk = chunks.at(worldPos);
|
||||
chunk.second->pos = worldPos;
|
||||
|
||||
buildDensityMap(chunk.first, worldPos);
|
||||
buildElevationMap(chunks, chunk, localPos, worldPos);
|
||||
buildElevationMap(chunks, chunk);
|
||||
|
||||
populateChunk(chunk, worldPos);
|
||||
fillChunkBlocks(chunk);
|
||||
fillChunkStructures(chunk);
|
||||
}
|
||||
|
||||
void MapGen::buildDensityMap(MapGenJob* job, const glm::vec3& worldPos) {
|
||||
job->temperature = NoiseSample(temperature, worldPos, {4, 4}, false);
|
||||
job->humidity = NoiseSample(humidity, worldPos, {4, 4}, false);
|
||||
job->roughness = NoiseSample(roughness, worldPos, {4, 4}, false);
|
||||
void MapGen::buildDensityMap(MapGenJob* job, glm::ivec3 worldPos) {
|
||||
job->temperature = NoiseSample(temperature, {worldPos.x, 0, worldPos.z}, {4, 1}, true);
|
||||
job->humidity = NoiseSample(humidity, {worldPos.x, 0, worldPos.z}, {4, 1}, true);
|
||||
job->roughness = NoiseSample(roughness, {worldPos.x, 0, worldPos.z}, {4, 1}, true);
|
||||
|
||||
// TODO: This is... a travesty. Please stop doing this weird jank insertion into a
|
||||
// noisesample and create a proper constructor or *something*... could probs use a module owo
|
||||
|
||||
auto biome = biomes.getBiomeAt(job->temperature.get({}), job->humidity.get({}), job->roughness.get({}));
|
||||
|
||||
auto terrain = NoiseSample({4, 4});
|
||||
|
||||
float offsetH = 16.f / 4.f;
|
||||
|
@ -86,7 +97,6 @@ void MapGen::buildDensityMap(MapGenJob* job, const glm::vec3& worldPos) {
|
|||
for (int i = 0; i <= 4; i++) {
|
||||
for (int j = 0; j <= 4; j++) {
|
||||
for (int k = 0; k <= 4; k++) {
|
||||
//TODO: Find out why this is being stoopd
|
||||
glm::vec3 localPos = {(offsetH * i) / 1.01f, (offsetV * j) / 1.01f, (offsetH * k) / 1.01f};
|
||||
glm::vec3 pos = {(worldPos.x * 16 + offsetH * i) / 16.f, (worldPos.y * 16 + offsetV * j) / 16.f, (worldPos.z * 16 + offsetH * k) / 16.f};
|
||||
auto& biome = biomes.getBiomeAt(job->temperature.get(localPos), job->humidity.get(localPos), job->roughness.get(localPos));
|
||||
|
@ -103,10 +113,10 @@ void MapGen::buildDensityMap(MapGenJob* job, const glm::vec3& worldPos) {
|
|||
}
|
||||
}
|
||||
|
||||
void MapGen::buildElevationMap(std::array<std::pair<MapGenJob*, BlockChunk*>, 64>& chunks,
|
||||
std::pair<MapGenJob*, BlockChunk*>& chunk, const glm::vec3& localPos, const glm::vec3& worldPos) {
|
||||
|
||||
MapGenJob* upperChunk = nullptr;
|
||||
void MapGen::buildElevationMap(chunk_partials_map& chunks, chunk_partial& chunk) {
|
||||
glm::ivec3 worldPos = chunk.second->pos;
|
||||
MapGenJob* upperJob = nullptr;
|
||||
bool createdUpperJob = false;
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
const int x = i % 16;
|
||||
|
@ -114,20 +124,21 @@ void MapGen::buildElevationMap(std::array<std::pair<MapGenJob*, BlockChunk*>, 64
|
|||
|
||||
short depth = 16;
|
||||
|
||||
if (chunk.first->density[Space::Block::index({ x, 15, z })] > 0) {
|
||||
if (localPos.y < 3) {
|
||||
unsigned short index = localPos.x + 4 * (localPos.y + 1 + 4 * localPos.z);
|
||||
upperChunk = chunks[index].first;
|
||||
}
|
||||
if (upperChunk == nullptr) {
|
||||
upperChunk = new MapGenJob();
|
||||
buildDensityMap(upperChunk, worldPos + glm::vec3{ 0, 1, 0 });
|
||||
}
|
||||
if (chunk.first->density[Space::Block::index({x, 15, z})] > 0) {
|
||||
if (!upperJob) {
|
||||
glm::ivec3 rel = worldPos + glm::ivec3 {0, 1, 0};
|
||||
if (chunks.count(rel) != 0) upperJob = chunks.at(rel).first;
|
||||
else {
|
||||
// TODO: Consider pushing this into the partials array? Could be used to save some mapgen time.. but could also complicate the system.
|
||||
// If I do decide to do that I need to remove the delete command at the end of this function.
|
||||
upperJob = new MapGenJob();
|
||||
buildDensityMap(upperJob, rel);
|
||||
createdUpperJob = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 16; j++) {
|
||||
int ind = Space::Block::index({ x, j, z });
|
||||
|
||||
if (upperChunk->density[ind] <= 0) {
|
||||
if (upperJob->density[Space::Block::index({ x, j, z })] <= 0) {
|
||||
depth = j;
|
||||
break;
|
||||
}
|
||||
|
@ -137,23 +148,18 @@ void MapGen::buildElevationMap(std::array<std::pair<MapGenJob*, BlockChunk*>, 64
|
|||
|
||||
for (int y = 15; y >= 0; y--) {
|
||||
int ind = Space::Block::index({ x, y, z });
|
||||
|
||||
if (chunk.first->density[ind] > 0) {
|
||||
depth = std::min(depth + 1, 16);
|
||||
}
|
||||
else depth = 0;
|
||||
|
||||
depth = (chunk.first->density[ind] > 0 ? std::min(depth + 1, 16) : 0);
|
||||
chunk.first->depth[ind] = depth + (chunk.first->density[ind] - static_cast<int>(chunk.first->density[ind]));
|
||||
}
|
||||
}
|
||||
|
||||
if (localPos.y >= 3) delete upperChunk;
|
||||
if (createdUpperJob) delete upperJob;
|
||||
}
|
||||
|
||||
void MapGen::populateChunk(std::pair<MapGenJob*, BlockChunk*>& chunk, const glm::vec3& worldPos) {
|
||||
void MapGen::fillChunkBlocks(chunk_partial& chunk) {
|
||||
glm::ivec3 lp;
|
||||
|
||||
for (int m = 0; m < 4096; m++) {
|
||||
for (unsigned short m = 0; m < 4096; m++) {
|
||||
Vec::indAssignVec(m, lp);
|
||||
|
||||
auto biome = biomes.getBiomeAt(chunk.first->temperature.get(lp), chunk.first->humidity.get(lp), chunk.first->roughness.get(lp));
|
||||
|
@ -161,12 +167,44 @@ void MapGen::populateChunk(std::pair<MapGenJob*, BlockChunk*>& chunk, const glm:
|
|||
|
||||
int d = std::floor(chunk.first->depth[m]);
|
||||
|
||||
chunk.second->blocks[m] =
|
||||
d <= 1 ? DefinitionAtlas::AIR
|
||||
chunk.second->blocks[m]
|
||||
= d <= 1 ? DefinitionAtlas::AIR
|
||||
: d <= 2 ? biome.topBlock
|
||||
: d <= 4 ? biome.soilBlock
|
||||
: biome.rockBlock;
|
||||
}
|
||||
|
||||
chunk.second->mgRegenEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
void MapGen::fillChunkStructures(chunk_partial& chunk) {
|
||||
unsigned int cWood = defs.blockFromStr("zeus:default:wood").index;
|
||||
unsigned int cLeaves = defs.blockFromStr("zeus:default:leaves").index;
|
||||
|
||||
glm::ivec3 wp = chunk.second->pos;
|
||||
glm::ivec3 lp;
|
||||
|
||||
for (unsigned short m = 0; m < 4096; m++) {
|
||||
Vec::indAssignVec(m, lp);
|
||||
|
||||
glm::ivec3 p = wp * 16 + lp;
|
||||
|
||||
if (treeAbs.GetValue(p.x, p.y, p.z) > 1.2 && chunk.first->density[m] <= 2 && chunk.first->density[m] > 1) {
|
||||
glm::ivec3 rp {};
|
||||
for (unsigned int i = 0; i < 5; i++) {
|
||||
rp.x = lp.x - 2 + i;
|
||||
for (unsigned int j = 0; j < 5; j++) {
|
||||
rp.z = lp.z - 2 + j;
|
||||
for (unsigned int k = 0; k < 2; k++) {
|
||||
rp.y = lp.y + 3 + k;
|
||||
chunk.second->setBlock(rp, cLeaves);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < 5; i++) {
|
||||
chunk.second->setBlock(lp, cWood);
|
||||
if (++lp.y > 15) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,39 +18,45 @@ using namespace noise;
|
|||
|
||||
class MapGen {
|
||||
public:
|
||||
typedef std::pair<MapGenJob*, BlockChunk*> chunk_partial;
|
||||
typedef std::unordered_map<glm::ivec3, chunk_partial, Vec::ivec3> chunk_partials_map;
|
||||
|
||||
MapGen(unsigned int seed, DefinitionAtlas& atlas, BiomeAtlas& biome);
|
||||
std::vector<BlockChunk*> generateMapBlock(glm::vec3 mbPos);
|
||||
chunk_partials_map generateMapBlock(glm::ivec3 mbPos);
|
||||
private:
|
||||
void generateChunk(std::array<std::pair<MapGenJob*, BlockChunk*>, 64>& chunks, glm::vec3 localPos, glm::vec3 worldPos);
|
||||
// Generate a chunk at `worldPos`, and place it & any partials in `chunks`.
|
||||
void generateChunk(chunk_partials_map& chunks, glm::ivec3 worldPos);
|
||||
|
||||
void buildDensityMap(MapGenJob* job, const glm::vec3& worldPos);
|
||||
void buildElevationMap(std::array<std::pair<MapGenJob*, BlockChunk*>, 64>& chunks,
|
||||
std::pair<MapGenJob*, BlockChunk*>& chunk, const glm::vec3& localPos, const glm::vec3& worldPos);
|
||||
// Build the density map for a job.
|
||||
void buildDensityMap(MapGenJob* job, glm::ivec3 worldPos);
|
||||
|
||||
void populateChunk(std::pair<MapGenJob*, BlockChunk*>& chunk, const glm::vec3& worldPos);
|
||||
// Build the elevation map for a chunk, which uses the `chunks` partials array for efficiency.
|
||||
void buildElevationMap(chunk_partials_map& chunks, chunk_partial& chunk);
|
||||
|
||||
// Fill a chunk with blocks and any structures that should be included, may generate partials.
|
||||
// Returns chunks in the `chunk` vector.
|
||||
void fillChunkBlocks(chunk_partial& chunk);
|
||||
|
||||
// Fill a chunk with structures
|
||||
void fillChunkStructures(chunk_partial& chunk);
|
||||
|
||||
unsigned int seed = 0;
|
||||
|
||||
DefinitionAtlas& atlas;
|
||||
DefinitionAtlas& defs;
|
||||
BiomeAtlas& biomes;
|
||||
|
||||
module::Perlin temperatureBase;
|
||||
// module::Turbulence temperatureTurbulence;
|
||||
module::Turbulence temperatureTurbulence;
|
||||
module::ScaleBias temperature;
|
||||
|
||||
module::Perlin humidityBase;
|
||||
// module::Turbulence humidityTurbulence;
|
||||
module::Turbulence humidityTurbulence;
|
||||
module::ScaleBias humidity;
|
||||
|
||||
module::Perlin roughnessBase;
|
||||
// module::Turbulence roughnessTurbulence;
|
||||
module::Turbulence roughnessTurbulence;
|
||||
module::ScaleBias roughness;
|
||||
|
||||
// module::Perlin worldElevationBase;
|
||||
// module::ScaleBias worldElevationScaled;
|
||||
//
|
||||
// module::Perlin worldFeatureBase;
|
||||
// module::ScaleBias worldFeatureScaled;
|
||||
//
|
||||
// module::Add worldSmoothElevation;
|
||||
module::Perlin treeMap;
|
||||
module::Abs treeAbs;
|
||||
};
|
|
@ -19,8 +19,6 @@ public:
|
|||
|
||||
void set(glm::ivec3 pos, float value);
|
||||
float get(const glm::ivec3& pos);
|
||||
|
||||
|
||||
private:
|
||||
void reserveSpace();
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ MeshPart::MeshPart(const std::vector<BlockModelVertex>& vertices, const std::vec
|
|||
//Store the old positions in texUVs
|
||||
vertex.texUVs.x = vertex.tex.x;
|
||||
vertex.texUVs.y = vertex.tex.y;
|
||||
//Generate solid coordinates for the atlas positions
|
||||
//Generate solid coordinates for the defs positions
|
||||
vertex.tex.x = uv.x + ((uv.z - uv.x) * vertex.tex.x);
|
||||
vertex.tex.y = uv.y + ((uv.w - uv.y) * vertex.tex.y);
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ std::shared_ptr<AtlasRef> TextureAtlas::addImage(unsigned char *data, const std:
|
|||
auto space = findImageSpace(tileWidth, tileHeight);
|
||||
|
||||
if (space.x < 0) {
|
||||
std::cout << Log::err << "Failed to find space in dynamic atlas." << Log::endl;
|
||||
std::cout << Log::err << "Failed to find space in dynamic defs." << Log::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ std::vector<std::shared_ptr<BlockChunk>> WorldGenStream::update() {
|
|||
|
||||
if (!u.chunks.empty()) {
|
||||
for (auto chunk : u.chunks) {
|
||||
finishedChunks.push_back(std::shared_ptr<BlockChunk>(chunk));
|
||||
finishedChunks.push_back(std::shared_ptr<BlockChunk>(chunk.second.second));
|
||||
}
|
||||
u.chunks.clear();
|
||||
}
|
||||
|
@ -70,15 +70,12 @@ void WorldGenStream::threadFunction(WorldGenStream::Thread *thread) {
|
|||
bool empty = true;
|
||||
for (Unit& u : thread->tasks) {
|
||||
if (!u.unlocked) {
|
||||
|
||||
empty = false;
|
||||
u.chunks = thread->gen->generateMapBlock(u.pos);
|
||||
u.unlocked = true;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (empty) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ public:
|
|||
std::vector<std::shared_ptr<BlockChunk>> update();
|
||||
|
||||
struct Unit {
|
||||
glm::vec3 pos {};
|
||||
std::vector<BlockChunk*> chunks {};
|
||||
glm::ivec3 pos {};
|
||||
MapGen::chunk_partials_map chunks {};
|
||||
|
||||
bool unlocked = true;
|
||||
};
|
||||
|
|
|
@ -178,7 +178,6 @@ bool LocalDimension::setBlock(glm::ivec3 pos, unsigned int block) {
|
|||
|
||||
void LocalDimension::attemptMeshChunk(const sptr<BlockChunk>& chunk, bool updateAdjacents) {
|
||||
// if (!chunk->dirty) return; //TODO
|
||||
|
||||
auto dirs = Vec::cardinalVectors;
|
||||
bool allExists = true;
|
||||
for (auto dir : dirs) {
|
||||
|
@ -187,9 +186,15 @@ void LocalDimension::attemptMeshChunk(const sptr<BlockChunk>& chunk, bool update
|
|||
}
|
||||
}
|
||||
|
||||
if (allExists && chunk->shouldRender()) {
|
||||
chunk->dirty = false;
|
||||
pendingMesh.push_back(chunk->pos);
|
||||
if (allExists) {
|
||||
if (chunk->shouldRender()) {
|
||||
pendingMesh.push_back(chunk->pos);
|
||||
}
|
||||
else {
|
||||
removeMeshChunk(chunk->pos);
|
||||
}
|
||||
|
||||
chunk->dirty = false; //TODO: Make dirty work
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,32 +23,29 @@ BlockChunk::BlockChunk(const std::array<unsigned int, 4096>& blocks, const std::
|
|||
}
|
||||
}
|
||||
|
||||
renderedEmpty = empty;
|
||||
shouldHaveMesh = empty;
|
||||
}
|
||||
|
||||
bool BlockChunk::shouldRender() {
|
||||
bool should = !empty || !renderedEmpty;
|
||||
renderedEmpty = true;
|
||||
return should;
|
||||
return shouldHaveMesh;
|
||||
}
|
||||
|
||||
bool BlockChunk::setBlock(const glm::ivec3& pos, unsigned int block) {
|
||||
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return false;
|
||||
unsigned int ind = Space::Block::index(pos);
|
||||
if (ind >= (int)pow(16, 3)) return false;
|
||||
|
||||
if (blocks[ind] != block) {
|
||||
if (block == 0) {
|
||||
this->fullBlocks--;
|
||||
if (this->fullBlocks == 0) {
|
||||
std::cout << "Empty" << std::endl;
|
||||
this->empty = true;
|
||||
this->renderedEmpty = false;
|
||||
if (block == DefinitionAtlas::AIR) {
|
||||
fullBlocks--;
|
||||
if (fullBlocks == 0) {
|
||||
empty = true;
|
||||
shouldHaveMesh = false;
|
||||
}
|
||||
}
|
||||
else if (blocks[ind] == 0) {
|
||||
this->fullBlocks++;
|
||||
this->empty = false;
|
||||
this->renderedEmpty = true;
|
||||
else if (blocks[ind] == DefinitionAtlas::AIR) {
|
||||
if (fullBlocks == 0) shouldHaveMesh = true;
|
||||
empty = false;
|
||||
fullBlocks++;
|
||||
}
|
||||
|
||||
blocks[ind] = block;
|
||||
|
@ -189,5 +186,5 @@ void BlockChunk::mgRegenEmpty() {
|
|||
}
|
||||
}
|
||||
|
||||
renderedEmpty = empty;
|
||||
shouldHaveMesh = empty;
|
||||
}
|
|
@ -44,7 +44,7 @@ public:
|
|||
Packet serialize();
|
||||
void deserialize(Packet& packet);
|
||||
|
||||
bool renderedEmpty = true;
|
||||
bool shouldHaveMesh = true;
|
||||
bool dirty = true;
|
||||
|
||||
glm::ivec3 pos;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "@aurailus:tnt",
|
||||
"description": "Bet you've never seen this one before.",
|
||||
"version": "0.0.1"
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
zepha.register_block("@aurailus:tnt:tnt", {
|
||||
name = "TNT",
|
||||
model = "base:block",
|
||||
textures = {
|
||||
"@aurailus:tnt:tnt_top",
|
||||
"@aurailus:tnt:tnt_bottom",
|
||||
"@aurailus:tnt:tnt_side"
|
||||
},
|
||||
toughness = {
|
||||
hand = 3,
|
||||
shovel = 1,
|
||||
pick = 2
|
||||
},
|
||||
drop = "@aurailus:tnt:tnt",
|
||||
on_break = function(pos)
|
||||
local amp = 20
|
||||
for i = -amp, amp do
|
||||
for j = -amp, amp do
|
||||
for k = -amp, amp do
|
||||
local offset = v{i, j, k}
|
||||
if vector.distance(v{}, offset) < amp then
|
||||
zepha.set_block(vector.add(pos, offset), "air")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
Binary file not shown.
After Width: | Height: | Size: 435 B |
Binary file not shown.
After Width: | Height: | Size: 929 B |
Binary file not shown.
After Width: | Height: | Size: 859 B |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,5 @@
|
|||
runfile(_PATH .. "dropped_item")
|
||||
runfile(_PATH .. "rabbit")
|
||||
runfile(_PATH .. "raven")
|
||||
runfile(_PATH .. "bee")
|
||||
runfile(_PATH .. "test")
|
|
@ -0,0 +1,30 @@
|
|||
local friendly = false
|
||||
|
||||
zepha.register_entity("zeus:default:bee", {
|
||||
display = "model",
|
||||
display_object = "zeus:default:bee",
|
||||
display_texture = "zeus:default:bee",
|
||||
|
||||
on_create = function(self)
|
||||
self.object:set_scale(1/12)
|
||||
|
||||
self.object.anims:define({
|
||||
fly = {1, 45}
|
||||
})
|
||||
|
||||
self.object.anims:set_anim("fly"):play()
|
||||
end,
|
||||
on_update = function(self, delta)
|
||||
self.object:set_pos({
|
||||
x = self.object.pos.x + 0.03 * math.sin(math.rad(self.object.yaw + 90)),
|
||||
y = self.object.pos.y,
|
||||
z = self.object.pos.z + 0.03 * math.cos(math.rad(self.object.yaw + 90))})
|
||||
self.object.yaw = self.object.yaw + 2
|
||||
end
|
||||
})
|
||||
|
||||
zepha.register_keybind("zeus:default:spawn_bee", {
|
||||
description = "Spawn Bee",
|
||||
default = zepha.keys.b,
|
||||
on_press = function() zepha.add_entity("zeus:default:bee", vector.add(zepha.player.pos, v{0, 1.7, 0})) end
|
||||
})
|
|
@ -0,0 +1,48 @@
|
|||
local friendly = false
|
||||
|
||||
zepha.register_entity("zeus:default:raven", {
|
||||
display = "model",
|
||||
display_object = "zeus:default:bird",
|
||||
display_texture = "zeus:default:raven",
|
||||
|
||||
on_create = function(self)
|
||||
self.object:set_scale(1/16)
|
||||
|
||||
self.object.anims:define({
|
||||
fly = {1, 100},
|
||||
preen = {101, 200},
|
||||
hover = {202, 260}
|
||||
})
|
||||
|
||||
self.object.anims:set_anim("hover"):play()
|
||||
end,
|
||||
on_update = function(self, delta)
|
||||
local dist = vector.distance(zepha.player.pos, self.object.pos)
|
||||
|
||||
if dist < 5 and not self.targeting then
|
||||
self.targeting = true
|
||||
self.object.anims:set_anim("fly"):play()
|
||||
elseif dist > 6 and self.targeting then
|
||||
self.targeting = false
|
||||
self.object.anims:set_anim("hover"):play()
|
||||
end
|
||||
|
||||
if self.targeting then
|
||||
self.object.pos = v {
|
||||
self.object.pos.x + 0.08 * math.sin(math.rad(self.object.yaw)),
|
||||
self.object.pos.y,
|
||||
self.object.pos.z + 0.08 * math.cos(math.rad(self.object.yaw))
|
||||
}
|
||||
|
||||
self.object.yaw = math.deg(math.atan2(zepha.player.pos.x - self.object.pos.x, zepha.player.pos.z - self.object.pos.z)) + 180
|
||||
else
|
||||
self.object.yaw = math.deg(math.atan2(zepha.player.pos.x - self.object.pos.x, zepha.player.pos.z - self.object.pos.z))
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
zepha.register_keybind("zeus:default:spawn_raven", {
|
||||
description = "Spawn Raven",
|
||||
default = zepha.keys.z,
|
||||
on_press = function() zepha.add_entity("zeus:default:raven", vector.add(zepha.player.pos, v{0, 1.7, 0})) end
|
||||
})
|
|
@ -5,6 +5,7 @@ runfile(_PATH .. "entity/_index")
|
|||
runfile(_PATH .. "biomes/_index")
|
||||
|
||||
local blockTypes = {
|
||||
"@aurailus:tnt:tnt",
|
||||
"zeus:default:grass_slab",
|
||||
"zeus:kinetic:axle_0",
|
||||
"zeus:default:stone",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 856 B |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Loading…
Reference in New Issue