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
|
#include "critter-script.hpp"
//#include "raycast.hpp"
#include "point.hpp"
#include "critter.hpp"
#include "search-result.hpp"
#include "search-astar.hpp"
#include "entity/name-of.hpp"
#include <cr/Optional.h>
namespace floormat {
using walk_mode = critter_script::walk_mode;
namespace {
bool walk_line(point dest, const std::shared_ptr<critter>& c, size_t& i, const Ns& dt)
{
auto res = c->move_toward(i, dt, dest);
return res.blocked || c->position() == dest;
}
struct walk_script final : critter_script
{
struct line_tag_t {};
struct path_tag_t {};
StringView name() const override;
const void* id() const override;
void on_init(const std::shared_ptr<critter>& c) override;
void on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt) override;
void on_destroy(const std::shared_ptr<critter>& c, script_destroy_reason reason) override;
void delete_self() noexcept override;
walk_script(point dest, line_tag_t);
//walk_script(point dest, path_search_result path, path_tag_t);
private:
point dest;
Optional<path_search_result> path;
walk_mode mode = walk_mode::none;
};
walk_script::walk_script(point dest, line_tag_t) :
dest{dest}, mode{walk_mode::line}
{
}
void walk_script::on_init(const std::shared_ptr<critter>& c)
{
c->movement.AUTO = true;
}
void walk_script::on_update(const std::shared_ptr<critter>& c, size_t& i, const Ns& dt)
{
auto& m = c->movement;
if (m.L | m.R | m.U | m.D)
m.AUTO = false;
if (!m.AUTO)
goto done;
switch (mode)
{
case walk_mode::none:
fm_abort("bad walk_mode 'none'");
case walk_mode::line:
fm_assert(!path);
if (walk_line(dest, c, i, dt))
goto done;
return;
case walk_mode::path:
fm_abort("todo!");
//break;
}
std::unreachable();
fm_assert(false);
done:
Debug{} << " finished walking";
m.AUTO = false;
c->script.do_clear(c);
}
constexpr StringView script_name = name_of<walk_script>;
StringView walk_script::name() const { return "walk"_s; }
const void* walk_script::id() const
{
return &script_name;
}
void walk_script::on_destroy(const std::shared_ptr<critter>& c, script_destroy_reason reason)
{
}
void walk_script::delete_self() noexcept
{
delete this;
}
} // namespace
Pointer<critter_script> critter_script::make_walk_script(point dest, const path_search_result& path, walk_mode mode)
{
switch (mode)
{
case walk_mode::line:
fm_assert(path.empty());
return Pointer<critter_script>(new walk_script{dest, walk_script::line_tag_t{}});
case walk_mode::path:
fm_abort("todo!");
fm_assert(!path.empty());
case walk_mode::none:
break;
}
fm_abort("bad walk_mode %d", (int)mode);
}
} // namespace floormat
|