set(SOURCES_COMMON
array.c
+ biome.c
bintree.c
list.c
map.c
--- /dev/null
+#include "biome.h"
+#include "perlin.h"
+
+int seed = 0;
+
+f64 get_wetness(v3s32 pos)
+{
+ return smooth2d((((u32) 1 << 31) + pos.x) / 128.0, (((u32) 1 << 31) + pos.z) / 128.0, 0, 3) * 0.5 + 0.5;
+}
--- /dev/null
+#ifndef _BIOME_H_
+#define _BIOME_H_
+
+#include "types.h"
+
+typedef enum
+{
+ SO_HEIGHT,
+ SO_MOUNTAIN_FACTOR,
+ SO_MOUNTAIN_HEIGHT,
+ SO_BOULDER_CENTER,
+ SO_BOULDER,
+ SO_WETNESS,
+} SeedOffset;
+
+f64 get_wetness(v3s32 pos);
+
+extern int seed;
+
+#endif
static void make_vertices(Object *object, MapBlock *block)
{
+ v3s32 node_bp = {block->pos.x * MAPBLOCK_SIZE, block->pos.y * MAPBLOCK_SIZE, block->pos.z * MAPBLOCK_SIZE};
+
ITERATE_MAPBLOCK {
MapNode *node = &block->data[x][y][z];
if (npos.x >= 0 && npos.x < MAPBLOCK_SIZE && npos.y >= 0 && npos.y < MAPBLOCK_SIZE && npos.z >= 0 && npos.z < MAPBLOCK_SIZE)
neighbor = block->data[npos.x][npos.y][npos.z].type;
else {
- MapNode nn = map_get_node(client_map.map, (v3s32) {npos.x + block->pos.x * MAPBLOCK_SIZE, npos.y + block->pos.y * MAPBLOCK_SIZE, npos.z + block->pos.z * MAPBLOCK_SIZE});
+ MapNode nn = map_get_node(client_map.map, (v3s32) {npos.x + node_bp.x, npos.y + node_bp.y, npos.z + node_bp.z});
neighbor = nn.type;
}
vertex.position.z += offset.z;
if (client_def->render)
- client_def->render(node, &vertex);
+ client_def->render((v3s32) {x + node_bp.x, y + node_bp.y, z + node_bp.z}, node, &vertex);
object_add_vertex(object, &vertex);
}
+#include "biome.h"
#include "client/client.h"
#include "client/client_node.h"
#include "node.h"
-static void render_state_biome(MapNode *node, Vertex3D *vertex)
+static void render_state_biome(v3s32 pos, __attribute__((unused)) MapNode *node, Vertex3D *vertex)
{
- vertex->color.h = node->state.biome.x;
- vertex->color.s = node->state.biome.y;
- vertex->color.v = node->state.biome.z;
+ double min, max;
+ min = 0.15;
+ max = 0.45;
+
+ vertex->color.h = get_wetness(pos) * (max - min) + min;
+ vertex->color.s = 1.0f;
+ vertex->color.v = 1.0f;
}
ClientNodeDefintion client_node_definitions[NODE_UNLOADED] = {
{
char *texture_path;
Texture *texture;
- void (*render)(MapNode *node, Vertex3D *vertex);
+ void (*render)(v3s32 pos, MapNode *node, Vertex3D *vertex);
} ClientNodeDefintion;
extern ClientNodeDefintion client_node_definitions[];
{
MapNode node;
node.type = type;
- memset(&node.state, 0, sizeof(NodeState));
if (node.type != NODE_UNLOADED && node_definitions[node.type].create)
node_definitions[node.type].create(&node);
typedef struct MapNode
{
Node type;
- NodeState state;
} MapNode;
typedef MapNode MapBlockData[MAPBLOCK_SIZE][MAPBLOCK_SIZE][MAPBLOCK_SIZE];
#include "node.h"
#include "util.h"
-static void create_state_biome(MapNode *node)
-{
- node->state.biome = (v3f32) {1.0f, 0.0f, 1.0f};
-}
-
NodeDefintion node_definitions[NODE_UNLOADED] = {
// invalid
{
{
.visible = true,
.solid = true,
- .create = &create_state_biome,
- .serialize = NULL, // currently v3f is not serialized
+ .create = NULL,
+ .serialize = NULL,
.deserialize = NULL,
},
// dirt
#include <stdbool.h>
#include "types.h"
-typedef v3f32 NodeStateBiome;
-
-typedef union
-{
- NodeStateBiome biome;
-} NodeState;
-
typedef enum
{
NODE_INVALID, // Used for unknown nodes received from server (caused by outdated clients)
#include <stdio.h>
#include <math.h>
+#include "biome.h"
#include "perlin.h"
#include "server/mapgen.h"
#include "server/server_map.h"
u32 ux = x + block->pos.x * MAPBLOCK_SIZE + ((u32) 1 << 31);
for (u8 z = 0; z < MAPBLOCK_SIZE; z++) {
u32 uz = z + block->pos.z * MAPBLOCK_SIZE + ((u32) 1 << 31);
- s32 height = smooth2d(ux / 32.0, uz / 32.0, 0, 0) * 16.0 + 128.0;
+ s32 height = smooth2d(ux / 32.0, uz / 32.0, 0, seed + SO_HEIGHT) * 16.0 + 128.0;
bool is_mountain = false;
- double mountain_factor = (smooth2d(ux / 1000.0, uz / 1000.0, 0, 1) - 0.3) * 5.0;
+ double mountain_factor = (smooth2d(ux / 1000.0, uz / 1000.0, 0, seed + SO_MOUNTAIN_FACTOR) - 0.3) * 5.0;
if (mountain_factor > 0.0) {
- height = pow(height * pow(((smooth2d(ux / 50.0, uz / 50.0, 2, 2) + 1.0) * 256.0 + 128.0), mountain_factor), 1.0 / (mountain_factor + 1.0));
+ height = pow(height * pow(((smooth2d(ux / 50.0, uz / 50.0, 2, seed + SO_MOUNTAIN_HEIGHT) + 1.0) * 256.0 + 128.0), mountain_factor), 1.0 / (mountain_factor + 1.0));
is_mountain = true;
}
else if (diff < 1)
node = (is_mountain && ay > 256) ? NODE_SNOW : NODE_AIR;
- if (! is_mountain && diff == 0 && (smooth2d(x + block->pos.x * 16, z + block->pos.z * 16, 0, 3) * 0.5 + 0.5) < 0.0001f) {
+ if (! is_mountain && diff == 0 && (smooth2d(x + block->pos.x * 16, z + block->pos.z * 16, 0, seed + SO_BOULDER_CENTER) * 0.5 + 0.5) < 0.0001f) {
for (s8 bx = -1; bx <= 1; bx++) {
for (s8 by = -1; by <= 1; by++) {
for (s8 bz = -1; bz <= 1; bz++) {
v3s32 pos = {block->pos.x * MAPBLOCK_SIZE + x + bx, block->pos.y * MAPBLOCK_SIZE + y + by, block->pos.z * MAPBLOCK_SIZE + z + bz};
- if (smooth3d(pos.x, pos.y, pos.z, 0, 4) > 0.0)
+ if (smooth3d(pos.x, pos.y, pos.z, 0, seed + SO_BOULDER) > 0.0)
set_node(pos, map_node_create(NODE_STONE), MGS_BOULDERS, changed_blocks);
}
}
if (extra->mgs_buffer[x][y][z] <= MGS_TERRAIN) {
block->data[x][y][z] = map_node_create(node);
extra->mgs_buffer[x][y][z] = MGS_TERRAIN;
-
- if (node == NODE_GRASS) {
- double min, max;
- min = 0.15;
- max = 0.45;
- block->data[x][y][z].state.biome.x = (smooth2d(ux / 128.0, uz / 128.0, 0, 3) * 0.5 + 0.5) * (max - min) + min;
- block->data[x][y][z].state.biome.y = 1.0;
- }
}
pthread_mutex_unlock(&block->mtx);
}
{ \
return a.x == b.x && a.y == b.y; \
} \
+ v2 ## type v2 ## type ## _add(v2 ## type a, v2 ## type b) \
+ { \
+ return (v2 ## type) {a.x + b.x, a.y + b.y}; \
+ } \
bool read_v3 ## type(int fd, v3 ## type *ptr) \
{ \
READVEC(type, 3) \
bool v3 ## type ## _equals(v3 ## type a, v3 ## type b) \
{ \
return a.x == b.x && a.y == b.y && a.z == b.z; \
+ } \
+ v3 ## type v3 ## type ## _add(v3 ## type a, v3 ## type b) \
+ { \
+ return (v3 ## type) {a.x + b.x, a.y + b.y, a.z + b.z}; \
}
#define DEFTYP(type, bits) \
DEFRW(v2 ## type) \
DEFBOX(2 ## type) \
bool v2 ## type ## _equals(v2 ## type a, v2 ## type b); \
+ v2 ## type v2 ## type ## _add(v2 ## type a, v2 ## type b); \
typedef struct {type x, y, z;} v3 ## type; \
DEFRW(v3 ## type) \
DEFBOX(3 ## type) \
bool v3 ## type ## _equals(v3 ## type a, v3 ## type b); \
+ v3 ## type v3 ## type ## _add(v3 ## type a, v3 ## type b);
#define DEFTYP(from, to) \
typedef from to; \