Support deleting items
This commit is contained in:
parent
259beba780
commit
11f220d8ea
1 changed files with 91 additions and 68 deletions
|
|
@ -240,6 +240,28 @@ namespace gmtk
|
|||
float state = 0.f;
|
||||
};
|
||||
|
||||
geom::point<float, 2> position(ecs::container & world, item const & i)
|
||||
{
|
||||
if (i.target)
|
||||
{
|
||||
auto end = world.get(i.target).get<path_vertex const>().location;
|
||||
return geom::lerp(i.start.center(), end.center(), i.state);
|
||||
}
|
||||
else
|
||||
return i.start.center();
|
||||
}
|
||||
|
||||
float scale(ecs::container & world, item const & i)
|
||||
{
|
||||
if (i.target)
|
||||
{
|
||||
auto end = world.get(i.target).get<path_vertex const>().location;
|
||||
return 3.f * std::pow(3.f, -geom::lerp<float>(i.start.level, end.level, i.state));
|
||||
}
|
||||
else
|
||||
return 3.f * std::pow(3.f, -i.start.level);
|
||||
}
|
||||
|
||||
bool within_grid(location const & l)
|
||||
{
|
||||
int max = std::pow(3, l.level + 1);
|
||||
|
|
@ -453,17 +475,19 @@ namespace gmtk
|
|||
}
|
||||
}
|
||||
|
||||
void draw_item(resource_type type, geom::point<float, 2> const & pos, float scale, gfx::painter & painter)
|
||||
void draw_item(resource_type type, geom::point<float, 2> const & pos, float scale, gfx::painter & painter, bool selected = false)
|
||||
{
|
||||
auto color = color_of(type);
|
||||
|
||||
gfx::color_rgba bcolor = selected ? gfx::red : gfx::black;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case resource_type::coal:
|
||||
case resource_type::stone:
|
||||
case resource_type::iron_ore:
|
||||
case resource_type::copper_ore:
|
||||
painter.circle(pos, 0.075f * scale, {0, 0, 0, 255});
|
||||
painter.circle(pos, 0.075f * scale, bcolor);
|
||||
painter.circle(pos, 0.05f * scale, color);
|
||||
break;
|
||||
case resource_type::stone_brick:
|
||||
|
|
@ -471,7 +495,7 @@ namespace gmtk
|
|||
case resource_type::copper_plate:
|
||||
{
|
||||
auto box = geom::expand(geom::box<float, 2>::singleton(pos), 0.075f * scale);
|
||||
painter.rect(box, {0, 0, 0, 255});
|
||||
painter.rect(box, bcolor);
|
||||
box = geom::shrink(box, 0.025f * scale);
|
||||
painter.rect(box, color);
|
||||
}
|
||||
|
|
@ -484,8 +508,9 @@ namespace gmtk
|
|||
bool first = true;
|
||||
for (float radius : {0.075f * scale, 0.05f * scale})
|
||||
{
|
||||
auto c = first ? bcolor : color;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
painter.triangle(pos, pos + geom::direction(geom::rad(i * 60.f)) * radius, pos + geom::direction(geom::rad((i + 1) * 60.f)) * radius, first ? gfx::black : color);
|
||||
painter.triangle(pos, pos + geom::direction(geom::rad(i * 60.f)) * radius, pos + geom::direction(geom::rad((i + 1) * 60.f)) * radius, c);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -494,7 +519,7 @@ namespace gmtk
|
|||
case resource_type::green_science_pack:
|
||||
{
|
||||
auto box = geom::expand(geom::box<float, 2>::singleton(pos), 0.075f * scale);
|
||||
painter.triangle(box.corner(0, 0), box.corner(1, 0), box.corner(0.5f, 1), {0, 0, 0, 255});
|
||||
painter.triangle(box.corner(0, 0), box.corner(1, 0), box.corner(0.5f, 1), bcolor);
|
||||
box = geom::shrink(box, 0.025f * scale);
|
||||
painter.triangle(box.corner(0, 0), box.corner(1, 0), box.corner(0.5f, 1), color);
|
||||
}
|
||||
|
|
@ -610,22 +635,7 @@ namespace gmtk
|
|||
|
||||
map.world.apply<item const>([&](item const & i)
|
||||
{
|
||||
geom::point<float, 2> pos;
|
||||
float scale;
|
||||
if (i.target)
|
||||
{
|
||||
auto end = map.world.get(i.target).get<path_vertex const>().location;
|
||||
pos = geom::lerp(i.start.center(), end.center(), i.state);
|
||||
scale = std::pow(3.f, -geom::lerp<float>(i.start.level, end.level, i.state));
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = i.start.center();
|
||||
scale = std::pow(3.f, -i.start.level);
|
||||
}
|
||||
scale *= 3.f;
|
||||
|
||||
draw_item(i.type, pos, scale, painter);
|
||||
draw_item(i.type, position(map.world, i), scale(map.world, i), painter);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -685,6 +695,17 @@ namespace gmtk
|
|||
transitioned = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (selected_item_)
|
||||
{
|
||||
auto const & i = map_.world.get(*selected_item_).get<item const>();
|
||||
if (i.target)
|
||||
map_.world.detach<occupied>(i.target);
|
||||
else
|
||||
map_.world.detach<occupied>(map_.world.index<path_index>().get(i.start));
|
||||
map_.world.destroy(*selected_item_);
|
||||
selected_item_ = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.down && event.button == app::mouse_button::right)
|
||||
|
|
@ -1046,6 +1067,7 @@ namespace gmtk
|
|||
view_box_[0] = geom::expand(view_box_[0], (view_box_[1].length() * aspect_ratio - view_box_[0].length()) / 2.f);
|
||||
|
||||
selected_ = std::nullopt;
|
||||
selected_item_ = std::nullopt;
|
||||
|
||||
if (!view_transition_)
|
||||
{
|
||||
|
|
@ -1054,41 +1076,50 @@ namespace gmtk
|
|||
1.f - mouse_[1] * 1.f / screen_size_[1]
|
||||
);
|
||||
|
||||
float s = std::pow(3.f, 1 + view_stack_.back().level);
|
||||
|
||||
m[0] *= s;
|
||||
m[1] *= s;
|
||||
|
||||
auto l = view_stack_.back();
|
||||
|
||||
location p{1 + l.level, {std::floor(m[0]), std::floor(m[1])}};
|
||||
|
||||
geom::interval xrange{3 * l.coords[0], 3 * l.coords[0] + 2};
|
||||
geom::interval yrange{3 * l.coords[1], 3 * l.coords[1] + 2};
|
||||
auto xwrange = geom::expand(xrange, 1);
|
||||
auto ywrange = geom::expand(yrange, 1);
|
||||
|
||||
if (geom::contains(xrange, p.coords[0]) && geom::contains(yrange, p.coords[1]))
|
||||
selected_ = p;
|
||||
else if (view_stack_.size() > 1 && within_grid(p) && ((geom::contains(xwrange, p.coords[0]) && geom::contains(yrange, p.coords[1])) || (geom::contains(xrange, p.coords[0]) && geom::contains(ywrange, p.coords[1]))))
|
||||
map_.world.apply<item const>([&](ecs::handle entity, item const & i)
|
||||
{
|
||||
selected_ = p;
|
||||
while (selected_->level > 0)
|
||||
{
|
||||
if (auto entity = map_.world.index<index>().find(p.up()))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
break;
|
||||
auto box = geom::expand(geom::box<float, 2>::singleton(position(map_.world, i)), scale(map_.world, i) / 9.f);
|
||||
if (geom::contains(box, m))
|
||||
selected_item_ = entity;
|
||||
});
|
||||
|
||||
selected_ = std::nullopt;
|
||||
break;
|
||||
{
|
||||
float s = std::pow(3.f, 1 + view_stack_.back().level);
|
||||
|
||||
// TODO:
|
||||
selected_ = selected_->up();
|
||||
}
|
||||
}
|
||||
else if (!within_grid(p))
|
||||
if (auto entity = map_.world.index<index>().find(p))
|
||||
m[0] *= s;
|
||||
m[1] *= s;
|
||||
|
||||
auto l = view_stack_.back();
|
||||
|
||||
location p{1 + l.level, {std::floor(m[0]), std::floor(m[1])}};
|
||||
|
||||
geom::interval xrange{3 * l.coords[0], 3 * l.coords[0] + 2};
|
||||
geom::interval yrange{3 * l.coords[1], 3 * l.coords[1] + 2};
|
||||
auto xwrange = geom::expand(xrange, 1);
|
||||
auto ywrange = geom::expand(yrange, 1);
|
||||
|
||||
if (geom::contains(xrange, p.coords[0]) && geom::contains(yrange, p.coords[1]))
|
||||
selected_ = p;
|
||||
else if (view_stack_.size() > 1 && within_grid(p) && ((geom::contains(xwrange, p.coords[0]) && geom::contains(yrange, p.coords[1])) || (geom::contains(xrange, p.coords[0]) && geom::contains(ywrange, p.coords[1]))))
|
||||
{
|
||||
selected_ = p;
|
||||
while (selected_->level > 0)
|
||||
{
|
||||
if (auto entity = map_.world.index<index>().find(p.up()))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
break;
|
||||
|
||||
selected_ = std::nullopt;
|
||||
break;
|
||||
|
||||
// TODO:
|
||||
selected_ = selected_->up();
|
||||
}
|
||||
}
|
||||
else if (!within_grid(p))
|
||||
if (auto entity = map_.world.index<index>().find(p))
|
||||
selected_ = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1108,7 +1139,7 @@ namespace gmtk
|
|||
draw(map_, view_level, painter_);
|
||||
|
||||
if (selected_)
|
||||
draw_selection(*selected_, painter_, {255, 0, 255, 255});
|
||||
draw_selection(*selected_, painter_, {255, 0, 0, 255});
|
||||
|
||||
if (belt_start_)
|
||||
draw_selection(*belt_start_, painter_, {255, 255, 0, 255});
|
||||
|
|
@ -1140,6 +1171,12 @@ namespace gmtk
|
|||
painter_.triangle(p10 - d, p11 - n, p11 - d, c1, c0, c1);
|
||||
}
|
||||
|
||||
if (selected_item_)
|
||||
{
|
||||
auto const & i = map_.world.get(*selected_item_).get<item const>();
|
||||
draw_item(i.type, position(map_.world, i), scale(map_.world, i), painter_, true);
|
||||
}
|
||||
|
||||
if (selected_)
|
||||
if (auto entity = map_.world.index<index>().find(*selected_))
|
||||
if (auto t = map_.world.get(*entity).get_if<transformer>())
|
||||
|
|
@ -1202,21 +1239,7 @@ namespace gmtk
|
|||
|
||||
std::optional<location> selected_;
|
||||
std::optional<location> belt_start_;
|
||||
|
||||
geom::point<float, 2> screen_to_grid(geom::point<float, 2> const & p)
|
||||
{
|
||||
auto result = view_box_.corner(
|
||||
p[0] / screen_size_[0],
|
||||
1.f - p[1] / screen_size_[1]
|
||||
);
|
||||
|
||||
float s = std::pow(3.f, 1 + view_stack_.back().level);
|
||||
|
||||
result[0] *= s;
|
||||
result[1] *= s;
|
||||
|
||||
return result;
|
||||
}
|
||||
std::optional<ecs::handle> selected_item_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue