diff options
-rw-r--r-- | editor/draw.cpp | 12 | ||||
-rw-r--r-- | editor/editor.cpp | 7 | ||||
-rw-r--r-- | editor/events.cpp | 1 | ||||
-rw-r--r-- | editor/imgui.cpp | 6 | ||||
-rw-r--r-- | editor/keys.hpp | 2 | ||||
-rw-r--r-- | editor/update.cpp | 9 | ||||
-rw-r--r-- | editor/vobj-editor.cpp | 25 | ||||
-rw-r--r-- | editor/vobj-editor.hpp | 3 | ||||
-rw-r--r-- | loader/vobj.cpp | 22 | ||||
-rw-r--r-- | src/chunk-scenery.cpp | 2 | ||||
-rw-r--r-- | src/light.cpp | 4 |
11 files changed, 56 insertions, 37 deletions
diff --git a/editor/draw.cpp b/editor/draw.cpp index b6edf215..9060f865 100644 --- a/editor/draw.cpp +++ b/editor/draw.cpp @@ -59,13 +59,13 @@ void app::draw_cursor() anim_mesh.draw(shader, *sel.atlas, sel.r, sel.frame, Vector3(pos), 1); } } - else if (const auto* ed = _editor.current_vobj_editor()) + else if (const auto* vo = _editor.current_vobj_editor()) { - if (!ed->is_anything_selected()) + if (!vo->is_anything_selected()) shader.set_tint(inactive_color); - if (ed->is_anything_selected()) + if (vo->is_anything_selected()) { - const auto& atlas = ed->get_selected()->factory->atlas(); + const auto& atlas = vo->get_selected()->factory->atlas(); draw(_wireframe_quad, TILE_SIZE2); shader.set_tint({1, 1, 1, 0.75f}); auto [_f, _w, anim_mesh] = M->meshes(); @@ -182,7 +182,7 @@ void app::draw() draw_collision_boxes(); if (_editor.current_tile_editor() || _editor.current_scenery_editor() && _editor.current_scenery_editor()->is_anything_selected() || - _editor.current_vobj_editor()) + _editor.current_vobj_editor() && _editor.current_vobj_editor()->is_anything_selected()) draw_cursor(); draw_ui(); render_menu(); @@ -204,7 +204,7 @@ clickable* app::find_clickable_scenery(const Optional<Vector2i>& pixel) const auto pos_ = *pixel - c.dest.min() + Vector2i(c.src.min()); const auto pos = !c.mirrored ? pos_ : Vector2i(int(c.src.sizeX()) - 1 - pos_[0], pos_[1]); size_t idx = unsigned(pos.y()) * c.stride + unsigned(pos.x()); - fm_assert(idx < c.bitmask.size()); + fm_assert(c.bitmask.isEmpty() || idx < c.bitmask.size()); if (c.bitmask.isEmpty() || c.bitmask[idx]) { depth = c.depth; diff --git a/editor/editor.cpp b/editor/editor.cpp index 3c470bf2..1b0611e1 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -88,6 +88,7 @@ void editor::on_mouse_move(world& world, global_coords& pos, int mods) void editor::on_click_(world& world, global_coords pos, button b) { + // todo make template if (auto* mode = current_tile_editor(); mode != nullptr) { if (auto opt = mode->get_selected(); opt || b == button::remove) @@ -126,10 +127,10 @@ void editor::on_click_(world& world, global_coords pos, button b) default: break; case button::place: if (const auto& sel = mode->get_selected()) - mode->place_tile(world, pos, sel); + mode->place_tile(world, pos, sel, *_app); break; case button::remove: - mode->place_tile(world, pos, {}); + mode->place_tile(world, pos, {}, *_app); break; } } @@ -144,7 +145,7 @@ void editor::on_click(world& world, global_coords pos, int mods, button b) _last_pos = { InPlaceInit, pos, pos, mode->check_snap(mods), b }; on_click_(world, pos, b); } - else if (current_scenery_editor()) + else if (current_scenery_editor() || current_vobj_editor()) { _last_pos = {}; on_click_(world, pos, b); diff --git a/editor/events.cpp b/editor/events.cpp index 3aa4c022..ed263bdc 100644 --- a/editor/events.cpp +++ b/editor/events.cpp @@ -132,6 +132,7 @@ auto app::resolve_keybinding(int k_, int mods_) -> std::tuple<key, int> case SDLK_2: return { key_mode_floor, mods }; case SDLK_3: return { key_mode_walls, mods }; case SDLK_4: return { key_mode_scenery, mods }; + case SDLK_5: return { key_mode_vobj, mods }; case SDLK_c | ALT: return { key_render_collision_boxes, mods }; case SDLK_l | ALT: return { key_render_clickables, mods }; case SDLK_t: return { key_render_all_z_levels, mods }; diff --git a/editor/imgui.cpp b/editor/imgui.cpp index 926ca82b..b465bc3e 100644 --- a/editor/imgui.cpp +++ b/editor/imgui.cpp @@ -54,7 +54,7 @@ float app::draw_main_menu() const auto* ed_sc = _editor.current_scenery_editor(); const auto* ed_w = _editor.current_tile_editor(); bool b_none = mode == m::none, b_floor = mode == m::floor, b_walls = mode == m::walls, - b_scenery = mode == m::scenery, b_collisions = _render_bboxes, + b_scenery = mode == m::scenery, b_vobj = mode == m::vobj, b_collisions = _render_bboxes, b_clickables = _render_clickables, b_all_z_levels = _render_all_z_levels; const bool b_rotate = ed_sc && ed_sc->is_anything_selected() || mode == editor_mode::walls && ed_w; @@ -67,6 +67,8 @@ float app::draw_main_menu() do_key(key_mode_walls); if (ImGui::MenuItem("Scenery", "4", b_scenery)) do_key(key_mode_scenery); + if (ImGui::MenuItem("Virtual objects", "5", b_vobj)) + do_key(key_mode_vobj); ImGui::SeparatorText("Modify"); if (ImGui::MenuItem("Rotate", "R", false, b_rotate)) do_key(key_rotate_tile); @@ -102,7 +104,7 @@ void app::draw_ui() const float main_menu_height = draw_main_menu(); [[maybe_unused]] auto font = font_saver{ctx.FontSize*dpi}; - if (_editor.current_tile_editor() || _editor.current_scenery_editor()) + if (_editor.current_tile_editor() || _editor.current_scenery_editor() || _editor.current_vobj_editor()) draw_editor_pane(main_menu_height); draw_fps(); draw_tile_under_cursor(); diff --git a/editor/keys.hpp b/editor/keys.hpp index 56f4e59e..197cfb9a 100644 --- a/editor/keys.hpp +++ b/editor/keys.hpp @@ -17,7 +17,7 @@ enum key : unsigned { key_left, key_right, key_up, key_down, key_NO_REPEAT, key_rotate_tile, - key_mode_none, key_mode_floor, key_mode_walls, key_mode_scenery, + key_mode_none, key_mode_floor, key_mode_walls, key_mode_scenery, key_mode_vobj, key_render_collision_boxes, key_render_clickables, key_render_all_z_levels, key_GLOBAL, key_new_file, diff --git a/editor/update.cpp b/editor/update.cpp index 5c6d4319..5ab588d1 100644 --- a/editor/update.cpp +++ b/editor/update.cpp @@ -95,6 +95,7 @@ void app::do_mouse_up_down(uint8_t button, bool is_down, int mods) case editor_mode::floor: case editor_mode::walls: case editor_mode::scenery: + case editor_mode::vobj: auto pos = *cursor.tile; switch (button) { @@ -146,10 +147,12 @@ void app::do_set_mode(editor_mode mode) void app::do_escape() { - if (auto* ed = _editor.current_scenery_editor()) - ed->clear_selection(); if (auto* ed = _editor.current_tile_editor()) ed->clear_selection(); + if (auto* sc = _editor.current_scenery_editor()) + sc->clear_selection(); + if (auto* vo = _editor.current_vobj_editor()) + vo->clear_selection(); kill_popups(false); } @@ -172,6 +175,8 @@ void app::do_key(key k, int mods) return do_set_mode(editor_mode::walls); case key_mode_scenery: return do_set_mode(editor_mode::scenery); + case key_mode_vobj: + return do_set_mode(editor_mode::vobj); case key_render_collision_boxes: return void(_render_bboxes = !_render_bboxes); case key_render_clickables: diff --git a/editor/vobj-editor.cpp b/editor/vobj-editor.cpp index 2cec6a5c..d242f68f 100644 --- a/editor/vobj-editor.cpp +++ b/editor/vobj-editor.cpp @@ -3,6 +3,7 @@ #include "loader/loader.hpp" #include "src/world.hpp" #include "src/light.hpp" +#include "app.hpp" #include <array> #include <utility> #include <Corrade/Containers/StringView.h> @@ -39,23 +40,23 @@ auto vobj_editor::get_type(StringView name) -> const vobj_* bool vobj_editor::is_item_selected(const vobj_& x) const { return _selected == &x; } bool vobj_editor::is_anything_selected() const { return _selected != nullptr; } -void vobj_editor::place_tile(world& w, global_coords pos, const vobj_* x) +void vobj_editor::place_tile(world& w, global_coords pos, const vobj_* x, struct app& a) { if (!x) { - // don't regen colliders auto [c, t] = w[pos]; - const auto px = Vector2(pos.local()) * TILE_SIZE2; const auto& es = c.entities(); - for (auto i = es.size()-1; i != (size_t)-1; i--) +start: while (auto id = a.object_at_cursor()) { - const auto& e = *es[i]; - if (!e.is_virtual()) - continue; - auto center = Vector2(e.coord.local())*TILE_SIZE2 + Vector2(e.offset) + Vector2(e.bbox_offset), - min = center - Vector2(e.bbox_size/2), max = min + Vector2(e.bbox_size); - if (px >= min && px <= max) - c.remove_entity(i); + for (auto i = es.size()-1; i != (size_t)-1; i--) + { + if (es[i]->id == id) + { + c.remove_entity(i); + goto start; + } + } + break; } } else @@ -81,7 +82,7 @@ struct light_factory final : vobj_factory std::shared_ptr<entity> make(world& w, object_id id, global_coords pos) const override { - auto ret = w.make_entity<light>(id, {pos.chunk(), pos.local(), 0}, light_proto{}); + auto ret = w.make_entity<light>(id, pos, light_proto{}); return ret; } }; diff --git a/editor/vobj-editor.hpp b/editor/vobj-editor.hpp index 634311f2..e026a498 100644 --- a/editor/vobj-editor.hpp +++ b/editor/vobj-editor.hpp @@ -15,6 +15,7 @@ struct global_coords; struct entity; struct anim_atlas; struct vobj_info; +struct app; #if defined __clang__ || defined __CLION_IDE__ #pragma clang diagnostic push @@ -55,7 +56,7 @@ struct vobj_editor final bool is_item_selected(const vobj_& x) const; bool is_anything_selected() const; - static void place_tile(world& w, global_coords pos, const vobj_* x); + static void place_tile(world& w, global_coords pos, const vobj_* x, app& a); auto cbegin() const noexcept { return _types.cbegin(); } auto cend() const noexcept { return _types.cend(); } diff --git a/loader/vobj.cpp b/loader/vobj.cpp index 9d167368..75351cd4 100644 --- a/loader/vobj.cpp +++ b/loader/vobj.cpp @@ -41,23 +41,27 @@ void nlohmann::adl_serializer<vobj>::from_json(const json& j, vobj& val) namespace floormat::loader_detail { +#if defined __GNUG__ && !defined __clang__ +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + std::shared_ptr<struct anim_atlas> loader_impl::make_vobj_anim_atlas(StringView name, StringView image_filename) { auto tex = texture(VOBJ_PATH, image_filename); anim_def def; def.object_name = name; const auto size = tex.pixels().size(); - const auto width = size[1], height = size[0]; - def.pixel_size = { (unsigned)width, (unsigned)height }; + const auto width = (unsigned)size[1], height = (unsigned)size[0]; + def.pixel_size = { width, height }; def.nframes = 1; def.fps = 0; - anim_group g; - g.name = "n"_s; - anim_frame f; - f.size = def.pixel_size; - g.frames = { f }; - def.groups = { std::move(g) }; - + def.groups = {{ + .name = "n"_s, + .frames = {{ + .ground = Vector2i(def.pixel_size/2), + .size = def.pixel_size + }} + }}; auto atlas = std::make_shared<struct anim_atlas>(name, tex, std::move(def)); return atlas; } diff --git a/src/chunk-scenery.cpp b/src/chunk-scenery.cpp index a2a61907..d12a754b 100644 --- a/src/chunk-scenery.cpp +++ b/src/chunk-scenery.cpp @@ -139,7 +139,7 @@ auto chunk::ensure_scenery_mesh(scenery_scratch_buffers buffers) noexcept -> sce const auto count = fm_begin( size_t ret = 0; for (const auto& e : _entities) - ret += !e->is_dynamic() && !e->is_virtual(); + ret += !e->is_dynamic(); return ret; ); diff --git a/src/light.cpp b/src/light.cpp index e1dd00b9..921b0e4d 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -1,11 +1,14 @@ #include "light.hpp" #include "shaders/shader.hpp" +#include "loader/loader.hpp" +#include "loader/vobj-info.hpp" #include <cmath> namespace floormat { light_proto::light_proto() { + atlas = loader.vobj("light"_s).atlas; pass = pass_mode::pass; type = entity_type::light; } @@ -30,6 +33,7 @@ float light::depth_offset() const } Vector2 light::ordinal_offset(Vector2b) const { return {}; } + entity_type light::type() const noexcept { return entity_type::light; } bool light::update(size_t, float) { return false; } bool light::is_virtual() const { return true; } |