blob: 7a50566dac7bf794a9d812a9d9b7106d3e71e191 (
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& oʹ) const
{
if (type != oʹ.type)
return false;
if (!object_proto::operator==(oʹ))
return false;
const auto& o = static_cast<const hole_proto&>(oʹ);
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 std::shared_ptr<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ʹ : c->world().neighbors(c->coord()))
if (cʹ)
mark_chunk_modifiedʹ(*cʹ);
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
|