summaryrefslogtreecommitdiffhomepage
path: root/src/hole.cpp
blob: 1bb8bb9943cfd7f79ee74956aa93248a92d7628b (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
#include "hole.hpp"
#include "chunk.hpp"
#include "loader/loader.hpp"
#include "loader/vobj-cell.hpp"
#include "shaders/shader.hpp"
#include "tile-constants.hpp"
#include "world.hpp"
#include "compat/non-const.hpp"
#include "compat/borrowed-ptr.inl"

namespace floormat {

template class bptr<hole>;
template class bptr<const hole>;

namespace {

void mark_chunk_modifiedʹ(chunk& c)
{
    c.mark_passability_modified();
    //c.mark_ground_modified(); // todo!
    //c.mark_walls_modified();  // todo!
}

} // namespace

hole_proto::~hole_proto() noexcept = default;
hole_proto::hole_proto(const hole_proto&) = default;
hole_proto& hole_proto::operator=(const hole_proto&) = default;
hole_proto::hole_proto(hole_proto&&) noexcept = default;
hole_proto& hole_proto::operator=(hole_proto&&) noexcept = default;

bool hole_proto::flags::operator==(const struct flags&) const = default;

bool hole_proto::operator==(const object_proto&) const
{
    if (type !=.type)
        return false;

    if (!object_proto::operator==())
        return false;

    const auto& o = static_cast<const hole_proto&>();
    return height == o.height && z_offset == o.z_offset && flags == o.flags;
}

hole_proto::hole_proto()
{
    atlas = loader.vobj("hole"_s).atlas;
    pass = pass_mode::pass;
    type = object_type::hole;
}

hole::hole(object_id id, floormat::chunk& c, const hole_proto& proto):
    object{id, c, proto}, height{proto.height}, flags{proto.flags}
{
}

hole::~hole() noexcept
{
    if (c->is_teardown()) [[unlikely]]
        return;
}

void hole::update(const bptr<object>&, size_t&, const Ns&) {}

hole::operator hole_proto() const
{
    hole_proto ret;
    static_cast<object_proto&>(ret) = object_proto(*this);
    ret.height = height;
    ret.flags = flags;
    return ret;
}

void hole::maybe_mark_neighbor_chunks_modified()
{
    for (auto* const: c->world().neighbors(c->coord()))
        if ()
            mark_chunk_modifiedʹ(*);
    mark_chunk_modifiedʹ(*c);
}

float hole::depth_offset() const
{
    constexpr auto ret = 4 / tile_shader::depth_tile_size;
    return ret;
}

Vector2 hole::ordinal_offset(Vector2b) const
{
    constexpr auto ret = Vector2(TILE_COUNT, TILE_COUNT) * TILE_SIZE2;
    return ret;
}

void hole::set_height(uint8_t heightʹ)
{
    if (height != heightʹ)
    {
        non_const(height) = heightʹ;
        maybe_mark_neighbor_chunks_modified();
    }
}

void hole::set_z_offset(uint8_t z)
{
    if (z_offset != z)
    {
        non_const(z_offset) = z;
        maybe_mark_neighbor_chunks_modified();
    }
}


void hole::set_enabled(bool on_render, bool on_physics, bool on_both)
{
    non_const(flags).on_render = on_render;

    if (flags.on_physics != on_physics || on_both != flags.enabled)
    {
        non_const(flags).on_physics = on_physics;
        maybe_mark_neighbor_chunks_modified();
    }

    non_const(flags).enabled = on_both;
}

object_type hole::type() const noexcept { return object_type::hole; }
bool hole::is_virtual() const { return true; }
bool hole::is_dynamic() const { return true; }
bool hole::updates_passability() const { return true; }

} // namespace floormat