1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#include "wall-editor.hpp"
#include "compat/array-size.hpp"
#include "src/wall-defs.hpp"
#include "src/wall-atlas.hpp"
#include "src/world.hpp"
#include "loader/loader.hpp"
#include "loader/wall-cell.hpp"
#include <Corrade/Containers/ArrayView.h>
namespace floormat {
using namespace floormat::Wall;
namespace {
struct rot_pair { rotation r; Direction_ d; };
constexpr inline rot_pair rot_map[] = {
{ rotation::N, Direction_::N },
{ rotation::W, Direction_::W },
};
static_assert(array_size(rot_map) == Direction_COUNT);
constexpr rotation dir_to_rot(Direction_ D)
{
for (auto [r, d] : rot_map)
if (D == d)
return r;
fm_abort("invalid rotation '%d'!", (int)D);
}
constexpr Direction_ rot_to_dir(rotation R)
{
for (auto [r, d] : rot_map)
if (r == R)
return d;
fm_abort("invalid rotation '%d'!", (int)R);
}
constexpr rotation next_rot(rotation r)
{
auto dir_0 = (unsigned)rot_to_dir(r);
auto dir_1 = (dir_0 + 1) % Direction_COUNT;
return dir_to_rot((Direction_)dir_1);
}
static_assert(next_rot(rotation::N) == rotation::W);
static_assert(next_rot(rotation::W) == rotation::N);
} // namespace
void wall_editor::load_atlases()
{
fm_assert(_atlases.empty());
for (const auto& wa : loader.wall_atlas_list())
{
if (wa.name != loader.INVALID) [[likely]]
(void)loader.wall_atlas(wa.name);
fm_assert(wa.atlas);
_atlases[wa.name] = wa;
}
fm_assert(!_atlases.empty());
}
wall_editor::wall_editor()
{
load_atlases();
}
StringView wall_editor::name() const { return "wall"_s; }
enum rotation wall_editor::rotation() const { return _r; }
void wall_editor::set_rotation(enum rotation r) { _r = r; }
void wall_editor::toggle_rotation() { _r = next_rot(_r); }
bptr<wall_atlas> wall_editor::get_selected() const { return _selected_atlas; }
void wall_editor::select_atlas(const bptr<wall_atlas>& atlas) { _selected_atlas = atlas; }
void wall_editor::clear_selection() { _selected_atlas = nullptr; }
bool wall_editor::is_atlas_selected(const bptr<wall_atlas>& atlas) const { return _selected_atlas == atlas; }
bool wall_editor::is_anything_selected() const { return _selected_atlas != nullptr; }
void wall_editor::place_tile(world& w, global_coords coords, const bptr<wall_atlas>& atlas)
{
auto [c, t] = w[coords];
switch (_r)
{
case rotation::N: t.wall_north() = { atlas, (variant_t)-1 }; break;
case rotation::W: t.wall_west() = { atlas, (variant_t)-1 }; break;
default: fm_assert(false);
}
//c.mark_walls_modified();
for (int y = -1; y <= 1; y++)
for (int x = -1; x <= 1; x++)
if (auto* ch = w.at(coords + Vector2i(x, y)))
ch->mark_walls_modified();
}
editor_snap_mode wall_editor::check_snap(int mods) const
{
(void)mods;
if (!is_anything_selected())
return editor_snap_mode::none;
if (_r == rotation::N)
return editor_snap_mode::horizontal;
else if (_r == rotation::W)
return editor_snap_mode::vertical;
else
fm_assert(false);
}
} // namespace floormat
|