summaryrefslogtreecommitdiffhomepage
path: root/src/hole.cpp
blob: ad29c75259d0d465bbae60da05cd591e1cd5861f (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
#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"

namespace floormat {
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