yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sprite_behavior_json.h
Go to the documentation of this file.
1#ifndef YAZE_CORE_SPRITE_BEHAVIOR_JSON_H_
2#define YAZE_CORE_SPRITE_BEHAVIOR_JSON_H_
3
4#include <stdexcept>
5
6#include "absl/status/statusor.h"
8#include "nlohmann/json.hpp"
9
10namespace yaze::project {
11inline nlohmann::json SpriteBehaviorToJson(const SpriteBehavior& behavior) {
12 auto actions = nlohmann::json::array();
13 for (const auto& action : behavior.actions)
14 actions.push_back({{"name", action.name},
15 {"animation", action.animation},
16 {"block_player", action.block_player},
17 {"message_id", action.message_id},
18 {"message_next", action.message_next},
19 {"move", action.move},
20 {"x_speed", action.x_speed},
21 {"y_speed", action.y_speed},
22 {"bounce_tiles", action.bounce_tiles},
23 {"timer_ticks", action.timer_ticks},
24 {"timer_next", action.timer_next}});
25 return {{"profile", behavior.profile},
26 {"source_sha256", behavior.source_sha256},
27 {"actions", actions}};
28}
29
30inline absl::StatusOr<SpriteBehavior> SpriteBehaviorFromJson(
31 const nlohmann::json& json) {
32 auto invalid = [] {
33 return absl::InvalidArgumentError("Invalid Oracle action model");
34 };
35 try {
36 if (!json.is_object() || json.size() != 3 ||
37 json.at("profile") != "oracle_actions_v1")
38 return invalid();
39 SpriteBehavior behavior;
40 behavior.profile = "oracle_actions_v1";
41 const auto& hashes = json.at("source_sha256");
42 const auto& actions = json.at("actions");
43 if (!hashes.is_array() || hashes.size() != 3 || !actions.is_array() ||
44 actions.empty() || actions.size() > 16)
45 return invalid();
46 for (int i = 0; i < 3; ++i) {
47 behavior.source_sha256[i] = hashes[i].get<std::string>();
48 if (behavior.source_sha256[i].size() != 64 ||
49 behavior.source_sha256[i].find_first_not_of("0123456789abcdef") !=
50 std::string::npos)
51 return invalid();
52 }
53 for (const auto& value : actions) {
54 if (!value.is_object() || value.size() != 11)
55 return invalid();
56 auto number = [&](const char* key, int low, int high) {
57 const auto& n = value.at(key);
58 if (!n.is_number_integer() || n < low || n > high)
59 throw std::runtime_error("Action field out of range");
60 return n.get<int>();
61 };
63 action.name = value.at("name").get<std::string>();
64 if (action.name.empty() || action.name.size() > 80 ||
65 action.name.find_first_of("\r\n\0", 0, 3) != std::string::npos)
66 return invalid();
67 action.animation = number("animation", 0, 255);
68 action.block_player = value.at("block_player").get<bool>();
69 action.message_id = number("message_id", -1, 65535);
70 action.message_next = number("message_next", -1, actions.size() - 1);
71 action.move = value.at("move").get<bool>();
72 action.x_speed = number("x_speed", -128, 127);
73 action.y_speed = number("y_speed", -128, 127);
74 action.bounce_tiles = value.at("bounce_tiles").get<bool>();
75 action.timer_ticks = number("timer_ticks", 0, 255);
76 action.timer_next = number("timer_next", -1, actions.size() - 1);
77 if ((action.message_id < 0 && action.message_next >= 0) ||
78 (action.bounce_tiles && (!action.move || action.x_speed == -128 ||
79 action.y_speed == -128)) ||
80 (!action.move && (action.x_speed || action.y_speed)))
81 return invalid();
82 behavior.actions.push_back(std::move(action));
83 }
84 return behavior;
85 } catch (const std::exception&) {
86 return invalid();
87 }
88}
89} // namespace yaze::project
90#endif
absl::StatusOr< SpriteBehavior > SpriteBehaviorFromJson(const nlohmann::json &json)
nlohmann::json SpriteBehaviorToJson(const SpriteBehavior &behavior)
std::vector< SpriteBehaviorAction > actions
std::array< std::string, 3 > source_sha256