diff options
Diffstat (limited to 'src/world.c')
| -rw-r--r-- | src/world.c | 333 |
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) { |
