Просмотр исходного кода

fix icon collision, draw enemy/player stats

jblanked 1 год назад
Родитель
Сommit
9b9187881d
8 измененных файлов с 416 добавлено и 364 удалено
  1. 17 1
      game/draw.c
  2. 2 1
      game/draw.h
  3. 15 1
      game/enemy.c
  4. 4 1
      game/game.c
  5. 345 326
      game/icon.c
  6. 4 4
      game/icon.h
  7. 27 28
      game/player.c
  8. 2 2
      game/player.h

+ 17 - 1
game/draw.c

@@ -30,7 +30,7 @@ void draw_user_stats(Canvas *canvas, Vector pos, GameManager *manager)
 
 
     // first draw a black rectangle to make the text more readable
     // first draw a black rectangle to make the text more readable
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
-    canvas_draw_box(canvas, pos.x - 1, pos.y - 7, 32, 21);
+    canvas_draw_box(canvas, pos.x - 1, pos.y - 7, 34, 21);
     canvas_invert_color(canvas);
     canvas_invert_color(canvas);
 
 
     char health[32];
     char health[32];
@@ -47,6 +47,19 @@ void draw_user_stats(Canvas *canvas, Vector pos, GameManager *manager)
     canvas_draw_str(canvas, pos.x, pos.y + 14, level);
     canvas_draw_str(canvas, pos.x, pos.y + 14, level);
 }
 }
 
 
+void draw_username(Canvas *canvas, Vector pos, char *username)
+{
+    // first draw a black rectangle to make the text more readable
+    // draw box around the username
+    canvas_invert_color(canvas);
+    canvas_draw_box(canvas, pos.x - camera_x - (strlen(username) * 2) - 1, pos.y - camera_y - 14, strlen(username) * 4 + 1, 8);
+    canvas_invert_color(canvas);
+
+    // draw username over player's head
+    canvas_set_font_custom(canvas, FONT_SIZE_SMALL);
+    canvas_draw_str(canvas, pos.x - camera_x - (strlen(username) * 2), pos.y - camera_y - 7, username);
+}
+
 // Draw a line of icons (16 width)
 // Draw a line of icons (16 width)
 void draw_icon_line(Canvas *canvas, Vector pos, int amount, bool horizontal, const Icon *icon)
 void draw_icon_line(Canvas *canvas, Vector pos, int amount, bool horizontal, const Icon *icon)
 {
 {
@@ -89,14 +102,17 @@ void draw_icon_half_world(Canvas *canvas, bool right, const Icon *icon)
         }
         }
     }
     }
 }
 }
+char g_temp_spawn_name[32];
 // Draw an icon at a specific position (with collision detection)
 // Draw an icon at a specific position (with collision detection)
 void spawn_icon(Level *level, const Icon *icon, float x, float y, uint8_t width, uint8_t height)
 void spawn_icon(Level *level, const Icon *icon, float x, float y, uint8_t width, uint8_t height)
 {
 {
+    snprintf(g_temp_spawn_name, sizeof(g_temp_spawn_name), "%s", icon_get_id(icon));
     Entity *e = level_add_entity(level, &icon_desc);
     Entity *e = level_add_entity(level, &icon_desc);
     IconContext *icon_ctx = entity_context_get(e);
     IconContext *icon_ctx = entity_context_get(e);
     icon_ctx->icon = icon;
     icon_ctx->icon = icon;
     icon_ctx->width = width;
     icon_ctx->width = width;
     icon_ctx->height = height;
     icon_ctx->height = height;
+    snprintf(icon_ctx->id, sizeof(icon_ctx->id), "%s", g_temp_spawn_name);
     // Set the entity position to the center of the icon
     // Set the entity position to the center of the icon
     entity_pos_set(e, (Vector){x + (width / 2), y + (height / 2)});
     entity_pos_set(e, (Vector){x + (width / 2), y + (height / 2)});
 }
 }

+ 2 - 1
game/draw.h

@@ -7,9 +7,10 @@ extern int camera_x;
 extern int camera_y;
 extern int camera_y;
 void draw_background(Canvas *canvas, Vector pos);
 void draw_background(Canvas *canvas, Vector pos);
 void draw_user_stats(Canvas *canvas, Vector pos, GameManager *manager);
 void draw_user_stats(Canvas *canvas, Vector pos, GameManager *manager);
+void draw_username(Canvas *canvas, Vector pos, char *username);
 void draw_icon_line(Canvas *canvas, Vector pos, int amount, bool horizontal, const Icon *icon);
 void draw_icon_line(Canvas *canvas, Vector pos, int amount, bool horizontal, const Icon *icon);
 void draw_icon_half_world(Canvas *canvas, bool right, const Icon *icon);
 void draw_icon_half_world(Canvas *canvas, bool right, const Icon *icon);
 void spawn_icon(Level *level, const Icon *icon, float x, float y, uint8_t width, uint8_t height);
 void spawn_icon(Level *level, const Icon *icon, float x, float y, uint8_t width, uint8_t height);
 void spawn_icon_line(Level *level, const Icon *icon, float x, float y, uint8_t width, uint8_t height, uint8_t amount, bool horizontal);
 void spawn_icon_line(Level *level, const Icon *icon, float x, float y, uint8_t width, uint8_t height, uint8_t amount, bool horizontal);
-
+extern char g_temp_spawn_name[32];
 // create custom icons at https://lopaka.app/sandbox
 // create custom icons at https://lopaka.app/sandbox

+ 15 - 1
game/enemy.c

@@ -117,6 +117,7 @@ static void enemy_render(Entity *self, GameManager *manager, Canvas *canvas, voi
         return;
         return;
 
 
     EnemyContext *enemy_context = (EnemyContext *)context;
     EnemyContext *enemy_context = (EnemyContext *)context;
+    GameContext *game_context = game_manager_game_context_get(manager);
 
 
     // Get the position of the enemy
     // Get the position of the enemy
     Vector pos = entity_pos_get(self);
     Vector pos = entity_pos_get(self);
@@ -139,8 +140,17 @@ static void enemy_render(Entity *self, GameManager *manager, Canvas *canvas, voi
         pos.x - camera_x - (enemy_context->size.x / 2),
         pos.x - camera_x - (enemy_context->size.x / 2),
         pos.y - camera_y - (enemy_context->size.y / 2));
         pos.y - camera_y - (enemy_context->size.y / 2));
 
 
+    // instead of username, draw health
+    char health_str[32];
+    snprintf(health_str, sizeof(health_str), "%.0f", (double)enemy_context->health);
+    draw_username(canvas, pos, health_str);
+
     // Draw user stats (this has to be done for all enemies)
     // Draw user stats (this has to be done for all enemies)
-    draw_user_stats(canvas, (Vector){0, 7}, manager);
+    draw_user_stats(canvas, (Vector){0, 50}, manager);
+
+    // draw player username from GameContext
+    Vector posi = entity_pos_get(game_context->players[0]);
+    draw_username(canvas, posi, game_context->player_context->username);
 }
 }
 
 
 // Enemy collision function
 // Enemy collision function
@@ -211,6 +221,10 @@ static void enemy_collision(Entity *self, Entity *other, GameManager *manager, v
 
 
                 // Increase healthy by 10% of the enemy's strength
                 // Increase healthy by 10% of the enemy's strength
                 game_context->player_context->health += enemy_context->strength * 0.1f;
                 game_context->player_context->health += enemy_context->strength * 0.1f;
+                if (game_context->player_context->health > 100)
+                {
+                    game_context->player_context->health = 100;
+                }
 
 
                 // Decrease enemy health by player strength
                 // Decrease enemy health by player strength
                 enemy_context->health -= game_context->player_context->strength;
                 enemy_context->health -= game_context->player_context->strength;

+ 4 - 1
game/game.c

@@ -54,7 +54,10 @@ static void game_stop(void *ctx)
         return;
         return;
     }
     }
     GameContext *game_context = ctx;
     GameContext *game_context = ctx;
