Separated BuildingsData to a singleton as RoadLinesData
This commit is contained in:
248
src/modules/stream/buildings_data.cpp
Normal file
248
src/modules/stream/buildings_data.cpp
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
#include <core/os/memory.h>
|
||||||
|
#include <core/io/json.h>
|
||||||
|
#include <core/os/file_access.h>
|
||||||
|
#include <core/io/config_file.h>
|
||||||
|
#include <scene/resources/packed_scene.h>
|
||||||
|
#include "from_string.h"
|
||||||
|
#include "buildings_data.h"
|
||||||
|
|
||||||
|
BuildingsData *BuildingsData::singleton;
|
||||||
|
|
||||||
|
static ConfigFile config;
|
||||||
|
|
||||||
|
BuildingsData::BuildingsData()
|
||||||
|
: undo_log_size(64)
|
||||||
|
{
|
||||||
|
load_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildingsData::~BuildingsData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildingsData *BuildingsData::get_singleton()
|
||||||
|
{
|
||||||
|
if (!singleton)
|
||||||
|
singleton = memnew(BuildingsData);
|
||||||
|
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::cleanup()
|
||||||
|
{
|
||||||
|
if (singleton) {
|
||||||
|
singleton->~BuildingsData();
|
||||||
|
Memory::free_static(singleton, false);
|
||||||
|
singleton = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::read_buildings_json(const String &buildings_path)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
List<Variant> keys;
|
||||||
|
json.get_key_list(&keys);
|
||||||
|
List<Variant>::Element *e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
struct building b;
|
||||||
|
String key = e->get();
|
||||||
|
Dictionary entry = json[key];
|
||||||
|
String id = entry.get("id", "empty");
|
||||||
|
if (id == "empty") {
|
||||||
|
e = e->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
building::from_dict(&b, json[key], key);
|
||||||
|
buildings.push_back(b);
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
String key = e->get();
|
||||||
|
/* Transform */
|
||||||
|
print_line("key: " + key);
|
||||||
|
String id = json[key].get("id");
|
||||||
|
print_line("id: " + id);
|
||||||
|
String aabb = json[key].get("aabb");
|
||||||
|
print_line("aabb: " + aabb);
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
filter_generated_stuff();
|
||||||
|
print_line("entries count: " + itos(buildings.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::save_buildings_json(const String &buildings_path)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
String buildings_json = FileAccess::get_file_as_string(buildings_path);
|
||||||
|
String backup_path = buildings_path + ".bak";
|
||||||
|
String store_path = buildings_path;
|
||||||
|
filter_generated_stuff();
|
||||||
|
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 BuildingsData::building::from_dict(building *b, const Dictionary &dict,
|
||||||
|
const String &key)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
b->key = key;
|
||||||
|
b->xform = from_string<Transform>(key);
|
||||||
|
b->id = dict.get("id", "empty");
|
||||||
|
b->pattern_id = dict.get("pattern_id", 0);
|
||||||
|
b->generated = dict.get("generated", false);
|
||||||
|
Array residents = dict.get("residents", Array());
|
||||||
|
b->residents.resize(residents.size());
|
||||||
|
for (i = 0; i < (int)residents.size(); i++)
|
||||||
|
b->residents.write[i] = residents[i];
|
||||||
|
Array workers = dict.get("workers", Array());
|
||||||
|
b->workers.resize(workers.size());
|
||||||
|
for (i = 0; i < (int)workers.size(); i++)
|
||||||
|
b->workers.write[i] = workers[i];
|
||||||
|
Array guests = dict.get("guests", Array());
|
||||||
|
b->guests.resize(guests.size());
|
||||||
|
for (i = 0; i < (int)guests.size(); i++)
|
||||||
|
b->guests.write[i] = guests[i];
|
||||||
|
String doors_s = dict.get("doors", "[ ]");
|
||||||
|
Array doors = from_string<Array>(doors_s);
|
||||||
|
b->doors.resize(doors.size());
|
||||||
|
for (i = 0; i < (int)doors.size(); i++)
|
||||||
|
b->doors.write[i] = from_string<Transform>(doors[i]);
|
||||||
|
String aabb_s = dict.get("aabb", AABB());
|
||||||
|
b->aabb = from_string<AABB>(aabb_s);
|
||||||
|
Array worktime = dict.get("worktime", Array());
|
||||||
|
if (worktime.size() == 0) {
|
||||||
|
worktime.resize(2);
|
||||||
|
worktime[0] = 0;
|
||||||
|
worktime[1] = 23;
|
||||||
|
}
|
||||||
|
b->worktime[0] = worktime[0];
|
||||||
|
b->worktime[1] = worktime[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static inline void v2a(Array &ret, const Vector<T> &data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ret.resize(data.size());
|
||||||
|
for (i = 0; i < (int)data.size(); i++)
|
||||||
|
ret[i] = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary BuildingsData::building::to_dict() const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Dictionary ret;
|
||||||
|
ret["id"] = id;
|
||||||
|
ret["pattern_id"] = pattern_id;
|
||||||
|
ret["generated"] = generated;
|
||||||
|
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 BuildingsData::filter_generated_stuff()
|
||||||
|
{
|
||||||
|
ConfigFile config;
|
||||||
|
Error result = config.load("res://config/stream.conf");
|
||||||
|
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||||
|
Array gen_prefixes = config.get_value("lines", "gen_prefixes");
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; i < (int)buildings.size(); i++) {
|
||||||
|
for (j = 0; j < (int)gen_prefixes.size(); j++) {
|
||||||
|
String prefix = gen_prefixes[j];
|
||||||
|
if (buildings[i].id.begins_with(prefix)) {
|
||||||
|
buildings[i].generated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::load_data()
|
||||||
|
{
|
||||||
|
Error result = config.load("res://config/stream.conf");
|
||||||
|
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||||
|
Dictionary buildings_data =
|
||||||
|
config.get_value("buildings", "building_data");
|
||||||
|
List<Variant> keys;
|
||||||
|
buildings_data.get_key_list(&keys);
|
||||||
|
List<Variant>::Element *e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
String key = e->get();
|
||||||
|
building_data[key] = buildings_data[key];
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
e = keys.front();
|
||||||
|
while (e) {
|
||||||
|
String key = e->get();
|
||||||
|
print_line(key + ": " + buildings_data[key]);
|
||||||
|
e = e->next();
|
||||||
|
}
|
||||||
|
String buildings_path = config.get_value("buildings", "buildings_path");
|
||||||
|
read_buildings_json(buildings_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildingsData::checkpoint()
|
||||||
|
{
|
||||||
|
struct checkpoint_data cp;
|
||||||
|
cp.building_data = building_data;
|
||||||
|
cp.buildings = buildings;
|
||||||
|
undo_log.push_back(cp);
|
||||||
|
while ((int)undo_log.size() > undo_log_size)
|
||||||
|
undo_log.erase(undo_log.begin());
|
||||||
|
}
|
||||||
|
void BuildingsData::undo()
|
||||||
|
{
|
||||||
|
struct checkpoint_data cp = *undo_log.end();
|
||||||
|
building_data = cp.building_data;
|
||||||
|
buildings = cp.buildings;
|
||||||
|
}
|
||||||
58
src/modules/stream/buildings_data.h
Normal file
58
src/modules/stream/buildings_data.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef BUILDINGS_DATA_H
|
||||||
|
#define BUILFINGS_DATA_H
|
||||||
|
#include <vector>
|
||||||
|
#include <core/reference.h>
|
||||||
|
class PackedScene;
|
||||||
|
class ResourceInteractiveLoader;
|
||||||
|
class BuildingsData {
|
||||||
|
public:
|
||||||
|
/* Per-building information */
|
||||||
|
struct building {
|
||||||
|
String id;
|
||||||
|
int pattern_id;
|
||||||
|
Vector<int> residents, workers, guests;
|
||||||
|
Vector<Transform> doors;
|
||||||
|
String key;
|
||||||
|
Transform xform;
|
||||||
|
AABB aabb;
|
||||||
|
int worktime[2];
|
||||||
|
bool generated;
|
||||||
|
static void from_dict(struct building *b,
|
||||||
|
const Dictionary &dict,
|
||||||
|
const String &key);
|
||||||
|
Dictionary to_dict() const;
|
||||||
|
};
|
||||||
|
/* Scene objects data */
|
||||||
|
struct scene_data {
|
||||||
|
Ref<PackedScene> packed_scene;
|
||||||
|
String path;
|
||||||
|
Ref<ResourceInteractiveLoader> loader;
|
||||||
|
std::vector<int> buildings;
|
||||||
|
};
|
||||||
|
HashMap<String, struct scene_data> scenes;
|
||||||
|
/* Data for each building type */
|
||||||
|
HashMap<String, String> building_data;
|
||||||
|
/* Data for each building in a world */
|
||||||
|
std::vector<struct building> buildings;
|
||||||
|
struct checkpoint_data {
|
||||||
|
HashMap<String, String> building_data;
|
||||||
|
std::vector<struct building> buildings;
|
||||||
|
};
|
||||||
|
std::vector<struct checkpoint_data> undo_log;
|
||||||
|
int undo_log_size;
|
||||||
|
BuildingsData();
|
||||||
|
virtual ~BuildingsData();
|
||||||
|
static BuildingsData *singleton;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void read_buildings_json(const String &buildings_path);
|
||||||
|
void save_buildings_json(const String &buildings_path);
|
||||||
|
void filter_generated_stuff();
|
||||||
|
void remove_generated_stuff();
|
||||||
|
void load_data();
|
||||||
|
void checkpoint();
|
||||||
|
void undo();
|
||||||
|
static BuildingsData *get_singleton();
|
||||||
|
static void cleanup();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
#include <core/io/json.h>
|
|
||||||
#include <core/os/file_access.h>
|
|
||||||
#include <core/set.h>
|
#include <core/set.h>
|
||||||
#include <scene/main/viewport.h>
|
#include <scene/main/viewport.h>
|
||||||
#include <scene/resources/packed_scene.h>
|
#include <scene/resources/packed_scene.h>
|
||||||
@@ -9,167 +7,18 @@
|
|||||||
#include <modules/voxel/terrain/voxel_lod_terrain.h>
|
#include <modules/voxel/terrain/voxel_lod_terrain.h>
|
||||||
#include "from_string.h"
|
#include "from_string.h"
|
||||||
#include "road_processing.h"
|
#include "road_processing.h"
|
||||||
#include "stream.h"
|
|
||||||
#include "road_debug.h"
|
#include "road_debug.h"
|
||||||
|
#include "buildings_data.h"
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
void StreamWorld::read_buildings_json(const String &buildings_path)
|
#define data() (BuildingsData::get_singleton())
|
||||||
{
|
|
||||||
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;
|
|
||||||
List<Variant> keys;
|
|
||||||
json.get_key_list(&keys);
|
|
||||||
List<Variant>::Element *e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
struct building b;
|
|
||||||
String key = e->get();
|
|
||||||
Dictionary entry = json[key];
|
|
||||||
String id = entry.get("id", "empty");
|
|
||||||
if (id == "empty") {
|
|
||||||
e = e->next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
building::from_dict(&b, json[key], key);
|
|
||||||
buildings.push_back(b);
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
String key = e->get();
|
|
||||||
/* Transform */
|
|
||||||
print_line("key: " + key);
|
|
||||||
String id = json[key].get("id");
|
|
||||||
print_line("id: " + id);
|
|
||||||
String aabb = json[key].get("aabb");
|
|
||||||
print_line("aabb: " + aabb);
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
filter_generated_stuff();
|
|
||||||
print_line("entries count: " + itos(buildings.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void StreamWorld::save_buildings_json(const String &buildings_path)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
String buildings_json = FileAccess::get_file_as_string(buildings_path);
|
|
||||||
String backup_path = buildings_path + ".bak";
|
|
||||||
String store_path = buildings_path;
|
|
||||||
filter_generated_stuff();
|
|
||||||
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,
|
|
||||||
const String &key)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
b->key = key;
|
|
||||||
b->xform = from_string<Transform>(key);
|
|
||||||
b->id = dict.get("id", "empty");
|
|
||||||
b->pattern_id = dict.get("pattern_id", 0);
|
|
||||||
b->generated = dict.get("generated", false);
|
|
||||||
Array residents = dict.get("residents", Array());
|
|
||||||
b->residents.resize(residents.size());
|
|
||||||
for (i = 0; i < (int)residents.size(); i++)
|
|
||||||
b->residents.write[i] = residents[i];
|
|
||||||
Array workers = dict.get("workers", Array());
|
|
||||||
b->workers.resize(workers.size());
|
|
||||||
for (i = 0; i < (int)workers.size(); i++)
|
|
||||||
b->workers.write[i] = workers[i];
|
|
||||||
Array guests = dict.get("guests", Array());
|
|
||||||
b->guests.resize(guests.size());
|
|
||||||
for (i = 0; i < (int)guests.size(); i++)
|
|
||||||
b->guests.write[i] = guests[i];
|
|
||||||
String doors_s = dict.get("doors", "[ ]");
|
|
||||||
Array doors = from_string<Array>(doors_s);
|
|
||||||
b->doors.resize(doors.size());
|
|
||||||
for (i = 0; i < (int)doors.size(); i++)
|
|
||||||
b->doors.write[i] = from_string<Transform>(doors[i]);
|
|
||||||
String aabb_s = dict.get("aabb", AABB());
|
|
||||||
b->aabb = from_string<AABB>(aabb_s);
|
|
||||||
Array worktime = dict.get("worktime", Array());
|
|
||||||
if (worktime.size() == 0) {
|
|
||||||
worktime.resize(2);
|
|
||||||
worktime[0] = 0;
|
|
||||||
worktime[1] = 23;
|
|
||||||
}
|
|
||||||
b->worktime[0] = worktime[0];
|
|
||||||
b->worktime[1] = worktime[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static inline void v2a(Array &ret, const Vector<T> &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
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
Dictionary ret;
|
|
||||||
ret["id"] = id;
|
|
||||||
ret["pattern_id"] = pattern_id;
|
|
||||||
ret["generated"] = generated;
|
|
||||||
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()
|
void StreamWorld::create_tilemap()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < (int)buildings.size(); i++) {
|
for (i = 0; i < (int)data()->buildings.size(); i++) {
|
||||||
int tile_x = buildings[i].xform.origin.x / tile_size;
|
int tile_x = data()->buildings[i].xform.origin.x / tile_size;
|
||||||
int tile_z = buildings[i].xform.origin.z / tile_size;
|
int tile_z = data()->buildings[i].xform.origin.z / tile_size;
|
||||||
std::tuple<int, int> key = std::make_tuple(tile_x, tile_z);
|
std::tuple<int, int> key = std::make_tuple(tile_x, tile_z);
|
||||||
if (tiles.find(key) != tiles.end())
|
if (tiles.find(key) != tiles.end())
|
||||||
tiles[key].push_back(i);
|
tiles[key].push_back(i);
|
||||||
@@ -287,7 +136,7 @@ void StreamWorld::load_tile(int tx, int ty)
|
|||||||
const std::vector<int> &items = tiles[key];
|
const std::vector<int> &items = tiles[key];
|
||||||
for (i = 0; i < (int)items.size(); i++) {
|
for (i = 0; i < (int)items.size(); i++) {
|
||||||
print_line("load item: " + itos(i) + ": " + itos(items[i]) +
|
print_line("load item: " + itos(i) + ": " + itos(items[i]) +
|
||||||
": " + buildings[items[i]].id);
|
": " + data()->buildings[items[i]].id);
|
||||||
load_building(items[i]);
|
load_building(items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,7 +148,7 @@ void StreamWorld::erase_tile(int tx, int ty)
|
|||||||
const std::vector<int> &items = tiles[key];
|
const std::vector<int> &items = tiles[key];
|
||||||
for (i = 0; i < (int)items.size(); i++) {
|
for (i = 0; i < (int)items.size(); i++) {
|
||||||
print_line("unload item: " + itos(i) + ": " + itos(items[i]) +
|
print_line("unload item: " + itos(i) + ": " + itos(items[i]) +
|
||||||
": " + buildings[items[i]].id);
|
": " + data()->buildings[items[i]].id);
|
||||||
unload_building(items[i]);
|
unload_building(items[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,24 +165,25 @@ void StreamWorld::unload_building(int id)
|
|||||||
|
|
||||||
void StreamWorld::request_item(int type, int item)
|
void StreamWorld::request_item(int type, int item)
|
||||||
{
|
{
|
||||||
String id = buildings[item].id;
|
String id = data()->buildings[item].id;
|
||||||
if (id == "empty")
|
if (id == "empty")
|
||||||
return;
|
return;
|
||||||
String path = building_data[id];
|
String path = data()->building_data[id];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
if (!scenes.has(id)) {
|
if (!data()->scenes.has(id)) {
|
||||||
print_line("Requesting " + itos(item) + " " + path);
|
print_line("Requesting " + itos(item) + " " + path);
|
||||||
struct scene_data sd;
|
struct BuildingsData::scene_data sd;
|
||||||
sd.path = path;
|
sd.path = path;
|
||||||
sd.loader = ResourceLoader::load_interactive(
|
sd.loader = ResourceLoader::load_interactive(
|
||||||
path, "PackedScene", true);
|
path, "PackedScene", true);
|
||||||
if (std::find(sd.buildings.begin(), sd.buildings.end(),
|
if (std::find(sd.buildings.begin(), sd.buildings.end(),
|
||||||
item) == sd.buildings.end())
|
item) == sd.buildings.end())
|
||||||
sd.buildings.push_back(item);
|
sd.buildings.push_back(item);
|
||||||
scenes[id] = sd;
|
data()->scenes[id] = sd;
|
||||||
} else {
|
} else {
|
||||||
struct scene_data &sd = scenes[id];
|
struct BuildingsData::scene_data &sd =
|
||||||
|
data()->scenes[id];
|
||||||
if (std::find(sd.buildings.begin(), sd.buildings.end(),
|
if (std::find(sd.buildings.begin(), sd.buildings.end(),
|
||||||
item) == sd.buildings.end())
|
item) == sd.buildings.end())
|
||||||
sd.buildings.push_back(item);
|
sd.buildings.push_back(item);
|
||||||
@@ -341,15 +191,16 @@ void StreamWorld::request_item(int type, int item)
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
print_line("Removing " + itos(item) + " " + path);
|
print_line("Removing " + itos(item) + " " + path);
|
||||||
if (scenes.has(id)) {
|
if (data()->scenes.has(id)) {
|
||||||
std::vector<int>::iterator b =
|
std::vector<int>::iterator b =
|
||||||
scenes[id].buildings.begin();
|
data()->scenes[id].buildings.begin();
|
||||||
std::vector<int>::iterator e =
|
std::vector<int>::iterator e =
|
||||||
scenes[id].buildings.end();
|
data()->scenes[id].buildings.end();
|
||||||
// if (item_nodes.has(item))
|
// if (item_nodes.has(item))
|
||||||
// item_nodes[item]->queue_delete();
|
// item_nodes[item]->queue_delete();
|
||||||
scenes[id].buildings.erase(std::remove(b, e, item),
|
data()->scenes[id].buildings.erase(
|
||||||
scenes[id].buildings.end());
|
std::remove(b, e, item),
|
||||||
|
data()->scenes[id].buildings.end());
|
||||||
if (item_nodes.has(item)) {
|
if (item_nodes.has(item)) {
|
||||||
item_nodes[item]->queue_delete();
|
item_nodes[item]->queue_delete();
|
||||||
item_nodes.erase(item);
|
item_nodes.erase(item);
|
||||||
@@ -362,74 +213,40 @@ void StreamWorld::request_item(int type, int item)
|
|||||||
void StreamWorld::update_items()
|
void StreamWorld::update_items()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const String *key = scenes.next(nullptr);
|
const String *key = data()->scenes.next(nullptr);
|
||||||
while (key) {
|
while (key) {
|
||||||
if (!scenes[*key].packed_scene.is_valid()) {
|
if (!data()->scenes[*key].packed_scene.is_valid()) {
|
||||||
key = scenes.next(key);
|
key = data()->scenes.next(key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (int)scenes[*key].buildings.size(); i++) {
|
for (i = 0; i < (int)data()->scenes[*key].buildings.size();
|
||||||
if (item_nodes.has(scenes[*key].buildings[i]))
|
i++) {
|
||||||
|
if (item_nodes.has(data()->scenes[*key].buildings[i]))
|
||||||
continue;
|
continue;
|
||||||
Node *psc = scenes[*key].packed_scene->instance();
|
Node *psc =
|
||||||
|
data()->scenes[*key].packed_scene->instance();
|
||||||
Spatial *psp = Object::cast_to<Spatial>(psc);
|
Spatial *psp = Object::cast_to<Spatial>(psc);
|
||||||
item_nodes[scenes[*key].buildings[i]] = psc;
|
item_nodes[data()->scenes[*key].buildings[i]] = psc;
|
||||||
current_scene->add_child(psp);
|
current_scene->add_child(psp);
|
||||||
psp->set_global_transform(
|
psp->set_global_transform(
|
||||||
buildings[scenes[*key].buildings[i]].xform);
|
data()->buildings[data()->scenes[*key]
|
||||||
|
.buildings[i]]
|
||||||
|
.xform);
|
||||||
}
|
}
|
||||||
key = scenes.next(key);
|
key = data()->scenes.next(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamWorld::filter_generated_stuff()
|
|
||||||
{
|
|
||||||
ConfigFile config;
|
|
||||||
Error result = config.load("res://config/stream.conf");
|
|
||||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
|
||||||
Array gen_prefixes = config.get_value("lines", "gen_prefixes");
|
|
||||||
int i, j;
|
|
||||||
for (i = 0; i < (int)buildings.size(); i++) {
|
|
||||||
for (j = 0; j < (int)gen_prefixes.size(); j++) {
|
|
||||||
String prefix = gen_prefixes[j];
|
|
||||||
if (buildings[i].id.begins_with(prefix)) {
|
|
||||||
buildings[i].generated = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StreamWorld::remove_generated_stuff()
|
|
||||||
{
|
|
||||||
std::vector<int> erased_indices;
|
|
||||||
erased_indices.reserve(buildings.size());
|
|
||||||
int i, j;
|
|
||||||
for (i = 0; i < (int)buildings.size(); i++) {
|
|
||||||
if (buildings[i].generated)
|
|
||||||
erased_indices.push_back(i);
|
|
||||||
}
|
|
||||||
for (i = erased_indices.size() - 1; i >= 0; i--) {
|
|
||||||
int index = erased_indices[i];
|
|
||||||
unload_building(index);
|
|
||||||
buildings.erase(buildings.begin() + index);
|
|
||||||
for (j = index; j < (int)buildings.size(); j++)
|
|
||||||
item_nodes[j] = item_nodes[j + 1];
|
|
||||||
item_nodes.erase(buildings.size());
|
|
||||||
}
|
|
||||||
update_items();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StreamWorld::remove_building(int index)
|
void StreamWorld::remove_building(int index)
|
||||||
{
|
{
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
int i;
|
int i;
|
||||||
unload_building(index);
|
unload_building(index);
|
||||||
buildings.erase(buildings.begin() + index);
|
data()->buildings.erase(data()->buildings.begin() + index);
|
||||||
for (i = index; i < (int)buildings.size(); i++) {
|
for (i = index; i < (int)data()->buildings.size(); i++) {
|
||||||
item_nodes[i] = item_nodes[i + 1];
|
item_nodes[i] = item_nodes[i + 1];
|
||||||
}
|
}
|
||||||
item_nodes.erase(buildings.size());
|
item_nodes.erase(data()->buildings.size());
|
||||||
update_items();
|
update_items();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,14 +263,14 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
Transform ret;
|
Transform ret;
|
||||||
String rkey;
|
String rkey;
|
||||||
int id = -1;
|
int id = -1;
|
||||||
for (i = 0; i < (int)buildings.size(); i++) {
|
for (i = 0; i < (int)data()->buildings.size(); i++) {
|
||||||
Vector3 o = xform.origin;
|
Vector3 o = xform.origin;
|
||||||
Vector3 m = buildings[i].xform.origin;
|
Vector3 m = data()->buildings[i].xform.origin;
|
||||||
float mdst = o.distance_squared_to(m);
|
float mdst = o.distance_squared_to(m);
|
||||||
if (dst > mdst) {
|
if (dst > mdst) {
|
||||||
ret = buildings[i].xform;
|
ret = data()->buildings[i].xform;
|
||||||
dst = mdst;
|
dst = mdst;
|
||||||
rkey = buildings[i].key;
|
rkey = data()->buildings[i].key;
|
||||||
id = i;
|
id = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -463,7 +280,7 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
ret_data[1] = dst;
|
ret_data[1] = dst;
|
||||||
ret_data[2] = rkey;
|
ret_data[2] = rkey;
|
||||||
ret_data[3] = id;
|
ret_data[3] = id;
|
||||||
ret_data[4] = buildings[id].id;
|
ret_data[4] = data()->buildings[id].id;
|
||||||
emit_signal("command_result", command, ret_data);
|
emit_signal("command_result", command, ret_data);
|
||||||
} else if (command == "get_building_id_for_key") {
|
} else if (command == "get_building_id_for_key") {
|
||||||
if (args.size() == 0) {
|
if (args.size() == 0) {
|
||||||
@@ -474,8 +291,8 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
Array ret_data;
|
Array ret_data;
|
||||||
ret_data.resize(1);
|
ret_data.resize(1);
|
||||||
int id = -1, i;
|
int id = -1, i;
|
||||||
for (i = 0; i < (int)buildings.size(); i++)
|
for (i = 0; i < (int)data()->buildings.size(); i++)
|
||||||
if (buildings[i].key == key) {
|
if (data()->buildings[i].key == key) {
|
||||||
id = i;
|
id = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -487,25 +304,26 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int id = args[0];
|
int id = args[0];
|
||||||
if (id < 0 || id >= (int)buildings.size())
|
if (id < 0 || id >= (int)data()->buildings.size())
|
||||||
return;
|
return;
|
||||||
String key = buildings[id].key;
|
String key = data()->buildings[id].key;
|
||||||
buildings[id].xform == args[1];
|
data()->buildings[id].xform == args[1];
|
||||||
if (item_nodes.has(id)) {
|
if (item_nodes.has(id)) {
|
||||||
Spatial *bnode =
|
Spatial *bnode =
|
||||||
Object::cast_to<Spatial>(item_nodes[id]);
|
Object::cast_to<Spatial>(item_nodes[id]);
|
||||||
bnode->set_global_transform(args[1]);
|
bnode->set_global_transform(args[1]);
|
||||||
}
|
}
|
||||||
VariantWriter::write_to_string(buildings[id].xform, key);
|
VariantWriter::write_to_string(data()->buildings[id].xform,
|
||||||
buildings[id].key = key;
|
key);
|
||||||
|
data()->buildings[id].key = key;
|
||||||
} else if (command == "checkpoint")
|
} else if (command == "checkpoint")
|
||||||
checkpoint();
|
data()->checkpoint();
|
||||||
else if (command == "undo")
|
else if (command == "undo")
|
||||||
undo();
|
data()->undo();
|
||||||
else if (command == "buildings_save") {
|
else if (command == "buildings_save") {
|
||||||
String buildings_path =
|
String buildings_path =
|
||||||
config.get_value("buildings", "buildings_path");
|
config.get_value("buildings", "buildings_path");
|
||||||
save_buildings_json(buildings_path);
|
data()->save_buildings_json(buildings_path);
|
||||||
} else if (command == "get_building_types") {
|
} else if (command == "get_building_types") {
|
||||||
Dictionary buildings_data =
|
Dictionary buildings_data =
|
||||||
config.get_value("buildings", "building_data");
|
config.get_value("buildings", "building_data");
|
||||||
@@ -521,13 +339,13 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
String new_type = args[1];
|
String new_type = args[1];
|
||||||
Dictionary buildings_data =
|
Dictionary buildings_data =
|
||||||
config.get_value("buildings", "building_data");
|
config.get_value("buildings", "building_data");
|
||||||
if (!building_data.has(new_type)) {
|
if (!data()->building_data.has(new_type)) {
|
||||||
print_error("unknown building type: " + new_type);
|
print_error("unknown building type: " + new_type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String old_type = buildings[id].id;
|
String old_type = data()->buildings[id].id;
|
||||||
unload_building(id);
|
unload_building(id);
|
||||||
buildings[id].id = new_type;
|
data()->buildings[id].id = new_type;
|
||||||
load_building(id);
|
load_building(id);
|
||||||
update_items();
|
update_items();
|
||||||
print_line("changed building: " + itos(id) +
|
print_line("changed building: " + itos(id) +
|
||||||
@@ -540,11 +358,11 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
}
|
}
|
||||||
const Dictionary &building_dict = args[0];
|
const Dictionary &building_dict = args[0];
|
||||||
const String &key = args[1];
|
const String &key = args[1];
|
||||||
struct building b;
|
struct BuildingsData::building b;
|
||||||
// TODO: check that key is valid
|
// TODO: check that key is valid
|
||||||
building::from_dict(&b, building_dict, key);
|
BuildingsData::building::from_dict(&b, building_dict, key);
|
||||||
buildings.push_back(b);
|
data()->buildings.push_back(b);
|
||||||
load_building(buildings.size() - 1);
|
load_building(data()->buildings.size() - 1);
|
||||||
// TODO: check it is enmough
|
// TODO: check it is enmough
|
||||||
} else if (command == "remove_building") {
|
} else if (command == "remove_building") {
|
||||||
if (args.size() == 0) {
|
if (args.size() == 0) {
|
||||||
@@ -559,11 +377,11 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::vector<int> erased_indices;
|
std::vector<int> erased_indices;
|
||||||
erased_indices.reserve(buildings.size());
|
erased_indices.reserve(data()->buildings.size());
|
||||||
String prefix = args[0];
|
String prefix = args[0];
|
||||||
int i, j;
|
int i, j;
|
||||||
for (i = 0; i < (int)buildings.size(); i++) {
|
for (i = 0; i < (int)data()->buildings.size(); i++) {
|
||||||
if (buildings[i].id.begins_with(prefix))
|
if (data()->buildings[i].id.begins_with(prefix))
|
||||||
erased_indices.push_back(i);
|
erased_indices.push_back(i);
|
||||||
}
|
}
|
||||||
print_line("delete buildings: " + itos(erased_indices.size()) +
|
print_line("delete buildings: " + itos(erased_indices.size()) +
|
||||||
@@ -571,10 +389,11 @@ void StreamWorld::run_command(const String &command, const Array &args)
|
|||||||
for (i = erased_indices.size() - 1; i >= 0; i--) {
|
for (i = erased_indices.size() - 1; i >= 0; i--) {
|
||||||
int index = erased_indices[i];
|
int index = erased_indices[i];
|
||||||
unload_building(index);
|
unload_building(index);
|
||||||
buildings.erase(buildings.begin() + index);
|
data()->buildings.erase(data()->buildings.begin() +
|
||||||
for (j = index; j < (int)buildings.size(); j++)
|
index);
|
||||||
|
for (j = index; j < (int)data()->buildings.size(); j++)
|
||||||
item_nodes[j] = item_nodes[j + 1];
|
item_nodes[j] = item_nodes[j + 1];
|
||||||
item_nodes.erase(buildings.size());
|
item_nodes.erase(data()->buildings.size());
|
||||||
}
|
}
|
||||||
update_items();
|
update_items();
|
||||||
} else if (command == "remove_generated_stuff") {
|
} else if (command == "remove_generated_stuff") {
|
||||||
@@ -619,24 +438,25 @@ void StreamWorld::_notification(int which)
|
|||||||
if (Engine::get_singleton()->is_editor_hint())
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
break;
|
break;
|
||||||
update_view();
|
update_view();
|
||||||
const String *key = scenes.next(nullptr);
|
const String *key = data()->scenes.next(nullptr);
|
||||||
while (key) {
|
while (key) {
|
||||||
if (scenes[*key].packed_scene.is_valid()) {
|
if (data()->scenes[*key].packed_scene.is_valid()) {
|
||||||
key = scenes.next(key);
|
key = data()->scenes.next(key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Error result = scenes[*key].loader->poll();
|
Error result = data()->scenes[*key].loader->poll();
|
||||||
if (result == ERR_FILE_EOF) {
|
if (result == ERR_FILE_EOF) {
|
||||||
Ref<PackedScene> sc =
|
Ref<PackedScene> sc =
|
||||||
scenes[*key].loader->get_resource();
|
data()->scenes[*key]
|
||||||
scenes[*key].packed_scene = sc;
|
.loader->get_resource();
|
||||||
|
data()->scenes[*key].packed_scene = sc;
|
||||||
print_line("Loaded scene: " +
|
print_line("Loaded scene: " +
|
||||||
scenes[*key].path + " OK");
|
data()->scenes[*key].path + " OK");
|
||||||
} else if (result != OK)
|
} else if (result != OK)
|
||||||
print_error("Could not load the resource :( " +
|
print_error("Could not load the resource :( " +
|
||||||
scenes[*key].path + " " +
|
data()->scenes[*key].path + " " +
|
||||||
itos(result));
|
itos(result));
|
||||||
key = scenes.next(key);
|
key = data()->scenes.next(key);
|
||||||
}
|
}
|
||||||
update_items();
|
update_items();
|
||||||
|
|
||||||
@@ -662,7 +482,6 @@ StreamWorld::StreamWorld()
|
|||||||
, viewer(nullptr)
|
, viewer(nullptr)
|
||||||
, terrain(nullptr)
|
, terrain(nullptr)
|
||||||
, current_scene(nullptr)
|
, current_scene(nullptr)
|
||||||
, undo_log_size(64)
|
|
||||||
, world_extent(0)
|
, world_extent(0)
|
||||||
, tile_size(0)
|
, tile_size(0)
|
||||||
, view_distance(0)
|
, view_distance(0)
|
||||||
@@ -670,24 +489,6 @@ StreamWorld::StreamWorld()
|
|||||||
{
|
{
|
||||||
Error result = config.load("res://config/stream.conf");
|
Error result = config.load("res://config/stream.conf");
|
||||||
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
|
||||||
Dictionary buildings_data =
|
|
||||||
config.get_value("buildings", "building_data");
|
|
||||||
List<Variant> keys;
|
|
||||||
buildings_data.get_key_list(&keys);
|
|
||||||
List<Variant>::Element *e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
String key = e->get();
|
|
||||||
building_data[key] = buildings_data[key];
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
e = keys.front();
|
|
||||||
while (e) {
|
|
||||||
String key = e->get();
|
|
||||||
print_line(key + ": " + buildings_data[key]);
|
|
||||||
e = e->next();
|
|
||||||
}
|
|
||||||
String buildings_path = config.get_value("buildings", "buildings_path");
|
|
||||||
read_buildings_json(buildings_path);
|
|
||||||
RoadProcessing::load_data();
|
RoadProcessing::load_data();
|
||||||
world_extent = config.get_value("world", "world_extent");
|
world_extent = config.get_value("world", "world_extent");
|
||||||
tile_size = config.get_value("world", "tile_size");
|
tile_size = config.get_value("world", "tile_size");
|
||||||
@@ -707,26 +508,6 @@ StreamWorld::StreamWorld()
|
|||||||
view_distance = config.get_value("world", "view_distance");
|
view_distance = config.get_value("world", "view_distance");
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
void StreamWorld::checkpoint()
|
|
||||||
{
|
|
||||||
struct checkpoint_data cp;
|
|
||||||
cp.building_data = building_data;
|
|
||||||
cp.buildings = buildings;
|
|
||||||
undo_log.push_back(cp);
|
|
||||||
while ((int)undo_log.size() > undo_log_size)
|
|
||||||
undo_log.erase(undo_log.begin());
|
|
||||||
}
|
|
||||||
void StreamWorld::undo()
|
|
||||||
{
|
|
||||||
struct checkpoint_data cp = *undo_log.end();
|
|
||||||
int id;
|
|
||||||
for (id = 0; id < (int)buildings.size(); id++)
|
|
||||||
unload_building(id);
|
|
||||||
building_data = cp.building_data;
|
|
||||||
buildings = cp.buildings;
|
|
||||||
update_view();
|
|
||||||
update_items();
|
|
||||||
}
|
|
||||||
void StreamWorld::cleanup()
|
void StreamWorld::cleanup()
|
||||||
{
|
{
|
||||||
RoadProcessing::cleanup();
|
RoadProcessing::cleanup();
|
||||||
@@ -735,3 +516,33 @@ StreamWorld::~StreamWorld()
|
|||||||
{
|
{
|
||||||
RoadProcessing::cleanup();
|
RoadProcessing::cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamWorld::remove_generated_stuff()
|
||||||
|
{
|
||||||
|
std::vector<int> erased_indices;
|
||||||
|
erased_indices.reserve(data()->buildings.size());
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; i < (int)data()->buildings.size(); i++) {
|
||||||
|
if (data()->buildings[i].generated)
|
||||||
|
erased_indices.push_back(i);
|
||||||
|
}
|
||||||
|
for (i = erased_indices.size() - 1; i >= 0; i--) {
|
||||||
|
int index = erased_indices[i];
|
||||||
|
unload_building(index);
|
||||||
|
data()->buildings.erase(data()->buildings.begin() + index);
|
||||||
|
for (j = index; j < (int)data()->buildings.size(); j++)
|
||||||
|
item_nodes[j] = item_nodes[j + 1];
|
||||||
|
item_nodes.erase(data()->buildings.size());
|
||||||
|
}
|
||||||
|
update_items();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamWorld::undo()
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
for (id = 0; id < (int)data()->buildings.size(); id++)
|
||||||
|
unload_building(id);
|
||||||
|
data()->undo();
|
||||||
|
update_view();
|
||||||
|
update_items();
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <core/io/config_file.h>
|
#include <core/io/config_file.h>
|
||||||
class VoxelViewer;
|
class VoxelViewer;
|
||||||
class VoxelLodTerrain;
|
class VoxelLodTerrain;
|
||||||
|
class BuildingsData;
|
||||||
class StreamWorld : public Spatial {
|
class StreamWorld : public Spatial {
|
||||||
GDCLASS(StreamWorld, Spatial)
|
GDCLASS(StreamWorld, Spatial)
|
||||||
private:
|
private:
|
||||||
@@ -15,30 +16,6 @@ private:
|
|||||||
VoxelLodTerrain *terrain;
|
VoxelLodTerrain *terrain;
|
||||||
Node *current_scene;
|
Node *current_scene;
|
||||||
ConfigFile config;
|
ConfigFile config;
|
||||||
/* Per-building information */
|
|
||||||
struct building {
|
|
||||||
String id;
|
|
||||||
int pattern_id;
|
|
||||||
Vector<int> residents, workers, guests;
|
|
||||||
Vector<Transform> doors;
|
|
||||||
String key;
|
|
||||||
Transform xform;
|
|
||||||
AABB aabb;
|
|
||||||
int worktime[2];
|
|
||||||
bool generated;
|
|
||||||
static void from_dict(struct building *b,
|
|
||||||
const Dictionary &dict,
|
|
||||||
const String &key);
|
|
||||||
Dictionary to_dict() const;
|
|
||||||
};
|
|
||||||
/* Scene objects data */
|
|
||||||
struct scene_data {
|
|
||||||
Ref<PackedScene> packed_scene;
|
|
||||||
String path;
|
|
||||||
Ref<ResourceInteractiveLoader> loader;
|
|
||||||
std::vector<int> buildings;
|
|
||||||
};
|
|
||||||
HashMap<String, struct scene_data> scenes;
|
|
||||||
HashMap<int, Node *> item_nodes;
|
HashMap<int, Node *> item_nodes;
|
||||||
using tile_key_t = std::tuple<int, int>;
|
using tile_key_t = std::tuple<int, int>;
|
||||||
struct tile_hash : public std::unary_function<key_t, std::size_t> {
|
struct tile_hash : public std::unary_function<key_t, std::size_t> {
|
||||||
@@ -49,19 +26,9 @@ private:
|
|||||||
};
|
};
|
||||||
using tile_map_t = std::unordered_map<const tile_key_t,
|
using tile_map_t = std::unordered_map<const tile_key_t,
|
||||||
std::vector<int>, tile_hash>;
|
std::vector<int>, tile_hash>;
|
||||||
/* Data for each building type */
|
|
||||||
HashMap<String, String> building_data;
|
|
||||||
/* Data for each building in a world */
|
|
||||||
std::vector<struct building> buildings;
|
|
||||||
Vector3 eye;
|
Vector3 eye;
|
||||||
tile_map_t tiles;
|
tile_map_t tiles;
|
||||||
tile_map_t loaded_tiles;
|
tile_map_t loaded_tiles;
|
||||||
struct checkpoint_data {
|
|
||||||
HashMap<String, String> building_data;
|
|
||||||
std::vector<struct building> buildings;
|
|
||||||
};
|
|
||||||
std::vector<struct checkpoint_data> undo_log;
|
|
||||||
int undo_log_size;
|
|
||||||
|
|
||||||
int world_extent;
|
int world_extent;
|
||||||
int tile_size;
|
int tile_size;
|
||||||
@@ -69,8 +36,6 @@ private:
|
|||||||
bool initialized;
|
bool initialized;
|
||||||
int current_x, current_z;
|
int current_x, current_z;
|
||||||
void _notification(int which);
|
void _notification(int which);
|
||||||
void read_buildings_json(const String &buildings_path);
|
|
||||||
void save_buildings_json(const String &buildings_path);
|
|
||||||
void create_tilemap();
|
void create_tilemap();
|
||||||
void update_view();
|
void update_view();
|
||||||
void viewer_dead();
|
void viewer_dead();
|
||||||
@@ -81,12 +46,10 @@ private:
|
|||||||
void unload_building(int id);
|
void unload_building(int id);
|
||||||
void request_item(int type, int item);
|
void request_item(int type, int item);
|
||||||
void update_items();
|
void update_items();
|
||||||
void filter_generated_stuff();
|
|
||||||
void remove_generated_stuff();
|
|
||||||
void remove_building(int index);
|
void remove_building(int index);
|
||||||
void checkpoint();
|
void remove_generated_stuff();
|
||||||
void undo();
|
|
||||||
void place_zebras();
|
void place_zebras();
|
||||||
|
void undo();
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user