From e1a0c6e4e081e2d1e0d664820b29f34f986b23dc Mon Sep 17 00:00:00 2001 From: En Yi Date: Thu, 21 Sep 2023 21:48:32 +0800 Subject: [PATCH] Implement Chest Entity Internal Changelog: - chest entity: Basically crates, but high def, and fragile - Add new spawn type for chest - Add atk modifier for player->chest - Make crate non-fragile - Ignore chest for collision check and move with player --- scenes/editor_scene.c | 27 ++++++++++++++++++++++++--- scenes/ent_impl.h | 2 ++ scenes/game_systems.c | 18 +++++++++++++++--- scenes/items_ent.c | 25 ++++++++++++++++++++++++- scenes/scene_impl.h | 7 +++++++ 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/scenes/editor_scene.c b/scenes/editor_scene.c index ef58319..3d85a5f 100644 --- a/scenes/editor_scene.c +++ b/scenes/editor_scene.c @@ -17,6 +17,7 @@ enum EntitySpawnSelection { TOGGLE_SPIKE, TOGGLE_WATER, TOGGLE_AIR_POCKET, + SPAWN_CHEST, SPAWN_CRATE, SPAWN_CRATE_ARROW_L, SPAWN_CRATE_ARROW_R, @@ -27,7 +28,7 @@ enum EntitySpawnSelection { SPAWN_WATER_RUNNER, }; -#define MAX_SPAWN_TYPE 14 +#define MAX_SPAWN_TYPE 15 static unsigned int current_spawn_selection = 0; static bool metal_toggle = false; static bool crate_activation = false; @@ -48,6 +49,7 @@ static char* get_spawn_selection_string(enum EntitySpawnSelection sel) case TOGGLE_SPIKE: return "spike"; case TOGGLE_WATER: return "water"; case TOGGLE_AIR_POCKET: return "air pocket"; + case SPAWN_CHEST: return "chest"; case SPAWN_CRATE: return (metal_toggle) ? "metal crate" : "wooden crate"; case SPAWN_CRATE_ARROW_D: return (metal_toggle) ? "metal down arrow crate" : "wooden down arrow crate"; case SPAWN_CRATE_ARROW_U: return (metal_toggle) ? "metal up arrow crate" : "wooden up arrow crate"; @@ -216,6 +218,9 @@ static void level_scene_render_func(Scene_t* scene) case BOULDER_ENT_TAG: colour = GRAY; break; + case CHEST_ENT_TAG: + colour = YELLOW; + break; default: colour = BLACK; break; @@ -449,6 +454,18 @@ static void level_scene_render_func(Scene_t* scene) EndDrawing(); } +static void spawn_chest(Scene_t* scene, unsigned int tile_idx) +{ + LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); + Entity_t* p_crate = create_chest(&scene->ent_manager, &scene->engine->assets); + if (p_crate == NULL) return; + + CTransform_t* p_ctransform = get_component(p_crate, CTRANSFORM_COMP_T); + p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE; + p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE; + p_ctransform->active = true; +} + static void spawn_crate(Scene_t* scene, unsigned int tile_idx, bool metal, ContainerItem_t item, bool active) { LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); @@ -573,6 +590,9 @@ static void toggle_block_system(Scene_t* scene) } } break; + case SPAWN_CHEST: + spawn_chest(scene, tile_idx); + break; } change_a_tile(&tilemap, tile_idx, new_type); last_tile_idx = tile_idx; @@ -819,8 +839,9 @@ void init_sandbox_scene(LevelScene_t* scene) Vector2 draw_pos = {0, 0}; const Color crate_colour = metal_toggle ? GRAY : BROWN; const Color draw_colour[MAX_SPAWN_TYPE] = { - BLACK, MAROON, ORANGE, ColorAlpha(RAYWHITE, 0.5), ColorAlpha(BLUE, 0.5), ColorAlpha(RAYWHITE, 0.5), - crate_colour, crate_colour, crate_colour, crate_colour, crate_colour, crate_colour, + BLACK, MAROON, ORANGE, ColorAlpha(RAYWHITE, 0.5), ColorAlpha(BLUE, 0.5), + ColorAlpha(RAYWHITE, 0.5), YELLOW, crate_colour, crate_colour, crate_colour, + crate_colour, crate_colour, crate_colour, ColorAlpha(RAYWHITE, 0.5), ColorAlpha(RAYWHITE, 0.5) }; for (uint8_t i = 0; i < MAX_SPAWN_TYPE; ++i) diff --git a/scenes/ent_impl.h b/scenes/ent_impl.h index 9afdc72..bc4f1a0 100644 --- a/scenes/ent_impl.h +++ b/scenes/ent_impl.h @@ -7,6 +7,7 @@ typedef enum EntityTag { PLAYER_ENT_TAG, ENEMY_ENT_TAG, CRATES_ENT_TAG, + CHEST_ENT_TAG, BOULDER_ENT_TAG, DESTRUCTABLE_ENT_TAG, DYNMEM_ENT_TAG, @@ -25,5 +26,6 @@ Entity_t* create_boulder(EntityManager_t* ent_manager, Assets_t* assets); Entity_t* create_arrow(EntityManager_t* ent_manager, Assets_t* assets, uint8_t dir); Entity_t* create_bomb(EntityManager_t* ent_manager, Assets_t* assets, Vector2 launch_dir); Entity_t* create_explosion(EntityManager_t* ent_manager, Assets_t* assets); +Entity_t* create_chest(EntityManager_t* ent_manager, Assets_t* assets); #endif // __ENT_IMPL_H diff --git a/scenes/game_systems.c b/scenes/game_systems.c index 1847972..8d52106 100644 --- a/scenes/game_systems.c +++ b/scenes/game_systems.c @@ -668,10 +668,16 @@ void tile_collision_system(Scene_t* scene) if (p_other_bbox == NULL) continue; CTransform_t *p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T); + + SolidType_t solid = p_other_bbox->solid? SOLID : NOT_SOLID; + if (p_ent->m_tag == PLAYER_ENT_TAG && p_other_ent->m_tag == CHEST_ENT_TAG) + { + solid = NOT_SOLID; + } check_collision_and_move( &tilemap, p_ent, &p_other_ct->position, p_other_bbox->size, - p_other_bbox->solid? SOLID : NOT_SOLID + solid ); } } @@ -681,7 +687,7 @@ void tile_collision_system(Scene_t* scene) // Post movement edge check to zero out velocity uint8_t edges = check_bbox_edges( &data->tilemap, p_ent, - p_ctransform->position, p_ctransform->prev_position, p_bbox->size, false + p_ctransform->position, p_ctransform->prev_position, p_bbox->size, true ); if (edges & (1<<3)) { @@ -1447,7 +1453,13 @@ void hitbox_update_system(Scene_t* scene) ) { hit = true; - if (p_hitbox->atk > p_other_hurtbox->def) + + uint8_t full_atk = p_hitbox->atk; + if (p_ent->m_tag == PLAYER_ENT_TAG && p_other_ent->m_tag == CHEST_ENT_TAG) + { + full_atk = p_other_hurtbox->def + 1; + } + if (full_atk > p_other_hurtbox->def) { p_other_hurtbox->damage_src = ent_idx; if (p_other_ent->m_tag == CRATES_ENT_TAG) diff --git a/scenes/items_ent.c b/scenes/items_ent.c index c1b66cb..3e1a8a7 100644 --- a/scenes/items_ent.c +++ b/scenes/items_ent.c @@ -39,7 +39,7 @@ Entity_t* create_crate(EntityManager_t* ent_manager, Assets_t* assets, bool meta CBBox_t* p_bbox = add_component(p_crate, CBBOX_COMP_T); set_bbox(p_bbox, TILE_SIZE, TILE_SIZE); p_bbox->solid = true; - p_bbox->fragile = !metal; + p_bbox->fragile = false; CTransform_t* p_ctransform = add_component(p_crate, CTRANSFORM_COMP_T); p_ctransform->grav_delay = 7; @@ -202,3 +202,26 @@ Entity_t* create_explosion(EntityManager_t* ent_manager, Assets_t* assets) p_clifetimer->life_time = 3; return p_explosion; } + +Entity_t* create_chest(EntityManager_t* ent_manager, Assets_t* assets) +{ + Entity_t* p_chest = add_entity(ent_manager, CHEST_ENT_TAG); + if (p_chest == NULL) return NULL; + + CBBox_t* p_bbox = add_component(p_chest, CBBOX_COMP_T); + set_bbox(p_bbox, TILE_SIZE, TILE_SIZE); + p_bbox->solid = true; + p_bbox->fragile = true; + + CTransform_t* p_ctransform = add_component(p_chest, CTRANSFORM_COMP_T); + p_ctransform->grav_delay = 7; + p_ctransform->shape_factor = (Vector2){0.7,0.7}; + add_component(p_chest, CMOVEMENTSTATE_T); + add_component(p_chest, CTILECOORD_COMP_T); + CHurtbox_t* p_hurtbox = add_component(p_chest, CHURTBOX_T); + p_hurtbox->size = p_bbox->size; + p_hurtbox->def = 4; + p_hurtbox->damage_src = -1; + + return p_chest; +} diff --git a/scenes/scene_impl.h b/scenes/scene_impl.h index 51e6248..6415baa 100644 --- a/scenes/scene_impl.h +++ b/scenes/scene_impl.h @@ -21,6 +21,12 @@ typedef enum TileType { #define MAX_TILE_SPRITES 32 +typedef struct CoinCounter +{ + uint16_t current; + uint16_t total; +}CoinCounter_t; + typedef struct LevelSceneData { TileGrid_t tilemap; RenderTexture2D game_viewport; @@ -29,6 +35,7 @@ typedef struct LevelSceneData { Sprite_t* tile_sprites[MAX_TILE_SPRITES]; LevelPack_t* level_pack; unsigned int current_level; + CoinCounter_t coins; }LevelSceneData_t; typedef struct LevelScene {