126 lines
3.2 KiB
C
126 lines
3.2 KiB
C
#include "grid.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#define GRID_MIN_WIDTH 8
|
|
#define GRID_MIN_HEIGHT 8
|
|
|
|
static bool from_grid_index(Grid *grid, uint16_t grid_index, uint16_t *out_x, uint16_t *out_y) {
|
|
assert(grid != NULL);
|
|
assert(out_x != NULL);
|
|
assert(out_y != NULL);
|
|
|
|
if (!grid || !out_x || !out_y) return false;
|
|
if (grid_index >= grid->width * grid->height) return false;
|
|
|
|
*out_x = grid_index % grid->width;
|
|
*out_y = grid_index / grid->width;
|
|
return true;
|
|
}
|
|
|
|
bool grid_initialize(Grid *grid, uint16_t width, uint16_t height) {
|
|
assert(grid != NULL);
|
|
|
|
if(width < GRID_MIN_WIDTH || height < GRID_MIN_HEIGHT) {
|
|
return false;
|
|
}
|
|
|
|
grid->width = width;
|
|
grid->height = height;
|
|
grid->cells = calloc(width * height, sizeof(Grid_Cell));
|
|
|
|
for(uint16_t i = 0; i < (width * height); i++) {
|
|
Grid_Cell *cell = &grid->cells[i];
|
|
assert(from_grid_index(grid, i, &cell->x, &cell->y));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void grid_dispose(Grid *grid) {
|
|
assert(grid != NULL);
|
|
|
|
free(grid->cells);
|
|
memset(grid, 0, sizeof(Grid));
|
|
}
|
|
|
|
static bool to_grid_index(Grid *grid, uint16_t x, uint16_t y, uint16_t *out_grid_index) {
|
|
assert(grid != NULL);
|
|
assert(out_grid_index != NULL);
|
|
|
|
if(!grid || !out_grid_index) {
|
|
return false;
|
|
}
|
|
if(x >= grid->width || y >= grid->height) {
|
|
return false;
|
|
}
|
|
|
|
*out_grid_index = y * grid->width + x;
|
|
return true;
|
|
}
|
|
|
|
Grid_Cell *grid_get_cell(Grid *grid, uint16_t x, uint16_t y) {
|
|
assert(grid != NULL);
|
|
if(x >= grid->width || y >= grid->height) {
|
|
return NULL;
|
|
}
|
|
|
|
uint16_t grid_index = 0;
|
|
if(!to_grid_index(grid, x, y, &grid_index)) {
|
|
return NULL;
|
|
}
|
|
|
|
return &grid->cells[grid_index];
|
|
}
|
|
|
|
bool grid_try_add_entity_to_cell(Grid_Cell *cell, Entity *entity) {
|
|
assert(cell != NULL);
|
|
assert(entity != NULL);
|
|
|
|
// TODO: SS - Could check what type of cell it is to determine if
|
|
// we're allowed to place an entity here. Is it a wall? Lava?
|
|
|
|
if(cell->entity != NULL) {
|
|
return false;
|
|
}
|
|
|
|
cell->entity = entity;
|
|
entity->x = cell->x;
|
|
entity->y = cell->y;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool grid_try_remove_entity_from_cell(Grid_Cell *cell) {
|
|
assert(cell != NULL);
|
|
|
|
if(cell->entity == NULL) {
|
|
return false;
|
|
}
|
|
|
|
cell->entity->x = 0;
|
|
cell->entity->y = 0;
|
|
cell->entity = NULL;
|
|
|
|
return true;
|
|
}
|
|
|
|
void grid_move_entity_from_cell_to_cell(Grid_Cell *cell_a, Grid_Cell *cell_b) {
|
|
assert(cell_a != NULL);
|
|
assert(cell_b != NULL);
|
|
|
|
assert(cell_a->entity != NULL); // We expect cell A to have an Entity to move.
|
|
assert(cell_b->entity == NULL); // We expect cell B to NOT have an Entity.
|
|
|
|
Entity *entity_to_be_moved = cell_a->entity;
|
|
|
|
uint16_t start_x = cell_a->x;
|
|
uint16_t start_y = cell_a->y;
|
|
|
|
assert(grid_try_remove_entity_from_cell(cell_a));
|
|
assert(grid_try_add_entity_to_cell(cell_b, entity_to_be_moved));
|
|
|
|
entity_to_be_moved->prev_x = start_x;
|
|
entity_to_be_moved->prev_y = start_y;
|
|
} |