diff --git a/src/game/shared/game_world.c b/src/game/shared/game_world.c index ec382ef..3dfc64e 100644 --- a/src/game/shared/game_world.c +++ b/src/game/shared/game_world.c @@ -123,6 +123,163 @@ void game_world_destroy_entity(Game_World *world, Entity_ID entity_id, bool dest } } +void game_world_tick(Game_World *world) { + // Game-logic! :) + + for(uint16_t i = 0; i < world->max_entities; i++) { + Entity *entity = &world->entities[i]; + if(!entity->active) { + continue; + } + + switch(entity->type) { + case Entity_Type_Snake_Head: { + + break; + } + case Entity_Type_Snake_Body: { + // Skip. + break; + } + case Entity_Type_Food: { + // Skip (for now). + break; + } + default: { + printf("Unhandled entity-type %i.\n", entity->type); + break; + } + } + + { // Move entity + int16_t dx = 0; + int16_t dy = 0; + + switch(entity->move_direction) { + case Entity_Movement_Direction_None: { + break; + } + case Entity_Movement_Direction_Up: { + dy = -1; + break; + } + case Entity_Movement_Direction_Down: { + dy = 1; + break; + } + case Entity_Movement_Direction_Right: { + dx = 1; + break; + } + case Entity_Movement_Direction_Left: { + dx = -1; + break; + } + } + + if(dx != 0 || dy != 0) { + // Try moving. + + // Figure out what cell we're on and what cell we want to go to. + Grid_Cell *current_cell = grid_get_cell(&world->grid, entity->x, entity->y); + assert(current_cell != NULL); + Grid_Cell *target_cell = grid_get_cell(&world->grid, entity->x + dx, entity->y + dy); + + // { // Debug-logging. + // printf("Current cell = (x: %u, y: %u, entity: %p).\n", current_cell->x, current_cell->y, current_cell->entity); + // if(target_cell != NULL) { + // printf("Target cell = (x: %u, y: %u, entity: %p).\n", target_cell->x, target_cell->y, target_cell->entity); + // } + // else { + // printf("Target cell = NULL!\n"); + // } + // } + + if(target_cell == NULL) { + // Target cell does not exist. + // TODO: SS - Check the session's settings. + // Maybe each session could decide whether the snake should "loop-around" or not. + // If the snake shouldn't loop around, die. + } + else { + bool should_move_to_target_cell = false; + bool snake_ate = false; + + if(target_cell->entity != NULL) { + // Target cell is occupied. + + // Check what type of entity it is and determine what should happen. + switch(target_cell->entity->type) { + case Entity_Type_Snake_Head: { + // TODO: SS - Die. + break; + } + case Entity_Type_Snake_Body: { + // TODO: SS - Die. + break; + } + case Entity_Type_Food: { + // Eat! + assert(grid_try_remove_entity_from_cell(target_cell)); + + snake_ate = true; + should_move_to_target_cell = true; + + break; + } + } + } + else { + // Target cell is unoccupied and free to enter. + should_move_to_target_cell = true; + } + + if(should_move_to_target_cell) { + { // Move snake recursively. + Entity *e = entity; + Grid_Cell *t = target_cell; + while(e != NULL) { + Grid_Cell *a = grid_get_cell(&world->grid, e->x, e->y); + assert(a != NULL); + + grid_move_entity_from_cell_to_cell(a, t); + + e = game_world_try_get_entity_by_id(world, e->child); + t = a; + } + } + + if(snake_ate) { + Entity *e = entity; + uint16_t child_index = 0; + while(e->child != INVALID_ENTITY_ID) { + e = game_world_try_get_entity_by_id(world, e->child); + child_index += 1; + } + + Entity_ID child_entity = INVALID_ENTITY_ID; + assert(game_world_create_entity( + world, + Entity_Type_Snake_Body, + e->prev_x, + e->prev_y, + &child_entity + )); + + assert(e->child == INVALID_ENTITY_ID); + e->child = child_entity; + + { // Spawn food. + + } + } + } + } + } + } + } +} + Entity *game_world_try_get_entity_by_id(Game_World *world, Entity_ID id) { assert(world != NULL); diff --git a/src/game/shared/game_world.h b/src/game/shared/game_world.h index d9813c3..2ca87a2 100644 --- a/src/game/shared/game_world.h +++ b/src/game/shared/game_world.h @@ -25,6 +25,8 @@ void game_world_destroy(Game_World *world); bool game_world_create_entity(Game_World *world, Entity_Type type, uint16_t x, uint16_t y, Entity_ID *out_entity_id); void game_world_destroy_entity(Game_World *world, Entity_ID entity_id, bool destroy_children); +void game_world_tick(Game_World *world); + // TODO: SS - "void game_world_spawn_player(Game_World *world, ..)" Entity *game_world_try_get_entity_by_id(Game_World *world, Entity_ID id); diff --git a/src/game/simulation/simulation_world.c b/src/game/simulation/simulation_world.c index c05fed3..7c92336 100644 --- a/src/game/simulation/simulation_world.c +++ b/src/game/simulation/simulation_world.c @@ -181,156 +181,7 @@ void simulation_world_tick(Simulation_World *simulation_world) { } } - // Game-logic! :) - - for(uint16_t i = 0; i < gw->max_entities; i++) { - Entity *entity = &gw->entities[i]; - if(!entity->active) { - continue; - } - - switch(entity->type) { - case Entity_Type_Snake_Head: { - - break; - } - case Entity_Type_Snake_Body: { - // Skip. - break; - } - case Entity_Type_Food: { - // Skip (for now). - break; - } - default: { - printf("Unhandled entity-type %i.\n", entity->type); - break; - } - } - - { // Move entity - int16_t dx = 0; - int16_t dy = 0; - - switch(entity->move_direction) { - case Entity_Movement_Direction_None: { - break; - } - case Entity_Movement_Direction_Up: { - dy = -1; - break; - } - case Entity_Movement_Direction_Down: { - dy = 1; - break; - } - case Entity_Movement_Direction_Right: { - dx = 1; - break; - } - case Entity_Movement_Direction_Left: { - dx = -1; - break; - } - } - - if(dx != 0 || dy != 0) { - // Try moving. - - // Figure out what cell we're on and what cell we want to go to. - Grid_Cell *current_cell = grid_get_cell(&gw->grid, entity->x, entity->y); - assert(current_cell != NULL); - Grid_Cell *target_cell = grid_get_cell(&gw->grid, entity->x + dx, entity->y + dy); - - // { // Debug-logging. - // printf("Current cell = (x: %u, y: %u, entity: %p).\n", current_cell->x, current_cell->y, current_cell->entity); - // if(target_cell != NULL) { - // printf("Target cell = (x: %u, y: %u, entity: %p).\n", target_cell->x, target_cell->y, target_cell->entity); - // } - // else { - // printf("Target cell = NULL!\n"); - // } - // } - - if(target_cell == NULL) { - // Target cell does not exist. - // TODO: SS - Check the session's settings. - // Maybe each session could decide whether the snake should "loop-around" or not. - // If the snake shouldn't loop around, die. - } - else { - bool should_move_to_target_cell = false; - bool snake_should_grow = false; - - if(target_cell->entity != NULL) { - // Target cell is occupied. - - // Check what type of entity it is and determine what should happen. - switch(target_cell->entity->type) { - case Entity_Type_Snake_Head: { - // TODO: SS - Die. - break; - } - case Entity_Type_Snake_Body: { - // TODO: SS - Die. - break; - } - case Entity_Type_Food: { - // Eat! - assert(grid_try_remove_entity_from_cell(target_cell)); - - snake_should_grow = true; - should_move_to_target_cell = true; - - break; - } - } - } - else { - // Target cell is unoccupied and free to enter. - should_move_to_target_cell = true; - } - - if(should_move_to_target_cell) { - { // Move snake recursively. - Entity *e = entity; - Grid_Cell *t = target_cell; - while(e != NULL) { - Grid_Cell *a = grid_get_cell(&gw->grid, e->x, e->y); - assert(a != NULL); - - grid_move_entity_from_cell_to_cell(a, t); - - e = game_world_try_get_entity_by_id(gw, e->child); - t = a; - } - } - - if(snake_should_grow) { - Entity *e = entity; - uint16_t child_index = 0; - while(e->child != INVALID_ENTITY_ID) { - e = game_world_try_get_entity_by_id(gw, e->child); - child_index += 1; - } - - Entity_ID child_entity = INVALID_ENTITY_ID; - assert(game_world_create_entity( - gw, - Entity_Type_Snake_Body, - e->prev_x, - e->prev_y, - &child_entity - )); - - assert(e->child == INVALID_ENTITY_ID); - e->child = child_entity; - } - } - } - } - } - } + game_world_tick(gw); } break;