@@ -5368,16 +5368,82 @@ bool Game_Interpreter::CommandEasyRpgProcessJson(lcf::rpg::EventCommand const& c
53685368 return true ;
53695369#else
53705370
5371+ // Helper lambda for getting values from variables
5372+ auto get_var_value = [](int var_type, int var_id) -> std::string {
5373+ switch (var_type) {
5374+ case 0 : // Switch
5375+ return std::to_string (Main_Data::game_switches->Get (var_id));
5376+ case 1 : // Variable
5377+ return std::to_string (Main_Data::game_variables->Get (var_id));
5378+ case 2 : // String
5379+ return ToString (Main_Data::game_strings->Get (var_id));
5380+ default :
5381+ Output::Warning (" CommandEasyRpgProcessJson: Unsupported var_type {}" , var_type);
5382+ return {};
5383+ }
5384+ };
5385+
5386+ // Helper lambda for setting values to variables
5387+ auto set_var_value = [](int var_type, int var_id, const std::string& value) -> bool {
5388+ switch (var_type) {
5389+ case 0 : // Switch
5390+ Main_Data::game_switches->Set (var_id, atoi (value.c_str ()) != 0 );
5391+ break ;
5392+ case 1 : // Variable
5393+ Main_Data::game_variables->Set (var_id, atoi (value.c_str ()));
5394+ break ;
5395+ case 2 : // String
5396+ Main_Data::game_strings->Asg (var_id, value);
5397+ break ;
5398+ default :
5399+ Output::Warning (" CommandEasyRpgProcessJson: Unsupported var_type {}" , var_type);
5400+ return false ;
5401+ }
5402+ return true ;
5403+ };
5404+
53715405 int operation = ValueOrVariable (com.parameters [0 ], com.parameters [1 ]);
5372- int source_var_id = ValueOrVariable (com.parameters [2 ], com.parameters [3 ]);
5406+
5407+ json* json_data = nullptr ;
5408+ std::optional<json> json_data_imm;
5409+
5410+ int source_var_id = -1 ;
5411+
5412+ int pos = 0 ;
5413+ std::string json_path = Main_Data::game_strings->GetWithModeAndPos (com.string , com.parameters [8 ], com.parameters [9 ], pos, *Main_Data::game_variables);
5414+
5415+ if (com.parameters [2 ] == 0 ) {
5416+ std::string json_str = Main_Data::game_strings->GetWithModeAndPos (com.string , com.parameters [2 ], com.parameters [3 ], pos, *Main_Data::game_variables);
5417+ json_data_imm = Json_Helper::Parse (json_str);
5418+ if (json_data_imm) {
5419+ json_data = &*json_data_imm;
5420+ } else {
5421+ Output::Warning (" JSON Parse error for {}" , json_str);
5422+ return true ;
5423+ }
5424+ } else {
5425+ source_var_id = ValueOrVariable (com.parameters [2 ] - 1 , com.parameters [3 ]);
5426+ json_data = Main_Data::game_strings->ParseJson (source_var_id);
5427+
5428+ if (!json_data) {
5429+ Output::Warning (" JSON Parse error for {}" , Main_Data::game_strings->Get (source_var_id));
5430+ return true ;
5431+ }
5432+ }
5433+
53735434 int target_var_type = ValueOrVariable (com.parameters [4 ], com.parameters [5 ]);
53745435 int target_var_id = ValueOrVariable (com.parameters [6 ], com.parameters [7 ]);
53755436
5376- std::string json_path = ToString (CommandStringOrVariable (com, 8 , 9 ));
5377- auto * json_data = Main_Data::game_strings->ParseJson (source_var_id);
5437+ int flags = com.parameters [10 ];
5438+ bool pretty_print = (flags & 4 ) == 4 ;
5439+
5440+ if ((flags & 1 ) == 1 ) { // parse command codes
5441+ json_path = Game_Strings::Extract (json_path, false );
5442+ } else if ((flags & 2 ) == 2 ) { // parse command codes, numbers as hex
5443+ json_path = Game_Strings::Extract (json_path, true );
5444+ }
53785445
5379- if (!json_data) {
5380- Output::Warning (" JSON Parse error for {}" , Main_Data::game_strings->Get (source_var_id));
5446+ if (!Json_Helper::CheckJsonPointer (json_path)) {
53815447 return true ;
53825448 }
53835449
@@ -5388,54 +5454,133 @@ bool Game_Interpreter::CommandEasyRpgProcessJson(lcf::rpg::EventCommand const& c
53885454
53895455 std::optional<std::string> result;
53905456
5391- if (operation == 0 ) { // Get operation: Extract a value from JSON data
5457+ switch (operation) {
5458+ case 0 : { // Get operation: Extract a value from JSON data
53925459 result = Json_Helper::GetValue (*json_data, json_path);
5393-
53945460 if (result) {
5395- switch (target_var_type) {
5396- case 0 : // Switch
5397- Main_Data::game_switches->Set (target_var_id, atoi (result->c_str ()) != 0 );
5398- break ;
5399- case 1 : // Variable
5400- Main_Data::game_variables->Set (target_var_id, atoi (result->c_str ()));
5401- break ;
5402- case 2 : // String
5403- Main_Data::game_strings->Asg ({ target_var_id }, *result);
5404- break ;
5405- default :
5406- Output::Warning (" CommandEasyRpgProcessJson: Unsupported target_var_type {}" , operation);
5407- return true ;
5408- }
5461+ set_var_value (target_var_type, target_var_id, *result);
54095462 }
5463+ break ;
54105464 }
5411- else if (operation == 1 ) { // Set operation: Update JSON data with a new value
5412- std::string new_value;
5413-
5414- switch (target_var_type) {
5415- case 0 : // Switch
5416- new_value = std::to_string (Main_Data::game_switches->Get (target_var_id));
5417- break ;
5418- case 1 : // Variable
5419- new_value = std::to_string (Main_Data::game_variables->Get (target_var_id));
5420- break ;
5421- case 2 : // String
5422- new_value = ToString (Main_Data::game_strings->Get (target_var_id));
5423- break ;
5424- default :
5425- Output::Warning (" CommandEasyRpgProcessJson: Unsupported target_var_type {}" , operation);
5465+ case 1 : { // Set operation: Update JSON data with a new value
5466+ if (json_data_imm) {
5467+ Output::Warning (" CommandEasyRpgProcessJson: Cannot modify constant JSON string" );
54265468 return true ;
54275469 }
54285470
5471+ std::string new_value = get_var_value (target_var_type, target_var_id);
54295472 result = Json_Helper::SetValue (*json_data, json_path, new_value);
5430-
54315473 if (result) {
5432- Main_Data::game_strings->Asg ({ source_var_id }, *result);
5474+ Main_Data::game_strings->Asg (source_var_id, *result);
5475+ }
5476+ break ;
5477+ }
5478+ case 2 : { // GetLength operation
5479+ size_t length = Json_Helper::GetLength (*json_data, json_path);
5480+ std::string length_str;
5481+ if (target_var_type == 0 ) {
5482+ // For switches, true if length > 0
5483+ length_str = (length > 0 ) ? " 1" : " 0" ;
5484+ }
5485+ else {
5486+ length_str = std::to_string (length);
5487+ }
5488+ set_var_value (target_var_type, target_var_id, length_str);
5489+ break ;
5490+ }
5491+ case 3 : { // GetKeys operation
5492+ bool create_keys_obj = (flags & 8 ) == 8 ;
5493+ auto keys = Json_Helper::GetKeys (*json_data, json_path);
5494+ std::string keys_str;
5495+ for (size_t i = 0 ; i < keys.size (); ++i) {
5496+ if (i > 0 ) keys_str += " ," ;
5497+ keys_str += " \" " + (keys)[i] + " \" " ;
5498+ }
5499+ std::string json_str = " [" + keys_str + " ]" ;
5500+ if (create_keys_obj) {
5501+ json_str = fmt::format (R"( {{ "keys": {} }})" , json_str);
5502+ }
5503+ set_var_value (target_var_type, target_var_id, json_str);
5504+ break ;
5505+ }
5506+ case 4 : { // GetType operation
5507+ std::string type = Json_Helper::GetType (*json_data, json_path);
5508+ std::string value;
5509+ if (target_var_type == 0 ) {
5510+ // For switches, true if it exists and not null
5511+ value = (!type.empty () && type != " null" );
5512+ }
5513+ else if (target_var_type == 1 ) {
5514+ // For variables, numeric code for type
5515+ int type_code = 0 ;
5516+ if (type == " object" ) type_code = 1 ;
5517+ else if (type == " array" ) type_code = 2 ;
5518+ else if (type == " string" ) type_code = 3 ;
5519+ else if (type == " number" ) type_code = 4 ;
5520+ else if (type == " boolean" ) type_code = 5 ;
5521+ else if (type == " null" ) type_code = 6 ;
5522+ value = std::to_string (type_code);
5523+ }
5524+ else {
5525+ value = type;
5526+ }
5527+ set_var_value (target_var_type, target_var_id, value);
5528+ break ;
5529+ }
5530+ case 5 : { // Remove operation: Remove value from JSON data
5531+ if (json_data_imm) {
5532+ Output::Warning (" CommandEasyRpgProcessJson: Cannot modify constant JSON string" );
5533+ return true ;
5534+ }
5535+
5536+ std::string result = Json_Helper::RemoveValue (*json_data, json_path);
5537+ if (!result.empty ()) {
5538+ Main_Data::game_strings->Asg (source_var_id, result);
5539+ }
5540+ break ;
5541+ }
5542+ case 6 : { // Push operation: Add value to end of array
5543+ if (json_data_imm) {
5544+ Output::Warning (" CommandEasyRpgProcessJson: Cannot modify constant JSON string" );
5545+ return true ;
5546+ }
5547+
5548+ std::string value = get_var_value (target_var_type, target_var_id);
5549+ std::string result = Json_Helper::PushValue (*json_data, json_path, value);
5550+ if (!result.empty ()) {
5551+ Main_Data::game_strings->Asg (source_var_id, result);
54335552 }
5553+ break ;
5554+ }
5555+ case 7 : { // Pop operation: Remove and return last element of array
5556+ auto [json_obj, element] = Json_Helper::PopValue (*json_data, json_path);
5557+ if (!json_obj.empty ()) {
5558+ // Set popped value to target variable
5559+ set_var_value (target_var_type, target_var_id, element);
5560+ // Update source with modified JSON after pop
5561+ if (!json_data_imm) {
5562+ Main_Data::game_strings->Asg (source_var_id, json_obj);
5563+ }
5564+ }
5565+ break ;
54345566 }
5435- else {
5567+ case 8 : { // Contains operation: Check if path exists
5568+ bool exists = Json_Helper::Contains (*json_data, json_path);
5569+ set_var_value (target_var_type, target_var_id, exists ? " 1" : " 0" );
5570+ break ;
5571+ }
5572+ default :
54365573 Output::Warning (" CommandEasyRpgProcessJson: Invalid Operation {}" , operation);
54375574 }
54385575
5576+ if (target_var_type == 2 && pretty_print == 1 ) { // Only works with strings
5577+ std::string target_str = ToString (Main_Data::game_strings->Get (target_var_id));
5578+ if (auto parsed_json = Json_Helper::Parse (target_str)) {
5579+ std::string formatted = Json_Helper::PrettyPrint (*parsed_json, 2 );
5580+ Main_Data::game_strings->Asg ({ target_var_id }, formatted);
5581+ }
5582+ }
5583+
54395584 return true ;
54405585
54415586#endif // !HAVE_NLOHMANN_JSON
0 commit comments