diff --git a/scenes/editor_scene.c b/scenes/editor_scene.c index 0bec5c3..0c4ac6f 100644 --- a/scenes/editor_scene.c +++ b/scenes/editor_scene.c @@ -421,8 +421,10 @@ void init_level_scene(LevelScene_t* scene) sc_array_add(&scene->scene.systems, &player_bbox_update_system); sc_array_add(&scene->scene.systems, &friction_coefficient_update_system); sc_array_add(&scene->scene.systems, &global_external_forces_system); + sc_array_add(&scene->scene.systems, &moveable_update_system); sc_array_add(&scene->scene.systems, &movement_update_system); sc_array_add(&scene->scene.systems, &update_tilemap_system); + sc_array_add(&scene->scene.systems, &player_pushing_system); sc_array_add(&scene->scene.systems, &tile_collision_system); sc_array_add(&scene->scene.systems, &hitbox_update_system); //sc_array_add(&scene->scene.systems, &update_tilemap_system); diff --git a/scenes/game_systems.c b/scenes/game_systems.c index f5ecdf2..1db2c25 100644 --- a/scenes/game_systems.c +++ b/scenes/game_systems.c @@ -178,8 +178,8 @@ static bool check_collision_and_move( ) { p_ct->position = Vector2Add(p_ct->position, offset); - return true; } + return true; } return false; } @@ -800,6 +800,92 @@ void global_external_forces_system(Scene_t* scene) } } +void moveable_update_system(Scene_t* scene) +{ + CMoveable_t* p_moveable; + unsigned long ent_idx; + sc_map_foreach(&scene->ent_manager.component_map[CMOVEABLE_T], ent_idx, p_moveable) + { + Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx); + CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T); + + if (p_moveable->gridmove) + { + memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity)); + memset(&p_ctransform->accel, 0, sizeof(p_ctransform->velocity)); + p_ctransform->position = p_moveable->target_pos; + p_moveable->gridmove = false; + } + + } + +} + +void player_pushing_system(Scene_t* scene) +{ + LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); + TileGrid_t tilemap = data->tilemap; + + Entity_t* p_player; + sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) + { + CMovementState_t* p_movement = get_component(p_player, CMOVEMENTSTATE_T); + if (!(p_movement->ground_state & 1)) continue; + + CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T); + CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T); + // Get the occupied tiles + // For each tile, loop through the entities, check collision and move + // exclude self + unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE; + unsigned int tile_y1 = (p_ctransform->position.y + 1) / TILE_SIZE; + unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x) / TILE_SIZE; + unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE; + + for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++) + { + for (unsigned int tile_x = tile_x1; tile_x <= tile_x2; tile_x++) + { + unsigned int tile_idx = tile_y * tilemap.width + tile_x; + if(tilemap.tiles[tile_idx].tile_type != EMPTY_TILE) continue; + + unsigned int other_ent_idx; + sc_map_foreach_key(&tilemap.tiles[tile_idx].entities_set, other_ent_idx) + { + if (other_ent_idx == p_player->m_id) continue; + + Entity_t *p_other_ent = get_entity(&scene->ent_manager, other_ent_idx); + if (!p_other_ent->m_alive) continue; // To only allow one way collision check + + CMoveable_t *p_other_moveable = get_component(p_other_ent, CMOVEABLE_T); + if (p_other_moveable == NULL) continue; + + CTransform_t *p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T); + CBBox_t *p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T); + if (check_collision_and_move( + &scene->ent_manager, &tilemap, p_player->m_id, + p_ctransform, p_bbox->size, p_other_ct->position, + p_other_bbox->size, false + ) + ) + { + p_other_moveable->gridmove = true; + p_other_moveable->target_pos = p_other_ct->position; + if (p_ctransform->position.x < p_other_ct->position.x) + { + p_other_moveable->target_pos.x = p_other_ct->position.x + TILE_SIZE; + } + else + { + p_other_moveable->target_pos.x = p_other_ct->position.x - TILE_SIZE; + } + } + } + } + } + } +} + void movement_update_system(Scene_t* scene) { // Update movement diff --git a/scenes/game_systems.h b/scenes/game_systems.h index 68e576c..997f5ce 100644 --- a/scenes/game_systems.h +++ b/scenes/game_systems.h @@ -6,8 +6,10 @@ void term_level_scene_data(LevelSceneData_t* data); void player_movement_input_system(Scene_t* scene); void player_bbox_update_system(Scene_t* scene); +void player_pushing_system(Scene_t* scene); void tile_collision_system(Scene_t* scene); void friction_coefficient_update_system(Scene_t* scene); +void moveable_update_system(Scene_t* scene); void global_external_forces_system(Scene_t* scene); void movement_update_system(Scene_t* scene); void player_ground_air_transition_system(Scene_t* scene); diff --git a/scenes/items_ent.c b/scenes/items_ent.c index ab215b1..2dac558 100644 --- a/scenes/items_ent.c +++ b/scenes/items_ent.c @@ -31,7 +31,8 @@ Entity_t* create_boulder(EntityManager_t* ent_manager, Assets_t* assets) add_component(p_boulder, CTRANSFORM_COMP_T); add_component(p_boulder, CMOVEMENTSTATE_T); add_component(p_boulder, CTILECOORD_COMP_T); - add_component(p_boulder, CMOVEABLE_T); + CMoveable_t* p_cmove = add_component(p_boulder, CMOVEABLE_T); + p_cmove->move_speed = 4; CHurtbox_t* p_hurtbox = add_component(p_boulder, CHURTBOX_T); p_hurtbox->size = p_bbox->size; p_hurtbox->fragile = false;