Zoomer belt fixes
This commit is contained in:
parent
1f1dc2b35f
commit
b0ab5c3d5b
1 changed files with 143 additions and 62 deletions
|
|
@ -60,6 +60,31 @@ namespace gmtk
|
|||
return {{{(coords[0] - extra) * s, (coords[0] + 1.f + extra) * s}, {(coords[1] - extra) * s, (coords[1] + 1.f + extra) * s}}};
|
||||
}
|
||||
|
||||
location left() const
|
||||
{
|
||||
return {level, {coords[0] - 1, coords[1]}};
|
||||
}
|
||||
|
||||
location right() const
|
||||
{
|
||||
return {level, {coords[0] + 1, coords[1]}};
|
||||
}
|
||||
|
||||
location bottom() const
|
||||
{
|
||||
return {level, {coords[0], coords[1] - 1}};
|
||||
}
|
||||
|
||||
location top() const
|
||||
{
|
||||
return {level, {coords[0], coords[1] + 1}};
|
||||
}
|
||||
|
||||
location moved(geom::vector<int, 2> const & delta) const
|
||||
{
|
||||
return {level, coords + delta};
|
||||
}
|
||||
|
||||
location down() const
|
||||
{
|
||||
return {level + 1, {coords[0] * 3 + 1, coords[1] * 3 + 1}};
|
||||
|
|
@ -115,9 +140,22 @@ namespace gmtk
|
|||
|
||||
struct location location;
|
||||
|
||||
boost::container::flat_set<ecs::handle> belts = {};
|
||||
boost::container::flat_set<ecs::handle> belts_to = {};
|
||||
boost::container::flat_set<ecs::handle> belts_from = {};
|
||||
};
|
||||
|
||||
void add_belt(ecs::container & world, ecs::handle from, ecs::handle to)
|
||||
{
|
||||
world.get(from).get<path_vertex>().belts_to.insert(to);
|
||||
world.get(to).get<path_vertex>().belts_from.insert(from);
|
||||
}
|
||||
|
||||
void remove_belt(ecs::container & world, ecs::handle from, ecs::handle to)
|
||||
{
|
||||
world.get(from).get<path_vertex>().belts_to.erase(to);
|
||||
world.get(to).get<path_vertex>().belts_from.erase(from);
|
||||
}
|
||||
|
||||
struct occupied
|
||||
{
|
||||
psemek_ecs_declare_uuid("occupied")
|
||||
|
|
@ -226,6 +264,75 @@ namespace gmtk
|
|||
using index = index_base<vertex, util::make_uuid("vertex_index")>;
|
||||
using path_index = index_base<path_vertex, util::make_uuid("path_vertex_index")>;
|
||||
|
||||
void sink_belt(ecs::container & world, location m)
|
||||
{
|
||||
if (auto entity = world.index<index>().find(m.up()); !entity || !world.get(*entity).contains<zoomer>())
|
||||
return;
|
||||
|
||||
auto & index = world.index<path_index>();
|
||||
|
||||
auto c = m.up().down();
|
||||
|
||||
auto d = m.coords - c.coords;
|
||||
|
||||
auto ce = index.get(c);
|
||||
auto me = index.get(m);
|
||||
|
||||
auto & cv = world.get(ce).get<path_vertex>();
|
||||
|
||||
if (cv.belts_to.contains(me))
|
||||
{
|
||||
auto & mv = world.get(me).get<path_vertex>();
|
||||
auto ne = *mv.belts_to.begin();
|
||||
|
||||
remove_belt(world, ce, me);
|
||||
remove_belt(world, me, ne);
|
||||
|
||||
auto cd = m.down();
|
||||
auto md = cd.moved(d);
|
||||
|
||||
auto cde = index.get(cd);
|
||||
auto mde = index.get(md);
|
||||
|
||||
add_belt(world, cde, mde);
|
||||
add_belt(world, mde, ne);
|
||||
|
||||
sink_belt(world, md);
|
||||
}
|
||||
else if (cv.belts_from.contains(me))
|
||||
{
|
||||
auto & mv = world.get(me).get<path_vertex>();
|
||||
auto ne = *mv.belts_from.begin();
|
||||
|
||||
remove_belt(world, ne, me);
|
||||
remove_belt(world, me, ce);
|
||||
|
||||
auto cd = m.down();
|
||||
auto md = cd.moved(d);
|
||||
|
||||
auto cde = index.get(cd);
|
||||
auto mde = index.get(md);
|
||||
|
||||
add_belt(world, ne, mde);
|
||||
add_belt(world, mde, cde);
|
||||
|
||||
sink_belt(world, md);
|
||||
}
|
||||
}
|
||||
|
||||
void sink(ecs::container & world, location & c, location & m)
|
||||
{
|
||||
if (auto entity = world.index<index>().find(m.up()); !entity || !world.get(*entity).contains<zoomer>())
|
||||
return;
|
||||
|
||||
auto d = m.coords - c.coords;
|
||||
|
||||
c = m.down();
|
||||
m = c.moved(d);
|
||||
|
||||
sink(world, c, m);
|
||||
}
|
||||
|
||||
void generate_next_task(random::generator & rng, map & map)
|
||||
{
|
||||
color type;
|
||||
|
|
@ -307,7 +414,7 @@ namespace gmtk
|
|||
|
||||
map.world.apply<path_vertex const>([&](path_vertex const & vertex)
|
||||
{
|
||||
for (auto b : vertex.belts)
|
||||
for (auto b : vertex.belts_to)
|
||||
{
|
||||
auto q = map.world.get(b).get<path_vertex const>().location;
|
||||
float w0 = 0.3f * std::pow(3.f, 1.f - vertex.location.level);
|
||||
|
|
@ -319,7 +426,7 @@ namespace gmtk
|
|||
|
||||
map.world.apply<path_vertex const>([&](path_vertex const & vertex)
|
||||
{
|
||||
for (auto b : vertex.belts)
|
||||
for (auto b : vertex.belts_to)
|
||||
{
|
||||
auto q = map.world.get(b).get<path_vertex const>().location;
|
||||
|
||||
|
|
@ -381,15 +488,15 @@ namespace gmtk
|
|||
});
|
||||
}
|
||||
|
||||
void draw_selection(location const & l, gfx::painter & painter)
|
||||
void draw_selection(location const & l, gfx::painter & painter, gfx::color_rgba const & color)
|
||||
{
|
||||
auto b = l.bbox();
|
||||
float s = std::pow(3.f, -l.level) * 0.1f;
|
||||
|
||||
painter.line(b.corner(0, 0), b.corner(1, 0), s, {255, 0, 255, 255}, true);
|
||||
painter.line(b.corner(1, 0), b.corner(1, 1), s, {255, 0, 255, 255}, true);
|
||||
painter.line(b.corner(1, 1), b.corner(0, 1), s, {255, 0, 255, 255}, true);
|
||||
painter.line(b.corner(0, 1), b.corner(0, 0), s, {255, 0, 255, 255}, true);
|
||||
painter.line(b.corner(0, 0), b.corner(1, 0), s, color, true);
|
||||
painter.line(b.corner(1, 0), b.corner(1, 1), s, color, true);
|
||||
painter.line(b.corner(1, 1), b.corner(0, 1), s, color, true);
|
||||
painter.line(b.corner(0, 1), b.corner(0, 0), s, color, true);
|
||||
}
|
||||
|
||||
struct application
|
||||
|
|
@ -474,58 +581,31 @@ namespace gmtk
|
|||
auto d = selected_->coords - belt_start_->coords;
|
||||
if (std::abs(d[0]) + std::abs(d[1]) == 1)
|
||||
{
|
||||
bool from_zoom = false;
|
||||
bool to_zoom = false;
|
||||
auto s = belt_start_->down();
|
||||
|
||||
if (auto entity = map_.world.index<index>().find(*belt_start_))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
from_zoom = true;
|
||||
(void)from_zoom;
|
||||
|
||||
if (auto entity = map_.world.index<index>().find(*selected_))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
to_zoom = true;
|
||||
|
||||
auto vx = [&](int i)
|
||||
{
|
||||
auto p = belt_start_->down();
|
||||
|
||||
if (i < 2 && from_zoom)
|
||||
{
|
||||
p.coords += d;
|
||||
p = p.down();
|
||||
}
|
||||
|
||||
if (i >= 2 && to_zoom)
|
||||
{
|
||||
p.coords += d;
|
||||
p = p.down();
|
||||
}
|
||||
|
||||
p.coords += d * i;
|
||||
|
||||
return p;
|
||||
};
|
||||
location belt[4];
|
||||
for (int i = 0; i <= 3; ++i)
|
||||
belt[i] = s.moved(d * i);
|
||||
sink(map_.world, belt[0], belt[1]);
|
||||
sink(map_.world, belt[3], belt[2]);
|
||||
|
||||
auto & index = map_.world.index<path_index>();
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
auto p = vx(i);
|
||||
auto q = vx(i + 1);
|
||||
auto p = belt[i];
|
||||
auto q = belt[i + 1];
|
||||
|
||||
auto s = index.get(p);
|
||||
auto t = index.get(q);
|
||||
|
||||
auto & sv = map_.world.get(s).get<path_vertex>();
|
||||
auto & tv = map_.world.get(t).get<path_vertex>();
|
||||
|
||||
if (sv.belts.contains(t))
|
||||
sv.belts.erase(t);
|
||||
if (sv.belts_to.contains(t))
|
||||
remove_belt(map_.world, s, t);
|
||||
else
|
||||
{
|
||||
if (tv.belts.contains(s))
|
||||
tv.belts.erase(s);
|
||||
sv.belts.insert(t);
|
||||
remove_belt(map_.world, t, s);
|
||||
add_belt(map_.world, s, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -575,6 +655,13 @@ namespace gmtk
|
|||
vertex{*selected_},
|
||||
zoomer{}
|
||||
);
|
||||
|
||||
auto c = selected_->down();
|
||||
|
||||
sink_belt(map_.world, c.left());
|
||||
sink_belt(map_.world, c.right());
|
||||
sink_belt(map_.world, c.bottom());
|
||||
sink_belt(map_.world, c.top());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -648,7 +735,7 @@ namespace gmtk
|
|||
{
|
||||
{
|
||||
auto & v = map_.world.get(map_.world.index<path_index>().get(i.start)).get<path_vertex const>();
|
||||
if (!v.belts.contains(i.target))
|
||||
if (!v.belts_to.contains(i.target))
|
||||
{
|
||||
map_.world.detach<occupied>(i.target);
|
||||
map_.world.destroy(entity);
|
||||
|
|
@ -672,19 +759,10 @@ namespace gmtk
|
|||
map_.world.detach<occupied>(s);
|
||||
|
||||
auto & v = map_.world.get(s).get<path_vertex const>();
|
||||
if (v.belts.empty())
|
||||
if (v.belts_to.empty() && v.belts_from.empty())
|
||||
{
|
||||
bool should_destroy = true;
|
||||
map_.world.apply<path_vertex const>([&](path_vertex const & v){
|
||||
if (v.belts.contains(s))
|
||||
should_destroy = false;
|
||||
});
|
||||
|
||||
if (should_destroy)
|
||||
{
|
||||
map_.world.destroy(entity);
|
||||
return;
|
||||
}
|
||||
map_.world.destroy(entity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -707,7 +785,7 @@ namespace gmtk
|
|||
|
||||
std::vector<ecs::handle> targets;
|
||||
|
||||
for (auto b : map_.world.get(map_.world.index<path_index>().get(i.start)).get<path_vertex>().belts)
|
||||
for (auto b : map_.world.get(map_.world.index<path_index>().get(i.start)).get<path_vertex>().belts_to)
|
||||
if (!map_.world.get(b).contains<occupied>())
|
||||
targets.push_back(b);
|
||||
|
||||
|
|
@ -787,7 +865,10 @@ namespace gmtk
|
|||
draw(map_, view_level, painter_);
|
||||
|
||||
if (selected_)
|
||||
draw_selection(*selected_, painter_);
|
||||
draw_selection(*selected_, painter_, {255, 0, 255, 255});
|
||||
|
||||
if (belt_start_)
|
||||
draw_selection(*belt_start_, painter_, {255, 255, 0, 255});
|
||||
|
||||
painter_.render(geom::orthographic_camera{view_box_}.transform());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue