aboutsummaryrefslogtreecommitdiffstats
path: root/src/world.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/world.c')
-rw-r--r--src/world.c333
1 files changed, 172 insertions, 161 deletions
diff --git a/src/world.c b/src/world.c
index deb3b97..fced57d 100644
--- a/src/world.c
+++ b/src/world.c
@@ -412,166 +412,6 @@ void averageOutAreaWorld(const World* world, Color* heightmap, Rectangle area)
setWorldAreaToHeight(heightmap, area, height);
}
-Seed generatePond(World* world, Color* heightmap, WorldUID* placeId,
- WorldUID* id, Seed seed)
-{
- // Create pond entity.
- Vector3 position = getRandomPositionFromCenter(world, &seed,
- PLACE_POND_MIN_DISTANCE,
- PLACE_POND_MAX_DISTANCE);
- Entity pond = createEntity(POND, position);
- world->entities[*id] = pond;
- world->places[*placeId] = *id;
-
- *id = *id + 1;
- *placeId = *placeId + 1;
-
- // Get lowest height.
- int height = 255;
-
- Vector2 start = worldPositionToPixel(world, pond.box.min.x, pond.box.min.z);
- Vector2 end = worldPositionToPixel(world, pond.box.max.x, pond.box.max.z);
-
- for (int y = start.y; y < end.y; ++y)
- {
- for (int x = start.x; x < end.x; ++x)
- {
- int pixelHeight = heightmap[y * WORLD_IMAGE_WIDTH + x].r;
-
- if (pixelHeight < height)
- {
- height = pixelHeight;
- }
- }
- }
-
- height -= PLACE_POND_DEPTH * (world->size.y / 255.0 * 2.0);
-
- // Set new height.
- int area = PLACE_POND_OUTER_AREA;
- int edge = PLACE_POND_DEPTH * (world->size.y / 255.0 * 2.0) / 4.0 + height;
-
- for (int y = start.y - area; y < end.y + area; ++y)
- {
- for (int x = start.x - area; x < end.x + area; ++x)
- {
- if ((x == start.x || x == end.x || // Closest edge.
- y == start.y || y == end.y) &&
- (x >= start.x && x <= end.x &&
- y >= start.y && y <= end.y))
- {
- heightmap[y * WORLD_IMAGE_WIDTH + x] = (Color){edge, edge, edge, 255};
- }
- else if (x < start.x || x > end.x || // Smooth out rest of the edge.
- y < start.y || y > end.y)
- {
- int distance = Vector2Distance(
- (Vector2){x, y},
- Vector2Scale(Vector2Add(start, end), 0.5));
- int edgeHeight = distance + edge;
-
- // Average out the heights.
- if (distance > Vector2Distance(start, end) / 2.0 +
- PLACE_POND_WALKING_AREA)
- {
- edgeHeight += heightmap[y * WORLD_IMAGE_WIDTH + x].r;
- edgeHeight /= 2;
- }
-
- heightmap[y * WORLD_IMAGE_WIDTH + x] =
- (Color){edgeHeight, edgeHeight, edgeHeight, 255};
- }
- else
- {
- heightmap[y * WORLD_IMAGE_WIDTH + x] =
- (Color){height, height, height, 255};
- }
- }
- }
-
- return seed;
-}
-
-void generateWorldSamanthasPlace(World* world, const Assets* assets,
- Color* heightmap, WorldUID* placeId,
- WorldUID* id)
-{
- // Make area flat.
- float width = SAMANTHAS_SPOT_SIZE * (WORLD_IMAGE_WIDTH / world->size.x)
- * 2.0;
- float height = SAMANTHAS_SPOT_SIZE * (WORLD_IMAGE_HEIGHT / world->size.z)
- * 2.0;
-
- Rectangle area = (Rectangle){
- .x = WORLD_IMAGE_WIDTH / 2.0 - width / 2.0,
- .y = WORLD_IMAGE_HEIGHT / 2.0 - height / 2.0,
- .width = width,
- .height = height
- };
-
- averageOutAreaWorld(world, heightmap, area);
-
- // Samanthas spot.
- Vector3 center = Vector3Scale(world->size, 0.5);
- Entity spot = createEntity(SAMANTHAS_SPOT, center);
- world->entities[*id] = spot;
- world->places[*placeId] = *id;
-
- *id = *id + 1;
- *placeId = *placeId + 1;
-
- // Samantha.
- Entity samantha = createEntity(SAMANTHA, Vector3Add(center,
- SAMANTHA_OFFSET));
- world->entities[*id] = samantha;
- *id = *id + 1;
-
- // Trashcans yippee!
- Vector3 trashPosition = (Vector3){-SAMANTHAS_SPOT,
- 0.0,
- SAMANTHAS_SPOT_SIZE / 2.0};
-
- for (int index = 0; index < SAMANTHAS_SPOT_TRASHCAN_COUNT; ++index)
- {
- Entity trashcan = createEntity(TRASHCAN,
- Vector3Add(trashPosition, center));
- world->entities[*id] = trashcan;
- *id = *id + 1;
- trashPosition.x += (float)(SAMANTHAS_SPOT_SIZE * 2.0)
- / SAMANTHAS_SPOT_TRASHCAN_COUNT;
- }
-
- // Trash and medical trash yippee!
- trashPosition = (Vector3){-SAMANTHAS_SPOT,
- 0.0,
- SAMANTHAS_SPOT_SIZE / 1.5};
-
- for (int index = 0; index < SAMANTHAS_SPOT_TRASH_COUNT; ++index)
- {
- Entity trash = createEntity(index % 2 == 0 ? TRASH : MEDICAL_TRASH,
- Vector3Add(trashPosition, center));
- world->entities[*id] = trash;
- *id = *id + 1;
- trashPosition.x += (float)(SAMANTHAS_SPOT_SIZE * 2.0)
- / SAMANTHAS_SPOT_TRASH_COUNT;
- }
-
- // Floor.
- Mesh floor = GenMeshPlane(SAMANTHAS_SPOT_SIZE * 2.0,
- SAMANTHAS_SPOT_SIZE * 2.0,
- 2, 2);
- world->samanthasSpotFloor = LoadModelFromMesh(floor);
- world->samanthasSpotFloor.materials[0].maps[MATERIAL_MAP_DIFFUSE]
- .texture = assets->textures[SAMANTHA_FLOOR_TEXTURE];
-}
-
-void generateJohnsShop(World* world, Color* colors, WorldUID* placeId)
-{
- Vector3 position = Vector3Scale(world->size, 0.5);
- Entity johnsShop = createEntity(JOHNS_STORE, position);
- world->entities[*placeId] = johnsShop;
-}
-
Seed generateWorldPlants(World* world, Seed seed, int start, int end)
{
for (int index = start; index < end; ++index)
@@ -745,17 +585,188 @@ Seed generateWorldCharacters(World* world, Seed seed, WorldUID start)
return seed;
}
+Seed generateWorldPond(World* world, Color* heightmap, WorldUID* placeId,
+ WorldUID* id, Seed seed)
+{
+ // Create pond entity.
+ Vector3 position = getRandomPositionFromCenter(world, &seed,
+ PLACE_POND_MIN_DISTANCE,
+ PLACE_POND_MAX_DISTANCE);
+ Entity pond = createEntity(POND, position);
+ world->entities[*id] = pond;
+ world->places[*placeId] = *id;
+
+ *id = *id + 1;
+ *placeId = *placeId + 1;
+
+ // Get lowest height.
+ int height = 255;
+
+ Vector2 start = worldPositionToPixel(world, pond.box.min.x, pond.box.min.z);
+ Vector2 end = worldPositionToPixel(world, pond.box.max.x, pond.box.max.z);
+
+ for (int y = start.y; y < end.y; ++y)
+ {
+ for (int x = start.x; x < end.x; ++x)
+ {
+ int pixelHeight = heightmap[y * WORLD_IMAGE_WIDTH + x].r;
+
+ if (pixelHeight < height)
+ {
+ height = pixelHeight;
+ }
+ }
+ }
+
+ height -= PLACE_POND_DEPTH * (world->size.y / 255.0 * 2.0);
+
+ // Set new height.
+ int area = PLACE_POND_OUTER_AREA;
+ int edge = PLACE_POND_DEPTH * (world->size.y / 255.0 * 2.0) / 4.0 + height;
+
+ for (int y = start.y - area; y < end.y + area; ++y)
+ {
+ for (int x = start.x - area; x < end.x + area; ++x)
+ {
+ if ((x == start.x || x == end.x || // Closest edge.
+ y == start.y || y == end.y) &&
+ (x >= start.x && x <= end.x &&
+ y >= start.y && y <= end.y))
+ {
+ heightmap[y * WORLD_IMAGE_WIDTH + x] = (Color){edge, edge, edge, 255};
+ }
+ else if (x < start.x || x > end.x || // Smooth out rest of the edge.
+ y < start.y || y > end.y)
+ {
+ int distance = Vector2Distance(
+ (Vector2){x, y},
+ Vector2Scale(Vector2Add(start, end), 0.5));
+ int edgeHeight = distance + edge;
+
+ // Average out the heights.
+ if (distance > Vector2Distance(start, end) / 2.0 +
+ PLACE_POND_WALKING_AREA)
+ {
+ edgeHeight += heightmap[y * WORLD_IMAGE_WIDTH + x].r;
+ edgeHeight /= 2;
+ }
+
+ heightmap[y * WORLD_IMAGE_WIDTH + x] =
+ (Color){edgeHeight, edgeHeight, edgeHeight, 255};
+ }
+ else
+ {
+ heightmap[y * WORLD_IMAGE_WIDTH + x] =
+ (Color){height, height, height, 255};
+ }
+ }
+ }
+
+ return seed;
+}
+
+void generateWorldSamanthasPlace(World* world, const Assets* assets,
+ Color* heightmap, WorldUID* placeId,
+ WorldUID* id)
+{
+ // Make area flat.
+ float width = SAMANTHAS_SPOT_SIZE * (WORLD_IMAGE_WIDTH / world->size.x)
+ * 2.0;
+ float height = SAMANTHAS_SPOT_SIZE * (WORLD_IMAGE_HEIGHT / world->size.z)
+ * 2.0;
+
+ Rectangle area = (Rectangle){
+ .x = WORLD_IMAGE_WIDTH / 2.0 - width / 2.0,
+ .y = WORLD_IMAGE_HEIGHT / 2.0 - height / 2.0,
+ .width = width,
+ .height = height
+ };
+
+ averageOutAreaWorld(world, heightmap, area);
+
+ // Samanthas spot.
+ Vector3 center = Vector3Scale(world->size, 0.5);
+ Entity spot = createEntity(SAMANTHAS_SPOT, center);
+ world->entities[*id] = spot;
+ world->places[*placeId] = *id;
+
+ *id = *id + 1;
+ *placeId = *placeId + 1;
+
+ // Samantha.
+ Entity samantha = createEntity(SAMANTHA, Vector3Add(center,
+ SAMANTHA_OFFSET));
+ world->entities[*id] = samantha;
+ *id = *id + 1;
+
+ // Trashcans yippee!
+ Vector3 trashPosition = (Vector3){-SAMANTHAS_SPOT,
+ 0.0,
+ SAMANTHAS_SPOT_SIZE / 2.0};
+
+ for (int index = 0; index < SAMANTHAS_SPOT_TRASHCAN_COUNT; ++index)
+ {
+ Entity trashcan = createEntity(TRASHCAN,
+ Vector3Add(trashPosition, center));
+ world->entities[*id] = trashcan;
+ *id = *id + 1;
+ trashPosition.x += (float)(SAMANTHAS_SPOT_SIZE * 2.0)
+ / SAMANTHAS_SPOT_TRASHCAN_COUNT;
+ }
+
+ // Trash and medical trash yippee!
+ trashPosition = (Vector3){-SAMANTHAS_SPOT,
+ 0.0,
+ SAMANTHAS_SPOT_SIZE / 1.5};
+
+ for (int index = 0; index < SAMANTHAS_SPOT_TRASH_COUNT; ++index)
+ {
+ Entity trash = createEntity(index % 2 == 0 ? TRASH : MEDICAL_TRASH,
+ Vector3Add(trashPosition, center));
+ world->entities[*id] = trash;
+ *id = *id + 1;
+ trashPosition.x += (float)(SAMANTHAS_SPOT_SIZE * 2.0)
+ / SAMANTHAS_SPOT_TRASH_COUNT;
+ }
+
+ // Floor.
+ Mesh floor = GenMeshPlane(SAMANTHAS_SPOT_SIZE * 2.0,
+ SAMANTHAS_SPOT_SIZE * 2.0,
+ 2, 2);
+ world->samanthasSpotFloor = LoadModelFromMesh(floor);
+ world->samanthasSpotFloor.materials[0].maps[MATERIAL_MAP_DIFFUSE]
+ .texture = assets->textures[SAMANTHA_FLOOR_TEXTURE];
+}
+
+Seed generateWorldJohnsShop(World* world, Color* colors, Seed seed,
+ WorldUID* placeId, WorldUID* id)
+{
+ Vector3 position = Vector3Scale(world->size, 0.5);
+ position.x += 30.0;
+ Entity johnsShop = createEntity(JOHNS_STORE, position);
+ world->entities[*id] = johnsShop;
+ world->places[*placeId] = *id;
+
+ *id = *id + 1;
+ *placeId = *placeId + 1;
+
+ return seed;
+}
+
Seed generateWorldPlaces(World* world, const Assets* assets, Color* colors,
Seed seed, WorldUID* id)
{
WorldUID placeId = 0;
// Pond.
- seed = generatePond(world, colors, &placeId, id, seed);
+ seed = generateWorldPond(world, colors, &placeId, id, seed);
// Samantha's place.
generateWorldSamanthasPlace(world, assets, colors, &placeId, id);
+ // John's stop.
+ seed = generateWorldJohnsShop(world, colors, seed, &placeId, id);
+
// Sanity check (something I should do more often...)
if (placeId != WORLD_PLACE_COUNT)
{