diff --git a/src/modules/stream/stream.cpp b/src/modules/stream/stream.cpp index e4c3d63..767ec19 100644 --- a/src/modules/stream/stream.cpp +++ b/src/modules/stream/stream.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -30,7 +29,8 @@ void StreamWorld::read_buildings_json(const String &buildings_path) while (e) { struct building b; String key = e->get(); - String id = json[key].get("id"); + Dictionary entry = json[key]; + String id = entry.get("id", "empty"); if (id == "empty") { e = e->next(); continue; @@ -66,16 +66,24 @@ void StreamWorld::save_buildings_json(const String &buildings_path) { int i; String buildings_json = FileAccess::get_file_as_string(buildings_path); - Variant json_v; - String es; - int eline; - Error status = JSON::parse(buildings_json, json_v, es, eline); - ERR_FAIL_COND_MSG(status != OK, "Can't parse json: " + es + - " at line: " + itos(eline)); - - Dictionary json = json_v; - for (i = 0; i < (int)buildings.size(); i++) - print_line("entries count: " + itos(buildings.size())); + String backup_path = buildings_path + ".bak"; + String store_path = buildings_path + ".new"; + FileAccess *fa = FileAccess::open(backup_path, FileAccess::WRITE); + fa->store_string(buildings_json); + fa->close(); + Dictionary json; + for (i = 0; i < (int)buildings.size(); i++) { + String key; + VariantWriter::write_to_string(buildings[i].xform, key); + Dictionary dict = buildings[i].to_dict(); + dict["index"] = i; + json[key] = dict; + } + String json_string = JSON::print(json, "\t", false); + fa = FileAccess::open(store_path, FileAccess::WRITE); + fa->store_string(json_string); + fa->close(); + print_line("entries count: " + itos(buildings.size())); } void StreamWorld::building::from_dict(building *b, const Dictionary &dict, @@ -102,7 +110,7 @@ void StreamWorld::building::from_dict(building *b, const Dictionary &dict, Array doors = from_string(doors_s); b->doors.resize(doors.size()); for (i = 0; i < (int)doors.size(); i++) - b->doors.write[i] = doors[i]; + b->doors.write[i] = from_string(doors[i]); String aabb_s = dict.get("aabb", AABB()); b->aabb = from_string(aabb_s); Array worktime = dict.get("worktime", Array()); @@ -115,9 +123,48 @@ void StreamWorld::building::from_dict(building *b, const Dictionary &dict, b->worktime[1] = worktime[1]; } +template static inline void v2a(Array &ret, const Vector &data) +{ + int i; + ret.resize(data.size()); + for (i = 0; i < (int)data.size(); i++) + ret[i] = data[i]; +} + Dictionary StreamWorld::building::to_dict() const { - return Dictionary(); + int i; + Dictionary ret; + ret["id"] = id; + ret["pattern_id"] = pattern_id; + Array r, w, g; + v2a(r, residents); + ret["residents"] = r; + v2a(w, workers); + ret["workers"] = w; + v2a(g, guests); + ret["guests"] = g; + Array d; + v2a(d, doors); + String doors_s; + Array d2; + d2.resize(d.size()); + for (i = 0; i < (int)d.size(); i++) { + String tmp; + VariantWriter::write_to_string(d[i], tmp); + d2[i] = tmp; + } + VariantWriter::write_to_string(d2, doors_s); + ret["doors"] = doors_s; + String aabb_s; + VariantWriter::write_to_string(aabb, aabb_s); + ret["aabb"] = aabb_s; + Array wt; + wt.resize(2); + wt[0] = worktime[0]; + wt[1] = worktime[1]; + ret["worktime"] = wt; + return ret; } void StreamWorld::create_tilemap() @@ -404,7 +451,9 @@ void StreamWorld::run_command(const String &command, const Array &args) } else if (command == "buildings_undo") { /* TODO */ } else if (command == "buildings_save") { - /* TODO */ + String buildings_path = + config.get_value("buildings", "buildings_path"); + save_buildings_json(buildings_path); } else print_error("No command " + command); } @@ -486,7 +535,6 @@ StreamWorld::StreamWorld() , view_distance(0) , initialized(false) { - ConfigFile config; Error result = config.load("res://config/stream.conf"); ERR_FAIL_COND_MSG(result != OK, "Failed to load config"); Dictionary buildings_data = diff --git a/src/modules/stream/stream.h b/src/modules/stream/stream.h index e536377..bd28b3c 100644 --- a/src/modules/stream/stream.h +++ b/src/modules/stream/stream.h @@ -5,6 +5,7 @@ #include #include #include +#include class VoxelViewer; class VoxelLodTerrain; class StreamWorld : public Spatial { @@ -13,6 +14,7 @@ private: VoxelViewer *viewer; VoxelLodTerrain *terrain; Node *current_scene; + ConfigFile config; struct building { String id; int pattern_id;