Compare commits

..

No commits in common. "55ba03f2d60248e3b8a450452c28e841e0d5a39b" and "402d6f658e1bab0df2b6027cc1c6563bb2d6fcb3" have entirely different histories.

14 changed files with 319 additions and 320 deletions

View File

@ -45,6 +45,7 @@ typedef struct _CBBox_t {
typedef struct _CTransform_t { typedef struct _CTransform_t {
Vector2 prev_position; Vector2 prev_position;
Vector2 prev_velocity; Vector2 prev_velocity;
Vector2 position;
Vector2 velocity; Vector2 velocity;
Vector2 accel; Vector2 accel;
Vector2 fric_coeff; Vector2 fric_coeff;
@ -232,7 +233,6 @@ static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
struct Entity { struct Entity {
Vector2 spawn_pos; Vector2 spawn_pos;
Vector2 position;
unsigned long m_id; unsigned long m_id;
unsigned int m_tag; unsigned int m_tag;
unsigned long components[N_COMPONENTS]; unsigned long components[N_COMPONENTS];

View File

@ -8,7 +8,7 @@
#include "zstd.h" #include "zstd.h"
#include <stdio.h> #include <stdio.h>
uint8_t n_loaded[N_ASSETS_TYPE] = {0}; uint8_t n_loaded[6] = {0};
// Hard limit number of // Hard limit number of
typedef struct TextureData typedef struct TextureData
@ -70,7 +70,7 @@ static void unload_level_pack(LevelPack_t pack)
// Maybe need a circular buffer?? // Maybe need a circular buffer??
Texture2D* add_texture(Assets_t* assets, const char* name, const char* path) Texture2D* add_texture(Assets_t* assets, const char* name, const char* path)
{ {
uint8_t tex_idx = n_loaded[AST_TEXTURE]; uint8_t tex_idx = n_loaded[0];
assert(tex_idx < MAX_TEXTURES); assert(tex_idx < MAX_TEXTURES);
Texture2D tex = LoadTexture(path); Texture2D tex = LoadTexture(path);
if (tex.width == 0 || tex.height == 0) return NULL; if (tex.width == 0 || tex.height == 0) return NULL;
@ -78,13 +78,13 @@ Texture2D* add_texture(Assets_t* assets, const char* name, const char* path)
textures[tex_idx].texture = tex; textures[tex_idx].texture = tex;
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN); strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx); sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
n_loaded[AST_TEXTURE]++; n_loaded[0]++;
return &textures[tex_idx].texture; return &textures[tex_idx].texture;
} }
Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file) Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file)
{ {
uint8_t tex_idx = n_loaded[AST_TEXTURE]; uint8_t tex_idx = n_loaded[0];
assert(tex_idx < MAX_TEXTURES); assert(tex_idx < MAX_TEXTURES);
int res_id = rresGetResourceId(rres_file->dir, filename); int res_id = rresGetResourceId(rres_file->dir, filename);
@ -102,7 +102,7 @@ Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* file
textures[tex_idx].texture = tex; textures[tex_idx].texture = tex;
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN); strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx); sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
n_loaded[AST_TEXTURE]++; n_loaded[0]++;
out_tex = &textures[tex_idx].texture; out_tex = &textures[tex_idx].texture;
} }
rresUnloadResourceChunk(chunk); rresUnloadResourceChunk(chunk);
@ -111,7 +111,7 @@ Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* file
Sound* add_sound_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file) Sound* add_sound_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file)
{ {
uint8_t snd_idx = n_loaded[AST_SOUND]; uint8_t snd_idx = n_loaded[2];
assert(snd_idx < MAX_SOUNDS); assert(snd_idx < MAX_SOUNDS);
int res_id = rresGetResourceId(rres_file->dir, filename); int res_id = rresGetResourceId(rres_file->dir, filename);
@ -128,69 +128,55 @@ Sound* add_sound_rres(Assets_t* assets, const char* name, const char* filename,
sfx[snd_idx].sound = snd; sfx[snd_idx].sound = snd;
strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN); strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx); sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx);
n_loaded[AST_SOUND]++; n_loaded[2]++;
out_snd = &sfx[snd_idx].sound; out_snd = &sfx[snd_idx].sound;
} }
rresUnloadResourceChunk(chunk); rresUnloadResourceChunk(chunk);
return out_snd; return out_snd;
} }
Texture2D* add_texture_from_img(Assets_t* assets, const char* name, Image img)
{
uint8_t tex_idx = n_loaded[AST_TEXTURE];
assert(tex_idx < MAX_TEXTURES);
Texture2D tex = LoadTextureFromImage(img);
if (tex.width == 0 || tex.height == 0) return NULL;
textures[tex_idx].texture = tex;
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
n_loaded[AST_TEXTURE]++;
return &textures[tex_idx].texture;
}
Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture) Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture)
{ {
uint8_t spr_idx = n_loaded[AST_SPRITE]; uint8_t spr_idx = n_loaded[1];
assert(spr_idx < MAX_SPRITES); assert(spr_idx < MAX_SPRITES);
memset(sprites + spr_idx, 0, sizeof(SpriteData_t)); memset(sprites + spr_idx, 0, sizeof(SpriteData_t));
sprites[spr_idx].sprite.texture = texture; sprites[spr_idx].sprite.texture = texture;
strncpy(sprites[spr_idx].name, name, MAX_NAME_LEN); strncpy(sprites[spr_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_sprites, sprites[spr_idx].name, spr_idx); sc_map_put_s64(&assets->m_sprites, sprites[spr_idx].name, spr_idx);
n_loaded[AST_SPRITE]++; n_loaded[1]++;
return &sprites[spr_idx].sprite; return &sprites[spr_idx].sprite;
} }
Sound* add_sound(Assets_t* assets, const char* name, const char* path) Sound* add_sound(Assets_t* assets, const char* name, const char* path)
{ {
uint8_t snd_idx = n_loaded[AST_SOUND]; uint8_t snd_idx = n_loaded[2];
assert(snd_idx < MAX_SOUNDS); assert(snd_idx < MAX_SOUNDS);
sfx[snd_idx].sound = LoadSound(path); sfx[snd_idx].sound = LoadSound(path);
strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN); strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx); sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx);
n_loaded[AST_SOUND]++; n_loaded[2]++;
return &sfx[snd_idx].sound; return &sfx[snd_idx].sound;
} }
Font* add_font(Assets_t* assets, const char* name, const char* path) Font* add_font(Assets_t* assets, const char* name, const char* path)
{ {
uint8_t fnt_idx = n_loaded[AST_FONT]; uint8_t fnt_idx = n_loaded[3];
assert(fnt_idx < MAX_FONTS); assert(fnt_idx < MAX_FONTS);
fonts[fnt_idx].font = LoadFont(path); fonts[fnt_idx].font = LoadFont(path);
strncpy(fonts[fnt_idx].name, name, MAX_NAME_LEN); strncpy(fonts[fnt_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_fonts, fonts[fnt_idx].name, fnt_idx); sc_map_put_s64(&assets->m_fonts, fonts[fnt_idx].name, fnt_idx);
n_loaded[AST_FONT]++; n_loaded[3]++;
return &fonts[fnt_idx].font; return &fonts[fnt_idx].font;
} }
EmitterConfig_t* add_emitter_conf(Assets_t* assets, const char* name) EmitterConfig_t* add_emitter_conf(Assets_t* assets, const char* name)
{ {
uint8_t emitter_idx = n_loaded[AST_EMITTER_CONF]; uint8_t emitter_idx = n_loaded[5];
assert(emitter_idx < MAX_EMITTER_CONF); assert(emitter_idx < MAX_EMITTER_CONF);
memset(emitter_confs + emitter_idx, 0, sizeof(EmitterConfData_t)); memset(emitter_confs + emitter_idx, 0, sizeof(EmitterConfData_t));
strncpy(emitter_confs[emitter_idx].name, name, MAX_NAME_LEN); strncpy(emitter_confs[emitter_idx].name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_emitter_confs, emitter_confs[emitter_idx].name, emitter_idx); sc_map_put_s64(&assets->m_emitter_confs, emitter_confs[emitter_idx].name, emitter_idx);
n_loaded[AST_EMITTER_CONF]++; n_loaded[5]++;
return &emitter_confs[emitter_idx].conf; return &emitter_confs[emitter_idx].conf;
} }
@ -199,7 +185,7 @@ LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path
FILE* file = fopen(path, "rb"); FILE* file = fopen(path, "rb");
if (file == NULL) return NULL; if (file == NULL) return NULL;
LevelPackData_t* pack_info = levelpacks + n_loaded[AST_LEVELPACK]; LevelPackData_t* pack_info = levelpacks + n_loaded[4];
fread(&pack_info->pack.n_levels, sizeof(uint32_t), 1, file); fread(&pack_info->pack.n_levels, sizeof(uint32_t), 1, file);
pack_info->pack.levels = calloc(pack_info->pack.n_levels, sizeof(LevelMap_t)); pack_info->pack.levels = calloc(pack_info->pack.n_levels, sizeof(LevelMap_t));
@ -215,10 +201,10 @@ LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path
} }
fclose(file); fclose(file);
uint8_t pack_idx = n_loaded[AST_LEVELPACK]; uint8_t pack_idx = n_loaded[4];
strncpy(pack_info->name, name, MAX_NAME_LEN); strncpy(pack_info->name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_levelpacks, levelpacks[pack_idx].name, pack_idx); sc_map_put_s64(&assets->m_levelpacks, levelpacks[pack_idx].name, pack_idx);
n_loaded[AST_LEVELPACK]++; n_loaded[4]++;
return &levelpacks[pack_idx].pack; return &levelpacks[pack_idx].pack;
} }
@ -226,7 +212,7 @@ LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path
static LevelPack_t* add_level_pack_zst(Assets_t* assets, const char* name, const uint8_t* zst_buffer, uint32_t len) static LevelPack_t* add_level_pack_zst(Assets_t* assets, const char* name, const uint8_t* zst_buffer, uint32_t len)
{ {
LevelPackData_t* pack_info = levelpacks + n_loaded[AST_LEVELPACK]; LevelPackData_t* pack_info = levelpacks + n_loaded[4];
size_t read = 0; size_t read = 0;
ZSTD_inBuffer input = { level_decompressor.in_buffer, read, 0 }; ZSTD_inBuffer input = { level_decompressor.in_buffer, read, 0 };
@ -364,10 +350,10 @@ load_end:
} }
pack_info->pack.n_levels = lvls; pack_info->pack.n_levels = lvls;
uint8_t pack_idx = n_loaded[AST_LEVELPACK]; uint8_t pack_idx = n_loaded[4];
strncpy(pack_info->name, name, MAX_NAME_LEN); strncpy(pack_info->name, name, MAX_NAME_LEN);
sc_map_put_s64(&assets->m_levelpacks, levelpacks[pack_idx].name, pack_idx); sc_map_put_s64(&assets->m_levelpacks, levelpacks[pack_idx].name, pack_idx);
n_loaded[AST_LEVELPACK]++; n_loaded[4]++;
return &levelpacks[pack_idx].pack; return &levelpacks[pack_idx].pack;
} }
@ -429,19 +415,19 @@ void init_assets(Assets_t* assets)
void free_all_assets(Assets_t* assets) void free_all_assets(Assets_t* assets)
{ {
for (uint8_t i = 0; i < n_loaded[AST_TEXTURE]; ++i) for (uint8_t i = 0; i < n_loaded[0]; ++i)
{ {
UnloadTexture(textures[i].texture); UnloadTexture(textures[i].texture);
} }
for (uint8_t i = 0; i < n_loaded[AST_SOUND]; ++i) for (uint8_t i = 0; i < n_loaded[2]; ++i)
{ {
UnloadSound(sfx[i].sound); UnloadSound(sfx[i].sound);
} }
for (uint8_t i = 0; i < n_loaded[AST_FONT]; ++i) for (uint8_t i = 0; i < n_loaded[3]; ++i)
{ {
UnloadFont(fonts[i].font); UnloadFont(fonts[i].font);
} }
for (uint8_t i = 0; i < n_loaded[AST_LEVELPACK]; ++i) for (uint8_t i = 0; i < n_loaded[4]; ++i)
{ {
unload_level_pack(levelpacks[i].pack); unload_level_pack(levelpacks[i].pack);
} }

View File

@ -5,17 +5,6 @@
#include "raylib.h" #include "raylib.h"
#include "rres.h" #include "rres.h"
#include "particle_sys.h" #include "particle_sys.h"
#define N_ASSETS_TYPE 6
typedef enum AssetType
{
AST_TEXTURE = 0,
AST_SPRITE,
AST_SOUND,
AST_FONT,
AST_LEVELPACK,
AST_EMITTER_CONF,
}AssetType_t;
typedef struct Assets typedef struct Assets
{ {
@ -60,7 +49,6 @@ void free_all_assets(Assets_t* assets);
void term_assets(Assets_t* assets); void term_assets(Assets_t* assets);
Texture2D* add_texture(Assets_t* assets, const char* name, const char* path); Texture2D* add_texture(Assets_t* assets, const char* name, const char* path);
Texture2D* add_texture_from_img(Assets_t* assets, const char* name, Image img);
Sound* add_sound(Assets_t * assets, const char* name, const char* path); Sound* add_sound(Assets_t * assets, const char* name, const char* path);
Font* add_font(Assets_t* assets, const char* name, const char* path); Font* add_font(Assets_t* assets, const char* name, const char* path);
LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path); LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path);

View File

@ -65,8 +65,9 @@ uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check
{ {
if (ent->p_ent->m_id == p_other_ent->m_id) continue; if (ent->p_ent->m_id == p_other_ent->m_id) continue;
if (!ent->p_ent->m_alive) continue; if (!ent->p_ent->m_alive) continue;
CTransform_t *p_ctransform = get_component(p_other_ent, CTRANSFORM_COMP_T);
CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T); CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T);
if (p_bbox == NULL) continue; if (p_bbox == NULL || p_ctransform == NULL) continue;
//if (p_bbox->solid && !p_bbox->fragile) //if (p_bbox->solid && !p_bbox->fragile)
if (p_bbox->solid) if (p_bbox->solid)
{ {
@ -74,7 +75,7 @@ uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check
find_AABB_overlap( find_AABB_overlap(
(Vector2){ent->bbox.x, ent->bbox.y}, (Vector2){ent->bbox.x, ent->bbox.y},
(Vector2){ent->bbox.width, ent->bbox.height}, (Vector2){ent->bbox.width, ent->bbox.height},
p_other_ent->position, p_bbox->size, &overlap p_ctransform->position, p_bbox->size, &overlap
) )
) )
{ {
@ -133,13 +134,14 @@ uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool
{ {
if (ent->p_ent->m_id == p_other_ent->m_id) continue; if (ent->p_ent->m_id == p_other_ent->m_id) continue;
if (!ent->p_ent->m_alive) continue; if (!ent->p_ent->m_alive) continue;
CTransform_t *p_ctransform = get_component(p_other_ent, CTRANSFORM_COMP_T);
CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T); CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T);
if (p_bbox == NULL) continue; if (p_bbox == NULL || p_ctransform == NULL) continue;
if (p_bbox->solid) if (p_bbox->solid)
{ {
Rectangle box = { Rectangle box = {
.x = p_other_ent->position.x, .x = p_ctransform->position.x,
.y = p_other_ent->position.y, .y = p_ctransform->position.y,
.width = p_bbox->size.x, .width = p_bbox->size.x,
.height = p_bbox->size.y, .height = p_bbox->size.y,
}; };
@ -155,26 +157,27 @@ uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool
} }
// TODO: This should be a point collision check, not an AABB check // TODO: This should be a point collision check, not an AABB check
uint8_t check_collision_at(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid) uint8_t check_collision_offset(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid, Vector2 offset)
{ {
Vector2 new_pos = Vector2Add(pos, offset);
CollideEntity_t ent = { CollideEntity_t ent = {
.p_ent = p_ent, .p_ent = p_ent,
.bbox = (Rectangle){pos.x, pos.y, bbox_sz.x, bbox_sz.y}, .bbox = (Rectangle){new_pos.x, new_pos.y, bbox_sz.x, bbox_sz.y},
.prev_bbox = (Rectangle){pos.x, pos.y, bbox_sz.x, bbox_sz.y}, .prev_bbox = (Rectangle){pos.x, pos.y, bbox_sz.x, bbox_sz.y},
.area = (TileArea_t){ .area = (TileArea_t){
.tile_x1 = (pos.x) / grid->tile_size, .tile_x1 = (new_pos.x) / grid->tile_size,
.tile_y1 = (pos.y) / grid->tile_size, .tile_y1 = (new_pos.y) / grid->tile_size,
.tile_x2 = (pos.x + bbox_sz.x - 1) / grid->tile_size, .tile_x2 = (new_pos.x + bbox_sz.x - 1) / grid->tile_size,
.tile_y2 = (pos.y + bbox_sz.y - 1) / grid->tile_size .tile_y2 = (new_pos.y + bbox_sz.y - 1) / grid->tile_size
} }
}; };
return check_collision(&ent, grid, false); return check_collision(&ent, grid, false);
} }
bool check_on_ground(Entity_t* p_ent, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid) bool check_on_ground(Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid)
{ {
Vector2 new_pos = Vector2Add(p_ent->position, (Vector2){0, 1}); Vector2 new_pos = Vector2Add(pos, (Vector2){0, 1});
CollideEntity_t ent = { CollideEntity_t ent = {
.p_ent = p_ent, .p_ent = p_ent,
.bbox = (Rectangle){new_pos.x, new_pos.y + bbox_sz.y, bbox_sz.x, 1}, .bbox = (Rectangle){new_pos.x, new_pos.y + bbox_sz.y, bbox_sz.x, 1},
@ -192,13 +195,12 @@ bool check_on_ground(Entity_t* p_ent, Vector2 prev_pos, Vector2 bbox_sz, TileGri
uint8_t check_bbox_edges( uint8_t check_bbox_edges(
TileGrid_t* tilemap, TileGrid_t* tilemap,
Entity_t* p_ent, Vector2 bbox, Entity_t* p_ent, Vector2 pos, Vector2 bbox,
bool ignore_fragile bool ignore_fragile
) )
{ {
uint8_t detected = 0; uint8_t detected = 0;
Vector2 pos = p_ent->position;
// Too lazy to adjust the tile area to check, so just make a big one // Too lazy to adjust the tile area to check, so just make a big one
CollideEntity_t ent = CollideEntity_t ent =
{ {

View File

@ -59,7 +59,7 @@ typedef struct CollideEntity {
void remove_entity_from_tilemap(EntityManager_t *p_manager, TileGrid_t* tilemap, Entity_t* p_ent); void remove_entity_from_tilemap(EntityManager_t *p_manager, TileGrid_t* tilemap, Entity_t* p_ent);
uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check_oneway); uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check_oneway);
uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool check_oneway); uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool check_oneway);
uint8_t check_collision_at(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid); uint8_t check_collision_offset(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid, Vector2 offset);
bool check_on_ground(Entity_t* p_ent, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid); bool check_on_ground(Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid);
uint8_t check_bbox_edges(TileGrid_t* tilemap, Entity_t* p_ent, Vector2 bbox, bool ignore_fragile); uint8_t check_bbox_edges(TileGrid_t* tilemap, Entity_t* p_ent, Vector2 pos, Vector2 bbox, bool ignore_fragile);
#endif // __COLLISION_FUNCS_H #endif // __COLLISION_FUNCS_H

View File

@ -230,8 +230,3 @@ void print_mempool_stats(char* buffer)
); );
} }
} }
uint32_t get_num_of_free_entities(void)
{
return ent_mempool.free_list.count;
}

View File

@ -13,5 +13,4 @@ void* get_component_wtih_id(ComponentEnum_t comp_type, unsigned long idx);
void free_component_to_mempool(ComponentEnum_t comp_type, unsigned long idx); void free_component_to_mempool(ComponentEnum_t comp_type, unsigned long idx);
void print_mempool_stats(char* buffer); void print_mempool_stats(char* buffer);
uint32_t get_num_of_free_entities(void);
#endif //__MEMPOOL_H #endif //__MEMPOOL_H

View File

@ -136,7 +136,7 @@ static void level_scene_render_func(Scene_t* scene)
CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T); CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T);
CMovementState_t* p_mstate = get_component(p_ent, CMOVEMENTSTATE_T); CMovementState_t* p_mstate = get_component(p_ent, CMOVEMENTSTATE_T);
sprintf(buffer, "Pos: %.3f\n %.3f", p_ent->position.x, p_ent->position.y); sprintf(buffer, "Pos: %.3f\n %.3f", p_ct->position.x, p_ct->position.y);
DrawText(buffer, gui_x, gui_y, 12, BLACK); DrawText(buffer, gui_x, gui_y, 12, BLACK);
sprintf(buffer, "Vel: %.3f\n %.3f", p_ct->velocity.x, p_ct->velocity.y); sprintf(buffer, "Vel: %.3f\n %.3f", p_ct->velocity.x, p_ct->velocity.y);
DrawText(buffer, gui_x + 80, gui_y, 12, BLACK); DrawText(buffer, gui_x + 80, gui_y, 12, BLACK);
@ -290,6 +290,7 @@ static void render_editor_game_scene(Scene_t* scene)
char buffer[64] = {0}; char buffer[64] = {0};
sc_map_foreach_value(&scene->ent_manager.entities, p_ent) sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
{ {
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
// Draw the spawn point // Draw the spawn point
@ -302,10 +303,10 @@ static void render_editor_game_scene(Scene_t* scene)
Vector2 box_size = {0}; Vector2 box_size = {0};
if (p_bbox != NULL) box_size = p_bbox->size; if (p_bbox != NULL) box_size = p_bbox->size;
if ( if (
p_ent->position.x + box_size.x < min.x * tilemap.tile_size p_ct->position.x + box_size.x < min.x * tilemap.tile_size
|| p_ent->position.x > max.x * tilemap.tile_size || p_ct->position.x > max.x * tilemap.tile_size
|| p_ent->position.y + box_size.y < min.y * tilemap.tile_size || p_ct->position.y + box_size.y < min.y * tilemap.tile_size
|| p_ent->position.y > max.y * tilemap.tile_size || p_ct->position.y > max.y * tilemap.tile_size
) continue; ) continue;
Color colour; Color colour;
@ -335,11 +336,11 @@ static void render_editor_game_scene(Scene_t* scene)
{ {
if (p_ent->m_tag == BOULDER_ENT_TAG) if (p_ent->m_tag == BOULDER_ENT_TAG)
{ {
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, colour); DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, colour);
} }
else else
{ {
DrawRectangle(p_ent->position.x, p_ent->position.y, p_bbox->size.x, p_bbox->size.y, colour); DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour);
} }
if (p_ent->m_tag == CRATES_ENT_TAG) if (p_ent->m_tag == CRATES_ENT_TAG)
@ -351,42 +352,42 @@ static void render_editor_game_scene(Scene_t* scene)
{ {
case CONTAINER_LEFT_ARROW: case CONTAINER_LEFT_ARROW:
DrawLine( DrawLine(
p_ent->position.x, p_ct->position.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_RIGHT_ARROW: case CONTAINER_RIGHT_ARROW:
DrawLine( DrawLine(
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->size.x, p_ct->position.x + p_bbox->size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_UP_ARROW: case CONTAINER_UP_ARROW:
DrawLine( DrawLine(
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y, p_ct->position.y,
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_DOWN_ARROW: case CONTAINER_DOWN_ARROW:
DrawLine( DrawLine(
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->size.y, p_ct->position.y + p_bbox->size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_BOMB: case CONTAINER_BOMB:
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, BLACK); DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
break; break;
default: default:
break; break;
@ -402,8 +403,8 @@ static void render_editor_game_scene(Scene_t* scene)
for (uint8_t i = 0;i < p_hitbox->n_boxes; ++i) for (uint8_t i = 0;i < p_hitbox->n_boxes; ++i)
{ {
Rectangle rec = { Rectangle rec = {
.x = p_ent->position.x + p_hitbox->boxes[i].x, .x = p_ct->position.x + p_hitbox->boxes[i].x,
.y = p_ent->position.y + p_hitbox->boxes[i].y, .y = p_ct->position.y + p_hitbox->boxes[i].y,
.width = p_hitbox->boxes[i].width, .width = p_hitbox->boxes[i].width,
.height = p_hitbox->boxes[i].height, .height = p_hitbox->boxes[i].height,
}; };
@ -413,8 +414,8 @@ static void render_editor_game_scene(Scene_t* scene)
if (p_hurtbox != NULL) if (p_hurtbox != NULL)
{ {
Rectangle rec = { Rectangle rec = {
.x = p_ent->position.x + p_hurtbox->offset.x, .x = p_ct->position.x + p_hurtbox->offset.x,
.y = p_ent->position.y + p_hurtbox->offset.y, .y = p_ct->position.y + p_hurtbox->offset.y,
.width = p_hurtbox->size.x, .width = p_hurtbox->size.x,
.height = p_hurtbox->size.y, .height = p_hurtbox->size.y,
}; };
@ -426,7 +427,7 @@ static void render_editor_game_scene(Scene_t* scene)
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx]; const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL) if (spr.sprite != NULL)
{ {
Vector2 pos = Vector2Add(p_ent->position, spr.offset); Vector2 pos = Vector2Add(p_ct->position, spr.offset);
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x); draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
} }
} }
@ -434,7 +435,8 @@ static void render_editor_game_scene(Scene_t* scene)
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent) sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
{ {
DrawCircleV(p_ent->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN); CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
DrawCircleV(p_ct->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
} }
draw_particle_system(&scene->part_sys); draw_particle_system(&scene->part_sys);
@ -516,10 +518,9 @@ static void spawn_chest(Scene_t* scene, unsigned int tile_idx)
Entity_t* p_crate = create_chest(&scene->ent_manager); Entity_t* p_crate = create_chest(&scene->ent_manager);
if (p_crate == NULL) return; if (p_crate == NULL) return;
p_crate->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_crate->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
CTransform_t* p_ctransform = get_component(p_crate, CTRANSFORM_COMP_T); 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; p_ctransform->active = true;
} }
@ -528,10 +529,10 @@ static void spawn_crate(Scene_t* scene, unsigned int tile_idx, bool metal, Conta
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
Entity_t* p_crate = create_crate(&scene->ent_manager, metal, item); Entity_t* p_crate = create_crate(&scene->ent_manager, metal, item);
if (p_crate == NULL) return; if (p_crate == NULL) return;
p_crate->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_crate->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
CTransform_t* p_ctransform = get_component(p_crate, CTRANSFORM_COMP_T); 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 = active; p_ctransform->active = active;
} }
@ -541,8 +542,9 @@ static void spawn_boulder(Scene_t* scene, unsigned int tile_idx)
Entity_t* p_boulder = create_boulder(&scene->ent_manager); Entity_t* p_boulder = create_boulder(&scene->ent_manager);
if (p_boulder == NULL) return; if (p_boulder == NULL) return;
p_boulder->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE; CTransform_t* p_ctransform = get_component(p_boulder, CTRANSFORM_COMP_T);
p_boulder->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE; p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
} }
static void toggle_block_system(Scene_t* scene) static void toggle_block_system(Scene_t* scene)
@ -640,8 +642,9 @@ static void toggle_block_system(Scene_t* scene)
Entity_t* p_ent = create_water_runner(&scene->ent_manager, DEFAULT_MAP_WIDTH, DEFAULT_MAP_HEIGHT, tile_idx); Entity_t* p_ent = create_water_runner(&scene->ent_manager, DEFAULT_MAP_WIDTH, DEFAULT_MAP_HEIGHT, tile_idx);
if (p_ent != NULL) if (p_ent != NULL)
{ {
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size; CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size; p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
} }
} }
break; break;
@ -650,8 +653,9 @@ static void toggle_block_system(Scene_t* scene)
Entity_t* p_ent = create_level_end(&scene->ent_manager); Entity_t* p_ent = create_level_end(&scene->ent_manager);
if (p_ent != NULL) if (p_ent != NULL)
{ {
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1); CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);; p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);;
} }
} }
break; break;
@ -962,7 +966,8 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
break; break;
case ACTION_SET_SPAWNPOINT: case ACTION_SET_SPAWNPOINT:
{ {
p_player->spawn_pos = p_player->position; CTransform_t* p_ct = get_component(p_player, CTRANSFORM_COMP_T);
p_player->spawn_pos = p_ct->position;
} }
break; break;
default: default:

