Selaa lähdekoodia

add npcs and fix default level

jblanked 11 kuukautta sitten
vanhempi
commit
58c89badc1
6 muutettua tiedostoa jossa 106 lisäystä ja 127 poistoa
  1. 10 2
      game/game.c
  2. 39 7
      game/level.c
  3. 2 1
      game/level.h
  4. 46 60
      game/storage.c
  5. 8 55
      game/world.c
  6. 1 2
      game/world.h

+ 10 - 2
game/game.c

@@ -17,11 +17,20 @@ static void game_start(GameManager *game_manager, void *ctx)
     game_context->current_level = 0;
     game_context->level_count = 0;
     game_context->enemy_count = 0;
+    game_context->npc_count = 0;
 
     // set all levels to NULL
     for (int i = 0; i < MAX_LEVELS; i++)
         game_context->levels[i] = NULL;
 
+    // set all enemies to NULL
+    for (int i = 0; i < MAX_ENEMIES; i++)
+        game_context->enemies[i] = NULL;
+
+    // set all npcs to NULL
+    for (int i = 0; i < MAX_NPCS; i++)
+        game_context->npcs[i] = NULL;
+
     // attempt to allocate all levels
     for (int i = 0; i < MAX_LEVELS; i++)
     {
@@ -29,9 +38,8 @@ static void game_start(GameManager *game_manager, void *ctx)
         {
             if (i == 0)
             {
-                game_context->levels[0] = game_manager_add_level(game_manager, generic_level("town_world_v2", 0));
+                game_context->levels[0] = game_manager_add_level(game_manager, training_world());
                 game_context->level_count = 1;
-                break;
             }
             break;
         }

+ 39 - 7
game/level.c

@@ -12,7 +12,7 @@ bool allocate_level(GameManager *manager, int index)
     if (!world_list)
     {
         FURI_LOG_E("Game", "Failed to load world list");
-        game_context->levels[0] = game_manager_add_level(manager, generic_level("town_world_v2", 0));
+        game_context->levels[0] = game_manager_add_level(manager, training_world());
         game_context->level_count = 1;
         return false;
     }
@@ -29,7 +29,7 @@ bool allocate_level(GameManager *manager, int index)
     furi_string_free(world_list);
     return true;
 }
-static void set_world(Level *level, GameManager *manager, char *id)
+void set_world(Level *level, GameManager *manager, char *id)
 {
     char file_path[256];
     snprintf(file_path, sizeof(file_path),
@@ -40,7 +40,7 @@ static void set_world(Level *level, GameManager *manager, char *id)
     if (!json_data_str || furi_string_empty(json_data_str))
     {
         FURI_LOG_E("Game", "Failed to load json data from file");
-        draw_town_world(manager, level);
+        // draw_town_world(manager, level);
         return;
     }
 
@@ -58,7 +58,7 @@ static void set_world(Level *level, GameManager *manager, char *id)
     if (!draw_json_world_furi(manager, level, json_data_str))
     {
         FURI_LOG_E("Game", "Failed to draw world");
-        draw_town_world(manager, level);
+        // draw_town_world(manager, level);
         furi_string_free(json_data_str);
     }
     else
@@ -73,7 +73,7 @@ static void set_world(Level *level, GameManager *manager, char *id)
         if (!enemy_data_str || furi_string_empty(enemy_data_str))
         {
             FURI_LOG_E("Game", "Failed to get enemy data");
-            draw_town_world(manager, level);
+            // draw_town_world(manager, level);
             return;
         }
 
@@ -93,7 +93,39 @@ static void set_world(Level *level, GameManager *manager, char *id)
             furi_string_free(single_enemy_data);
         }
         furi_string_free(enemy_data_str);
-        FURI_LOG_I("Game", "Finished loading world data");
+
+        // Draw NPCs
+        FURI_LOG_I("Game", "Drawing NPCs");
+        snprintf(file_path, sizeof(file_path),
+                 STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/%s/%s_npc_data.json",
+                 id, id);
+
+        FuriString *npc_data_str = flipper_http_load_from_file(file_path);
+        if (!npc_data_str || furi_string_empty(npc_data_str))
+        {
+            FURI_LOG_E("Game", "Failed to get npc data");
+            // draw_town_world(manager, level);
+            return;
+        }
+
+        // Loop through the array
+        for (int i = 0; i < MAX_NPCS; i++)
+        {
+            FuriString *single_npc_data = get_json_array_value_furi("npc_data", i, npc_data_str);
+            if (!single_npc_data || furi_string_empty(single_npc_data))
+            {
+                // No more npc elements found
+                if (single_npc_data)
+                    furi_string_free(single_npc_data);
+                break;
+            }
+
+            spawn_npc(level, manager, single_npc_data);
+            furi_string_free(single_npc_data);
+        }
+        furi_string_free(npc_data_str);
+
+        FURI_LOG_I("Game", "World drawn");
     }
 }
 static void level_start(Level *level, GameManager *manager, void *context)
