level.c 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include <game/level.h>
  2. static void level_start(Level *level, GameManager *manager, void *context)
  3. {
  4. UNUSED(manager);
  5. LevelContext *level_context = context;
  6. // check if the world exists
  7. if (!world_exists(level_context->id))
  8. {
  9. FURI_LOG_E("Game", "World does not exist");
  10. easy_flipper_dialog("[WORLD ERROR]", "No world data installed.\n\n\nSettings -> Game ->\nInstall Official World Pack");
  11. draw_town_world(level);
  12. return;
  13. }
  14. // get the world data
  15. FuriString *world_data = load_furi_world(level_context->id);
  16. if (!world_data)
  17. {
  18. FURI_LOG_E("Game", "Failed to load world data");
  19. draw_town_world(level);
  20. return;
  21. }
  22. // draw the world
  23. if (!draw_json_world(level, furi_string_get_cstr(world_data)))
  24. {
  25. FURI_LOG_E("Game", "World exists but failed to draw.");
  26. draw_town_world(level);
  27. }
  28. furi_string_free(world_data);
  29. }
  30. static LevelContext *level_context_generic;
  31. static LevelContext *level_generic_alloc(const char *id, int index)
  32. {
  33. if (!level_context_generic)
  34. {
  35. level_context_generic = malloc(sizeof(LevelContext));
  36. }
  37. snprintf(level_context_generic->id, sizeof(level_context_generic->id), "%s", id);
  38. level_context_generic->index = index;
  39. return level_context_generic;
  40. }
  41. static void level_generic_free()
  42. {
  43. if (level_context_generic)
  44. {
  45. free(level_context_generic);
  46. level_context_generic = NULL;
  47. }
  48. }
  49. static void level_alloc_generic_world(Level *level, GameManager *manager, void *context)
  50. {
  51. if (!level_context_generic)
  52. {
  53. FURI_LOG_E("Game", "Generic level context not set");
  54. return;
  55. }
  56. LevelContext *level_context = context;
  57. snprintf(level_context->id, sizeof(level_context->id), "%s", level_context_generic->id);
  58. level_context->index = level_context_generic->index;
  59. player_spawn(level, manager);
  60. }
  61. // Do NOT touch (this is for dynamic level creation)
  62. const LevelBehaviour _generic_level = {
  63. .alloc = level_alloc_generic_world, // called once, when level allocated
  64. .free = NULL, // called once, when level freed
  65. .start = level_start, // called when level is changed to this level
  66. .stop = NULL, // called when level is changed from this level
  67. .context_size = sizeof(LevelContext), // size of level context, will be automatically allocated and freed
  68. };
  69. const LevelBehaviour *generic_level(const char *id, int index)
  70. {
  71. level_generic_free();
  72. level_context_generic = level_generic_alloc(id, index);
  73. return &_generic_level;
  74. }