summaryrefslogtreecommitdiff
path: root/src/game/worldgen.cpp
blob: f7d4757b23f6c9c8616c15ba2a8a9939a2af2c08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "game.hpp"

namespace game {

using namespace world;

static void add_entity(world_t *world, state_t *game, v2f_t x)
{
	float noise;
	deco_t *deco;
	deco_type_t type;
	v2f_t center, offset;

	noise = world->perlin.get(x, 0.53213f) + world->perlin.get(x, 0.12994f);
	noise = fabs(noise / 2);

	if (noise < 0.16)
		return;

	offset[0] = world->perlin.get(x, 0.17331f);
	offset[1] = world->perlin.get(x, 0.19571f);
	center = x + v2f_t(0.5f, 0.5f) + offset.norm() * 0.1;

	if (noise > 0.42) {
		unit_nest_t *nest = new unit_nest_t(game);
		nest->place(world, center);
		return;
	} else if (noise > 0.39) {
		unit_spider_t *spider = new unit_spider_t(game);
		spider->place(world, center);
		return;
	}

	if (noise > 0.36)
		type = DECO_EYETHING;
	else if (noise > 0.33)
		type = DECO_STONE;
	else if (noise > 0.26)
		type = DECO_SPIKE;
	else if (noise > 0.20)
		type = DECO_SPIKE_SMALL;
	else
		type = DECO_STONE_SMALL;

	deco = new deco_t(game, type);
	deco->phase_shift = offset[0] * 500.0;
	deco->place(world, center);
}

void worldgen(world_t *world, sector_index_t index, sector_t *sector,
             bool gen_tiles, bool gen_decos, void *data)
{
	state_t *game = (game::state_t*)data;

	if (!gen_tiles)
		goto decos;

	for (coord_t ly = 0; ly < SECTOR_SIZE; ly++)
	for (coord_t lx = 0; lx < SECTOR_SIZE; lx++) {
		tile_t *tile = sector->tiles + ly * SECTOR_SIZE + lx;
		tile_index_t tile_index(index[0] * SECTOR_SIZE + lx,
		                        index[1] * SECTOR_SIZE + ly);
		v2f_t x;
		float waterlevel, height;

		x = v2f_t(index) * SECTOR_SIZE + v2f_t(lx, ly);

		waterlevel = world->perlin.get(x, 1000.0f) * 0.3f +
			     world->perlin.get(x, 500.0f) * 0.1f;

		height = world->perlin.get(x, 40.0f) * 0.6f +
			 world->perlin.get(x, 20.0f) * 0.25f +
			 world->perlin.get(x, 10.0f) * 0.2f +
			 world->perlin.get(x, 4.0f) * 0.1f +
			 world->perlin.get(x, 1.0f) * 0.05f;

		if (height < waterlevel)
			tile->type = TILE_WATER;
		else if (height < waterlevel + 0.1)
			tile->type = TILE_DIRT;
		else if (world->perlin.get(x, 3.0f) > 0.0f)
			tile->type = TILE_STONE;
		else
			tile->type = TILE_DIRT;
	}

decos:
	if (!gen_decos)
		return;

	for (coord_t ly = 0; ly < SECTOR_SIZE; ly++)
	for (coord_t lx = 0; lx < SECTOR_SIZE; lx++) {
		tile_t *tile = sector->tiles + ly * SECTOR_SIZE + lx;
		tile_index_t tile_index(index[0] * SECTOR_SIZE + lx,
		                        index[1] * SECTOR_SIZE + ly);
		v2f_t x;

		x = v2f_t(index) * SECTOR_SIZE + v2f_t(lx, ly);

		if (tile->type == TILE_DIRT)
			add_entity(world, game, x);
	}
}

}