-    save_player_context(game_context->player_context);
+    if (game_context->player_context)
+    {
+        save_player_context(game_context->player_context);
+    }
 }
 }
 
 
 /*
 /*

+ 345 - 326
game/icon.c

@@ -1,13 +1,15 @@
 #include "game/icon.h"
 #include "game/icon.h"
 
 
-// Icon entity description
-
 static void icon_collision(Entity *self, Entity *other, GameManager *manager, void *context)
 static void icon_collision(Entity *self, Entity *other, GameManager *manager, void *context)
 {
 {
     UNUSED(manager);
     UNUSED(manager);
     UNUSED(self);
     UNUSED(self);
-    IconContext *icon = (IconContext *)context;
-    UNUSED(icon);
+    IconContext *icon_ctx = (IconContext *)context;
+    if (!icon_ctx)
+    {
+        FURI_LOG_E("Game", "Icon context is NULL");
+        return;
+    }
 
 
     if (entity_description_get(other) == &player_desc)
     if (entity_description_get(other) == &player_desc)
     {
     {
@@ -15,13 +17,12 @@ static void icon_collision(Entity *self, Entity *other, GameManager *manager, vo
         if (player)
         if (player)
         {
         {
             Vector pos = entity_pos_get(other);
             Vector pos = entity_pos_get(other);
-
-            // Bounce the player back by 2 units opposite their last movement direction
+            // Bounce back by 2
             pos.x -= player->dx * 2;
             pos.x -= player->dx * 2;
             pos.y -= player->dy * 2;
             pos.y -= player->dy * 2;
             entity_pos_set(other, pos);
             entity_pos_set(other, pos);
 
 
-            // Reset player's movement direction to prevent immediate re-collision
+            // Reset movement to prevent re-collision
             player->dx = 0;
             player->dx = 0;
             player->dy = 0;
             player->dy = 0;
         }
         }
@@ -32,21 +33,80 @@ static void icon_render(Entity *self, GameManager *manager, Canvas *canvas, void
 {
 {
     UNUSED(manager);
     UNUSED(manager);
     IconContext *icon_ctx = (IconContext *)context;
     IconContext *icon_ctx = (IconContext *)context;
+    if (!icon_ctx)
+    {
+        FURI_LOG_E("Game", "Icon context is NULL");
+        return;
+    }
     Vector pos = entity_pos_get(self);
     Vector pos = entity_pos_get(self);
-    canvas_draw_icon(canvas, pos.x - camera_x - icon_ctx->width / 2, pos.y - camera_y - icon_ctx->height / 2, icon_ctx->icon);
+
+    // Draw the icon, centered
+    canvas_draw_icon(
+        canvas,
+        pos.x - camera_x - icon_ctx->width / 2,
+        pos.y - camera_y - icon_ctx->height / 2,
+        icon_ctx->icon);
 }
 }
 
 
 static void icon_start(Entity *self, GameManager *manager, void *context)
 static void icon_start(Entity *self, GameManager *manager, void *context)
 {
 {
     UNUSED(manager);
     UNUSED(manager);
-    IconContext *icon_ctx = (IconContext *)context;
-    // Just add the collision rectangle for 16x16 icon
-    entity_collider_add_rect(self, icon_ctx->width + COLLISION_BOX_PADDING_HORIZONTAL, icon_ctx->height + COLLISION_BOX_PADDING_VERTICAL);
+
+    IconContext *icon_ctx_self = (IconContext *)context;
+    if (!icon_ctx_self)
+    {
+        FURI_LOG_E("Game", "Icon context self is NULL");
+        return;
+    }
+    IconContext *icon_ctx = entity_context_get(self);
+    if (!icon_ctx)
+    {
+        FURI_LOG_E("Game", "Icon context is NULL");
+        return;
+    }
+
+    IconContext *loaded_data = get_icon_context(g_temp_spawn_name);
+    if (!loaded_data)
+    {
+        FURI_LOG_E("Game", "Failed to find icon data for %s", g_temp_spawn_name);
+        return;
+    }
+
+    icon_ctx_self->icon = loaded_data->icon;
+    icon_ctx_self->width = loaded_data->width;
+    icon_ctx_self->height = loaded_data->height;
+    icon_ctx->icon = loaded_data->icon;
+    icon_ctx->width = loaded_data->width;
+    icon_ctx->height = loaded_data->height;
+
+    Vector pos = entity_pos_get(self);
+    pos.x += icon_ctx_self->width / 2;
+    pos.y += icon_ctx_self->height / 2;
+    entity_pos_set(self, pos);
+
+    entity_collider_add_circle(
+        self,
+        (icon_ctx_self->width + icon_ctx_self->height) / 4);
+
+    free(loaded_data);
 }
 }
 
 
+// -------------- Stop callback --------------
+static void icon_free(Entity *self, GameManager *manager, void *context)
+{
+    UNUSED(self);
+    UNUSED(manager);
+    UNUSED(context);
+    if (context)
+    {
+        free(context);
+    }
+}
+
+// -------------- Entity description --------------
 const EntityDescription icon_desc = {
 const EntityDescription icon_desc = {
     .start = icon_start,
     .start = icon_start,
-    .stop = NULL,
+    .stop = icon_free,
     .update = NULL,
     .update = NULL,
     .render = icon_render,
     .render = icon_render,
     .collision = icon_collision,
     .collision = icon_collision,
@@ -54,233 +114,151 @@ const EntityDescription icon_desc = {
     .context_size = sizeof(IconContext),
     .context_size = sizeof(IconContext),
 };
 };
 
 
-static IconContext _generic_icon = {
-    .icon = &I_icon_earth_15x16,
-    .width = 15,
-    .height = 16,
-};
+IconContext *icon_generic_alloc(const char *id, const Icon *icon, uint8_t width, uint8_t height)
+{
+    IconContext *ctx = malloc(sizeof(IconContext));
+    if (!ctx)
+    {
+        FURI_LOG_E("Game", "Failed to allocate IconContext");
+        return NULL;
+    }
+    snprintf(ctx->id, sizeof(ctx->id), "%s", id);
+    ctx->icon = icon;
+    ctx->width = width;
+    ctx->height = height;
+    return ctx;
+}
 
 
-IconContext *get_icon_context(char *name)
+IconContext *get_icon_context(const char *name)
 {
 {
     if (strcmp(name, "earth") == 0)
     if (strcmp(name, "earth") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_earth_15x16;
-        _generic_icon.width = 15;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("earth", &I_icon_earth_15x16, 15, 16);
     }
     }
-    if (strcmp(name, "home") == 0)
+    else if (strcmp(name, "home") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_home_15x16;
-        _generic_icon.width = 15;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("home", &I_icon_home_15x16, 15, 16);
     }
     }
-    if (strcmp(name, "house") == 0)
+    else if (strcmp(name, "house") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_house_48x32px;
-        _generic_icon.width = 48;
-        _generic_icon.height = 32;
-        return &_generic_icon;
+        return icon_generic_alloc("house", &I_icon_house_48x32px, 48, 32);
     }
     }
-    if (strcmp(name, "house_3d") == 0)
+    else if (strcmp(name, "house_3d") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_house_3d_34x45px;
-        _generic_icon.width = 34;
-        _generic_icon.height = 45;
-        return &_generic_icon;
+        return icon_generic_alloc("house_3d", &I_icon_house_3d_34x45px, 34, 45);
     }
     }
-    if (strcmp(name, "info") == 0)
+    else if (strcmp(name, "info") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_info_15x16;
-        _generic_icon.width = 15;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("info", &I_icon_info_15x16, 15, 16);
     }
     }
-    if (strcmp(name, "man") == 0)
+    else if (strcmp(name, "man") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_man_7x16;
-        _generic_icon.width = 7;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("man", &I_icon_man_7x16, 7, 16);
     }
     }
-    if (strcmp(name, "plant") == 0)
+    else if (strcmp(name, "plant") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_plant_16x16;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("plant", &I_icon_plant_16x16, 16, 16);
     }
     }
-    if (strcmp(name, "plant_fern") == 0)
+    else if (strcmp(name, "plant_fern") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_plant_fern_18x16px;
-        _generic_icon.width = 18;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("plant_fern", &I_icon_plant_fern_18x16px, 18, 16);
     }
     }
-    if (strcmp(name, "plant_pointy") == 0)
+    else if (strcmp(name, "plant_pointy") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_plant_pointy_13x16px;
-        _generic_icon.width = 13;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("plant_pointy", &I_icon_plant_pointy_13x16px, 13, 16);
     }
     }
-    if (strcmp(name, "tree") == 0)
+    else if (strcmp(name, "tree") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_tree_16x16;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("tree", &I_icon_tree_16x16, 16, 16);
     }
     }
-    if (strcmp(name, "tree_29x30") == 0)
+    else if (strcmp(name, "tree_29x30") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_tree_29x30px;
-        _generic_icon.width = 29;
-        _generic_icon.height = 30;
-        return &_generic_icon;
+        return icon_generic_alloc("tree_29x30", &I_icon_tree_29x30px, 29, 30);
     }
     }
-    if (strcmp(name, "tree_48x48") == 0)
+    else if (strcmp(name, "tree_48x48") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_tree_48x48px;
-        _generic_icon.width = 48;
-        _generic_icon.height = 48;
-        return &_generic_icon;
+        return icon_generic_alloc("tree_48x48", &I_icon_tree_48x48px, 48, 48);
     }
     }
-    if (strcmp(name, "woman") == 0)
+    else if (strcmp(name, "woman") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_woman_9x16;
-        _generic_icon.width = 9;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("woman", &I_icon_woman_9x16, 9, 16);
     }
     }
-    if (strcmp(name, "chest_closed") == 0)
+    else if (strcmp(name, "chest_closed") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_chest_closed_16x13px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 13;
-        return &_generic_icon;
+        return icon_generic_alloc("chest_closed", &I_icon_chest_closed_16x13px, 16, 13);
     }
     }
-    if (strcmp(name, "chest_open") == 0)
+    else if (strcmp(name, "chest_open") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_chest_open_16x16px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("chest_open", &I_icon_chest_open_16x16px, 16, 16);
     }
     }
-    if (strcmp(name, "fence") == 0)
+    else if (strcmp(name, "fence") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_fence_16x8px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return icon_generic_alloc("fence", &I_icon_fence_16x8px, 16, 8);
     }
     }
-    if (strcmp(name, "fence_end") == 0)
+    else if (strcmp(name, "fence_end") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_fence_end_16x8px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return icon_generic_alloc("fence_end", &I_icon_fence_end_16x8px, 16, 8);
     }
     }
-    if (strcmp(name, "fence_vertical_end") == 0)
+    else if (strcmp(name, "fence_vertical_end") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_fence_vertical_end_6x8px;
-        _generic_icon.width = 6;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return icon_generic_alloc("fence_vertical_end", &I_icon_fence_vertical_end_6x8px, 6, 8);
     }
     }
-    if (strcmp(name, "fence_vertical_start") == 0)
+    else if (strcmp(name, "fence_vertical_start") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_fence_vertical_start_6x15px;
-        _generic_icon.width = 6;
-        _generic_icon.height = 15;
-        return &_generic_icon;
+        return icon_generic_alloc("fence_vertical_start", &I_icon_fence_vertical_start_6x15px, 6, 15);
     }
     }
-    if (strcmp(name, "flower") == 0)
+    else if (strcmp(name, "flower") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_flower_16x16;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("flower", &I_icon_flower_16x16, 16, 16);
     }
     }
-    if (strcmp(name, "lake_bottom") == 0)
+    else if (strcmp(name, "lake_bottom") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_bottom_31x12px;
-        _generic_icon.width = 31;
-        _generic_icon.height = 12;
-        return &_generic_icon;
+        return icon_generic_alloc("lake_bottom", &I_icon_lake_bottom_31x12px, 31, 12);
     }
     }
-    if (strcmp(name, "lake_bottom_left") == 0)
+    else if (strcmp(name, "lake_bottom_left") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_bottom_left_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return icon_generic_alloc("lake_bottom_left", &I_icon_lake_bottom_left_24x22px, 24, 22);
     }
     }
-    if (strcmp(name, "lake_bottom_right") == 0)
+    else if (strcmp(name, "lake_bottom_right") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_bottom_right_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return icon_generic_alloc("lake_bottom_right", &I_icon_lake_bottom_right_24x22px, 24, 22);
     }
     }
-    if (strcmp(name, "lake_left") == 0)
+    else if (strcmp(name, "lake_left") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_left_11x31px;
-        _generic_icon.width = 11;
-        _generic_icon.height = 31;
-        return &_generic_icon;
+        return icon_generic_alloc("lake_left", &I_icon_lake_left_11x31px, 11, 31);
     }
     }
-    if (strcmp(name, "lake_right") == 0)
+    else if (strcmp(name, "lake_right") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_right_11x31; // Assuming it's 11x31
-        _generic_icon.width = 11;
-        _generic_icon.height = 31;
-        return &_generic_icon;
+        // Assuming 11x31
+        return icon_generic_alloc("lake_right", &I_icon_lake_right_11x31, 11, 31);
     }
     }
-    if (strcmp(name, "lake_top") == 0)
+    else if (strcmp(name, "lake_top") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_top_31x12px;
-        _generic_icon.width = 31;
-        _generic_icon.height = 12;
-        return &_generic_icon;
+        return icon_generic_alloc("lake_top", &I_icon_lake_top_31x12px, 31, 12);
     }
     }
-    if (strcmp(name, "lake_top_left") == 0)
+    else if (strcmp(name, "lake_top_left") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_top_left_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return icon_generic_alloc("lake_top_left", &I_icon_lake_top_left_24x22px, 24, 22);
     }
     }
-    if (strcmp(name, "lake_top_right") == 0)
+    else if (strcmp(name, "lake_top_right") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_lake_top_right_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return icon_generic_alloc("lake_top_right", &I_icon_lake_top_right_24x22px, 24, 22);
     }
     }
-    if (strcmp(name, "rock_large") == 0)
+    else if (strcmp(name, "rock_large") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_rock_large_18x19px;
-        _generic_icon.width = 18;
-        _generic_icon.height = 19;
-        return &_generic_icon;
+        return icon_generic_alloc("rock_large", &I_icon_rock_large_18x19px, 18, 19);
     }
     }
-    if (strcmp(name, "rock_medium") == 0)
+    else if (strcmp(name, "rock_medium") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_rock_medium_16x14px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 14;
-        return &_generic_icon;
+        return icon_generic_alloc("rock_medium", &I_icon_rock_medium_16x14px, 16, 14);
     }
     }
-    if (strcmp(name, "rock_small") == 0)
+    else if (strcmp(name, "rock_small") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_rock_small_10x8px;
-        _generic_icon.width = 10;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return icon_generic_alloc("rock_small", &I_icon_rock_small_10x8px, 10, 8);
     }
     }
 
 
     // If no match is found
     // If no match is found
+    FURI_LOG_E("Game", "Icon not found: %s", name);
     return NULL;
     return NULL;
 }
 }
 
 
@@ -288,222 +266,263 @@ IconContext *get_icon_context_furi(FuriString *name)
 {
 {
     if (furi_string_cmp(name, "earth") == 0)
     if (furi_string_cmp(name, "earth") == 0)
     {
     {
-        _generic_icon.icon = &I_icon_earth_15x16;
-        _generic_icon.width = 15;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return icon_generic_alloc("earth", &I_icon_earth_15x16, 15, 16);
+    }
+    else if (furi_string_cmp(name, "home") == 0)
+    {
+        return icon_generic_alloc("home", &I_icon_home_15x16, 15, 16);
+    }
+    else if (furi_string_cmp(name, "house") == 0)
+    {
+        return icon_generic_alloc("house", &I_icon_house_48x32px, 48, 32);
+    }
+    else if (furi_string_cmp(name, "house_3d") == 0)
+    {
+        return icon_generic_alloc("house_3d", &I_icon_house_3d_34x45px, 34, 45);
+    }
+    else if (furi_string_cmp(name, "info") == 0)
+    {
+        return icon_generic_alloc("info", &I_icon_info_15x16, 15, 16);
+    }
+    else if (furi_string_cmp(name, "man") == 0)
+    {
+        return icon_generic_alloc("man", &I_icon_man_7x16, 7, 16);
+    }
+    else if (furi_string_cmp(name, "plant") == 0)
+    {
+        return icon_generic_alloc("plant", &I_icon_plant_16x16, 16, 16);
+    }
+    else if (furi_string_cmp(name, "plant_fern") == 0)
+    {
+        return icon_generic_alloc("plant_fern", &I_icon_plant_fern_18x16px, 18, 16);
+    }
+    else if (furi_string_cmp(name, "plant_pointy") == 0)
+    {
+        return icon_generic_alloc("plant_pointy", &I_icon_plant_pointy_13x16px, 13, 16);
+    }
+    else if (furi_string_cmp(name, "tree") == 0)
+    {
+        return icon_generic_alloc("tree", &I_icon_tree_16x16, 16, 16);
+    }
+    else if (furi_string_cmp(name, "tree_29x30") == 0)
+    {
+        return icon_generic_alloc("tree_29x30", &I_icon_tree_29x30px, 29, 30);
+    }
+    else if (furi_string_cmp(name, "tree_48x48") == 0)
+    {
+        return icon_generic_alloc("tree_48x48", &I_icon_tree_48x48px, 48, 48);
+    }
+    else if (furi_string_cmp(name, "woman") == 0)
+    {
+        return icon_generic_alloc("woman", &I_icon_woman_9x16, 9, 16);
+    }
+    else if (furi_string_cmp(name, "chest_closed") == 0)
+    {
+        return icon_generic_alloc("chest_closed", &I_icon_chest_closed_16x13px, 16, 13);
+    }
+    else if (furi_string_cmp(name, "chest_open") == 0)
+    {
+        return icon_generic_alloc("chest_open", &I_icon_chest_open_16x16px, 16, 16);
+    }
+    else if (furi_string_cmp(name, "fence") == 0)
+    {
+        return icon_generic_alloc("fence", &I_icon_fence_16x8px, 16, 8);
+    }
+    else if (furi_string_cmp(name, "fence_end") == 0)
+    {
+        return icon_generic_alloc("fence_end", &I_icon_fence_end_16x8px, 16, 8);
+    }
+    else if (furi_string_cmp(name, "fence_vertical_end") == 0)
+    {
+        return icon_generic_alloc("fence_vertical_end", &I_icon_fence_vertical_end_6x8px, 6, 8);
+    }
+    else if (furi_string_cmp(name, "fence_vertical_start") == 0)
+    {
+        return icon_generic_alloc("fence_vertical_start", &I_icon_fence_vertical_start_6x15px, 6, 15);
+    }
+    else if (furi_string_cmp(name, "flower") == 0)
+    {
+        return icon_generic_alloc("flower", &I_icon_flower_16x16, 16, 16);
+    }
+    else if (furi_string_cmp(name, "lake_bottom") == 0)
+    {
+        return icon_generic_alloc("lake_bottom", &I_icon_lake_bottom_31x12px, 31, 12);
+    }
+    else if (furi_string_cmp(name, "lake_bottom_left") == 0)
+    {
+        return icon_generic_alloc("lake_bottom_left", &I_icon_lake_bottom_left_24x22px, 24, 22);
+    }
+    else if (furi_string_cmp(name, "lake_bottom_right") == 0)
+    {
+        return icon_generic_alloc("lake_bottom_right", &I_icon_lake_bottom_right_24x22px, 24, 22);
+    }
+    else if (furi_string_cmp(name, "lake_left") == 0)
+    {
+        return icon_generic_alloc("lake_left", &I_icon_lake_left_11x31px, 11, 31);
+    }
+    else if (furi_string_cmp(name, "lake_right") == 0)
+    {
+        // Assuming dimensions 11x31
+        return icon_generic_alloc("lake_right", &I_icon_lake_right_11x31, 11, 31);
+    }
+    else if (furi_string_cmp(name, "lake_top") == 0)
+    {
+        return icon_generic_alloc("lake_top", &I_icon_lake_top_31x12px, 31, 12);
+    }
+    else if (furi_string_cmp(name, "lake_top_left") == 0)
+    {
+        return icon_generic_alloc("lake_top_left", &I_icon_lake_top_left_24x22px, 24, 22);
+    }
+    else if (furi_string_cmp(name, "lake_top_right") == 0)
+    {
+        return icon_generic_alloc("lake_top_right", &I_icon_lake_top_right_24x22px, 24, 22);
+    }
+    else if (furi_string_cmp(name, "rock_large") == 0)
+    {
+        return icon_generic_alloc("rock_large", &I_icon_rock_large_18x19px, 18, 19);
+    }
+    else if (furi_string_cmp(name, "rock_medium") == 0)
+    {
+        return icon_generic_alloc("rock_medium", &I_icon_rock_medium_16x14px, 16, 14);
+    }
+    else if (furi_string_cmp(name, "rock_small") == 0)
+    {
+        return icon_generic_alloc("rock_small", &I_icon_rock_small_10x8px, 10, 8);
+    }
+
+    // If no match is found
+    FURI_LOG_E("Game", "Icon not found: %s", furi_string_get_cstr(name));
+    return NULL;
+}
+
+const char *icon_get_id(const Icon *icon)
+{
+    if (icon == &I_icon_earth_15x16)
+    {
+        return "earth";
     }
     }
-    if (furi_string_cmp(name, "home") == 0)
+    else if (icon == &I_icon_home_15x16)
     {
     {
-        _generic_icon.icon = &I_icon_home_15x16;
-        _generic_icon.width = 15;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "home";
     }
     }
-    if (furi_string_cmp(name, "house") == 0)
+    else if (icon == &I_icon_house_48x32px)
     {
     {
-        _generic_icon.icon = &I_icon_house_48x32px;
-        _generic_icon.width = 48;
-        _generic_icon.height = 32;
-        return &_generic_icon;
+        return "house";
     }
     }
-    if (furi_string_cmp(name, "house_3d") == 0)
+    else if (icon == &I_icon_house_3d_34x45px)
     {
     {
-        _generic_icon.icon = &I_icon_house_3d_34x45px;
-        _generic_icon.width = 34;
-        _generic_icon.height = 45;
-        return &_generic_icon;
+        return "house_3d";
     }
     }
-    if (furi_string_cmp(name, "info") == 0)
+    else if (icon == &I_icon_info_15x16)
     {
     {
-        _generic_icon.icon = &I_icon_info_15x16;
-        _generic_icon.width = 15;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "info";
     }
     }
-    if (furi_string_cmp(name, "man") == 0)
+    else if (icon == &I_icon_man_7x16)
     {
     {
-        _generic_icon.icon = &I_icon_man_7x16;
-        _generic_icon.width = 7;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "man";
     }
     }
-    if (furi_string_cmp(name, "plant") == 0)
+    else if (icon == &I_icon_plant_16x16)
     {
     {
-        _generic_icon.icon = &I_icon_plant_16x16;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "plant";
     }
     }
-    if (furi_string_cmp(name, "plant_fern") == 0)
+    else if (icon == &I_icon_plant_fern_18x16px)
     {
     {
-        _generic_icon.icon = &I_icon_plant_fern_18x16px;
-        _generic_icon.width = 18;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "plant_fern";
     }
     }
-    if (furi_string_cmp(name, "plant_pointy") == 0)
+    else if (icon == &I_icon_plant_pointy_13x16px)
     {
     {
-        _generic_icon.icon = &I_icon_plant_pointy_13x16px;
-        _generic_icon.width = 13;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "plant_pointy";
     }
     }
-    if (furi_string_cmp(name, "tree") == 0)
+    else if (icon == &I_icon_tree_16x16)
     {
     {
-        _generic_icon.icon = &I_icon_tree_16x16;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "tree";
     }
     }
-    if (furi_string_cmp(name, "tree_29x30") == 0)
+    else if (icon == &I_icon_tree_29x30px)
     {
     {
-        _generic_icon.icon = &I_icon_tree_29x30px;
-        _generic_icon.width = 29;
-        _generic_icon.height = 30;
-        return &_generic_icon;
+        return "tree_29x30";
     }
     }
-    if (furi_string_cmp(name, "tree_48x48") == 0)
+    else if (icon == &I_icon_tree_48x48px)
     {
     {
-        _generic_icon.icon = &I_icon_tree_48x48px;
-        _generic_icon.width = 48;
-        _generic_icon.height = 48;
-        return &_generic_icon;
+        return "tree_48x48";
     }
     }
-    if (furi_string_cmp(name, "woman") == 0)
+    else if (icon == &I_icon_woman_9x16)
     {
     {
-        _generic_icon.icon = &I_icon_woman_9x16;
-        _generic_icon.width = 9;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "woman";
     }
     }
-    if (furi_string_cmp(name, "chest_closed") == 0)
+    else if (icon == &I_icon_chest_closed_16x13px)
     {
     {
-        _generic_icon.icon = &I_icon_chest_closed_16x13px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 13;
-        return &_generic_icon;
+        return "chest_closed";
     }
     }
-    if (furi_string_cmp(name, "chest_open") == 0)
+    else if (icon == &I_icon_chest_open_16x16px)
     {
     {
-        _generic_icon.icon = &I_icon_chest_open_16x16px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "chest_open";
     }
     }
-    if (furi_string_cmp(name, "fence") == 0)
+    else if (icon == &I_icon_fence_16x8px)
     {
     {
-        _generic_icon.icon = &I_icon_fence_16x8px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return "fence";
     }
     }
-    if (furi_string_cmp(name, "fence_end") == 0)
+    else if (icon == &I_icon_fence_end_16x8px)
     {
     {
-        _generic_icon.icon = &I_icon_fence_end_16x8px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return "fence_end";
     }
     }
-    if (furi_string_cmp(name, "fence_vertical_end") == 0)
+    else if (icon == &I_icon_fence_vertical_end_6x8px)
     {
     {
-        _generic_icon.icon = &I_icon_fence_vertical_end_6x8px;
-        _generic_icon.width = 6;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return "fence_vertical_end";
     }
     }
-    if (furi_string_cmp(name, "fence_vertical_start") == 0)
+    else if (icon == &I_icon_fence_vertical_start_6x15px)
     {
     {
-        _generic_icon.icon = &I_icon_fence_vertical_start_6x15px;
-        _generic_icon.width = 6;
-        _generic_icon.height = 15;
-        return &_generic_icon;
+        return "fence_vertical_start";
     }
     }
-    if (furi_string_cmp(name, "flower") == 0)
+    else if (icon == &I_icon_flower_16x16)
     {
     {
-        _generic_icon.icon = &I_icon_flower_16x16;
-        _generic_icon.width = 16;
-        _generic_icon.height = 16;
-        return &_generic_icon;
+        return "flower";
     }
     }
-    if (furi_string_cmp(name, "lake_bottom") == 0)
+    else if (icon == &I_icon_lake_bottom_31x12px)
     {
     {
-        _generic_icon.icon = &I_icon_lake_bottom_31x12px;
-        _generic_icon.width = 31;
-        _generic_icon.height = 12;
-        return &_generic_icon;
+        return "lake_bottom";
     }
     }
-    if (furi_string_cmp(name, "lake_bottom_left") == 0)
+    else if (icon == &I_icon_lake_bottom_left_24x22px)
     {
     {
-        _generic_icon.icon = &I_icon_lake_bottom_left_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return "lake_bottom_left";
     }
     }
-    if (furi_string_cmp(name, "lake_bottom_right") == 0)
+    else if (icon == &I_icon_lake_bottom_right_24x22px)
     {
     {
-        _generic_icon.icon = &I_icon_lake_bottom_right_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return "lake_bottom_right";
     }
     }
-    if (furi_string_cmp(name, "lake_left") == 0)
+    else if (icon == &I_icon_lake_left_11x31px)
     {
     {
-        _generic_icon.icon = &I_icon_lake_left_11x31px;
-        _generic_icon.width = 11;
-        _generic_icon.height = 31;
-        return &_generic_icon;
+        return "lake_left";
     }
     }
-    if (furi_string_cmp(name, "lake_right") == 0)
+    else if (icon == &I_icon_lake_right_11x31)
     {
     {
-        _generic_icon.icon = &I_icon_lake_right_11x31; // Assuming dimensions
-        _generic_icon.width = 11;
-        _generic_icon.height = 31;
-        return &_generic_icon;
+        return "lake_right";
     }
     }
-    if (furi_string_cmp(name, "lake_top") == 0)
+    else if (icon == &I_icon_lake_top_31x12px)
     {
     {
-        _generic_icon.icon = &I_icon_lake_top_31x12px;
-        _generic_icon.width = 31;
-        _generic_icon.height = 12;
-        return &_generic_icon;
+        return "lake_top";
     }
     }
-    if (furi_string_cmp(name, "lake_top_left") == 0)
+    else if (icon == &I_icon_lake_top_left_24x22px)
     {
     {
-        _generic_icon.icon = &I_icon_lake_top_left_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return "lake_top_left";
     }
     }
-    if (furi_string_cmp(name, "lake_top_right") == 0)
+    else if (icon == &I_icon_lake_top_right_24x22px)
     {
     {
-        _generic_icon.icon = &I_icon_lake_top_right_24x22px;
-        _generic_icon.width = 24;
-        _generic_icon.height = 22;
-        return &_generic_icon;
+        return "lake_top_right";
     }
     }
-    if (furi_string_cmp(name, "rock_large") == 0)
+    else if (icon == &I_icon_rock_large_18x19px)
     {
     {
-        _generic_icon.icon = &I_icon_rock_large_18x19px;
-        _generic_icon.width = 18;
-        _generic_icon.height = 19;
-        return &_generic_icon;
+        return "rock_large";
     }
     }
-    if (furi_string_cmp(name, "rock_medium") == 0)
+    else if (icon == &I_icon_rock_medium_16x14px)
     {
     {
-        _generic_icon.icon = &I_icon_rock_medium_16x14px;
-        _generic_icon.width = 16;
-        _generic_icon.height = 14;
-        return &_generic_icon;
+        return "rock_medium";
     }
     }
-    if (furi_string_cmp(name, "rock_small") == 0)
+    else if (icon == &I_icon_rock_small_10x8px)
     {
     {
-        _generic_icon.icon = &I_icon_rock_small_10x8px;
-        _generic_icon.width = 10;
-        _generic_icon.height = 8;
-        return &_generic_icon;
+        return "rock_small";
     }
     }
 
 
     // If no match is found
     // If no match is found
+    FURI_LOG_E("Game", "Icon ID not found for given icon pointer.");
     return NULL;
     return NULL;
 }
 }

+ 4 - 4
game/icon.h

@@ -1,16 +1,16 @@
 #pragma once
 #pragma once
 #include "flip_world_icons.h"
 #include "flip_world_icons.h"
 #include "game.h"
 #include "game.h"
-#define COLLISION_BOX_PADDING_HORIZONTAL 10
-#define COLLISION_BOX_PADDING_VERTICAL 12
 
 
 typedef struct
 typedef struct
 {
 {
+    char id[32];
     const Icon *icon;
     const Icon *icon;
     uint8_t width;
     uint8_t width;
     uint8_t height;
     uint8_t height;
 } IconContext;
 } IconContext;
 
 
 extern const EntityDescription icon_desc;
 extern const EntityDescription icon_desc;
-IconContext *get_icon_context(char *name);
-IconContext *get_icon_context_furi(FuriString *name);
+IconContext *get_icon_context(const char *name);
+IconContext *get_icon_context_furi(FuriString *name);
+const char *icon_get_id(const Icon *icon);

+ 27 - 28
game/player.c

@@ -33,36 +33,36 @@ void player_spawn(Level *level, GameManager *manager)
 
 
     // Get player context
     // Get player context
     PlayerContext *player_context = entity_context_get(game_context->players[0]);
     PlayerContext *player_context = entity_context_get(game_context->players[0]);
-    if (!load_player_context(player_context))
+    // if (!load_player_context(player_context))
+    //  {
+    // Load player sprite
+    player_context->sprite_right = game_manager_sprite_load(manager, "player_right_naked_10x10px.fxbm");
+    player_context->sprite_left = game_manager_sprite_load(manager, "player_left_naked_10x10px.fxbm");
+    player_context->direction = PLAYER_RIGHT; // default direction
+    player_context->health = 100;
+    player_context->strength = 10;
+    player_context->level = 1;
+    player_context->xp = 0;
+    player_context->start_position = entity_pos_get(game_context->players[0]);
+    player_context->attack_timer = 0.1f;
+    player_context->elapsed_attack_timer = player_context->attack_timer;
+    player_context->health_regen = 1; // 1 health per second
+    player_context->elapsed_health_regen = 0;
+    player_context->max_health = 100 + ((player_context->level - 1) * 10); // 10 health per level
+
+    // Set player username
+    if (!load_char("Flip-Social-Username", player_context->username, 32))
     {
     {
-        // Load player sprite
-        player_context->sprite_right = game_manager_sprite_load(manager, "player_right_naked_10x10px.fxbm");
-        player_context->sprite_left = game_manager_sprite_load(manager, "player_left_naked_10x10px.fxbm");
-        player_context->direction = PLAYER_RIGHT; // default direction
-        player_context->health = 100;
-        player_context->strength = 10;
-        player_context->level = 1;
-        player_context->xp = 0;
-        player_context->start_position = entity_pos_get(game_context->players[0]);
-        player_context->attack_timer = 0.5f;
-        player_context->elapsed_attack_timer = player_context->attack_timer;
-        player_context->health_regen = 1; // 1 health per second
-        player_context->elapsed_health_regen = 0;
-        player_context->max_health = 100 + ((player_context->level - 1) * 10); // 10 health per level
-
-        // Set player username
-        if (!load_char("Flip-Social-Username", player_context->username, 32))
-        {
-            snprintf(player_context->username, 32, "Player");
-        }
-
-        game_context->player_context = player_context;
-        save_player_context(player_context);
-        return;
+        snprintf(player_context->username, 32, "Player");
     }
     }
 
 
-    // Copy loaded player context to player context
     game_context->player_context = player_context;
     game_context->player_context = player_context;
+    save_player_context(player_context);
+    //  return;
+    //  }
+
+    // Copy loaded player context to player context
+    // game_context->player_context = player_context;
 
 
     // Load player sprite (we'll add this to the JSON later when players can choose their sprite)
     // Load player sprite (we'll add this to the JSON later when players can choose their sprite)
     player_context->sprite_right = game_manager_sprite_load(manager, "player_right_naked_10x10px.fxbm");
     player_context->sprite_right = game_manager_sprite_load(manager, "player_right_naked_10x10px.fxbm");
@@ -195,8 +195,7 @@ static void player_render(Entity *self, GameManager *manager, Canvas *canvas, vo
     );
     );
 
 
     // draw username over player's head
     // draw username over player's head
-    canvas_set_font_custom(canvas, FONT_SIZE_SMALL);
-    canvas_draw_str(canvas, pos.x - camera_x - (strlen(player->username) * 2), pos.y - camera_y - 7, player->username);
+    // draw_username(canvas, pos, player->username);
 }
 }
 
 
 const EntityDescription player_desc = {
 const EntityDescription player_desc = {

+ 2 - 2
game/player.h

@@ -3,8 +3,8 @@
 #include <flip_world.h>
 #include <flip_world.h>
 #include <game/game.h>
 #include <game/game.h>
 
 
-#define PLAYER_COLLISION_VERTICAL 5
-#define PLAYER_COLLISION_HORIZONTAL 5
+#define PLAYER_COLLISION_VERTICAL 0   // was 5
+#define PLAYER_COLLISION_HORIZONTAL 0 // was 5
 
 
 // Maximum enemies
 // Maximum enemies
 #define MAX_ENEMIES 10
 #define MAX_ENEMIES 10