summaryrefslogtreecommitdiffhomepage
path: root/editor/vobj-editor.cpp
blob: 6dc8c9071e6f49732b82bd905618a8c28d7c2ee9 (plain)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "vobj-editor.hpp"
#include "src/world.hpp"
#include "src/light.hpp"
#include "src/hole.hpp"
#include "loader/loader.hpp"
#include "loader/vobj-cell.hpp"
#include "app.hpp"
#include "compat/borrowed-ptr.inl"
#include <Corrade/Containers/StringView.h>

namespace floormat {

StringView vobj_factory::name() const { return info().name; }
StringView vobj_factory::descr() const { return info().descr; }
bptr<anim_atlas> vobj_factory::atlas() const { return info().atlas; }
vobj_factory::vobj_factory() = default;
vobj_factory::~vobj_factory() noexcept = default;

vobj_editor::vobj_editor() = default;
void vobj_editor::select_tile(const vobj_& type) { _selected = &type; }
void vobj_editor::clear_selection() { _selected = nullptr; }

auto vobj_editor::get_selected() const -> const vobj_*
{
    if (_selected)
        return _selected;
    else
        return {};
}

auto vobj_editor::get_type(StringView name) -> const vobj_*
{
    auto it = _types.find(name);
    if (it != _types.cend())
        return &it->second;
    else
    {
        fm_warn_once("invalid vobj type '%s'", name.data());
        return nullptr;
    }
}

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, struct app& a)
{
    if (!x)
    {
        auto [c, t] = w[pos];
        const auto& es = c.objects();
start:  while (auto id = a.get_object_colliding_with_cursor())
        {
            for (auto i = (int)(es.size()-1); i >= 0; i--)
            {
                const auto= es[i];
                if (->id == id &&->is_virtual())
                {->destroy_script_pre(, script_destroy_reason::kill);
                    c.remove_object((unsigned)i);->destroy_script_post();->gone = true;
                    goto start;
                }
            }
            break;
        }
    }
    else
        x->factory->make(w, w.make_id(), pos);
}

#if defined __clang__ || defined __CLION_IDE__
#pragma clang diagnostic ignored "-Wweak-vtables"
#endif

namespace {

struct light_factory final : vobj_factory
{
    object_type type() const override;
    const vobj_cell& info() const override;
    bptr<object> make(world& w, object_id id, global_coords pos) const override;
};

object_type light_factory::type() const { return object_type::light; }

const vobj_cell& light_factory::info() const
{
    constexpr auto NAME = "light"_s;
    static const vobj_cell& ret = loader.vobj(NAME);
    fm_debug_assert(ret.name == NAME);
    fm_debug_assert(ret.atlas != nullptr);
    return ret;
}

bptr<object> light_factory::make(world& w, object_id id, global_coords pos) const
{
    auto ret = w.make_object<light>(id, pos, light_proto{});
    return ret;
}

struct hole_factory final : vobj_factory
{
    object_type type() const override;
    const vobj_cell& info() const override;
    bptr<object> make(world& w, object_id id, global_coords pos) const override;
};

object_type hole_factory::type() const { return object_type::hole; }

const vobj_cell& hole_factory::info() const
{
    constexpr auto NAME = "hole"_s;
    static const vobj_cell& ret = loader.vobj(NAME);
    fm_debug_assert(ret.name == NAME);
    fm_debug_assert(ret.atlas != nullptr);
    return ret;
}

bptr<object> hole_factory::make(world& w, object_id id, global_coords pos) const
{
    auto ret = w.make_object<hole>(id, pos, hole_proto{});
    return ret;
}

} // namespace

auto vobj_editor::make_vobj_type_map() -> std::map<String, vobj_>
{
    constexpr auto add = [](auto& m, Pointer<vobj_factory>&& x) {
        StringView name = x->name(), descr = x->descr();
        m[name] = vobj_editor::vobj_{ name, descr, move(x) };
    };
    std::map<String, vobj_> map;
    add(map, Pointer<light_factory>{InPlace});
    add(map, Pointer<hole_factory>{InPlace});
    return map;
}

} // namespace floormat