From ca6ff463979d5c250ab04e940bead875f11e7352 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 29 Nov 2022 19:35:25 +0100 Subject: scenery wip --- editor/draw.cpp | 11 +++++++++-- editor/editor.cpp | 36 ++++++++++++++++++++++++++++++++++-- editor/editor.hpp | 1 + editor/scenery-editor.cpp | 25 +++++++++++++++++++------ editor/scenery-editor.hpp | 8 ++++++-- editor/update.cpp | 44 ++++++++++++++++++++++++++++---------------- 6 files changed, 97 insertions(+), 28 deletions(-) (limited to 'editor') diff --git a/editor/draw.cpp b/editor/draw.cpp index e0ddc743..dbb34324 100644 --- a/editor/draw.cpp +++ b/editor/draw.cpp @@ -4,6 +4,7 @@ #include "shaders/tile.hpp" #include "main/clickable.hpp" #include "src/anim-atlas.hpp" +#include "draw/anim.hpp" #include namespace floormat { @@ -11,14 +12,14 @@ namespace floormat { void app::draw_cursor() { constexpr float LINE_WIDTH = 2; + auto& shader = M->shader(); + shader.set_tint({1, 0, 0, 1}); if (const auto [pos, b] = cursor.tile; b && !cursor.in_imgui) { const auto draw = [&, pos = pos](auto& mesh, const auto& size) { const auto pt = pos.to_signed(); const Vector3 center{Vector3i(pt[0], pt[1], 0) * iTILE_SIZE}; - auto& shader = M->shader(); - shader.set_tint({1, 0, 0, 1}); mesh.draw(shader, {center, size, LINE_WIDTH}); }; @@ -34,7 +35,13 @@ void app::draw_cursor() draw(_wireframe_quad, TILE_SIZE2); } else if (const auto* ed = _editor.current_scenery_editor(); ed && ed->is_anything_selected()) + { + const auto& sel = ed->get_selected().proto; draw(_wireframe_quad, TILE_SIZE2); + shader.set_tint({1, 1, 1, 0.75f}); + auto [_f, _w, anim_mesh] = M->meshes(); + anim_mesh.draw(shader, *sel.atlas, sel.frame.r, sel.frame.frame, cursor.tile->local()); + } } } diff --git a/editor/editor.cpp b/editor/editor.cpp index 3400f5af..11d26fdd 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -16,6 +16,14 @@ void editor::on_release() _last_pos = NullOpt; } +void editor::clear_selection() +{ + if (auto* ed = current_tile_editor()) + ed->clear_selection(); + else if (auto* ed = current_scenery_editor()) + ed->clear_selection(); +} + auto editor::get_snap_value(snap_mode snap, int mods) const -> snap_mode { @@ -81,6 +89,7 @@ void editor::on_mouse_move(world& world, global_coords& pos, int mods) void editor::on_click_(world& world, global_coords pos, button b) { if (auto* mode = current_tile_editor(); mode != nullptr) + { if (auto opt = mode->get_selected(); opt || b == button::remove) { switch (b) @@ -90,16 +99,39 @@ void editor::on_click_(world& world, global_coords pos, button b) default: break; } } + } + else if (auto* mode = current_scenery_editor()) + { + if (const auto& opt = mode->get_selected(); opt || b == button::remove) + { + switch (b) + { + default: break; + case button::place: + if (const auto& sel = mode->get_selected()) + mode->place_tile(world, pos, sel); + break; + case button::remove: + mode->place_tile(world, pos, {}); + break; + } + } + } on_release(); } void editor::on_click(world& world, global_coords pos, int mods, button b) { - if (auto* mode = current_tile_editor(); mode != nullptr) + if (auto* mode = current_tile_editor()) { _last_pos = { InPlaceInit, pos, pos, mode->check_snap(mods), b }; on_click_(world, pos, b); } + else if (current_scenery_editor()) + { + _last_pos = {}; + on_click_(world, pos, b); + } } editor::editor() = default; @@ -117,7 +149,7 @@ const tile_editor* editor::current_tile_editor() const noexcept case editor_mode::floor: return &_floor; case editor_mode::walls: - return &_wall; // todo + return &_wall; default: return nullptr; } diff --git a/editor/editor.hpp b/editor/editor.hpp index 1bbc3a89..eac544ad 100644 --- a/editor/editor.hpp +++ b/editor/editor.hpp @@ -36,6 +36,7 @@ struct editor final void on_click_(world& world, global_coords pos, button b); void on_mouse_move(world& world, global_coords& pos, int modifiers); void on_release(); + void clear_selection(); editor(); editor(editor&&) noexcept = default; diff --git a/editor/scenery-editor.cpp b/editor/scenery-editor.cpp index a6870180..d8f74f7d 100644 --- a/editor/scenery-editor.cpp +++ b/editor/scenery-editor.cpp @@ -2,12 +2,18 @@ #include "src/anim-atlas.hpp" #include "loader/loader.hpp" #include "compat/assert.hpp" +#include "src/world.hpp" namespace floormat { using rotation_ = rotation; using rotation_t = std::underlying_type_t; +scenery_editor::scenery_::operator bool() const noexcept +{ + return proto; +} + scenery_editor::scenery_editor() noexcept { load_atlases(); @@ -29,19 +35,19 @@ rotation_ scenery_editor::rotation() const void scenery_editor::next_rotation() { - if (auto& proto = _selected.proto; proto.atlas) - proto.frame.r = proto.atlas->next_rotation_from(proto.frame.r); + if (_selected) + set_rotation(_selected.proto.atlas->next_rotation_from(_selected.proto.frame.r)); } void scenery_editor::prev_rotation() { - if (auto& proto = _selected.proto; proto.atlas) - proto.frame.r = proto.atlas->prev_rotation_from(proto.frame.r); + if (_selected) + set_rotation(_selected.proto.atlas->next_rotation_from(_selected.proto.frame.r)); } void scenery_editor::select_tile(const scenery_& s) { - const auto rot = is_anything_selected() && s.proto.atlas->check_rotation(_selected.proto.frame.r) + const auto rot = s.proto.atlas && s.proto.atlas->check_rotation(_selected.proto.frame.r) ? _selected.proto.frame.r : s.proto.frame.r; _selected = s; @@ -53,7 +59,7 @@ void scenery_editor::clear_selection() _selected = {}; } -auto scenery_editor::get_selected() -> const scenery_& +auto scenery_editor::get_selected() const -> const scenery_& { return _selected; } @@ -73,4 +79,11 @@ bool scenery_editor::is_anything_selected() const return _selected.proto.atlas != nullptr; } +void scenery_editor::place_tile(world& w, global_coords pos, const scenery_& s) +{ + auto [c, t] = w[pos]; + t.scenery() = s.proto; + c.mark_scenery_modified(); +} + } // namespace floormat diff --git a/editor/scenery-editor.hpp b/editor/scenery-editor.hpp index eb78bb01..8e47a6b8 100644 --- a/editor/scenery-editor.hpp +++ b/editor/scenery-editor.hpp @@ -1,5 +1,5 @@ #pragma once -#include "src/scenery.hpp" +#include "scenery.hpp" #include #include #include @@ -7,12 +7,15 @@ namespace floormat { struct anim_atlas; +struct global_coords; +struct world; struct scenery_editor final { struct scenery_ final { String name, descr; scenery_proto proto; + operator bool() const noexcept; }; scenery_editor() noexcept; @@ -24,10 +27,11 @@ struct scenery_editor final void select_tile(const scenery_& s); void clear_selection(); - const scenery_& get_selected(); + const scenery_& get_selected() const; bool is_atlas_selected(const std::shared_ptr& atlas) const; bool is_item_selected(const scenery_& s) const; bool is_anything_selected() const; + void place_tile(world& w, global_coords pos, const scenery_& s); auto cbegin() const noexcept { return _atlases.cbegin(); } auto cend() const noexcept { return _atlases.cend(); } diff --git a/editor/update.cpp b/editor/update.cpp index cc68c4b5..18544a02 100644 --- a/editor/update.cpp +++ b/editor/update.cpp @@ -50,23 +50,33 @@ void app::do_mouse_move(int mods) void app::do_mouse_up_down(std::uint8_t button, bool is_down, int mods) { update_cursor_tile(cursor.pixel); - if (!_editor.current_tile_editor()) - { - if (cursor.tile) - if (auto* s = find_clickable_scenery(*cursor.pixel)) - s->item.activate(s->atlas); - } - else if (cursor.tile && !cursor.in_imgui && is_down) + + if (is_down && cursor.tile && !cursor.in_imgui) { - auto& w = M->world(); - auto pos = *cursor.tile; - switch (button) + switch (_editor.mode()) { - case mouse_button_left: - return _editor.on_click(w, pos, mods, editor::button::place); - case mouse_button_middle: - return _editor.on_click(w, pos, mods, editor::button::remove); - default: break; + default: + case editor_mode::none: + if (button == mouse_button_left) + if (auto* s = find_clickable_scenery(*cursor.pixel)) + return (void)s->item.activate(s->atlas); + break; + case editor_mode::floor: + case editor_mode::walls: + case editor_mode::scenery: + auto& w = M->world(); + auto pos = *cursor.tile; + switch (button) + { + case mouse_button_left: + return _editor.on_click(w, pos, mods, editor::button::place); + case mouse_button_middle: + return _editor.on_click(w, pos, mods, editor::button::remove); + case mouse_button_right: + return _editor.clear_selection(); + default: break; + } + break; } } _editor.on_release(); @@ -81,8 +91,10 @@ void app::do_key(key k, int mods) fm_warn("unhandled key: '%zu'", std::size_t(k)); return; case key_rotate_tile: - if (auto* ed = _editor.current_tile_editor(); ed) + if (auto* ed = _editor.current_tile_editor()) ed->toggle_rotation(); + else if (auto* ed = _editor.current_scenery_editor()) + ed->next_rotation(); return; case key_mode_none: return _editor.set_mode(editor_mode::none); -- cgit v1.2.3