Add start menu
This commit is contained in:
parent
7d64f80c87
commit
6a0087da18
1 changed files with 338 additions and 144 deletions
|
|
@ -373,7 +373,7 @@ namespace gmtk
|
|||
|
||||
struct map
|
||||
{
|
||||
ecs::container world;
|
||||
std::unique_ptr<ecs::container> world;
|
||||
|
||||
util::hash_map<card_type, int> cards = {};
|
||||
|
||||
|
|
@ -547,11 +547,11 @@ namespace gmtk
|
|||
|
||||
void clear_tile(map & map, location const & l)
|
||||
{
|
||||
auto entity = map.world.index<index>().find(l);
|
||||
auto entity = map.world->index<index>().find(l);
|
||||
if (!entity)
|
||||
return;
|
||||
|
||||
auto acc = map.world.get(*entity);
|
||||
auto acc = map.world->get(*entity);
|
||||
|
||||
if (acc.contains<source>() || acc.contains<lab>())
|
||||
return;
|
||||
|
|
@ -572,7 +572,7 @@ namespace gmtk
|
|||
}
|
||||
}
|
||||
|
||||
auto & index = map.world.index<path_index>();
|
||||
auto & index = map.world->index<path_index>();
|
||||
|
||||
for (int y = 0; y < 9; ++y)
|
||||
{
|
||||
|
|
@ -582,22 +582,22 @@ namespace gmtk
|
|||
|
||||
if (auto e = index.find(p))
|
||||
{
|
||||
auto & v = map.world.get(*e).get<path_vertex>();
|
||||
auto & v = map.world->get(*e).get<path_vertex>();
|
||||
|
||||
for (auto to : v.belts_to)
|
||||
{
|
||||
auto & tv = map.world.get(to).get<path_vertex>();
|
||||
auto & tv = map.world->get(to).get<path_vertex>();
|
||||
if (!within_tile(l, tv.location))
|
||||
remove_belt(map.world, to, *tv.belts_to.begin());
|
||||
remove_belt(map.world, *e, to);
|
||||
remove_belt(*map.world, to, *tv.belts_to.begin());
|
||||
remove_belt(*map.world, *e, to);
|
||||
}
|
||||
|
||||
for (auto from : v.belts_from)
|
||||
{
|
||||
auto & fv = map.world.get(from).get<path_vertex>();
|
||||
auto & fv = map.world->get(from).get<path_vertex>();
|
||||
if (!within_tile(l, fv.location))
|
||||
remove_belt(map.world, *fv.belts_from.begin(), from);
|
||||
remove_belt(map.world, from, *e);
|
||||
remove_belt(*map.world, *fv.belts_from.begin(), from);
|
||||
remove_belt(*map.world, from, *e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -608,17 +608,102 @@ namespace gmtk
|
|||
map.put_card(transformer_to_card(t->type));
|
||||
}
|
||||
|
||||
map.world.destroy(*entity);
|
||||
map.world->destroy(*entity);
|
||||
}
|
||||
|
||||
map starting_map()
|
||||
map start_menu_map()
|
||||
{
|
||||
map result;
|
||||
|
||||
result.world.index<index>();
|
||||
result.world.index<path_index>();
|
||||
result.world = std::make_unique<ecs::container>();
|
||||
|
||||
result.world.create(
|
||||
for (int y = 0; y < 3; ++y)
|
||||
for (int x = 0; x < 3; ++x)
|
||||
result.world->create(
|
||||
vertex{0, {x, y}},
|
||||
zoomer{}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{0, {-1, 1}},
|
||||
source{{color_type::black, shape_type::circle}}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{0, {3, 1}},
|
||||
source{{color_type::black, shape_type::circle}}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{1, {1, 1}},
|
||||
source{{color_type::red, shape_type::circle}}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{1, {7, 7}},
|
||||
source{{color_type::yellow, shape_type::circle}}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{1, {1, 4}},
|
||||
transformer{transformer_type::hue_shifter}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{1, {7, 4}},
|
||||
transformer{transformer_type::hue_shifter}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{1, {1, 7}},
|
||||
lab{}
|
||||
);
|
||||
|
||||
result.world->create(
|
||||
vertex{1, {7, 1}},
|
||||
lab{}
|
||||
);
|
||||
|
||||
auto & index = result.world->index<path_index>();
|
||||
|
||||
// Left black to hue shifter
|
||||
add_belt(*result.world, index.get({1, {-2, 4}}), index.get({1, {-1, 4}}));
|
||||
add_belt(*result.world, index.get({1, {-1, 4}}), index.get({2, {0, 13}}));
|
||||
add_belt(*result.world, index.get({2, {0, 13}}), index.get({2, {1, 13}}));
|
||||
add_belt(*result.world, index.get({2, {1, 13}}), index.get({2, {2, 13}}));
|
||||
add_belt(*result.world, index.get({2, {2, 13}}), index.get({2, {3, 13}}));
|
||||
add_belt(*result.world, index.get({2, {3, 13}}), index.get({2, {4, 13}}));
|
||||
|
||||
// Bottom-left red to hue shifter to left lab
|
||||
add_belt(*result.world, index.get({1, {1, -2}}), index.get({1, {1, -1}}));
|
||||
add_belt(*result.world, index.get({1, {1, -1}}), index.get({2, {4, 0}}));
|
||||
add_belt(*result.world, index.get({2, {4, 0}}), index.get({2, {4, 1}}));
|
||||
for (int y = 1; y < 22; ++y)
|
||||
add_belt(*result.world, index.get({2, {4, y}}), index.get({2, {4, y + 1}}));
|
||||
|
||||
add_belt(*result.world, index.get({1, {10, 4}}), index.get({1, {9, 4}}));
|
||||
add_belt(*result.world, index.get({1, {9, 4}}), index.get({2, {26, 13}}));
|
||||
add_belt(*result.world, index.get({2, {26, 13}}), index.get({2, {25, 13}}));
|
||||
|
||||
for (int y = 4; y < 22; ++y)
|
||||
add_belt(*result.world, index.get({2, {22, y + 1}}), index.get({2, {22, y}}));
|
||||
|
||||
for (int x = 22; x < 25; ++x)
|
||||
add_belt(*result.world, index.get({2, {x + 1, 13}}), index.get({2, {x, 13}}));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
map capmaign_map()
|
||||
{
|
||||
map result;
|
||||
|
||||
result.world = std::make_unique<ecs::container>();
|
||||
|
||||
result.world->index<index>();
|
||||
result.world->index<path_index>();
|
||||
|
||||
result.world->create(
|
||||
vertex{{0, {1, -1}}},
|
||||
lab{}
|
||||
);
|
||||
|
|
@ -968,7 +1053,7 @@ namespace gmtk
|
|||
{
|
||||
draw_grid({{{0.f, 3.f}, {0.f, 3.f}}}, view_level, painter);
|
||||
|
||||
map.world.apply<vertex const, zoomer const>([&](vertex const & v, zoomer const &)
|
||||
map.world->apply<vertex const, zoomer const>([&](vertex const & v, zoomer const &)
|
||||
{
|
||||
draw_grid(v.location.bbox(), view_level, painter);
|
||||
});
|
||||
|
|
@ -976,13 +1061,13 @@ namespace gmtk
|
|||
|
||||
void draw(map & map, gfx::painter & painter, float pixel_size)
|
||||
{
|
||||
map.world.apply<vertex const, crossing const>([&](vertex const & v, crossing const & c)
|
||||
map.world->apply<vertex const, crossing const>([&](vertex const & v, crossing const & c)
|
||||
{
|
||||
draw_structure(v.location.bbox(), c, painter);
|
||||
});
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
map.world.apply<path_vertex const>([&](path_vertex const & vertex)
|
||||
map.world->apply<path_vertex const>([&](path_vertex const & vertex)
|
||||
{
|
||||
float w = (i == 0 ? 0.3f : 0.25f);
|
||||
float w0 = w * std::pow(3.f, 1.f - vertex.location.level);
|
||||
|
|
@ -995,17 +1080,17 @@ namespace gmtk
|
|||
|
||||
for (auto b : vertex.belts_to)
|
||||
{
|
||||
auto q = map.world.get(b).get<path_vertex const>().location;
|
||||
auto q = map.world->get(b).get<path_vertex const>().location;
|
||||
float w1 = w * std::pow(3.f, 1.f - q.level);
|
||||
painter.line(vertex.location.center(), q.center(), w0, w1, c, c, false);
|
||||
}
|
||||
});
|
||||
|
||||
map.world.apply<path_vertex const>([&](path_vertex const & vertex)
|
||||
map.world->apply<path_vertex const>([&](path_vertex const & vertex)
|
||||
{
|
||||
for (auto b : vertex.belts_to)
|
||||
{
|
||||
auto q = map.world.get(b).get<path_vertex const>().location;
|
||||
auto q = map.world->get(b).get<path_vertex const>().location;
|
||||
|
||||
geom::vector d = q.center() - vertex.location.center();
|
||||
|
||||
|
|
@ -1025,7 +1110,7 @@ namespace gmtk
|
|||
}
|
||||
});
|
||||
|
||||
map.world.apply<vertex const, source const>([&](vertex const & v, source const & s)
|
||||
map.world->apply<vertex const, source const>([&](vertex const & v, source const & s)
|
||||
{
|
||||
geom::vector shift{0.f, 0.f};
|
||||
if (v.location.coords[0] < 0)
|
||||
|
|
@ -1040,14 +1125,14 @@ namespace gmtk
|
|||
painter.rect(shift + v.location.bbox(-0.225f), color_of(s.type));
|
||||
});
|
||||
|
||||
map.world.apply<vertex const, transformer const>([&](vertex const & v, transformer const & t)
|
||||
map.world->apply<vertex const, transformer const>([&](vertex const & v, transformer const & t)
|
||||
{
|
||||
auto box = v.location.bbox();
|
||||
// box = geom::expand(box, 0.125f * animation_factor(t.animate) * box[0].length());
|
||||
draw_structure(box, t, painter);
|
||||
});
|
||||
|
||||
map.world.apply<vertex const, lab const>([&](vertex const & v, lab const & l)
|
||||
map.world->apply<vertex const, lab const>([&](vertex const & v, lab const & l)
|
||||
{
|
||||
geom::vector shift{1.f, -1.f};
|
||||
|
||||
|
|
@ -1068,9 +1153,9 @@ namespace gmtk
|
|||
painter.text(pen, std::format("{}/{}", map.resource_count, stages[map.stage].count), {.scale = {vs, -vs}, .c = {0, 0, 0, 255}});
|
||||
});
|
||||
|
||||
map.world.apply<item const>([&](item const & i)
|
||||
map.world->apply<item const>([&](item const & i)
|
||||
{
|
||||
draw_item(i.type, position(map.world, i), scale(map.world, i), painter);
|
||||
draw_item(i.type, position(*map.world, i), scale(*map.world, i), painter);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1137,10 +1222,10 @@ namespace gmtk
|
|||
: seed_(make_seed())
|
||||
, map_rng_{seed_, 0xf24130ddef6fb31full}
|
||||
, item_rng_{seed_, 0xb9fc3979f9860bbdull}
|
||||
, map_(starting_map())
|
||||
, map_(start_menu_map())
|
||||
{
|
||||
log::info() << "Starting seed: " << seed_;
|
||||
view_stack_.push_back({-1, {0, 0}});
|
||||
set_start_menu();
|
||||
}
|
||||
|
||||
void on_event(app::resize_event const & event) override
|
||||
|
|
@ -1150,38 +1235,41 @@ namespace gmtk
|
|||
|
||||
void on_event(app::mouse_wheel_event const & event) override
|
||||
{
|
||||
if (event.delta > 0)
|
||||
if (!in_menu())
|
||||
{
|
||||
if (selected_ && !view_transition_)
|
||||
if (event.delta > 0)
|
||||
{
|
||||
bool transitioned = false;
|
||||
if (selected_ && !view_transition_)
|
||||
{
|
||||
bool transitioned = false;
|
||||
|
||||
if (auto entity = map_.world.index<index>().find(*selected_))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
if (auto entity = map_.world->index<index>().find(*selected_))
|
||||
if (map_.world->get(*entity).contains<zoomer>())
|
||||
{
|
||||
view_transition_ = {view_stack_.back()};
|
||||
view_stack_.push_back(*selected_);
|
||||
selected_ = std::nullopt;
|
||||
transitioned = true;
|
||||
}
|
||||
|
||||
if (!transitioned && within_grid(*selected_) && selected_->level == view_stack_.back().level + 1 && selected_->up() != view_stack_.back())
|
||||
{
|
||||
view_transition_ = {view_stack_.back()};
|
||||
view_stack_.push_back(*selected_);
|
||||
view_stack_.back() = selected_->up();
|
||||
selected_ = std::nullopt;
|
||||
transitioned = true;
|
||||
}
|
||||
|
||||
if (!transitioned && within_grid(*selected_) && selected_->level == view_stack_.back().level + 1 && selected_->up() != view_stack_.back())
|
||||
{
|
||||
view_transition_ = {view_stack_.back()};
|
||||
view_stack_.back() = selected_->up();
|
||||
selected_ = std::nullopt;
|
||||
transitioned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.delta < 0)
|
||||
{
|
||||
if (!view_transition_ && view_stack_.size() > 1)
|
||||
if (event.delta < 0)
|
||||
{
|
||||
view_transition_ = {view_stack_.back()};
|
||||
view_stack_.pop_back();
|
||||
selected_ = std::nullopt;
|
||||
if (!view_transition_ && view_stack_.size() > 1)
|
||||
{
|
||||
view_transition_ = {view_stack_.back()};
|
||||
view_stack_.pop_back();
|
||||
selected_ = std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1195,9 +1283,14 @@ namespace gmtk
|
|||
{
|
||||
if (event.down && event.button == app::mouse_button::left)
|
||||
{
|
||||
if (selected_ && active_card_)
|
||||
if (selected_button_)
|
||||
{
|
||||
if (auto entity = map_.world.index<index>().find(*selected_))
|
||||
if (*selected_button_ < menu_buttons_.size() && menu_buttons_[*selected_button_].action)
|
||||
menu_buttons_[*selected_button_].action();
|
||||
}
|
||||
else if (selected_ && active_card_)
|
||||
{
|
||||
if (auto entity = map_.world->index<index>().find(*selected_))
|
||||
{
|
||||
if (*active_card_ == card_type::eraser)
|
||||
{
|
||||
|
|
@ -1214,14 +1307,14 @@ namespace gmtk
|
|||
case card_type::mixer:
|
||||
case card_type::hue_shifter:
|
||||
case card_type::reshaper:
|
||||
map_.world.create(
|
||||
map_.world->create(
|
||||
vertex{*selected_},
|
||||
transformer{card_to_transformer(*active_card_).value()}
|
||||
);
|
||||
built = true;
|
||||
break;
|
||||
case card_type::crossing:
|
||||
map_.world.create(
|
||||
map_.world->create(
|
||||
vertex{*selected_},
|
||||
crossing{}
|
||||
);
|
||||
|
|
@ -1229,17 +1322,17 @@ namespace gmtk
|
|||
break;
|
||||
case card_type::zoomer:
|
||||
{
|
||||
map_.world.create(
|
||||
map_.world->create(
|
||||
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());
|
||||
sink_belt(*map_.world, c.left());
|
||||
sink_belt(*map_.world, c.right());
|
||||
sink_belt(*map_.world, c.bottom());
|
||||
sink_belt(*map_.world, c.top());
|
||||
built = true;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1281,10 +1374,10 @@ namespace gmtk
|
|||
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]);
|
||||
sink(*map_.world, belt[0], belt[1]);
|
||||
sink(*map_.world, belt[3], belt[2]);
|
||||
|
||||
auto & index = map_.world.index<path_index>();
|
||||
auto & index = map_.world->index<path_index>();
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
auto p = belt[i];
|
||||
|
|
@ -1293,20 +1386,20 @@ namespace gmtk
|
|||
auto s = index.get(p);
|
||||
auto t = index.get(q);
|
||||
|
||||
auto & sv = map_.world.get(s).get<path_vertex>();
|
||||
auto & sv = map_.world->get(s).get<path_vertex>();
|
||||
|
||||
if (sv.belts_to.contains(t))
|
||||
{
|
||||
remove_belt(map_.world, s, t);
|
||||
remove_belt(*map_.world, s, t);
|
||||
if (tutorial_state_ <= 1)
|
||||
tutorial_state_ = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (remove_belt(map_.world, t, s))
|
||||
if (remove_belt(*map_.world, t, s))
|
||||
if (tutorial_state_ <= 1)
|
||||
tutorial_state_ = 2;
|
||||
add_belt(map_.world, s, t);
|
||||
add_belt(*map_.world, s, t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1364,29 +1457,29 @@ namespace gmtk
|
|||
{
|
||||
map_.spawn_timer -= 1.f;
|
||||
|
||||
map_.world.apply<vertex const, source>(
|
||||
map_.world->apply<vertex const, source>(
|
||||
[&](vertex const & v, source & s)
|
||||
{
|
||||
auto p = v.location.down();
|
||||
|
||||
auto t = map_.world.index<path_index>().get(p);
|
||||
auto t = map_.world->index<path_index>().get(p);
|
||||
|
||||
if (!map_.world.get(t).contains<occupied>())
|
||||
if (!map_.world->get(t).contains<occupied>())
|
||||
{
|
||||
if (!map_.world.get(t).get<path_vertex>().belts_to.empty())
|
||||
if (!map_.world->get(t).get<path_vertex>().belts_to.empty())
|
||||
s.animate += 1.f;
|
||||
|
||||
auto i = map_.world.create(
|
||||
auto i = map_.world->create(
|
||||
item{s.type, p}
|
||||
);
|
||||
|
||||
map_.world.attach(t, occupied{i});
|
||||
map_.world->attach(t, occupied{i});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (map_.stage + 1 < std::size(stages) && map_.resource_count >= stages[map_.stage].count)
|
||||
if (!in_menu() && map_.stage + 1 < std::size(stages) && map_.resource_count >= stages[map_.stage].count)
|
||||
{
|
||||
for (auto card : stages[map_.stage].cards)
|
||||
map_.cards[card] += 1;
|
||||
|
|
@ -1397,7 +1490,7 @@ namespace gmtk
|
|||
|
||||
auto add = [&](location l)
|
||||
{
|
||||
if (!map_.world.index<index>().find(l))
|
||||
if (!map_.world->index<index>().find(l))
|
||||
spots.insert(l);
|
||||
};
|
||||
|
||||
|
|
@ -1416,7 +1509,7 @@ namespace gmtk
|
|||
|
||||
if (!spots.empty())
|
||||
{
|
||||
map_.world.create(
|
||||
map_.world->create(
|
||||
vertex{random::uniform_from(map_rng_, spots)},
|
||||
source{type}
|
||||
);
|
||||
|
|
@ -1430,23 +1523,23 @@ namespace gmtk
|
|||
tutorial_state_ = 3;
|
||||
}
|
||||
|
||||
map_.world.apply<vertex const, transformer>([&](vertex const & v, transformer & t)
|
||||
map_.world->apply<vertex const, transformer>([&](vertex const & v, transformer & t)
|
||||
{
|
||||
boost::container::flat_multimap<resource_type, location> has_inputs;
|
||||
|
||||
auto c = v.location.down();
|
||||
auto ce = map_.world.index<path_index>().get(c);
|
||||
auto ce = map_.world->index<path_index>().get(c);
|
||||
|
||||
if (map_.world.get(ce).contains<occupied>())
|
||||
if (map_.world->get(ce).contains<occupied>())
|
||||
return;
|
||||
|
||||
for (auto n : neighbours)
|
||||
{
|
||||
auto p = c.moved(n);
|
||||
if (auto ne = map_.world.index<path_index>().find(p))
|
||||
if (map_.world.get(*ne).get<path_vertex>().belts_to.contains(ce))
|
||||
if (auto occ = map_.world.get(*ne).get_if<occupied const>())
|
||||
if (auto i = map_.world.get(occ->entity).get_if<item const>())
|
||||
if (auto ne = map_.world->index<path_index>().find(p))
|
||||
if (map_.world->get(*ne).get<path_vertex>().belts_to.contains(ce))
|
||||
if (auto occ = map_.world->get(*ne).get_if<occupied const>())
|
||||
if (auto i = map_.world->get(occ->entity).get_if<item const>())
|
||||
if (i->start == p)
|
||||
has_inputs.insert({i->type, p});
|
||||
}
|
||||
|
|
@ -1476,21 +1569,21 @@ namespace gmtk
|
|||
for (int i = 0; i < recipe.inputs.count(type); ++i)
|
||||
{
|
||||
auto l = it->second;
|
||||
auto e = map_.world.index<path_index>().get(l);
|
||||
auto re = map_.world.get(e).get<occupied>().entity;
|
||||
auto e = map_.world->index<path_index>().get(l);
|
||||
auto re = map_.world->get(e).get<occupied>().entity;
|
||||
|
||||
map_.world.detach<occupied>(e);
|
||||
map_.world.destroy(re);
|
||||
map_.world->detach<occupied>(e);
|
||||
map_.world->destroy(re);
|
||||
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
auto r = map_.world.create(
|
||||
auto r = map_.world->create(
|
||||
item{recipe.output, c}
|
||||
);
|
||||
|
||||
map_.world.attach(ce, occupied{r});
|
||||
map_.world->attach(ce, occupied{r});
|
||||
|
||||
crafted = true;
|
||||
|
||||
|
|
@ -1506,16 +1599,16 @@ namespace gmtk
|
|||
}
|
||||
});
|
||||
|
||||
map_.world.apply<item>([&](ecs::handle entity, item & i)
|
||||
map_.world->apply<item>([&](ecs::handle entity, item & i)
|
||||
{
|
||||
if (i.target)
|
||||
{
|
||||
{
|
||||
auto & v = map_.world.get(i.target).get<path_vertex const>();
|
||||
auto & v = map_.world->get(i.target).get<path_vertex const>();
|
||||
if (v.belts_from.empty() && v.belts_to.empty())
|
||||
{
|
||||
map_.world.detach<occupied>(i.target);
|
||||
map_.world.destroy(entity);
|
||||
map_.world->detach<occupied>(i.target);
|
||||
map_.world->destroy(entity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1526,76 +1619,76 @@ namespace gmtk
|
|||
|
||||
i.state -= 1.f;
|
||||
|
||||
i.start = map_.world.get(i.target).get<path_vertex const>().location;
|
||||
map_.world.detach<occupied>(i.target);
|
||||
i.start = map_.world->get(i.target).get<path_vertex const>().location;
|
||||
map_.world->detach<occupied>(i.target);
|
||||
i.target = ecs::handle::null();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto s = map_.world.index<path_index>().get(i.start);
|
||||
map_.world.detach<occupied>(s);
|
||||
auto s = map_.world->index<path_index>().get(i.start);
|
||||
map_.world->detach<occupied>(s);
|
||||
|
||||
auto & v = map_.world.get(s).get<path_vertex const>();
|
||||
auto & v = map_.world->get(s).get<path_vertex const>();
|
||||
if (v.belts_to.empty() && v.belts_from.empty())
|
||||
{
|
||||
map_.world.destroy(entity);
|
||||
map_.world->destroy(entity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto cell = map_.world.index<index>().find(i.start.up()))
|
||||
if (auto cell = map_.world->index<index>().find(i.start.up()))
|
||||
{
|
||||
if (auto l = map_.world.get(*cell).get_if<lab>())
|
||||
if (auto l = map_.world->get(*cell).get_if<lab>())
|
||||
{
|
||||
if (i.type == stages[map_.stage].type)
|
||||
{
|
||||
map_.resource_count += 1;
|
||||
l->animate += 1.f;
|
||||
map_.world.destroy(entity);
|
||||
map_.world->destroy(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
l->animate_error += 1.f;
|
||||
map_.world.destroy(entity);
|
||||
map_.world->destroy(entity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (map_.world.get(*cell).contains<crossing>())
|
||||
if (map_.world->get(*cell).contains<crossing>())
|
||||
{
|
||||
auto c = i.start.up().down();
|
||||
auto d = c.coords - i.start.coords;
|
||||
auto n = c.moved(d);
|
||||
|
||||
auto & index = map_.world.index<path_index>();
|
||||
auto & index = map_.world->index<path_index>();
|
||||
|
||||
auto se = index.get(i.start);
|
||||
auto ce = index.get(c);
|
||||
auto ne = index.get(n);
|
||||
|
||||
if (map_.world.get(se).get<path_vertex>().belts_to.contains(ce))
|
||||
if (map_.world->get(se).get<path_vertex>().belts_to.contains(ce))
|
||||
{
|
||||
if (map_.world.get(ce).get<path_vertex>().belts_to.contains(ne) && !map_.world.get(ne).contains<occupied>())
|
||||
if (map_.world->get(ce).get<path_vertex>().belts_to.contains(ne) && !map_.world->get(ne).contains<occupied>())
|
||||
{
|
||||
i.target = ne;
|
||||
map_.world.attach(ne, occupied{entity});
|
||||
map_.world->attach(ne, occupied{entity});
|
||||
}
|
||||
else
|
||||
{
|
||||
map_.world.attach(se, occupied{entity});
|
||||
map_.world->attach(se, occupied{entity});
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (map_.world.get(*cell).get_if<transformer>())
|
||||
if (map_.world->get(*cell).get_if<transformer>())
|
||||
{
|
||||
auto se = map_.world.index<path_index>().get(i.start);
|
||||
auto ce = map_.world.index<path_index>().get(i.start.up().down());
|
||||
auto se = map_.world->index<path_index>().get(i.start);
|
||||
auto ce = map_.world->index<path_index>().get(i.start.up().down());
|
||||
|
||||
if (map_.world.get(se).get<path_vertex>().belts_to.contains(ce))
|
||||
if (map_.world->get(se).get<path_vertex>().belts_to.contains(ce))
|
||||
{
|
||||
map_.world.attach(map_.world.index<path_index>().get(i.start), occupied{entity});
|
||||
map_.world->attach(map_.world->index<path_index>().get(i.start), occupied{entity});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1603,30 +1696,30 @@ 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_to)
|
||||
if (!map_.world.get(b).contains<occupied>())
|
||||
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);
|
||||
|
||||
if (!targets.empty())
|
||||
i.target = random::uniform_from(item_rng_, targets);
|
||||
|
||||
if (i.target)
|
||||
map_.world.attach(i.target, occupied{entity});
|
||||
map_.world->attach(i.target, occupied{entity});
|
||||
else
|
||||
map_.world.attach(map_.world.index<path_index>().get(i.start), occupied{entity});
|
||||
map_.world->attach(map_.world->index<path_index>().get(i.start), occupied{entity});
|
||||
});
|
||||
|
||||
map_.world.apply<source>([&](source & s)
|
||||
map_.world->apply<source>([&](source & s)
|
||||
{
|
||||
s.animate = std::max(0.f, s.animate - 3.f * dt);
|
||||
});
|
||||
|
||||
map_.world.apply<transformer>([&](transformer & t)
|
||||
map_.world->apply<transformer>([&](transformer & t)
|
||||
{
|
||||
t.animate = std::max(0.f, t.animate - 3.f * dt);
|
||||
});
|
||||
|
||||
map_.world.apply<lab>([&](lab & l)
|
||||
map_.world->apply<lab>([&](lab & l)
|
||||
{
|
||||
l.animate = std::max(0.f, l.animate - 3.f * dt);
|
||||
l.animate_error = std::max(0.f, l.animate_error - 3.f * dt);
|
||||
|
|
@ -1665,24 +1758,24 @@ namespace gmtk
|
|||
selected_ = std::nullopt;
|
||||
selected_item_ = std::nullopt;
|
||||
|
||||
if (!view_transition_)
|
||||
if (!in_menu() && !view_transition_)
|
||||
{
|
||||
if (geom::contains(geom::shrink(view_box_[0], (view_box_[0].length() - view_box_[1].length()) / 2.f), mouse_world_[0]))
|
||||
map_.world.apply<item const>([&](ecs::handle entity, item const & i)
|
||||
map_.world->apply<item const>([&](ecs::handle entity, item const & i)
|
||||
{
|
||||
auto box = geom::expand(geom::box<float, 2>::singleton(position(map_.world, i)), scale(map_.world, i) / 9.f);
|
||||
auto box = geom::expand(geom::box<float, 2>::singleton(position(*map_.world, i)), scale(*map_.world, i) / 9.f);
|
||||
if (geom::contains(box, mouse_world_))
|
||||
selected_item_ = entity;
|
||||
});
|
||||
|
||||
if (selected_item_ && item_killing_spree_)
|
||||
{
|
||||
auto const & i = map_.world.get(*selected_item_).get<item const>();
|
||||
auto const & i = map_.world->get(*selected_item_).get<item const>();
|
||||
if (i.target)
|
||||
map_.world.detach<occupied>(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_);
|
||||
map_.world->detach<occupied>(map_.world->index<path_index>().get(i.start));
|
||||
map_.world->destroy(*selected_item_);
|
||||
selected_item_ = std::nullopt;
|
||||
}
|
||||
|
||||
|
|
@ -1710,8 +1803,8 @@ namespace gmtk
|
|||
selected_ = p;
|
||||
while (selected_->level > 0)
|
||||
{
|
||||
if (auto entity = map_.world.index<index>().find(p.up()))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
if (auto entity = map_.world->index<index>().find(p.up()))
|
||||
if (map_.world->get(*entity).contains<zoomer>())
|
||||
break;
|
||||
|
||||
selected_ = std::nullopt;
|
||||
|
|
@ -1722,7 +1815,7 @@ namespace gmtk
|
|||
}
|
||||
}
|
||||
else if (!within_grid(p))
|
||||
if (auto entity = map_.world.index<index>().find(p))
|
||||
if (auto entity = map_.world->index<index>().find(p))
|
||||
selected_ = p;
|
||||
}
|
||||
}
|
||||
|
|
@ -1732,6 +1825,13 @@ namespace gmtk
|
|||
float const target = p.first == active_card_;
|
||||
p.second += (target - p.second) * (- std::expm1(- 20.f * dt));
|
||||
}
|
||||
|
||||
menu_transition_ += ((in_menu() ? 1.f : 0.f) - menu_transition_) * (- std::expm1(- 20.f * dt));
|
||||
|
||||
for (int i = 0; i < menu_buttons_.size(); ++i)
|
||||
{
|
||||
menu_buttons_[i].selected_state += ((selected_button_ == i ? 1.f : 0.f) - menu_buttons_[i].selected_state) * (- std::expm1(- 20.f * dt));
|
||||
}
|
||||
}
|
||||
|
||||
void present() override
|
||||
|
|
@ -1756,9 +1856,9 @@ namespace gmtk
|
|||
{
|
||||
if (selected_)
|
||||
{
|
||||
if (auto entity = map_.world.index<index>().find(*selected_))
|
||||
if (auto entity = map_.world->index<index>().find(*selected_))
|
||||
{
|
||||
auto acc = map_.world.get(*entity);
|
||||
auto acc = map_.world->get(*entity);
|
||||
if (*active_card_ != card_type::eraser || (!acc.contains<source>() && !acc.contains<lab>()))
|
||||
{
|
||||
gfx::color_rgba color = {255, 128, 128, 255};
|
||||
|
|
@ -1795,14 +1895,14 @@ namespace gmtk
|
|||
location p0 = belt_start_->down();
|
||||
location p1 = p0.moved(d);
|
||||
|
||||
sink(map_.world, p0, p1);
|
||||
sink(*map_.world, p0, p1);
|
||||
|
||||
auto e0 = map_.world.index<path_index>().get(p0);
|
||||
auto e1 = map_.world.index<path_index>().get(p1);
|
||||
auto e0 = map_.world->index<path_index>().get(p0);
|
||||
auto e1 = map_.world->index<path_index>().get(p1);
|
||||
|
||||
if (map_.world.get(e0).get<path_vertex>().belts_to.contains(e1))
|
||||
if (map_.world->get(e0).get<path_vertex>().belts_to.contains(e1))
|
||||
c = {244, 160, 160, 255};
|
||||
else if (map_.world.get(e0).get<path_vertex>().belts_from.contains(e1))
|
||||
else if (map_.world->get(e0).get<path_vertex>().belts_from.contains(e1))
|
||||
c = {244, 244, 160, 255};
|
||||
|
||||
float w = 0.25f * std::pow(3.f, 1.f - selected_->level) / 2.f;
|
||||
|
|
@ -1815,8 +1915,9 @@ namespace gmtk
|
|||
draw_selection(belt_start_->bbox(), painter_, {64, 64, 64, 255});
|
||||
}
|
||||
|
||||
draw(map_, painter_, pixel_size);
|
||||
draw(map_, painter_, in_start_menu_ ? 0.f : pixel_size);
|
||||
|
||||
if (!in_menu())
|
||||
{
|
||||
float w = (view_box_[0].length() - view_box_[1].length()) / 2.f;
|
||||
geom::vector t{view_box_[1].length() / 5.f, 0.f};
|
||||
|
|
@ -1862,8 +1963,8 @@ namespace gmtk
|
|||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
std::optional<transformer_type> shown_recipies;
|
||||
|
|
@ -1875,8 +1976,8 @@ namespace gmtk
|
|||
}
|
||||
else if (selected_)
|
||||
{
|
||||
if (auto entity = map_.world.index<index>().find(*selected_))
|
||||
if (auto t = map_.world.get(*entity).get_if<transformer>())
|
||||
if (auto entity = map_.world->index<index>().find(*selected_))
|
||||
if (auto t = map_.world->get(*entity).get_if<transformer>())
|
||||
shown_recipies = t->type;
|
||||
}
|
||||
|
||||
|
|
@ -1955,9 +2056,9 @@ namespace gmtk
|
|||
if (selected_card_ || active_card_)
|
||||
helper_text = card_description(selected_card_.value_or(*active_card_));
|
||||
else if (selected_)
|
||||
if (auto entity = map_.world.index<index>().find(*selected_))
|
||||
if (auto entity = map_.world->index<index>().find(*selected_))
|
||||
{
|
||||
auto acc = map_.world.get(*entity);
|
||||
auto acc = map_.world->get(*entity);
|
||||
if (auto t = acc.get_if<transformer>())
|
||||
helper_text = card_description(transformer_to_card(t->type));
|
||||
else if (acc.contains<crossing>())
|
||||
|
|
@ -1970,7 +2071,7 @@ namespace gmtk
|
|||
helper_text = {"Consumer", "Consumes produced items"};
|
||||
}
|
||||
|
||||
if (helper_text.empty())
|
||||
if (!in_menu() && helper_text.empty())
|
||||
{
|
||||
if (tutorial_state_ == 0)
|
||||
{
|
||||
|
|
@ -2015,12 +2116,105 @@ namespace gmtk
|
|||
}
|
||||
}
|
||||
|
||||
selected_button_ = std::nullopt;
|
||||
|
||||
if (in_menu())
|
||||
{
|
||||
painter_.rect(view_box_, gfx::to_coloru8(gfx::color_4f{1.f, 1.f, 1.f, menu_transition_ * 0.5f}));
|
||||
|
||||
float button_width = pixel_size * 500.f;
|
||||
float button_height = pixel_size * 64.f;
|
||||
float button_spacing = pixel_size * 32.f;
|
||||
|
||||
float total_height = button_height * menu_buttons_.size() + button_spacing * (menu_buttons_.size() - 1.f);
|
||||
|
||||
auto pen = view_box_.center() + geom::vector{-button_width, total_height} / 2.f;
|
||||
|
||||
for (int i = 0; i < menu_buttons_.size(); ++i)
|
||||
{
|
||||
geom::box<float, 2> box;
|
||||
box[0] = {pen[0], pen[0] + button_width};
|
||||
box[1] = {pen[1] - button_height, pen[1]};
|
||||
|
||||
box = geom::expand(box, menu_buttons_[i].selected_state * 8.f * pixel_size);
|
||||
|
||||
if (geom::contains(box, mouse_world_))
|
||||
selected_button_ = i;
|
||||
|
||||
auto text_color = gfx::lerp(gfx::black.as_color_rgba(), gfx::color_rgba{191, 96, 0, 255}, menu_buttons_[i].selected_state);
|
||||
|
||||
painter_.rect(geom::expand(box, pixel_size * 5.f), text_color);
|
||||
painter_.rect(box, gfx::lerp(gfx::color_rgba{192, 192, 192, 255}, gfx::white.as_color_rgba(), menu_buttons_[i].selected_state));
|
||||
|
||||
float s = pixel_size * 4.f;
|
||||
|
||||
painter_.text(box.center(), menu_buttons_[i].text, {.scale = {s, -s}, .c = text_color});
|
||||
|
||||
pen[1] -= button_height;
|
||||
pen[1] -= button_spacing;
|
||||
}
|
||||
}
|
||||
|
||||
painter_.render(geom::orthographic_camera{view_box_}.transform());
|
||||
}
|
||||
|
||||
private:
|
||||
bool running_ = true;
|
||||
|
||||
bool in_start_menu_ = true;
|
||||
|
||||
float menu_transition_ = 1.f;
|
||||
|
||||
struct button
|
||||
{
|
||||
std::string text;
|
||||
std::function<void()> action;
|
||||
float selected_state = 0.f;
|
||||
};
|
||||
|
||||
std::vector<button> menu_buttons_;
|
||||
std::optional<int> selected_button_;
|
||||
|
||||
bool in_menu() const
|
||||
{
|
||||
return in_start_menu_;
|
||||
}
|
||||
|
||||
void start_campaign(bool /* challenge */)
|
||||
{
|
||||
map_ = capmaign_map();
|
||||
if (in_start_menu_)
|
||||
{
|
||||
view_transition_ = {view_stack_.back()};
|
||||
view_stack_.pop_back();
|
||||
}
|
||||
in_start_menu_ = false;
|
||||
reset_state();
|
||||
}
|
||||
|
||||
void reset_state()
|
||||
{
|
||||
active_card_ = std::nullopt;
|
||||
selected_card_ = std::nullopt;
|
||||
selected_ = std::nullopt;
|
||||
belt_start_ = std::nullopt;
|
||||
selected_item_ = std::nullopt;;
|
||||
card_animation_.clear();
|
||||
}
|
||||
|
||||
void set_start_menu()
|
||||
{
|
||||
view_stack_.clear();
|
||||
view_stack_.push_back({-1, {0, 0}});
|
||||
view_stack_.push_back({0, {1, 1}});
|
||||
|
||||
menu_buttons_.clear();
|
||||
menu_buttons_.push_back({"Campaign mode", [this]{ start_campaign(false); }});
|
||||
menu_buttons_.push_back({"Challenge mode", [this]{ start_campaign(true); }});
|
||||
menu_buttons_.push_back({"Sandbox mode", {}});
|
||||
menu_buttons_.push_back({"Exit", [this]{ stop(); }});
|
||||
}
|
||||
|
||||
std::uint64_t seed_;
|
||||
random::generator map_rng_;
|
||||
random::generator item_rng_;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue