Multiple levels support

This commit is contained in:
2024-10-08 04:31:36 +03:00
parent f62dbbf505
commit 69b62c8c97
3 changed files with 1767 additions and 100 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,9 @@ size = Vector3( 4, 8, 4 )
[sub_resource type="SpatialMaterial" id=4]
flags_transparent = true
albedo_color = Color( 1, 1, 1, 0.654902 )
flags_unshaded = true
flags_do_not_receive_shadows = true
albedo_color = Color( 1, 1, 1, 0.462745 )
[sub_resource type="CubeMesh" id=1]
material = SubResource( 4 )
@@ -35,7 +37,7 @@ margin_bottom = 20.0
margin_right = 35.0
margin_bottom = 20.0
text = "File"
items = [ "Save", null, 0, false, false, 100, 0, null, "", false ]
items = [ "Save", null, 0, false, false, 100, 0, null, "", false, "Build Mesh Library", null, 0, false, false, 101, 0, null, "", false ]
switch_on_hover = true
[node name="ElementMenu" type="MenuButton" parent="menu_panel"]
@@ -377,22 +379,20 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 4, -2 )
mesh = SubResource( 3 )
skeleton = NodePath("../..")
[node name="RemoteTransform" type="RemoteTransform" parent="."]
remote_path = NodePath("../bg_floor")
update_rotation = false
update_scale = false
[node name="bg_floor_base" type="Spatial" parent="."]
unique_name_in_owner = true
[node name="bg_floor_base" type="MeshInstance" parent="RemoteTransform"]
[node name="bg_floor_mi" type="MeshInstance" parent="bg_floor_base"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -0.5, -2 )
mesh = SubResource( 1 )
skeleton = NodePath("../..")
[node name="Area" type="Area" parent="RemoteTransform/bg_floor_base"]
[node name="Area" type="Area" parent="bg_floor_base/bg_floor_mi"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0 )
collision_layer = 49152
collision_mask = 49152
monitoring = false
[node name="CollisionShape" type="CollisionShape" parent="RemoteTransform/bg_floor_base/Area"]
[node name="CollisionShape" type="CollisionShape" parent="bg_floor_base/bg_floor_mi/Area"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0 )
shape = SubResource( 5 )

View File

@@ -101,7 +101,8 @@ public:
int rotation;
};
struct grid_layouts {};
struct grid_layout {
struct grid_layout {};
struct grid_layout_base {
int floor_count;
};
struct grid_layout_exterior {};
@@ -159,23 +160,21 @@ public:
flecs::entity layout =
ecs.entity(key.ascii().ptr()).child_of(top);
// one floor by default
layout.set<grid_layout>({ 0 });
layout.add<struct grid_layout>();
flecs::entity extr = ecs.entity("exterior").child_of(layout);
extr.add<grid_layout_exterior>();
flecs::entity intr = ecs.entity("interior").child_of(layout);
intr.add<grid_layout_interior>();
intr.set<grid_layout_base>({ 0 });
extr.set<grid_layout_base>({ 0 });
}
void create_new_exterior_floor(const String &key)
{
int i;
flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid());
flecs::entity layout = top.lookup(key.ascii().ptr());
assert(layout.is_valid());
struct grid_layout *l = layout.get_mut<grid_layout>();
int floor = l->floor_count;
flecs::entity ext = layout.lookup("exterior");
flecs::entity ext = get_base(key, true);
assert(ext.is_valid());
struct grid_layout_base *l = ext.get_mut<grid_layout_base>();
int floor = l->floor_count;
flecs::entity fl =
ecs.entity(("floor_" + itos(floor)).ascii().ptr())
.child_of(ext);
@@ -192,14 +191,10 @@ public:
void create_new_interior_floor(const String &key)
{
int i;
flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid());
flecs::entity layout = top.lookup(key.ascii().ptr());
assert(layout.is_valid());
struct grid_layout *l = layout.get_mut<grid_layout>();
int floor = l->floor_count;
flecs::entity intr = layout.lookup("interior");
flecs::entity intr = get_base(key, false);
assert(intr.is_valid());
struct grid_layout_base *l = intr.get_mut<grid_layout_base>();
int floor = l->floor_count;
flecs::entity fl =
ecs.entity(("floor_" + itos(floor)).ascii().ptr())
.child_of(intr);
@@ -217,29 +212,63 @@ public:
{
return grid_size;
}
inline flecs::entity get_grid_entity(const String &key, bool exterior,
int fl, int i) const
flecs::entity get_base(const String &key, bool exterior) const
{
flecs::entity top = ecs.lookup("grid_layouts");
assert(top.is_valid());
flecs::entity layout = top.lookup(key.ascii().ptr());
assert(layout.is_valid());
struct grid_layout *l = layout.get_mut<grid_layout>();
int floor_count = l->floor_count;
assert(fl >= 0 && fl < floor_count);
flecs::entity base;
if (exterior)
base = layout.lookup("exterior");
else
base = layout.lookup("interior");
return base;
}
flecs::entity get_floor(const String &key, bool exterior, int fl) const
{
flecs::entity base = get_base(key, exterior);
assert(base.is_valid());
String floor_key = "floor_" + itos(fl);
flecs::entity floor_e = base.lookup(floor_key.ascii().ptr());
return floor_e;
}
bool has_floor(const String &key, bool exterior, int fl) const
{
flecs::entity floor_e = get_floor(key, exterior, fl);
if (!floor_e.is_valid())
return false;
flecs::entity item_e = floor_e.lookup("item_0");
return item_e.is_valid();
}
void ensure_floor(const String &key, bool exterior, int fl)
{
int i;
if (has_floor(key, exterior, fl))
return;
flecs::entity base = get_base(key, exterior);
flecs::entity floor_e =
ecs.entity(("floor_" + itos(fl)).ascii().ptr())
.child_of(base);
assert(floor_e.is_valid());
for (i = 0; i < grid_size * grid_size; i++) {
flecs::entity item =
ecs.entity(("item_" + itos(i)).ascii().ptr())
.child_of(floor_e);
item.set<grid_floor_item>({ i, "empty", 0 });
}
assert(has_floor(key, exterior, fl));
print_line("ensured floor: " + itos(fl));
}
inline flecs::entity get_grid_entity(const String &key, bool exterior,
int fl, int i) const
{
flecs::entity base = get_floor(key, exterior, fl);
assert(base.is_valid());
String item_key = "item_" + itos(i);
flecs::entity item_data = base.lookup(
(floor_key + "::" + item_key).ascii().ptr());
flecs::entity item_data = base.lookup(item_key.ascii().ptr());
if (!item_data.is_valid())
print_error("lookup failed: " + floor_key +
"::" + item_key);
print_error("lookup failed: " + item_key);
assert(item_data.is_valid());
return item_data;
}
@@ -272,6 +301,7 @@ public:
}
Spatial *get_grid_node(const String &key, bool exterior, int fl, int i)
{
assert(has_floor(key, exterior, fl));
flecs::entity item_data = get_grid_entity(key, exterior, fl, i);
if (!item_data.has<struct grid_floor_item_node>()) {
Spatial *sp = memnew(Spatial);
@@ -284,7 +314,7 @@ public:
sp->set_transform(Transform(
Basis().rotated(Vector3(0, 1, 0),
Math_PI * rotation / 2.0f),
Vector3((x - 4) * 4, 0, (z - 4) * 4) -
Vector3((x - 4) * 4, 1 + 5 * fl, (z - 4) * 4) -
get_as_node<Spatial>("%bg_floor")
->get_transform()
.origin));
@@ -295,14 +325,8 @@ public:
const Vector3 &position)
{
int i;
String full_key = "grid_layouts::" + key;
if (exterior)
full_key += "::exterior";
else
full_key += "::interior";
String floor_key = "floor_" + itos(fl);
full_key += "::" + floor_key;
flecs::entity floor_e = ecs.lookup(full_key.ascii().ptr());
assert(has_floor(key, exterior, fl));
flecs::entity floor_e = get_floor(key, exterior, fl);
assert(floor_e.is_valid());
int selected = -1;
float dst = Math_INF;
@@ -416,13 +440,15 @@ public:
flecs::entity layout =
ecs.entity(layout_name.ascii().ptr())
.child_of(top);
layout.set<grid_layout>({ 0 });
layout.add<grid_layout>();
flecs::entity extr =
ecs.entity("exterior").child_of(layout);
extr.add<grid_layout_exterior>();
extr.set<grid_layout_base>({ 0 });
flecs::entity intr =
ecs.entity("interior").child_of(layout);
intr.add<grid_layout_interior>();
intr.set<grid_layout_base>({ 0 });
Dictionary store_layout = store[e->get()];
Dictionary store_interior = store_layout["interior"];
Dictionary store_exterior = store_layout["exterior"];
@@ -461,8 +487,8 @@ public:
{ index, element,
rotation });
}
struct grid_layout *l = layout.get_mut<
struct grid_layout>();
struct grid_layout_base *l = intr.get_mut<
struct grid_layout_base>();
l->floor_count++;
}
}
@@ -496,8 +522,8 @@ public:
{ index, element,
rotation });
}
struct grid_layout *l = layout.get_mut<
struct grid_layout>();
struct grid_layout_base *l = extr.get_mut<
struct grid_layout_base>();
l->floor_count++;
}
}
@@ -698,20 +724,6 @@ public:
e = e->next();
}
unserialize_layouts(conf_grid_layouts);
#if 0
if (conf_exterior_grid.has("default")) {
Array default_grid = conf_exterior_grid["default"];
if (default_grid.size() == grid_size * grid_size) {
grid.fill({ "empty, 0" });
for (i = 0; i < grid_size * grid_size; i++) {
Dictionary item = default_grid[i];
grid.write[i].element = item["element"];
grid.write[i].rotation =
item["rotation"];
}
}
}
#endif
}
};
ElementData *ElementData::singleton = nullptr;
@@ -720,17 +732,29 @@ class LayoutEditor : public Object {
GDCLASS(LayoutEditor, Object)
BuildingLayoutEditor *editor;
String grid_elements;
String level_value;
int current_cell;
String current_layout;
bool is_exterior;
int current_floor;
public:
LayoutEditor(BuildingLayoutEditor *editor)
: Object()
, editor(editor)
, grid_elements("%grid_elements")
, level_value("%level_value")
, current_cell(-1)
, current_layout("default")
, is_exterior(true)
, current_floor(0)
{
get_as_node<OptionButton>(grid_elements)
->connect("item_selected", this, "select_grid_element");
SpinBox *sb = get_as_node<SpinBox>(level_value);
sb->connect("value_changed", this, "set_current_floor");
sb->set_min(-6);
sb->set_max(6);
}
virtual ~LayoutEditor()
{
@@ -749,28 +773,35 @@ public:
->get_child(i)
->queue_delete();
}
List<String> layout_keys;
int grid_size =
ElementData::get_singleton()->get_grid_size();
assert(grid_size > 0);
const String layout_key = "default";
bool exterior = true;
int floor = 0;
int fl;
for (fl = -7; fl < 7; fl++) {
if (!ElementData::get_singleton()->has_floor(
current_layout, is_exterior, fl))
continue;
for (i = 0; i < grid_size * grid_size; i++) {
Spatial *node =
ElementData::get_singleton()
->get_grid_node(layout_key,
exterior, floor,
->get_grid_node(
current_layout,
is_exterior, fl,
i);
String element =
ElementData::get_singleton()
->get_grid_element(layout_key,
exterior,
floor, i);
editor->visualize_element_at(element, node);
->get_grid_element(
current_layout,
is_exterior, fl,
i);
editor->visualize_element_at(element,
node);
print_line("element: " + element);
}
}
}
editor->get_viewport()->get_camera()->set_global_translation(
Vector3(-14, 23, 32));
List<String> element_keys;
@@ -817,27 +848,27 @@ public:
Vector3 proj = result.position;
Transform xf(
Basis(),
Vector3(Math::stepify(proj.x, 4.0f), 0,
Vector3(Math::stepify(proj.x, 4.0f),
0 + current_floor * 5,
Math::stepify(proj.z, 4.0f)));
get_as_node<Spatial>("%refcube")
->set_global_transform(xf);
String layout_key = "default";
bool exterior = true;
int floor = 0;
int selected =
ElementData::get_singleton()
->get_closest_node_on_floor(
layout_key, exterior,
floor, xf.origin);
current_layout,
is_exterior,
current_floor,
xf.origin);
if (selected >= 0) {
current_cell = selected;
get_as_node<Spatial>("%refcube")
->set_global_transform(
ElementData::get_singleton()
->get_grid_node(
layout_key,
exterior,
floor,
current_layout,
is_exterior,
current_floor,
current_cell)
->get_global_transform());
print_line(
@@ -845,9 +876,9 @@ public:
"pos: " +
(ElementData::get_singleton()
->get_grid_node(
layout_key,
exterior,
floor,
current_layout,
is_exterior,
current_floor,
current_cell)
->get_global_transform()
.origin
@@ -855,8 +886,9 @@ public:
String element =
ElementData::get_singleton()
->get_grid_element(
layout_key,
exterior, floor,
current_layout,
is_exterior,
current_floor,
current_cell);
select_control_item<OptionButton>(
"%grid_elements", element);
@@ -864,28 +896,38 @@ public:
}
}
}
void set_current_floor(float value)
{
current_floor = (int)value;
Transform base = get_as_node<Spatial>("%bg_floor_base")
->get_global_transform();
base.origin.y = current_floor * 5.0f;
get_as_node<Spatial>("%bg_floor_base")
->set_global_transform(base);
ElementData::get_singleton()->ensure_floor(
current_layout, is_exterior, current_floor);
}
void select_grid_element(int index)
{
String layout_key = "default";
bool exterior = true;
int floor = 0;
print_line("selected: " + itos(current_cell) + " " +
itos(index));
const String &element =
get_as_node<OptionButton>("%grid_elements")
->get_item_text(index);
ElementData::get_singleton()->set_grid_element(
layout_key, exterior, floor, current_cell, element);
current_layout, is_exterior, current_floor,
current_cell, element);
editor->visualize_element_at(
element,
ElementData::get_singleton()->get_grid_node(
layout_key, exterior, floor, current_cell));
element, ElementData::get_singleton()->get_grid_node(
current_layout, is_exterior,
current_floor, current_cell));
}
static void _bind_methods()
{
ClassDB::bind_method(D_METHOD("select_grid_element", "index"),
&LayoutEditor::select_grid_element);
ClassDB::bind_method(D_METHOD("set_current_floor", "value"),
&LayoutEditor::set_current_floor);
}
};