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
scene_man
En Yi 2023-09-21 21:48:32 +08:00
parent 57f6a154b0
commit e1a0c6e4e0
5 changed files with 72 additions and 7 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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 {