summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-11-22 21:03:49 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-11-22 21:03:49 +0100
commit2141477c69d379b02ca52e0df9171834b37aadd7 (patch)
tree347f865c403fd86e24ae6f1d2d327554d23f1c33
parent4f458fba80cbcbfecf3fa54284e3004852bbc172 (diff)
scenery work
-rw-r--r--editor/app.hpp4
-rw-r--r--editor/draw.cpp16
-rw-r--r--editor/editor.hpp2
-rw-r--r--editor/imgui.cpp1
-rw-r--r--editor/tile-editor.cpp9
-rw-r--r--editor/update.cpp33
-rw-r--r--floormat/main.hpp3
-rw-r--r--loader/atlas.cpp1
-rw-r--r--main/draw.cpp2
-rw-r--r--main/main-impl.hpp4
-rw-r--r--src/scenery.cpp53
-rw-r--r--src/scenery.hpp3
12 files changed, 77 insertions, 54 deletions
diff --git a/editor/app.hpp b/editor/app.hpp
index badca9a9..7a1bf89d 100644
--- a/editor/app.hpp
+++ b/editor/app.hpp
@@ -28,6 +28,7 @@ struct anim_atlas;
struct cursor_state final {
Optional<Vector2i> pixel;
Optional<global_coords> tile;
+
bool in_imgui = false;
};
@@ -60,6 +61,7 @@ private:
int exec();
void update(float dt) override;
+ void update_world(float dt);
void update_cursor_tile(const Optional<Vector2i>& pixel);
void maybe_initialize_chunk(const chunk_coords& pos, chunk& c) override;
void maybe_initialize_chunk_(const chunk_coords& pos, chunk& c);
@@ -85,7 +87,7 @@ private:
void do_camera(float dt, const key_set& cmds, int mods);
void reset_camera_offset();
- clickable_scenery* find_clickable_scenery();
+ clickable_scenery* find_clickable_scenery(Vector2i pixel);
void do_quicksave();
void do_quickload();
diff --git a/editor/draw.cpp b/editor/draw.cpp
index 9915a93e..17be7aeb 100644
--- a/editor/draw.cpp
+++ b/editor/draw.cpp
@@ -35,21 +35,21 @@ void app::draw_cursor()
void app::draw()
{
- draw_cursor();
+ if (_editor.current_tile_editor())
+ draw_cursor();
draw_ui();
render_menu();
}
-clickable_scenery* app::find_clickable_scenery()
+clickable_scenery* app::find_clickable_scenery(Vector2i pixel_)
{
+ clickable_scenery* item = nullptr;
if (cursor.tile)
{
- float depth = -2;
- clickable_scenery* item = nullptr;
+ float depth = -1;
auto array = M->clickable_scenery();
- const auto pixel = Vector2ui(*cursor.pixel);
+ const auto pixel = Vector2ui(pixel_);
for (clickable_scenery& c : array)
- {
if (c.depth > depth && c.dest.contains(pixel))
{
const auto pos = pixel - c.dest.min() + c.src.min();
@@ -62,10 +62,8 @@ clickable_scenery* app::find_clickable_scenery()
item = &c;
}
}
- }
- return item;
}
- return nullptr;
+ return item;
}
} // namespace floormat
diff --git a/editor/editor.hpp b/editor/editor.hpp
index bcbc26d1..e0c4f848 100644
--- a/editor/editor.hpp
+++ b/editor/editor.hpp
@@ -58,7 +58,7 @@ private:
button btn;
};
Optional<drag_pos> _last_pos;
- editor_mode _mode = editor_mode::floor;
+ editor_mode _mode = editor_mode::none;
bool _dirty = false;
};
diff --git a/editor/imgui.cpp b/editor/imgui.cpp
index 7b64c133..afa55485 100644
--- a/editor/imgui.cpp
+++ b/editor/imgui.cpp
@@ -86,7 +86,6 @@ void app::draw_ui()
const float main_menu_height = draw_main_menu();
if (auto* ed = _editor.current_tile_editor(); ed != nullptr)
draw_editor_pane(*ed, main_menu_height);
- draw_cursor();
[[maybe_unused]] auto font = font_saver{ctx.FontSize*dpi};
draw_fps();
draw_tile_under_cursor();
diff --git a/editor/tile-editor.cpp b/editor/tile-editor.cpp
index 9f9b6571..4ae54d86 100644
--- a/editor/tile-editor.cpp
+++ b/editor/tile-editor.cpp
@@ -172,7 +172,9 @@ void tile_editor::place_tile(world& world, global_coords pos, const tile_image_p
void tile_editor::toggle_rotation()
{
- if (_rotation == editor_wall_rotation::W)
+ if (_mode != editor_mode::walls)
+ _rotation = editor_wall_rotation::N;
+ else if (_rotation == editor_wall_rotation::W)
_rotation = editor_wall_rotation::N;
else
_rotation = editor_wall_rotation::W;
@@ -187,7 +189,10 @@ void tile_editor::set_rotation(editor_wall_rotation r)
return;
case editor_wall_rotation::W:
case editor_wall_rotation::N:
- _rotation = r;
+ if (_mode == editor_mode::walls)
+ _rotation = r;
+ else
+ _rotation = editor_wall_rotation::N;
break;
}
}
diff --git a/editor/update.cpp b/editor/update.cpp
index c68c7517..a253c3c4 100644
--- a/editor/update.cpp
+++ b/editor/update.cpp
@@ -1,6 +1,7 @@
#include "app.hpp"
-#include "src/chunk.hpp"
+#include "src/world.hpp"
#include "src/tile-atlas.hpp"
+#include "main/clickable.hpp"
#include "floormat/events.hpp"
#include "floormat/main.hpp"
@@ -46,7 +47,14 @@ void app::do_mouse_move(int mods)
void app::do_mouse_up_down(std::uint8_t button, bool is_down, int mods)
{
- if (cursor.tile && !cursor.in_imgui && is_down)
+ 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)
{
auto& w = M->world();
auto pos = *cursor.tile;
@@ -60,7 +68,6 @@ void app::do_mouse_up_down(std::uint8_t button, bool is_down, int mods)
}
}
_editor.on_release();
- update_cursor_tile(cursor.pixel);
}
void app::do_key(key k, int mods)
@@ -98,19 +105,29 @@ void app::apply_commands(const key_set& keys)
do_key(k, key_modifiers[i]);
}
-using clickable_scenery = clickable<anim_atlas, scenery>;
-
-
+void app::update_world(float dt)
+{
+ auto& world = M->world();
+ auto [minx, maxx, miny, maxy] = M->get_draw_bounds();
+ minx--; miny--; maxx++; maxy++;
+ for (std::int16_t y = miny; y <= maxy; y++)
+ for (std::int16_t x = minx; x <= maxx; x++)
+ for (chunk_coords c{x, y}; auto [x, k, pt] : world[c])
+ if (auto [atlas, scenery] = x.scenery(); atlas != nullptr)
+ scenery.update(dt, *atlas);
+}
void app::update(float dt)
{
+ update_world(dt);
apply_commands(keys);
do_camera(dt, keys, get_key_modifiers());
- if (auto* s = find_clickable_scenery())
+ clear_non_repeated_keys();
+
+ if (!_editor.current_tile_editor() && cursor.tile && find_clickable_scenery(*cursor.pixel))
M->set_cursor(std::uint32_t(Cursor::Hand));
else
M->set_cursor(std::uint32_t(Cursor::Arrow));
- clear_non_repeated_keys();
}
} // namespace floormat
diff --git a/floormat/main.hpp b/floormat/main.hpp
index b4e4d536..a470f12e 100644
--- a/floormat/main.hpp
+++ b/floormat/main.hpp
@@ -19,6 +19,8 @@ template<typename Atlas, typename T> struct clickable;
struct floormat_main
{
+ struct draw_bounds final { std::int16_t minx, maxx, miny, maxy; };
+
floormat_main() noexcept;
virtual ~floormat_main() noexcept;
@@ -45,6 +47,7 @@ struct floormat_main
virtual std::uint32_t cursor() const noexcept = 0;
virtual global_coords pixel_to_tile(Vector2d position) const noexcept = 0;
+ virtual draw_bounds get_draw_bounds() const noexcept = 0;
virtual struct world& world() noexcept = 0;
virtual SDL_Window* window() noexcept = 0;
diff --git a/loader/atlas.cpp b/loader/atlas.cpp
index fdafc39e..ab289647 100644
--- a/loader/atlas.cpp
+++ b/loader/atlas.cpp
@@ -43,7 +43,6 @@ std::shared_ptr<anim_atlas> loader_impl::anim_atlas(StringView name)
fm_assert(anim_info.nframes == 1 || anim_info.fps > 0);
const auto size = tex.pixels().size();
const auto width = size[1], height = size[0];
- using Vector2uz = Math::Vector2<std::size_t>;
fm_assert(Vector2uz{anim_info.pixel_size} == Vector2uz(width, height));
auto atlas = std::make_shared<struct anim_atlas>(path, tex, std::move(anim_info));
diff --git a/main/draw.cpp b/main/draw.cpp
index ba15b365..54f33622 100644
--- a/main/draw.cpp
+++ b/main/draw.cpp
@@ -118,7 +118,7 @@ void main_impl::draw_anim() noexcept
const auto& f = atlas->frame(s.r, s.frame);
constexpr Vector2 pixel88 = tile_shader::project(TILE_MAX_DIM*TILE_SIZE20*.5f);
const auto world_pos = TILE_SIZE20 * Vector3(xy.x, xy.y, 0) + Vector3(g.offset);
- const Vector2ui offset((Vector2(_shader.camera_offset()) + Vector2(sz) - pixel88)*.5f
+ const Vector2ui offset((Vector2(_shader.camera_offset()) + Vector2(sz)*.5f)
+ _shader.project(world_pos) - Vector2(f.ground));
clickable<anim_atlas, scenery> item = {
*atlas, s,
diff --git a/main/main-impl.hpp b/main/main-impl.hpp
index 7adaeaec..dd745bef 100644
--- a/main/main-impl.hpp
+++ b/main/main-impl.hpp
@@ -88,13 +88,11 @@ private:
bool do_sleep = false;
} dt_expected;
- struct draw_bounds final { std::int16_t minx, maxx, miny, maxy; };
-
void recalc_viewport(Vector2i size) noexcept;
void draw_world() noexcept;
void draw_anim() noexcept;
- draw_bounds get_draw_bounds() const noexcept;
+ draw_bounds get_draw_bounds() const noexcept override;
[[nodiscard]] static bool check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept;
char maybe_register_debug_callback(fm_gpu_debug flag);
diff --git a/src/scenery.cpp b/src/scenery.cpp
index cf2c6e98..86561a13 100644
--- a/src/scenery.cpp
+++ b/src/scenery.cpp
@@ -56,6 +56,9 @@ scenery::scenery(float dt, frame_t frame, rotation r, bool passable, scenery_typ
void scenery::update(float dt, const anim_atlas& anim)
{
+ if (!active)
+ return;
+
switch (type)
{
default:
@@ -63,31 +66,31 @@ void scenery::update(float dt, const anim_atlas& anim)
case scenery_type::generic:
break;
case scenery_type::door:
- if (active)
- {
- const auto hz = std::uint8_t(anim.info().fps);
- const auto nframes = (int)anim.info().nframes;
- fm_debug_assert(anim.info().fps > 0 && anim.info().fps <= 0xff);
-
- delta += dt;
- const float frame_time = 1000.f/hz;
- const auto n = int(delta / frame_time);
- delta -= frame_time * n;
- fm_debug_assert(delta >= 0);
- const std::int8_t dir = passable ? 1 : -1;
- const int fr = frame + dir*n;
- active = fr > 0 && fr < nframes-1;
- passable = fr <= 0;
- frame = (frame_t)std::clamp(fr, 0, nframes-1);
- if (!active)
- delta = 0;
- }
+ const auto hz = std::uint8_t(anim.info().fps);
+ const auto nframes = (int)anim.info().nframes;
+ fm_debug_assert(anim.info().fps > 0 && anim.info().fps <= 0xff);
+
+ delta += dt;
+ const float frame_time = 1.f/hz;
+ const auto n = int(delta / frame_time);
+ delta -= frame_time * n;
+ fm_debug_assert(delta >= 0);
+ const std::int8_t dir = closing ? 1 : -1;
+ const int fr = frame + dir*n;
+ active = fr > 0 && fr < nframes-1;
+ passable = fr <= 0;
+ frame = (frame_t)std::clamp(fr, 0, nframes-1);
+ if (!active)
+ delta = 0;
break;
}
}
bool scenery::activate(const anim_atlas& atlas)
{
+ if (active)
+ return false;
+
switch (type)
{
default:
@@ -95,13 +98,11 @@ bool scenery::activate(const anim_atlas& atlas)
case scenery_type::generic:
break;
case scenery_type::door:
- if (!active)
- {
- fm_assert(frame == 0 || frame == atlas.info().nframes-1);
- active = true;
- return true;
- }
- break;
+ fm_assert(frame == 0 || frame == atlas.info().nframes-1);
+ closing = frame == 0;
+ frame += closing ? 1 : -1;
+ active = true;
+ return true;
}
return false;
}
diff --git a/src/scenery.hpp b/src/scenery.hpp
index fadf4da8..68bb084a 100644
--- a/src/scenery.hpp
+++ b/src/scenery.hpp
@@ -34,7 +34,8 @@ struct scenery final
rotation r : 3 = rotation::N;
std::uint8_t passable : 1 = false;
std::uint8_t active : 1 = false;
- scenery_type type : 3 = scenery_type::none;
+ std::uint8_t closing : 1 = true;
+ scenery_type type : 2 = scenery_type::none;
scenery() noexcept;
scenery(none_tag_t) noexcept;