View File

@ -202,16 +202,17 @@ static void render_regular_game_scene(Scene_t* scene)
sc_map_foreach_value(&scene->ent_manager.entities, p_ent) sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
{ {
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
// Entity culling // Entity culling
Vector2 box_size = {0}; Vector2 box_size = {0};
if (p_bbox != NULL) box_size = p_bbox->size; if (p_bbox != NULL) box_size = p_bbox->size;
if ( if (
p_ent->position.x + box_size.x < min.x * tilemap.tile_size p_ct->position.x + box_size.x < min.x * tilemap.tile_size
|| p_ent->position.x > max.x * tilemap.tile_size || p_ct->position.x > max.x * tilemap.tile_size
|| p_ent->position.y + box_size.y < min.y * tilemap.tile_size || p_ct->position.y + box_size.y < min.y * tilemap.tile_size
|| p_ent->position.y > max.y * tilemap.tile_size || p_ct->position.y > max.y * tilemap.tile_size
) continue; ) continue;
// Render Sprite only // Render Sprite only
@ -221,7 +222,7 @@ static void render_regular_game_scene(Scene_t* scene)
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx]; const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL) if (spr.sprite != NULL)
{ {
Vector2 pos = Vector2Add(p_ent->position, spr.offset); Vector2 pos = Vector2Add(p_ct->position, spr.offset);
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x); draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
} }
continue; continue;
@ -249,11 +250,11 @@ static void render_regular_game_scene(Scene_t* scene)
{ {
if (p_ent->m_tag == BOULDER_ENT_TAG) if (p_ent->m_tag == BOULDER_ENT_TAG)
{ {
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, colour); DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, colour);
} }
else else
{ {
DrawRectangle(p_ent->position.x, p_ent->position.y, p_bbox->size.x, p_bbox->size.y, colour); DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour);
} }
if (p_ent->m_tag == CRATES_ENT_TAG) if (p_ent->m_tag == CRATES_ENT_TAG)
@ -265,42 +266,42 @@ static void render_regular_game_scene(Scene_t* scene)
{ {
case CONTAINER_LEFT_ARROW: case CONTAINER_LEFT_ARROW:
DrawLine( DrawLine(
p_ent->position.x, p_ct->position.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_RIGHT_ARROW: case CONTAINER_RIGHT_ARROW:
DrawLine( DrawLine(
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->size.x, p_ct->position.x + p_bbox->size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_UP_ARROW: case CONTAINER_UP_ARROW:
DrawLine( DrawLine(
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y, p_ct->position.y,
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_DOWN_ARROW: case CONTAINER_DOWN_ARROW:
DrawLine( DrawLine(
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y, p_ct->position.y + p_bbox->half_size.y,
p_ent->position.x + p_bbox->half_size.x, p_ct->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->size.y, p_ct->position.y + p_bbox->size.y,
BLACK BLACK
); );
break; break;
case CONTAINER_BOMB: case CONTAINER_BOMB:
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, BLACK); DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
break; break;
default: default:
break; break;

View File

@ -86,7 +86,7 @@ static bool check_collision_and_move(
CBBox_t* p_bbox = get_component(ent, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(ent, CBBOX_COMP_T);
Vector2 overlap = {0,0}; Vector2 overlap = {0,0};
Vector2 prev_overlap = {0,0}; Vector2 prev_overlap = {0,0};
uint8_t overlap_mode = find_AABB_overlap(ent->position, p_bbox->size, *other_pos, other_bbox, &overlap); uint8_t overlap_mode = find_AABB_overlap(p_ct->position, p_bbox->size, *other_pos, other_bbox, &overlap);
if (overlap_mode == 1) if (overlap_mode == 1)
{ {
// If there is collision, use previous overlap to determine direction // If there is collision, use previous overlap to determine direction
@ -119,53 +119,53 @@ static bool check_collision_and_move(
// One way collision is a bit special // One way collision is a bit special
if ( if (
p_ct->prev_position.y + p_bbox->size.y - 1 < other_pos->y p_ct->prev_position.y + p_bbox->size.y - 1 < other_pos->y
&& ent->position.y + p_bbox->size.y - 1 >= other_pos->y && p_ct->position.y + p_bbox->size.y - 1 >= other_pos->y
) )
{ {
offset.y = other_pos->y - (ent->position.y + p_bbox->size.y); offset.y = other_pos->y - (p_ct->position.y + p_bbox->size.y);
} }
} }
ent->position = Vector2Add(ent->position, offset); p_ct->position = Vector2Add(p_ct->position, offset);
} }
else if (overlap_mode == 2) else if (overlap_mode == 2)
{ {
if ( other_solid != SOLID ) goto collision_end; if ( other_solid != SOLID ) goto collision_end;
// On complete overlap, find a free space in this order: top, left, right, bottom // On complete overlap, find a free space in this order: top, left, right, bottom
Vector2 point_to_test = {0}; Vector2 point_to_test = {0};
point_to_test.x = ent->position.x; point_to_test.x = p_ct->position.x;
point_to_test.y = other_pos->y - p_bbox->size.y + 1; point_to_test.y = other_pos->y - p_bbox->size.y + 1;
if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{ {
ent->position = point_to_test; p_ct->position = point_to_test;
goto collision_end; goto collision_end;
} }
point_to_test.x = other_pos->x - p_bbox->size.x + 1; point_to_test.x = other_pos->x - p_bbox->size.x + 1;
point_to_test.y = ent->position.y; point_to_test.y = p_ct->position.y;
if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{ {
ent->position = point_to_test; p_ct->position = point_to_test;
goto collision_end; goto collision_end;
} }
point_to_test.x = other_pos->x + other_bbox.x - 1; point_to_test.x = other_pos->x + other_bbox.x - 1;
point_to_test.y = ent->position.y; point_to_test.y = p_ct->position.y;
if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{ {
ent->position = point_to_test; p_ct->position = point_to_test;
goto collision_end; goto collision_end;
} }
point_to_test.x = ent->position.x; point_to_test.x = p_ct->position.x;
point_to_test.y = other_pos->y + other_bbox.y - 1; point_to_test.y = other_pos->y + other_bbox.y - 1;
if (!check_collision_at(ent, point_to_test, p_bbox->size, tilemap)) if (!check_collision_offset(ent, point_to_test, p_bbox->size, tilemap, (Vector2){0}))
{ {
ent->position = point_to_test; p_ct->position = point_to_test;
goto collision_end; goto collision_end;
} }
// If no free space, Move up no matter what // If no free space, Move up no matter what
//p_ct->position.x = p_ct->position.x; p_ct->position.x = p_ct->position.x;
ent->position.y = other_pos->y - p_bbox->size.y + 1; p_ct->position.y = other_pos->y - p_bbox->size.y + 1;
} }
collision_end: collision_end:
return overlap_mode > 0; return overlap_mode > 0;
@ -242,10 +242,12 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
{ {
if (p_ent->m_tag == BOULDER_ENT_TAG) if (p_ent->m_tag == BOULDER_ENT_TAG)
{ {
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
//const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
ParticleEmitter_t emitter = { ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_rock"), .spr = get_sprite(&scene->engine->assets, "p_rock"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 5, .n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update, .update_func = &simple_particle_system_update,
@ -256,10 +258,12 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
else if (p_ent->m_tag == CRATES_ENT_TAG) else if (p_ent->m_tag == CRATES_ENT_TAG)
{ {
const CContainer_t* p_container = get_component(p_ent, CCONTAINER_T); const CContainer_t* p_container = get_component(p_ent, CCONTAINER_T);
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
//const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
ParticleEmitter_t emitter = { ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, (p_container->material == WOODEN_CONTAINER) ? "p_wood" : "p_metal"), .spr = get_sprite(&scene->engine->assets, (p_container->material == WOODEN_CONTAINER) ? "p_wood" : "p_metal"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 5, .n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update, .update_func = &simple_particle_system_update,
@ -269,10 +273,11 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
} }
else if (p_ent->m_tag == CHEST_ENT_TAG) else if (p_ent->m_tag == CHEST_ENT_TAG)
{ {
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
ParticleEmitter_t emitter = { ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_wood"), .spr = get_sprite(&scene->engine->assets, "p_wood"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 5, .n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update, .update_func = &simple_particle_system_update,
@ -283,7 +288,7 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
ParticleEmitter_t emitter2 = { ParticleEmitter_t emitter2 = {
.spr = get_sprite(&scene->engine->assets, "p_coin"), .spr = get_sprite(&scene->engine->assets, "p_coin"),
.config = get_emitter_conf(&scene->engine->assets, "pe_single"), .config = get_emitter_conf(&scene->engine->assets, "pe_single"),
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 1, .n_particles = 1,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update, .update_func = &simple_particle_system_update,
@ -295,10 +300,11 @@ void destroy_entity(Scene_t* scene, TileGrid_t* tilemap, Entity_t* p_ent)
} }
else if (p_ent->m_tag == ARROW_ENT_TAG) else if (p_ent->m_tag == ARROW_ENT_TAG)
{ {
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
ParticleEmitter_t emitter = { ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_arrow"), .spr = get_sprite(&scene->engine->assets, "p_arrow"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 2, .n_particles = 2,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update, .update_func = &simple_particle_system_update,
@ -324,10 +330,11 @@ void player_respawn_system(Scene_t* scene)
Entity_t* ent = create_dead_player(&scene->ent_manager); Entity_t* ent = create_dead_player(&scene->ent_manager);
if (ent != NULL) if (ent != NULL)
{ {
ent->position = p_player->position; CTransform_t* new_ct = get_component(ent, CTRANSFORM_COMP_T);
memcpy(&new_ct->position, &p_ct->position, sizeof(p_ct->position));
} }
p_player->m_alive = true; p_player->m_alive = true;
p_player->position = p_player->spawn_pos; p_ct->position = p_player->spawn_pos;
memset(&p_ct->velocity, 0, sizeof(p_ct->velocity)); memset(&p_ct->velocity, 0, sizeof(p_ct->velocity));
memset(&p_ct->accel, 0, sizeof(p_ct->accel)); memset(&p_ct->accel, 0, sizeof(p_ct->accel));
} }
@ -367,14 +374,14 @@ void player_movement_input_system(Scene_t* scene)
if (p_pstate->player_dir.y < 0) if (p_pstate->player_dir.y < 0)
{ {
unsigned int tile_idx = get_tile_idx( unsigned int tile_idx = get_tile_idx(
p_player->position.x + p_bbox->half_size.x, p_ctransform->position.x + p_bbox->half_size.x,
p_player->position.y + p_bbox->half_size.y, p_ctransform->position.y + p_bbox->half_size.y,
data->tilemap.width data->tilemap.width
); );
if (tilemap.tiles[tile_idx].tile_type == LADDER && p_ctransform->velocity.y >= 0) if (tilemap.tiles[tile_idx].tile_type == LADDER && p_ctransform->velocity.y >= 0)
{ {
p_pstate->ladder_state = true; p_pstate->ladder_state = true;
p_player->position.y--; p_ctransform->position.y--;
} }
} }
else if (p_pstate->player_dir.y > 0) else if (p_pstate->player_dir.y > 0)
@ -384,31 +391,31 @@ void player_movement_input_system(Scene_t* scene)
if (p_mstate->ground_state & 1) if (p_mstate->ground_state & 1)
{ {
tile_idx = get_tile_idx( tile_idx = get_tile_idx(
p_player->position.x + p_bbox->half_size.x, p_ctransform->position.x + p_bbox->half_size.x,
p_player->position.y + p_bbox->size.y, p_ctransform->position.y + p_bbox->size.y,
data->tilemap.width data->tilemap.width
); );
} }
else else
{ {
tile_idx = get_tile_idx( tile_idx = get_tile_idx(
p_player->position.x + p_bbox->half_size.x, p_ctransform->position.x + p_bbox->half_size.x,
p_player->position.y + p_bbox->half_size.y, p_ctransform->position.y + p_bbox->half_size.y,
data->tilemap.width data->tilemap.width
); );
} }
if (tile_idx < tilemap.n_tiles && tilemap.tiles[tile_idx].tile_type == LADDER) if (tile_idx < tilemap.n_tiles && tilemap.tiles[tile_idx].tile_type == LADDER)
{ {
p_pstate->ladder_state = true; p_pstate->ladder_state = true;
p_player->position.y++; p_ctransform->position.y++;
} }
} }
} }
else else
{ {
unsigned int tile_x = (p_player->position.x + p_bbox->half_size.x) / TILE_SIZE; unsigned int tile_x = (p_ctransform->position.x + p_bbox->half_size.x) / TILE_SIZE;
unsigned int tile_y1 = (p_player->position.y + p_bbox->half_size.y) / TILE_SIZE; unsigned int tile_y1 = (p_ctransform->position.y + p_bbox->half_size.y) / TILE_SIZE;
unsigned int tile_y2 = (p_player->position.y + p_bbox->size.y) / TILE_SIZE; unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
p_pstate->ladder_state = false; p_pstate->ladder_state = false;
if (!(p_mstate->ground_state & 1)) if (!(p_mstate->ground_state & 1))
@ -425,7 +432,7 @@ void player_movement_input_system(Scene_t* scene)
p_ctransform->velocity.x = p_pstate->player_dir.x * 40; p_ctransform->velocity.x = p_pstate->player_dir.x * 40;
if (p_pstate->player_dir.y != 0) if (p_pstate->player_dir.y != 0)
{ {
p_player->position.x = tile_x * TILE_SIZE + 1; p_ctransform->position.x = tile_x * TILE_SIZE + 1;
} }
} }
} }
@ -465,12 +472,9 @@ void player_movement_input_system(Scene_t* scene)
} }
} }
Vector2 point_to_check = Vector2Add( uint8_t collide_type = check_collision_offset(
p_player->position, p_player, p_ctransform->position, p_bbox->size,
(Vector2){0, p_bbox->size.y - PLAYER_HEIGHT} &tilemap, (Vector2){0, p_bbox->size.y - PLAYER_HEIGHT}
);
uint8_t collide_type = check_collision_at(
p_player, point_to_check, p_bbox->size, &tilemap
); );
if (collide_type == 1) if (collide_type == 1)
{ {
@ -527,6 +531,7 @@ void player_bbox_update_system(Scene_t* scene)
Entity_t* p_player; Entity_t* p_player;
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
{ {
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T); CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T);
CMovementState_t* p_mstate = get_component(p_player, CMOVEMENTSTATE_T); CMovementState_t* p_mstate = get_component(p_player, CMOVEMENTSTATE_T);
@ -564,15 +569,15 @@ void player_bbox_update_system(Scene_t* scene)
} }
} }
Vector2 point_to_check = Vector2Add(p_player->position, offset);
if ( if (
check_collision_at( check_collision_offset(
p_player, point_to_check, new_bbox, &tilemap p_player, p_ctransform->position, new_bbox,
&tilemap, offset
) != 1 ) != 1
) )
{ {
set_bbox(p_bbox, new_bbox.x, new_bbox.y); set_bbox(p_bbox, new_bbox.x, new_bbox.y);
p_player->position = Vector2Add(p_player->position, offset); p_ctransform->position = Vector2Add(p_ctransform->position, offset);
} }
CHitBoxes_t* p_hitbox = get_component(p_player, CHITBOXES_T); CHitBoxes_t* p_hitbox = get_component(p_player, CHITBOXES_T);
@ -590,11 +595,12 @@ void player_crushing_system(Scene_t* scene)
Entity_t* p_player; Entity_t* p_player;
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
{ {
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
uint8_t edges = check_bbox_edges( uint8_t edges = check_bbox_edges(
&data->tilemap, p_player, &data->tilemap, p_player,
p_bbox->size, true p_ctransform->position, p_bbox->size, true
); );
// There is a second check for to ensure that there is an solid entity/tile overlapping the player bbox // There is a second check for to ensure that there is an solid entity/tile overlapping the player bbox
@ -606,13 +612,13 @@ void player_crushing_system(Scene_t* scene)
CollideEntity_t ent = CollideEntity_t ent =
{ {
.p_ent = p_player, .p_ent = p_player,
.bbox = (Rectangle){p_player->position.x, p_player->position.y, p_bbox->size.x, 1}, .bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, 1},
.prev_bbox = (Rectangle){p_player->position.x, p_player->position.y, p_bbox->size.x, p_bbox->size.y}, .prev_bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
.area = (TileArea_t){ .area = (TileArea_t){
.tile_x1 = (p_player->position.x) / TILE_SIZE, .tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
.tile_y1 = (p_player->position.y) / TILE_SIZE, .tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
.tile_x2 = (p_player->position.x + p_bbox->size.x - 1) / TILE_SIZE, .tile_x2 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE,
.tile_y2 = (p_player->position.y + p_bbox->size.y - 1) / TILE_SIZE, .tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
} }
}; };
@ -623,7 +629,7 @@ void player_crushing_system(Scene_t* scene)
collide |= 1 << 1; collide |= 1 << 1;
} }
ent.bbox.y = p_player->position.y + p_bbox->size.y; ent.bbox.y = p_ctransform->position.y + p_bbox->size.y;
collide_type = check_collision_line(&ent, &data->tilemap, true); collide_type = check_collision_line(&ent, &data->tilemap, true);
if (collide_type == 1) if (collide_type == 1)
{ {
@ -643,13 +649,13 @@ void player_crushing_system(Scene_t* scene)
CollideEntity_t ent = CollideEntity_t ent =
{ {
.p_ent = p_player, .p_ent = p_player,
.bbox = (Rectangle){p_player->position.x, p_player->position.y, 1, p_bbox->size.y}, .bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, 1, p_bbox->size.y},
.prev_bbox = (Rectangle){p_player->position.x, p_player->position.y, p_bbox->size.x, p_bbox->size.y}, .prev_bbox = (Rectangle){p_ctransform->position.x, p_ctransform->position.y, p_bbox->size.x, p_bbox->size.y},
.area = (TileArea_t){ .area = (TileArea_t){
.tile_x1 = (p_player->position.x) / TILE_SIZE, .tile_x1 = (p_ctransform->position.x) / TILE_SIZE,
.tile_y1 = (p_player->position.y) / TILE_SIZE, .tile_y1 = (p_ctransform->position.y) / TILE_SIZE,
.tile_x2 = (p_player->position.x + p_bbox->size.x - 1) / TILE_SIZE, .tile_x2 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE,
.tile_y2 = (p_player->position.y + p_bbox->size.y - 1) / TILE_SIZE, .tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE,
} }
}; };
@ -661,7 +667,7 @@ void player_crushing_system(Scene_t* scene)
} }
//Right //Right
ent.bbox.x = p_player->position.x + p_bbox->size.x; // 2 to account for the previous subtraction ent.bbox.x = p_ctransform->position.x + p_bbox->size.x; // 2 to account for the previous subtraction
collide_type = check_collision_line(&ent, &data->tilemap, false); collide_type = check_collision_line(&ent, &data->tilemap, false);
if (collide_type == 1) if (collide_type == 1)
{ {
@ -687,10 +693,11 @@ void spike_collision_system(Scene_t* scene)
sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox) sc_map_foreach(&scene->ent_manager.component_map[CBBOX_COMP_T], ent_idx, p_bbox)
{ {
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx); Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
unsigned int tile_x1 = (p_ent->position.x) / TILE_SIZE; CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
unsigned int tile_y1 = (p_ent->position.y) / TILE_SIZE; unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x + p_bbox->size.x - 1) / TILE_SIZE; unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y + p_bbox->size.y - 1) / TILE_SIZE; unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE;
unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE;
tile_x1 = (tile_x1 < 0) ? 0 : tile_x1; tile_x1 = (tile_x1 < 0) ? 0 : tile_x1;
tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2; tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2;
@ -705,7 +712,7 @@ void spike_collision_system(Scene_t* scene)
if(tilemap.tiles[tile_idx].tile_type == SPIKES) if(tilemap.tiles[tile_idx].tile_type == SPIKES)
{ {
uint8_t collide = find_AABB_overlap( uint8_t collide = find_AABB_overlap(
p_ent->position, p_bbox->size, p_ctransform->position, p_bbox->size,
(Vector2){ (Vector2){
tile_x * TILE_SIZE + tilemap.tiles[tile_idx].offset.x, tile_x * TILE_SIZE + tilemap.tiles[tile_idx].offset.x,
tile_y * TILE_SIZE + tilemap.tiles[tile_idx].offset.y tile_y * TILE_SIZE + tilemap.tiles[tile_idx].offset.y
@ -752,10 +759,10 @@ void tile_collision_system(Scene_t* scene)
// exclude self // exclude self
// This has an extra pixel when gathering potential collision, just to avoid missing any // This has an extra pixel when gathering potential collision, just to avoid missing any
// This is only done here, collision methods do not have this // This is only done here, collision methods do not have this
unsigned int tile_x1 = (p_ent->position.x - 1) / TILE_SIZE; unsigned int tile_x1 = (p_ctransform->position.x - 1) / TILE_SIZE;
unsigned int tile_y1 = (p_ent->position.y - 1) / TILE_SIZE; unsigned int tile_y1 = (p_ctransform->position.y - 1) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x + p_bbox->size.x) / TILE_SIZE; unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y + p_bbox->size.y) / TILE_SIZE; unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
tile_x1 = (tile_x1 < 0) ? 0 : tile_x1; tile_x1 = (tile_x1 < 0) ? 0 : tile_x1;
tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2; tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2;
@ -801,6 +808,8 @@ void tile_collision_system(Scene_t* scene)
CBBox_t *p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T); CBBox_t *p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
if (p_other_bbox == NULL) continue; 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; 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) if (p_ent->m_tag == PLAYER_ENT_TAG && p_other_ent->m_tag == CHEST_ENT_TAG)
{ {
@ -808,7 +817,7 @@ void tile_collision_system(Scene_t* scene)
} }
check_collision_and_move( check_collision_and_move(
&tilemap, p_ent, &tilemap, p_ent,
&p_other_ent->position, p_other_bbox->size, &p_other_ct->position, p_other_bbox->size,
solid solid
); );
} }
@ -832,7 +841,7 @@ void edge_velocity_check_system(Scene_t* scene)
// Post movement edge check to zero out velocity // Post movement edge check to zero out velocity
uint8_t edges = check_bbox_edges( uint8_t edges = check_bbox_edges(
&data->tilemap, p_ent, &data->tilemap, p_ent,
p_bbox->size, false p_ctransform->position, p_bbox->size, false
); );
if (edges & (1<<3)) if (edges & (1<<3))
{ {
@ -853,26 +862,26 @@ void edge_velocity_check_system(Scene_t* scene)
// Deal with float precision, by rounding when it is near to an integer enough by 2 dp // Deal with float precision, by rounding when it is near to an integer enough by 2 dp
float decimal; float decimal;
float fractional = modff(p_ent->position.x, &decimal); float fractional = modff(p_ctransform->position.x, &decimal);
if (fractional > 0.99) if (fractional > 0.99)
{ {
p_ent->position.x = decimal; p_ctransform->position.x = decimal;
(p_ent->position.x > 0) ? p_ent->position.x++ : p_ent->position.x--; (p_ctransform->position.x > 0) ? p_ctransform->position.x++ : p_ctransform->position.x--;
} }
else if (fractional < 0.01) else if (fractional < 0.01)
{ {
p_ent->position.x = decimal; p_ctransform->position.x = decimal;
} }
fractional = modff(p_ent->position.y, &decimal); fractional = modff(p_ctransform->position.y, &decimal);
if (fractional > 0.99) if (fractional > 0.99)
{ {
p_ent->position.y = decimal; p_ctransform->position.y = decimal;
(p_ent->position.y > 0) ? p_ent->position.y++ : p_ent->position.y--; (p_ctransform->position.y > 0) ? p_ctransform->position.y++ : p_ctransform->position.y--;
} }
else if (fractional < 0.01) else if (fractional < 0.01)
{ {
p_ent->position.y = decimal; p_ctransform->position.y = decimal;
} }
} }
} }
@ -966,7 +975,7 @@ void global_external_forces_system(Scene_t* scene)
// Zero out acceleration for contacts with sturdy entites and tiles // Zero out acceleration for contacts with sturdy entites and tiles
uint8_t edges = check_bbox_edges( uint8_t edges = check_bbox_edges(
&data->tilemap, p_ent, &data->tilemap, p_ent,
p_bbox->size, false p_ctransform->position, p_bbox->size, false
); );
if (edges & (1<<3)) if (edges & (1<<3))
{ {
@ -1010,11 +1019,11 @@ void moveable_update_system(Scene_t* scene)
if (p_moveable->gridmove) if (p_moveable->gridmove)
{ {
float remaining_distance = p_moveable->target_pos.x - p_ent->position.x; float remaining_distance = p_moveable->target_pos.x - p_ctransform->position.x;
if (fabs(remaining_distance) < 0.1) if (fabs(remaining_distance) < 0.1)
{ {
p_ctransform->prev_position = p_moveable->prev_pos; p_ctransform->prev_position = p_moveable->prev_pos;
p_ent->position = p_moveable->target_pos; p_ctransform->position = p_moveable->target_pos;
p_moveable->gridmove = false; p_moveable->gridmove = false;
p_bbox->solid = true; p_bbox->solid = true;
p_ctransform->movement_mode = REGULAR_MOVEMENT; p_ctransform->movement_mode = REGULAR_MOVEMENT;
@ -1022,11 +1031,11 @@ void moveable_update_system(Scene_t* scene)
} }
else if (remaining_distance > 0.1) else if (remaining_distance > 0.1)
{ {
p_ent->position.x += (remaining_distance > p_moveable->move_speed) ? p_moveable->move_speed : remaining_distance; p_ctransform->position.x += (remaining_distance > p_moveable->move_speed) ? p_moveable->move_speed : remaining_distance;
} }
else else
{ {
p_ent->position.x += (remaining_distance < -p_moveable->move_speed) ? -p_moveable->move_speed : remaining_distance; p_ctransform->position.x += (remaining_distance < -p_moveable->move_speed) ? -p_moveable->move_speed : remaining_distance;
memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity)); memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity));
} }
} }
@ -1040,8 +1049,8 @@ void moveable_update_system(Scene_t* scene)
// Point to check is the one row below // Point to check is the one row below
Vector2 point_to_check = { Vector2 point_to_check = {
.x = p_ent->position.x + p_bbox->half_size.x, .x = p_ctransform->position.x + p_bbox->half_size.x,
.y = p_ent->position.y + p_bbox->size.y + 1 .y = p_ctransform->position.y + p_bbox->size.y + 1
}; };
unsigned int tile_x = point_to_check.x / TILE_SIZE; unsigned int tile_x = point_to_check.x / TILE_SIZE;
unsigned int tile_y = point_to_check.y / TILE_SIZE; unsigned int tile_y = point_to_check.y / TILE_SIZE;
@ -1060,11 +1069,11 @@ void moveable_update_system(Scene_t* scene)
Entity_t* other_ent = get_entity(&scene->ent_manager, other_ent_idx); Entity_t* other_ent = get_entity(&scene->ent_manager, other_ent_idx);
CBBox_t* p_other_bbox = get_component(other_ent, CBBOX_COMP_T); CBBox_t* p_other_bbox = get_component(other_ent, CBBOX_COMP_T);
CTransform_t* p_other_ct = get_component(other_ent, CTRANSFORM_COMP_T); CTransform_t* p_other_ct = get_component(other_ent, CTRANSFORM_COMP_T);
Rectangle box = {other_ent->position.x, other_ent->position.y, p_other_bbox->size.x, p_other_bbox->size.y}; Rectangle box = {p_other_ct->position.x, p_other_ct->position.y, p_other_bbox->size.x, p_other_bbox->size.y};
if (!point_in_AABB(point_to_check, box) || Vector2LengthSqr(p_other_ct->velocity) != 0) continue; if (!point_in_AABB(point_to_check, box) || Vector2LengthSqr(p_other_ct->velocity) != 0) continue;
} }
tile_x = (p_ent->position.x) / TILE_SIZE - 1; tile_x = (p_ctransform->position.x) / TILE_SIZE - 1;
if (tile_x >= 0 && tile_x < tilemap.width) if (tile_x >= 0 && tile_x < tilemap.width)
{ {
@ -1150,7 +1159,7 @@ void moveable_update_system(Scene_t* scene)
{ {
p_moveable->gridmove = true; p_moveable->gridmove = true;
p_bbox->solid = false; p_bbox->solid = false;
p_moveable->prev_pos = p_ent->position; p_moveable->prev_pos = p_ctransform->position;
p_moveable->target_pos = Vector2Scale((Vector2){tile_x,tile_y-1}, TILE_SIZE); p_moveable->target_pos = Vector2Scale((Vector2){tile_x,tile_y-1}, TILE_SIZE);
memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity)); memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity));
memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel)); memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel));
@ -1180,7 +1189,7 @@ void player_pushing_system(Scene_t* scene)
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T); CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_player, CBBOX_COMP_T);
Vector2 point_to_check = p_player->position; Vector2 point_to_check = p_ctransform->position;
point_to_check.y += p_bbox->half_size.y; point_to_check.y += p_bbox->half_size.y;
if (p_pstate->player_dir.x > 0) if (p_pstate->player_dir.x > 0)
{ {
@ -1212,15 +1221,15 @@ void player_pushing_system(Scene_t* scene)
CTransform_t *p_other_ct = get_component(p_other_ent, CTRANSFORM_COMP_T); 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); CBBox_t *p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
Rectangle box = { Rectangle box = {
.x = p_other_ent->position.x, .x = p_other_ct->position.x,
.y = p_other_ent->position.y, .y = p_other_ct->position.y,
.width = p_other_bbox->size.x, .width = p_other_bbox->size.x,
.height = p_other_bbox->size.y .height = p_other_bbox->size.y
}; };
if (point_in_AABB(point_to_check, box)) if (point_in_AABB(point_to_check, box))
{ {
Vector2 target_pos = p_other_ent->position; Vector2 target_pos = p_other_ct->position;
if (p_player->position.x < p_other_ent->position.x) if (p_ctransform->position.x < p_other_ct->position.x)
{ {
target_pos.x += TILE_SIZE; target_pos.x += TILE_SIZE;
tile_x++; tile_x++;
@ -1240,7 +1249,7 @@ void player_pushing_system(Scene_t* scene)
) )
{ {
p_other_moveable->gridmove = true; p_other_moveable->gridmove = true;
p_other_moveable->prev_pos = p_other_ent->position; p_other_moveable->prev_pos = p_other_ct->position;
p_other_moveable->target_pos = target_pos; p_other_moveable->target_pos = target_pos;
memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity)); memset(&p_ctransform->velocity, 0, sizeof(p_ctransform->velocity));
memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel)); memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel));
@ -1289,46 +1298,46 @@ void movement_update_system(Scene_t* scene)
if (fabs(p_ctransform->velocity.x) < 1e-3) p_ctransform->velocity.x = 0; if (fabs(p_ctransform->velocity.x) < 1e-3) p_ctransform->velocity.x = 0;
if (fabs(p_ctransform->velocity.y) < 1e-3) p_ctransform->velocity.y = 0; if (fabs(p_ctransform->velocity.y) < 1e-3) p_ctransform->velocity.y = 0;
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
// Store previous position before update // Store previous position before update
p_ctransform->prev_position = p_ent->position; p_ctransform->prev_position = p_ctransform->position;
p_ent->position = Vector2Add( p_ctransform->position = Vector2Add(
p_ent->position, p_ctransform->position,
Vector2Scale(p_ctransform->velocity, delta_time) Vector2Scale(p_ctransform->velocity, delta_time)
); );
memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel)); memset(&p_ctransform->accel, 0, sizeof(p_ctransform->accel));
// Level boundary collision // Level boundary collision
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
unsigned int level_width = tilemap.width * TILE_SIZE; unsigned int level_width = tilemap.width * TILE_SIZE;
unsigned int level_height = tilemap.height * TILE_SIZE; unsigned int level_height = tilemap.height * TILE_SIZE;
if (p_bbox != NULL) if (p_bbox != NULL)
{ {
if(p_ent->position.x < 0 || p_ent->position.x + p_bbox->size.x > level_width) if(p_ctransform->position.x < 0 || p_ctransform->position.x + p_bbox->size.x > level_width)
{ {
p_ent->position.x = (p_ent->position.x < 0) ? 0 : p_ent->position.x; p_ctransform->position.x = (p_ctransform->position.x < 0) ? 0 : p_ctransform->position.x;
if (p_ent->position.x + p_bbox->size.x > level_width) if (p_ctransform->position.x + p_bbox->size.x > level_width)
{ {
p_ent->position.x = level_width - p_bbox->size.x; p_ctransform->position.x = level_width - p_bbox->size.x;
} }
else else
{ {
p_ent->position.x = p_ent->position.x; p_ctransform->position.x = p_ctransform->position.x;
} }
p_ctransform->velocity.x = 0; p_ctransform->velocity.x = 0;
} }
if(p_ent->position.y < 0 || p_ent->position.y + p_bbox->size.y > level_height) if(p_ctransform->position.y < 0 || p_ctransform->position.y + p_bbox->size.y > level_height)
{ {
p_ent->position.y = (p_ent->position.y < 0) ? 0 : p_ent->position.y; p_ctransform->position.y = (p_ctransform->position.y < 0) ? 0 : p_ctransform->position.y;
if (p_ent->position.y + p_bbox->size.y > level_height) if (p_ctransform->position.y + p_bbox->size.y > level_height)
{ {
p_ent->position.y = level_height - p_bbox->size.y; p_ctransform->position.y = level_height - p_bbox->size.y;
} }
else else
{ {
p_ent->position.y = p_ent->position.y; p_ctransform->position.y = p_ctransform->position.y;
} }
p_ctransform->velocity.y = 0; p_ctransform->velocity.y = 0;
} }
@ -1336,8 +1345,8 @@ void movement_update_system(Scene_t* scene)
else else
{ {
if ( if (
p_ent->position.x < 0 || p_ent->position.x > level_width p_ctransform->position.x < 0 || p_ctransform->position.x > level_width
|| p_ent->position.y < 0 || p_ent->position.y > level_height || p_ctransform->position.y < 0 || p_ctransform->position.y > level_height
) )
{ {
destroy_entity(scene, &tilemap, p_ent); destroy_entity(scene, &tilemap, p_ent);
@ -1409,7 +1418,7 @@ void state_transition_update_system(Scene_t* scene)
else if (p_ctransform->velocity.x < 0) p_mstate->x_dir = 0; else if (p_ctransform->velocity.x < 0) p_mstate->x_dir = 0;
bool on_ground = check_on_ground( bool on_ground = check_on_ground(
p_ent, p_ctransform->prev_position, p_bbox->size, p_ent, p_ctransform->position, p_ctransform->prev_position, p_bbox->size,
&data->tilemap &data->tilemap
); );
@ -1419,10 +1428,10 @@ void state_transition_update_system(Scene_t* scene)
} }
// Upthrust depends on water overlapping // Upthrust depends on water overlapping
unsigned int tile_x1 = (p_ent->position.x) / TILE_SIZE; unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE;
unsigned int tile_y1 = (p_ent->position.y) / TILE_SIZE; unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x + p_bbox->size.x) / TILE_SIZE; unsigned int tile_x2 = (p_ctransform->position.x + p_bbox->size.x) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y + p_bbox->size.y) / TILE_SIZE; unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE;
float water_area = 0; float water_area = 0;
for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++) for (unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++)
{ {
@ -1443,7 +1452,7 @@ void state_transition_update_system(Scene_t* scene)
Vector2 overlap; Vector2 overlap;
if (find_AABB_overlap( if (find_AABB_overlap(
p_ent->position, p_bbox->size, p_ctransform->position, p_bbox->size,
water_tl, water_sz, &overlap water_tl, water_sz, &overlap
)) ))
{ {
@ -1484,7 +1493,7 @@ void state_transition_update_system(Scene_t* scene)
ParticleEmitter_t emitter = { ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_water"), .spr = get_sprite(&scene->engine->assets, "p_water"),
.config = get_emitter_conf(&scene->engine->assets, "pe_burst"), .config = get_emitter_conf(&scene->engine->assets, "pe_burst"),
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 5, .n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &simple_particle_system_update, .update_func = &simple_particle_system_update,
@ -1504,7 +1513,10 @@ void update_entity_emitter_system(Scene_t* scene)
sc_map_foreach(&scene->ent_manager.component_map[CEMITTER_T], ent_idx, p_emitter) sc_map_foreach(&scene->ent_manager.component_map[CEMITTER_T], ent_idx, p_emitter)
{ {
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx); Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
Vector2 new_pos = Vector2Add(p_ent->position,p_emitter->offset); CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
//CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
Vector2 new_pos = Vector2Add(p_ctransform->position,p_emitter->offset);
//new_pos.y += p_bbox->half_size.y;
if (is_emitter_handle_alive(&scene->part_sys, p_emitter->handle)) if (is_emitter_handle_alive(&scene->part_sys, p_emitter->handle))
{ {
update_emitter_handle_position(&scene->part_sys, p_emitter->handle, new_pos); update_emitter_handle_position(&scene->part_sys, p_emitter->handle, new_pos);
@ -1539,14 +1551,14 @@ void update_tilemap_system(Scene_t* scene)
// Compute new occupied tile positions and add // Compute new occupied tile positions and add
// Extend the check by a little to avoid missing // Extend the check by a little to avoid missing
unsigned int tile_x1 = (p_ent->position.x) / TILE_SIZE; unsigned int tile_x1 = (p_ctransform->position.x) / TILE_SIZE;
unsigned int tile_y1 = (p_ent->position.y) / TILE_SIZE; unsigned int tile_y1 = (p_ctransform->position.y) / TILE_SIZE;
unsigned int tile_x2 = (p_ent->position.x) / TILE_SIZE; unsigned int tile_x2 = (p_ctransform->position.x) / TILE_SIZE;
unsigned int tile_y2 = (p_ent->position.y) / TILE_SIZE; unsigned int tile_y2 = (p_ctransform->position.y) / TILE_SIZE;
if (p_bbox != NULL) if (p_bbox != NULL)
{ {
tile_x2 = (p_ent->position.x + p_bbox->size.x - 1) / TILE_SIZE; tile_x2 = (p_ctransform->position.x + p_bbox->size.x - 1) / TILE_SIZE;
tile_y2 = (p_ent->position.y + p_bbox->size.y - 1) / TILE_SIZE; tile_y2 = (p_ctransform->position.y + p_bbox->size.y - 1) / TILE_SIZE;
} }
tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2; tile_x2 = (tile_x2 >= tilemap.width) ? tilemap.width - 1 : tile_x2;
tile_y2 = (tile_y2 >= tilemap.height) ? tilemap.width - 1 : tile_y2; tile_y2 = (tile_y2 >= tilemap.height) ? tilemap.width - 1 : tile_y2;
@ -1583,8 +1595,8 @@ void hitbox_update_system(Scene_t* scene)
for (uint8_t i = 0; i < p_hitbox->n_boxes; ++i) for (uint8_t i = 0; i < p_hitbox->n_boxes; ++i)
{ {
Vector2 hitbox_pos = { Vector2 hitbox_pos = {
.x = p_ent->position.x + p_hitbox->boxes[i].x, .x = p_ctransform->position.x + p_hitbox->boxes[i].x,
.y = p_ent->position.y + p_hitbox->boxes[i].y, .y = p_ctransform->position.y + p_hitbox->boxes[i].y,
}; };
unsigned int tile_x1 = (hitbox_pos.x) / TILE_SIZE; unsigned int tile_x1 = (hitbox_pos.x) / TILE_SIZE;
@ -1634,8 +1646,9 @@ void hitbox_update_system(Scene_t* scene)
CHurtbox_t* p_other_hurtbox = get_component(p_other_ent, CHURTBOX_T); CHurtbox_t* p_other_hurtbox = get_component(p_other_ent, CHURTBOX_T);
if (p_other_hurtbox == NULL) continue; if (p_other_hurtbox == 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); CBBox_t* p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
Vector2 hurtbox_pos = Vector2Add(p_other_ent->position, p_other_hurtbox->offset); Vector2 hurtbox_pos = Vector2Add(p_other_ct->position, p_other_hurtbox->offset);
if ( if (
find_AABB_overlap( find_AABB_overlap(
@ -1661,7 +1674,7 @@ void hitbox_update_system(Scene_t* scene)
CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T); CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T);
if (p_pstate != NULL) if (p_pstate != NULL)
{ {
if (p_ent->position.y + p_bbox->size.y <= p_other_ent->position.y) if (p_ctransform->position.y + p_bbox->size.y <= p_other_ct->position.y)
{ {
p_ctransform->velocity.y = -400; p_ctransform->velocity.y = -400;
if (p_pstate->jump_pressed) if (p_pstate->jump_pressed)
@ -1673,10 +1686,10 @@ void hitbox_update_system(Scene_t* scene)
} }
if (p_ent->m_tag == PLAYER_ENT_TAG) if (p_ent->m_tag == PLAYER_ENT_TAG)
{ {
data->camera.base_y = p_ent->position.y; data->camera.base_y = p_ctransform->position.y;
} }
} }
else if (p_ent->position.y >= p_other_ent->position.y + p_other_bbox->size.y) else if (p_ctransform->position.y >= p_other_ct->position.y + p_other_bbox->size.y)
{ {
p_ctransform->velocity.y = 0; p_ctransform->velocity.y = 0;
} }
@ -1747,17 +1760,17 @@ void boulder_destroy_wooden_tile_system(Scene_t* scene)
Entity_t* p_boulder; Entity_t* p_boulder;
sc_map_foreach_value(&scene->ent_manager.entities_map[BOULDER_ENT_TAG], p_boulder) sc_map_foreach_value(&scene->ent_manager.entities_map[BOULDER_ENT_TAG], p_boulder)
{ {
//const CTransform_t* p_ctransform = get_component(p_boulder, CTRANSFORM_COMP_T); const CTransform_t* p_ctransform = get_component(p_boulder, CTRANSFORM_COMP_T);
const CBBox_t* p_bbox = get_component(p_boulder, CBBOX_COMP_T); const CBBox_t* p_bbox = get_component(p_boulder, CBBOX_COMP_T);
//if (p_ctransform->velocity.y <= 0) continue; //if (p_ctransform->velocity.y <= 0) continue;
unsigned int tile_idx = get_tile_idx( unsigned int tile_idx = get_tile_idx(
p_boulder->position.x + p_bbox->half_size.x, p_ctransform->position.x + p_bbox->half_size.x,
p_boulder->position.y + p_bbox->size.y + 1, p_ctransform->position.y + p_bbox->size.y + 1,
tilemap.width tilemap.width
); );
unsigned int tile_x = (p_boulder->position.x + p_bbox->half_size.x) / tilemap.tile_size; unsigned int tile_x = (p_ctransform->position.x + p_bbox->half_size.x) / tilemap.tile_size;
if (tilemap.tiles[tile_idx].tile_type == ONEWAY_TILE) if (tilemap.tiles[tile_idx].tile_type == ONEWAY_TILE)
{ {
@ -1814,14 +1827,16 @@ void container_destroy_system(Scene_t* scene)
case CONTAINER_BOMB: case CONTAINER_BOMB:
if (dmg_src != NULL && dmg_src->m_tag == PLAYER_ENT_TAG) if (dmg_src != NULL && dmg_src->m_tag == PLAYER_ENT_TAG)
{ {
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
const CTransform_t* dmg_src_ctransform = get_component(dmg_src, CTRANSFORM_COMP_T);
const CBBox_t* dmg_src_bbox = get_component(dmg_src, CBBOX_COMP_T); const CBBox_t* dmg_src_bbox = get_component(dmg_src, CBBOX_COMP_T);
Vector2 launch_dir = {0, -1}; Vector2 launch_dir = {0, -1};
if (dmg_src->position.x + dmg_src_bbox->size.x <= p_ent->position.x) if (dmg_src_ctransform->position.x + dmg_src_bbox->size.x <= p_ctransform->position.x)
{ {
launch_dir.x = 1; launch_dir.x = 1;
} }
else if (dmg_src->position.x >= p_ent->position.x + p_bbox->size.x) else if (dmg_src_ctransform->position.x >= p_ctransform->position.x + p_bbox->size.x)
{ {
launch_dir.x = -1; launch_dir.x = -1;
} }
@ -1859,7 +1874,9 @@ void container_destroy_system(Scene_t* scene)
if (new_ent != NULL) if (new_ent != NULL)
{ {
new_ent->position = Vector2Add(new_ent->position, p_ent->position); CTransform_t* new_p_ct = get_component(new_ent, CTRANSFORM_COMP_T);
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
new_p_ct->position = Vector2Add(new_p_ct->position, p_ct->position);
} }
} }
} }
@ -1891,13 +1908,14 @@ void airtimer_update_system(Scene_t* scene)
{ {
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx); Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
if (!p_ent->m_alive) continue; if (!p_ent->m_alive) continue;
CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
CMovementState_t* p_movement = get_component(p_ent, CMOVEMENTSTATE_T); CMovementState_t* p_movement = get_component(p_ent, CMOVEMENTSTATE_T);
if (p_bbox == NULL || p_movement == NULL) continue; if (p_ctransform == NULL || p_bbox == NULL || p_movement == NULL) continue;
Vector2 point_to_check = { Vector2 point_to_check = {
p_ent->position.x + p_bbox->half_size.x, p_ctransform->position.x + p_bbox->half_size.x,
p_ent->position.y + p_bbox->half_size.y / 2, p_ctransform->position.y + p_bbox->half_size.y / 2,
}; };
unsigned int tile_idx = get_tile_idx( unsigned int tile_idx = get_tile_idx(
@ -1935,7 +1953,7 @@ void airtimer_update_system(Scene_t* scene)
.spr = get_sprite(&scene->engine->assets, "p_water"), .spr = get_sprite(&scene->engine->assets, "p_water"),
.config = get_emitter_conf(&scene->engine->assets, "pe_bubbling"), .config = get_emitter_conf(&scene->engine->assets, "pe_bubbling"),
//.position = new_pos, //.position = new_pos,
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 5, .n_particles = 5,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &floating_particle_system_update, .update_func = &floating_particle_system_update,
@ -1962,7 +1980,7 @@ void airtimer_update_system(Scene_t* scene)
ParticleEmitter_t emitter = { ParticleEmitter_t emitter = {
.spr = get_sprite(&scene->engine->assets, "p_bigbubble"), .spr = get_sprite(&scene->engine->assets, "p_bigbubble"),
.config = get_emitter_conf(&scene->engine->assets, "pe_slow"), .config = get_emitter_conf(&scene->engine->assets, "pe_slow"),
.position = p_ent->position, .position = p_ctransform->position,
.n_particles = 1, .n_particles = 1,
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data), .user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
.update_func = &floating_particle_system_update, .update_func = &floating_particle_system_update,
@ -2033,7 +2051,7 @@ void camera_update_system(Scene_t* scene)
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player) sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_player)
{ {
CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T); CTransform_t* p_ctransform = get_component(p_player, CTRANSFORM_COMP_T);
data->camera.target_pos.x = p_player->position.x; data->camera.target_pos.x = p_ctransform->position.x;
target_vel = p_ctransform->velocity; target_vel = p_ctransform->velocity;
CMovementState_t* p_movement = get_component(p_player, CMOVEMENTSTATE_T); CMovementState_t* p_movement = get_component(p_player, CMOVEMENTSTATE_T);
CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T); CPlayerState_t* p_pstate = get_component(p_player, CPLAYERSTATE_T);
@ -2044,11 +2062,11 @@ void camera_update_system(Scene_t* scene)
|| (p_pstate->ladder_state & 1) || (p_pstate->ladder_state & 1)
) )
{ {
data->camera.base_y = p_player->position.y; data->camera.base_y = p_ctransform->position.y;
} }
if (p_player->position.y >= data->camera.base_y) if (p_ctransform->position.y >= data->camera.base_y)
{ {
data->camera.target_pos.y = p_player->position.y; data->camera.target_pos.y = p_ctransform->position.y;
data->camera.target_pos.y += p_ctransform->velocity.y * 0.2; data->camera.target_pos.y += p_ctransform->velocity.y * 0.2;
} }
} }
@ -2105,9 +2123,10 @@ void level_end_detection_system(Scene_t* scene)
TileGrid_t tilemap = lvl_scene->data.tilemap; TileGrid_t tilemap = lvl_scene->data.tilemap;
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_flag) sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_flag)
{ {
CTransform_t* p_ct = get_component(p_flag, CTRANSFORM_COMP_T);
unsigned int tile_idx = get_tile_idx( unsigned int tile_idx = get_tile_idx(
p_flag->position.x, p_ct->position.x,
p_flag->position.y, p_ct->position.y,
tilemap.width tilemap.width
); );
@ -2117,13 +2136,14 @@ void level_end_detection_system(Scene_t* scene)
{ {
if (p_other_ent->m_tag != PLAYER_ENT_TAG) continue; if (p_other_ent->m_tag != PLAYER_ENT_TAG) 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); CBBox_t* p_other_bbox = get_component(p_other_ent, CBBOX_COMP_T);
Vector2 pos = Vector2Subtract(p_flag->position,(Vector2){tilemap.tile_size >> 1, tilemap.tile_size >> 1}); Vector2 pos = Vector2Subtract(p_ct->position,(Vector2){tilemap.tile_size >> 1, tilemap.tile_size >> 1});
if ( if (
find_AABB_overlap( find_AABB_overlap(
pos, (Vector2){tilemap.tile_size, tilemap.tile_size}, pos, (Vector2){tilemap.tile_size, tilemap.tile_size},
p_other_ent->position, p_other_bbox->size, NULL p_other_ct->position, p_other_bbox->size, NULL
) )
) )
{ {

View File

@ -159,17 +159,6 @@ Entity_t* create_bomb(EntityManager_t* ent_manager, Vector2 launch_dir)
Entity_t* p_bomb = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG); Entity_t* p_bomb = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG);
if (p_bomb == NULL) return NULL; if (p_bomb == NULL) return NULL;
p_bomb->position.x += (TILE_SIZE - 25) / 2;
p_bomb->position.y += (TILE_SIZE - 25) / 2;
if (launch_dir.x > 0)
{
p_bomb->position.x += TILE_SIZE/ 2;
}
else if (launch_dir.x < 0)
{
p_bomb->position.x -= TILE_SIZE / 2;
}
add_component(p_bomb, CTILECOORD_COMP_T); add_component(p_bomb, CTILECOORD_COMP_T);
add_component(p_bomb, CMOVEMENTSTATE_T); add_component(p_bomb, CMOVEMENTSTATE_T);
CHitBoxes_t* p_hitbox = add_component(p_bomb, CHITBOXES_T); CHitBoxes_t* p_hitbox = add_component(p_bomb, CHITBOXES_T);
@ -190,9 +179,19 @@ Entity_t* create_bomb(EntityManager_t* ent_manager, Vector2 launch_dir)
p_ctransform->active = true; p_ctransform->active = true;
p_ctransform->shape_factor = (Vector2){0.1, 0.1}; p_ctransform->shape_factor = (Vector2){0.1, 0.1};
p_ctransform->movement_mode = REGULAR_MOVEMENT; p_ctransform->movement_mode = REGULAR_MOVEMENT;
p_ctransform->position.x += (TILE_SIZE - 25) / 2;
p_ctransform->position.y += (TILE_SIZE - 25) / 2;
p_ctransform->velocity = Vector2Scale(Vector2Normalize(launch_dir), 500); p_ctransform->velocity = Vector2Scale(Vector2Normalize(launch_dir), 500);
if (launch_dir.x > 0)
{
p_ctransform->position.x += TILE_SIZE/ 2;
}
else if (launch_dir.x < 0)
{
p_ctransform->position.x -= TILE_SIZE / 2;
}
return p_bomb; return p_bomb;
} }
@ -201,8 +200,6 @@ Entity_t* create_explosion(EntityManager_t* ent_manager)
Entity_t* p_explosion = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG); Entity_t* p_explosion = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG);
if (p_explosion == NULL) return NULL; if (p_explosion == NULL) return NULL;
p_explosion->position.x -= 16;
p_explosion->position.y -= 16;
add_component(p_explosion, CTILECOORD_COMP_T); add_component(p_explosion, CTILECOORD_COMP_T);
CHitBoxes_t* p_hitbox = add_component(p_explosion, CHITBOXES_T); CHitBoxes_t* p_hitbox = add_component(p_explosion, CHITBOXES_T);
p_hitbox->n_boxes = 1; p_hitbox->n_boxes = 1;
@ -212,6 +209,8 @@ Entity_t* create_explosion(EntityManager_t* ent_manager)
CTransform_t* p_ctransform = add_component(p_explosion, CTRANSFORM_COMP_T); CTransform_t* p_ctransform = add_component(p_explosion, CTRANSFORM_COMP_T);
p_ctransform->movement_mode = KINEMATIC_MOVEMENT; p_ctransform->movement_mode = KINEMATIC_MOVEMENT;
p_ctransform->active = true; p_ctransform->active = true;
p_ctransform->position.x -= 16;
p_ctransform->position.y -= 16;
p_hitbox->boxes[0] = (Rectangle){0, 0, TILE_SIZE + 32, TILE_SIZE + 32}; p_hitbox->boxes[0] = (Rectangle){0, 0, TILE_SIZE + 32, TILE_SIZE + 32};
CSprite_t* p_cspr = add_component(p_explosion, CSPRITE_T); CSprite_t* p_cspr = add_component(p_explosion, CSPRITE_T);

View File

@ -105,8 +105,9 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
} }
Entity_t* ent = create_crate(&scene->scene.ent_manager, tmp_idx > 5, item); Entity_t* ent = create_crate(&scene->scene.ent_manager, tmp_idx > 5, item);
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size; CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size; p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
} }
else else
{ {
@ -128,8 +129,9 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
case 20: case 20:
{ {
Entity_t* ent = create_boulder(&scene->scene.ent_manager); Entity_t* ent = create_boulder(&scene->scene.ent_manager);
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size; CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size; p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
} }
break; break;
case 21: case 21:
@ -140,9 +142,10 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
case 22: case 22:
{ {
Entity_t* ent = create_player(&scene->scene.ent_manager); Entity_t* ent = create_player(&scene->scene.ent_manager);
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size; CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size; p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->spawn_pos = ent->position; p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
ent->spawn_pos = p_ct->position;
} }
break; break;
default: default:

View File

@ -223,8 +223,9 @@ void update_water_runner_system(Scene_t* scene)
while (move_left) while (move_left)
{ {
p_crunner->current_tile = p_crunner->bfs_tilemap.tilemap[p_crunner->current_tile].to; p_crunner->current_tile = p_crunner->bfs_tilemap.tilemap[p_crunner->current_tile].to;
ent->position.x = (p_crunner->current_tile % tilemap.width) * tilemap.tile_size; CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
ent->position.y = (p_crunner->current_tile / tilemap.width) * tilemap.tile_size; p_ct->position.x = (p_crunner->current_tile % tilemap.width) * tilemap.tile_size;
p_ct->position.y = (p_crunner->current_tile / tilemap.width) * tilemap.tile_size;
Tile_t* tile = tilemap.tiles + p_crunner->current_tile; Tile_t* tile = tilemap.tiles + p_crunner->current_tile;
tile->wet = true; tile->wet = true;

View File

@ -108,7 +108,7 @@ static void level_scene_render_func(Scene_t* scene)
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx]; const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL) if (spr.sprite != NULL)
{ {
Vector2 pos = Vector2Add(p_ent->position, spr.offset); Vector2 pos = Vector2Add(p_ct->position, spr.offset);
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x); draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
} }
} }
@ -318,8 +318,8 @@ static void toggle_block_system(Scene_t* scene)
if (p_ent == NULL) return; if (p_ent == NULL) return;
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T); CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size; p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size; p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
} }
else else
{ {