diff --git a/engine/EC/components.h b/engine/EC/components.h index 0b9392f..0ea6c49 100644 --- a/engine/EC/components.h +++ b/engine/EC/components.h @@ -14,7 +14,7 @@ enum ComponentEnum CJUMP_COMP_T, CPLAYERSTATE_T, CCONTAINER_T, - CHITBOX_T, + CHITBOXES_T, CHURTBOX_T, }; typedef enum ComponentEnum ComponentEnum_t; @@ -97,12 +97,12 @@ typedef struct _CContainer_t ContainerItem_t item; }CContainer_t; -typedef struct _CHitBox_t +typedef struct _CHitBoxes_t { - Vector2 offset; - Vector2 size; + Rectangle boxes[2]; + uint8_t n_boxes; bool strong; -}CHitBox_t; +}CHitBoxes_t; typedef struct _CHurtbox_t { diff --git a/engine/EC/mempool.c b/engine/EC/mempool.c index f3fc960..00b7748 100644 --- a/engine/EC/mempool.c +++ b/engine/EC/mempool.c @@ -12,7 +12,7 @@ static CMovementState_t cmstate_buffer[MAX_COMP_POOL_SIZE]; static CJump_t cjump_buffer[1]; // Only player is expected to have this static CPlayerState_t cplayerstate_buffer[1]; // Only player is expected to have this static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE]; -static CHitBox_t chitbox_buffer[MAX_COMP_POOL_SIZE]; +static CHitBoxes_t chitboxes_buffer[MAX_COMP_POOL_SIZE]; static CHurtbox_t churtbox_buffer[MAX_COMP_POOL_SIZE]; // Use hashmap as a Set @@ -40,7 +40,7 @@ static MemPool_t comp_mempools[N_COMPONENTS] = {cjump_buffer, 1, sizeof(CJump_t), NULL, {0}}, {cplayerstate_buffer, 1, sizeof(CPlayerState_t), NULL, {0}}, {ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}}, - {chitbox_buffer, MAX_COMP_POOL_SIZE, sizeof(CHitBox_t), NULL, {0}}, + {chitboxes_buffer, MAX_COMP_POOL_SIZE, sizeof(CHitBoxes_t), NULL, {0}}, {churtbox_buffer, MAX_COMP_POOL_SIZE, sizeof(CHurtbox_t), NULL, {0}}, }; static MemPool_t ent_mempool = {entity_buffer, MAX_COMP_POOL_SIZE, sizeof(Entity_t), NULL, {0}}; diff --git a/engine/editor_scene.c b/engine/editor_scene.c index e27b474..adb9251 100644 --- a/engine/editor_scene.c +++ b/engine/editor_scene.c @@ -68,16 +68,19 @@ static void level_scene_render_func(Scene_t* scene) } DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour); CHurtbox_t* p_hurtbox = get_component(&scene->ent_manager, p_ent, CHURTBOX_T); - CHitBox_t* p_hitbox = get_component(&scene->ent_manager, p_ent, CHITBOX_T); + CHitBoxes_t* p_hitbox = get_component(&scene->ent_manager, p_ent, CHITBOXES_T); if (p_hitbox != NULL) { - Rectangle rec = { - .x = p_ct->position.x + p_hitbox->offset.x, - .y = p_ct->position.y + p_hitbox->offset.y, - .width = p_hitbox->size.x, - .height = p_hitbox->size.y, - }; - DrawRectangleLinesEx(rec, 1.5, ORANGE); + for (uint8_t i=0;in_boxes;++i) + { + Rectangle rec = { + .x = p_ct->position.x + p_hitbox->boxes[i].x, + .y = p_ct->position.y + p_hitbox->boxes[i].y, + .width = p_hitbox->boxes[i].width, + .height = p_hitbox->boxes[i].height, + }; + DrawRectangleLinesEx(rec, 1.5, ORANGE); + } } if (p_hurtbox != NULL) { @@ -185,9 +188,22 @@ static void spawn_player(Scene_t *scene) add_component(&scene->ent_manager, p_ent, CPLAYERSTATE_T); add_component(&scene->ent_manager, p_ent, CTILECOORD_COMP_T); add_component(&scene->ent_manager, p_ent, CMOVEMENTSTATE_T); - CHitBox_t* p_hitbox = add_component(&scene->ent_manager, p_ent, CHITBOX_T); - p_hitbox->size = Vector2Add(p_bbox->size, (Vector2){2,2}); - p_hitbox->offset = (Vector2){-1, -1}; + CHitBoxes_t* p_hitbox = add_component(&scene->ent_manager, p_ent, CHITBOXES_T); + p_hitbox->n_boxes = 2; + p_hitbox->boxes[0] = (Rectangle) + { + .x = p_bbox->size.x / 4, + .y = -1, + .width = p_bbox->size.x / 2, + .height = p_bbox->size.y + 2, + }; + p_hitbox->boxes[1] = (Rectangle) + { + .x = -1, + .y = p_bbox->size.y / 4, + .width = p_bbox->size.x + 2 , + .height = p_bbox->size.y / 2, + }; } static void toggle_block_system(Scene_t *scene) diff --git a/engine/game_systems.c b/engine/game_systems.c index e020235..a29ebd3 100644 --- a/engine/game_systems.c +++ b/engine/game_systems.c @@ -368,6 +368,11 @@ void player_bbox_update_system(Scene_t *scene) set_bbox(p_bbox, new_bbox.x, new_bbox.y); p_ctransform->position = Vector2Add(p_ctransform->position, offset); } + + CHitBoxes_t* p_hitbox = get_component(&scene->ent_manager, p_player, CHITBOXES_T); + p_hitbox->boxes[0].height = p_bbox->size.y + 2; + p_hitbox->boxes[1].y = p_bbox->size.y / 4; + p_hitbox->boxes[1].height = p_bbox->size.y / 2; } } @@ -741,73 +746,79 @@ void hitbox_update_system(Scene_t *scene) TileGrid_t tilemap = data->tilemap; unsigned int ent_idx; - CHitBox_t* p_hitbox; + CHitBoxes_t* p_hitbox; //sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) - sc_map_foreach(&scene->ent_manager.component_map[CHITBOX_T], ent_idx, p_hitbox) + sc_map_foreach(&scene->ent_manager.component_map[CHITBOXES_T], ent_idx, p_hitbox) { Entity_t *p_ent = get_entity(&scene->ent_manager, ent_idx); CTransform_t* p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T); - Vector2 hitbox_pos = Vector2Add(p_ctransform->position, p_hitbox->offset); - - unsigned int tile_x1 = (hitbox_pos.x) / TILE_SIZE; - unsigned int tile_y1 = (hitbox_pos.y) / TILE_SIZE; - unsigned int tile_x2 = (hitbox_pos.x + p_hitbox->size.x - 1) / TILE_SIZE; - unsigned int tile_y2 = (hitbox_pos.y + p_hitbox->size.y - 1) / TILE_SIZE; - - for (unsigned int tile_y=tile_y1; tile_y <= tile_y2; tile_y++) + for (uint8_t i=0;in_boxes;++i) { - for (unsigned int tile_x=tile_x1; tile_x <= tile_x2; tile_x++) + Vector2 hitbox_pos = { + .x = p_ctransform->position.x + p_hitbox->boxes[i].x, + .y = p_ctransform->position.y + p_hitbox->boxes[i].y, + }; + + unsigned int tile_x1 = (hitbox_pos.x) / TILE_SIZE; + unsigned int tile_y1 = (hitbox_pos.y) / TILE_SIZE; + unsigned int tile_x2 = (hitbox_pos.x + p_hitbox->boxes[i].width - 1) / TILE_SIZE; + unsigned int tile_y2 = (hitbox_pos.y + p_hitbox->boxes[i].height - 1) / TILE_SIZE; + + for (unsigned int tile_y=tile_y1; tile_y <= tile_y2; tile_y++) { - unsigned int tile_idx = tile_y * tilemap.width + tile_x; - unsigned int other_ent_idx; - memset(checked_entities, 0, sizeof(checked_entities)); - sc_map_foreach_key(&tilemap.tiles[tile_idx].entities_set, other_ent_idx) + for (unsigned int tile_x=tile_x1; tile_x <= tile_x2; tile_x++) { - if (other_ent_idx == ent_idx) continue; - if (checked_entities[other_ent_idx]) 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 - if (p_other_ent->m_tag < p_ent->m_tag) continue; // To only allow one way collision check - - CHurtbox_t *p_other_hurtbox = get_component(&scene->ent_manager, p_other_ent, CHURTBOX_T); - if (p_other_hurtbox == NULL) continue; - CTransform_t *p_other_ct = get_component(&scene->ent_manager, p_other_ent, CTRANSFORM_COMP_T); - Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset); - - Vector2 overlap; - if (find_AABB_overlap(hitbox_pos, p_hitbox->size, hurtbox_pos, p_other_hurtbox->size, &overlap)) + unsigned int tile_idx = tile_y * tilemap.width + tile_x; + unsigned int other_ent_idx; + memset(checked_entities, 0, sizeof(checked_entities)); + sc_map_foreach_key(&tilemap.tiles[tile_idx].entities_set, other_ent_idx) { - if (!p_other_hurtbox->fragile) continue; - if (p_other_ent->m_tag == CRATES_ENT_TAG) + if (other_ent_idx == ent_idx) continue; + if (checked_entities[other_ent_idx]) 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 + if (p_other_ent->m_tag < p_ent->m_tag) continue; // To only allow one way collision check + + CHurtbox_t *p_other_hurtbox = get_component(&scene->ent_manager, p_other_ent, CHURTBOX_T); + if (p_other_hurtbox == NULL) continue; + CTransform_t *p_other_ct = get_component(&scene->ent_manager, p_other_ent, CTRANSFORM_COMP_T); + Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset); + + Vector2 overlap; + if (find_AABB_overlap(hitbox_pos, (Vector2){p_hitbox->boxes[i].width, p_hitbox->boxes[i].height}, hurtbox_pos, p_other_hurtbox->size, &overlap)) { - - CBBox_t * p_bbox = get_component(&scene->ent_manager, p_ent, CBBOX_COMP_T); - CPlayerState_t * p_pstate = get_component(&scene->ent_manager, p_ent, CPLAYERSTATE_T); - if ( - // TODO: Check Material of the crates - p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y - ) + if (!p_other_hurtbox->fragile) continue; + if (p_other_ent->m_tag == CRATES_ENT_TAG) { - p_ctransform->velocity.y = -400; - if (p_pstate->jump_pressed) + + CBBox_t * p_bbox = get_component(&scene->ent_manager, p_ent, CBBOX_COMP_T); + CPlayerState_t * p_pstate = get_component(&scene->ent_manager, p_ent, CPLAYERSTATE_T); + if ( + // TODO: Check Material of the crates + p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y + ) { - p_ctransform->velocity.y = -600; - CJump_t * p_cjump = get_component(&scene->ent_manager, p_ent, CJUMP_COMP_T); - p_cjump->short_hop = false; - p_cjump->jumped = true; + p_ctransform->velocity.y = -400; + if (p_pstate->jump_pressed) + { + p_ctransform->velocity.y = -600; + CJump_t * p_cjump = get_component(&scene->ent_manager, p_ent, CJUMP_COMP_T); + p_cjump->short_hop = false; + p_cjump->jumped = true; + } } - } - CTileCoord_t *p_tilecoord = get_component(&scene->ent_manager, p_other_ent, CTILECOORD_COMP_T); - for (size_t i=0;in_tiles;++i) - { - // Use previously store tile position - // Clear from those positions - unsigned int tile_idx = p_tilecoord->tiles[i]; - sc_map_del_64(&(tilemap.tiles[tile_idx].entities_set), other_ent_idx); + CTileCoord_t *p_tilecoord = get_component(&scene->ent_manager, p_other_ent, CTILECOORD_COMP_T); + for (size_t i=0;in_tiles;++i) + { + // Use previously store tile position + // Clear from those positions + unsigned int tile_idx = p_tilecoord->tiles[i]; + sc_map_del_64(&(tilemap.tiles[tile_idx].entities_set), other_ent_idx); + } + remove_entity(&scene->ent_manager, other_ent_idx); } - remove_entity(&scene->ent_manager, other_ent_idx); } } }