quadrants/source/world.cpp

154 lines
3.8 KiB
C++

#include "entity.cpp"
#include <string.h>
constexpr struct {
size_t min;
size_t max;
} QUADRANT_STARS = {100, 300};
constexpr struct {
size_t min;
size_t max;
} QUADRANT_ORBITALS = {0, 7};
constexpr auto QUADRANT_RANGE = 512;
constexpr auto QUADRANT_SIZE = (QUADRANT_RANGE * 2);
struct EntityUpdateInfo {
bool hasPassedQuadrant;
bool hasMoved;
};
struct Worldspace {
enum struct OrbitalType {
SUN,
MOON
};
struct Orbital {
OrbitalType type;
Vector2 localPosition;
float orientation;
float scale;
};
struct Quadrant {
QuadrantCoords id;
size_t starCount;
size_t orbitalCount;
Vector2 stars[QUADRANT_STARS.max];
Orbital orbitals[QUADRANT_ORBITALS.max];
};
Seed seed;
SpaceshipEntity player;
Vector2 nebulaParallaxScroll;
Quadrant loadedQuadrantMap[9];
};
Worldspace const CreateWorldspace(Seed const seed) {
Worldspace world = {0};
world.seed = seed;
world.player.entity.localPosition = Vector2{0, 0};
return world;
}
void GenerateWorldspace(Worldspace& world) {
QuadrantCoords offset = {-1, -1};
memset(((void*)world.loadedQuadrantMap), 0, (sizeof(Worldspace::Quadrant) * 9));
for (size_t i = 0; i < 3; i += 1) {
for (size_t j = 0; j < 3; j += 1) {
Worldspace::Quadrant* quadrant = (&world.loadedQuadrantMap[j + (i * 3)]);
QuadrantCoords const quadrantId = {
(world.player.entity.quadrantPosition.x + offset.x),
(world.player.entity.quadrantPosition.y + offset.y)
};
quadrant->id = quadrantId;
XorShifter seededGenerator = CreateXorShifter(
(QUADRANT_SIZE - (quadrantId.x + quadrantId.y)) * world.seed);
quadrant->starCount =
(size_t const)GetXorShifterValue(&seededGenerator, QUADRANT_STARS.min, QUADRANT_STARS.max);
quadrant->orbitalCount = (size_t const)GetXorShifterValue(
&seededGenerator, QUADRANT_ORBITALS.min, QUADRANT_ORBITALS.max);
for (size_t k = 0; k < quadrant->starCount; k += 1) {
quadrant->stars[k] = (Vector2){
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE),
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE)
};
}
for (size_t k = 0; k < quadrant->orbitalCount; k += 1) {
quadrant->orbitals[k] = (Worldspace::Orbital){
(Worldspace::OrbitalType)GetXorShifterValue(&seededGenerator, 0, 1),
(Vector2){
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE),
(float const)GetXorShifterValue(&seededGenerator, -QUADRANT_RANGE, QUADRANT_RANGE)
},
(float const)GetXorShifterValue(&seededGenerator, -PI, PI),
(((float const)GetXorShifterValue(&seededGenerator, 10, 100)) / 100.0f)
};
}
offset.x += 1;
}
offset.x = -1;
offset.y += 1;
}
}
bool const CheckEntityQuadrantBounds(Entity& entity, int* const xBounds, int* const yBounds) {
int const x = ((entity.localPosition.x > QUADRANT_RANGE) ?
1 : ((entity.localPosition.x < -QUADRANT_RANGE) ? -1 : 0));
int const y = ((entity.localPosition.y > QUADRANT_RANGE) ?
1 : ((entity.localPosition.y < -QUADRANT_RANGE) ? -1 : 0));
if (xBounds) {
*xBounds = x;
}
if (yBounds) {
*yBounds = y;
}
return !(x || y);
}
EntityUpdateInfo const UpdateEntity(Entity& entity) {
int quadrantBoundsCheckX;
int quadrantBoundsCheckY;
EntityUpdateInfo info = {0};
if (CheckEntityQuadrantBounds(entity, &quadrantBoundsCheckX, &quadrantBoundsCheckY)) {
entity.localPosition += entity.speed;
info.hasMoved = true;
} else {
if (quadrantBoundsCheckX) {
entity.localPosition.x = ((QUADRANT_RANGE * -quadrantBoundsCheckX) + entity.speed.x);
entity.quadrantPosition.x += quadrantBoundsCheckX;
}
if (quadrantBoundsCheckY) {
entity.localPosition.y = ((QUADRANT_RANGE * -quadrantBoundsCheckY) + entity.speed.y);
entity.quadrantPosition.y += quadrantBoundsCheckY;
}
info.hasPassedQuadrant = true;
info.hasMoved = true;
}
return info;
}