@@ -129,7 +161,7 @@ static void level_start(Level *level, GameManager *manager, void *context)
         if (!world_data)
         {
             FURI_LOG_E("Game", "Failed to fetch world data");
-            draw_town_world(manager, level);
+            // draw_town_world(manager, level);
             game_context->is_switching_level = false;
             // furi_delay_ms(1000);
             player_spawn(level, manager);

+ 2 - 1
game/level.h

@@ -8,4 +8,5 @@ typedef struct
 } LevelContext;
 
 const LevelBehaviour *generic_level(const char *id, int index);
-bool allocate_level(GameManager *manager, int index);
+bool allocate_level(GameManager *manager, int index);
+void set_world(Level *level, GameManager *manager, char *id);

+ 46 - 60
game/storage.c

@@ -897,62 +897,9 @@ static inline void furi_string_remove_str(FuriString *string, const char *needle
     furi_string_replace_str(string, needle, "", 0);
 }
 
-static FuriString *enemy_data(const FuriString *world_data)
+static FuriString *json_data(const FuriString *world_data, const char *key)
 {
-    size_t enemy_data_pos = furi_string_search_str(world_data, "enemy_data", 0);
-    if (enemy_data_pos == FURI_STRING_FAILURE)
-    {
-        FURI_LOG_E("Game", "Failed to find enemy_data in world data");
-
-        return NULL;
-    }
-
-    size_t bracket_start = furi_string_search_char(world_data, '[', enemy_data_pos);
-    if (bracket_start == FURI_STRING_FAILURE)
-    {
-        FURI_LOG_E("Game", "Failed to find start of enemy_data array");
-
-        return NULL;
-    }
-
-    size_t bracket_end = furi_string_search_char(world_data, ']', bracket_start);
-    if (bracket_end == FURI_STRING_FAILURE)
-    {
-        FURI_LOG_E("Game", "Failed to find end of enemy_data array");
-
-        return NULL;
-    }
-
-    FuriString *enemy_data_str = furi_string_alloc();
-    if (!enemy_data_str)
-    {
-        FURI_LOG_E("Game", "Failed to allocate enemy_data string");
-
-        return NULL;
-    }
-
-    furi_string_cat_str(enemy_data_str, "{\"enemy_data\":");
-
-    {
-        FuriString *temp_sub = furi_string_alloc();
-
-        furi_string_set_strn(
-            temp_sub,
-            furi_string_get_cstr(world_data) + bracket_start,
-            (bracket_end + 1) - bracket_start);
-
-        furi_string_cat(enemy_data_str, temp_sub);
-        furi_string_free(temp_sub);
-    }
-
-    furi_string_cat_str(enemy_data_str, "}");
-
-    return enemy_data_str;
-}
-
-static FuriString *json_data(const FuriString *world_data)
-{
-    size_t json_data_pos = furi_string_search_str(world_data, "json_data", 0);
+    size_t json_data_pos = furi_string_search_str(world_data, key, 0);
     if (json_data_pos == FURI_STRING_FAILURE)
     {
         FURI_LOG_E("Game", "Failed to find json_data in world data");
@@ -984,7 +931,9 @@ static FuriString *json_data(const FuriString *world_data)
         return NULL;
     }
 
-    furi_string_cat_str(json_data_str, "{\"json_data\":");
+    furi_string_cat_str(json_data_str, "{\"");
+    furi_string_cat_str(json_data_str, key);
+    furi_string_cat_str(json_data_str, "\":");
 
     {
         FuriString *temp_sub = furi_string_alloc();
@@ -1010,7 +959,7 @@ bool separate_world_data(char *id, FuriString *world_data)
         FURI_LOG_E("Game", "Invalid parameters");
         return false;
     }
-    FuriString *file_json_data = json_data(world_data);
+    FuriString *file_json_data = json_data(world_data, "json_data");
     if (!file_json_data || furi_string_size(file_json_data) == 0)
     {
         FURI_LOG_E("Game", "Failed to get json data in separate_world_data");
@@ -1051,10 +1000,48 @@ bool separate_world_data(char *id, FuriString *world_data)
     furi_string_replace_at(file_json_data, furi_string_size(file_json_data) - 1, 1, "");
     // include the comma at the end of the json_data array
     furi_string_cat_str(file_json_data, ",");
+
     furi_string_remove_str(world_data, furi_string_get_cstr(file_json_data));
     furi_string_free(file_json_data);
 
-    FuriString *file_enemy_data = enemy_data(world_data);
+    // save npc_data to disk
+    FuriString *file_npc_data = json_data(world_data, "npc_data");
+    if (!file_npc_data)
+    {
+        FURI_LOG_E("Game", "Failed to get npc data");
+        return false;
+    }
+
+    snprintf(file_path, sizeof(file_path),
+             STORAGE_EXT_PATH_PREFIX "/apps_data/flip_world/worlds/%s/%s_npc_data.json",
+             id, id);
+
+    if (!storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS))
+    {
+        FURI_LOG_E("Game", "Failed to open file for writing: %s", file_path);
+        storage_file_free(file);
+        furi_record_close(RECORD_STORAGE);
+        furi_string_free(file_npc_data);
+        return false;
+    }
+
+    data_size = furi_string_size(file_npc_data);
+    if (storage_file_write(file, furi_string_get_cstr(file_npc_data), data_size) != data_size)
+    {
+        FURI_LOG_E("Game", "Failed to write npc_data");
+    }
+    storage_file_close(file);
+
+    furi_string_replace_at(file_npc_data, 0, 1, "");
+    furi_string_replace_at(file_npc_data, furi_string_size(file_npc_data) - 1, 1, "");
+    // include the comma at the end of the npc_data array
+    furi_string_cat_str(file_npc_data, ",");
+
+    furi_string_remove_str(world_data, furi_string_get_cstr(file_npc_data));
+    furi_string_free(file_npc_data);
+
+    // Save enemy_data to disk
+    FuriString *file_enemy_data = json_data(world_data, "enemy_data");
     if (!file_enemy_data)
     {
         FURI_LOG_E("Game", "Failed to get enemy data");
@@ -1079,12 +1066,11 @@ bool separate_world_data(char *id, FuriString *world_data)
     {
         FURI_LOG_E("Game", "Failed to write enemy_data");
     }
+    furi_string_free(file_enemy_data);
 
     // Clean up
-    furi_string_free(file_enemy_data);
     storage_file_close(file);
     storage_file_free(file);
     furi_record_close(RECORD_STORAGE);
-
     return true;
 }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 8 - 55
game/world.c


+ 1 - 2
game/world.h

@@ -10,7 +10,6 @@
 
 // Maximum number of world objects
 #define MAX_WORLD_OBJECTS 25 // any more than that and we may run out of heap when switching worlds
-
-void draw_town_world(GameManager *manager, Level *level);
+const LevelBehaviour *training_world();
 bool draw_json_world_furi(GameManager *manager, Level *level, const FuriString *json_data);
 FuriString *fetch_world(const char *name);

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä