summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--editor/draw.cpp12
-rw-r--r--editor/editor.cpp7
-rw-r--r--editor/events.cpp1
-rw-r--r--editor/imgui.cpp6
-rw-r--r--editor/keys.hpp2
-rw-r--r--editor/update.cpp9
-rw-r--r--editor/vobj-editor.cpp25
-rw-r--r--editor/vobj-editor.hpp3
-rw-r--r--loader/vobj.cpp22
-rw-r--r--src/chunk-scenery.cpp2
-rw-r--r--src/light.cpp4
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; }