Add tutorial text

This commit is contained in:
Nikita Lisitsa 2024-08-19 17:17:45 +03:00
parent 73fe9294a9
commit bd899ad6ab

View file

@ -98,6 +98,31 @@ namespace gmtk
return color_of(r.color);
}
card_type transformer_to_card(transformer_type type)
{
switch (type)
{
case transformer_type::mixer: return card_type::mixer;
case transformer_type::square_maker: return card_type::square_maker;
case transformer_type::hue_shifter: return card_type::hue_shifter;
}
throw util::unknown_enum_value_exception{type};
}
std::optional<transformer_type> card_to_transformer(card_type type)
{
switch (type)
{
case card_type::mixer: return transformer_type::mixer;
case card_type::square_maker: return transformer_type::square_maker;
case card_type::hue_shifter: return transformer_type::hue_shifter;
default: return std::nullopt;
}
return std::nullopt;
}
struct recipe
{
boost::container::flat_set<resource_type> inputs;
@ -258,10 +283,12 @@ namespace gmtk
world.get(to).get<path_vertex>().belts_from.insert(from);
}
void remove_belt(ecs::container & world, ecs::handle from, ecs::handle to)
bool remove_belt(ecs::container & world, ecs::handle from, ecs::handle to)
{
bool removed = world.get(from).get<path_vertex>().belts_to.contains(to);
world.get(from).get<path_vertex>().belts_to.erase(to);
world.get(to).get<path_vertex>().belts_from.erase(from);
return removed;
}
struct occupied
@ -555,18 +582,7 @@ namespace gmtk
}
else if (auto t = acc.get_if<transformer>())
{
switch (t->type)
{
case transformer_type::mixer:
map.put_card(card_type::mixer);
break;
case transformer_type::square_maker:
map.put_card(card_type::square_maker);
break;
case transformer_type::hue_shifter:
map.put_card(card_type::hue_shifter);
break;
}
map.put_card(transformer_to_card(t->type));
}
map.world.destroy(*entity);
@ -695,13 +711,9 @@ namespace gmtk
draw_structure(bbox, crossing{}, painter);
break;
case card_type::mixer:
draw_structure(bbox, transformer{transformer_type::mixer}, painter);
break;
case card_type::square_maker:
draw_structure(bbox, transformer{transformer_type::square_maker}, painter);
break;
case card_type::hue_shifter:
draw_structure(bbox, transformer{transformer_type::hue_shifter}, painter);
draw_structure(bbox, transformer{card_to_transformer(type).value()}, painter);
break;
case card_type::zoomer:
draw_grid(bbox, -1.f, painter, true);
@ -844,6 +856,27 @@ namespace gmtk
}
}
std::vector<std::string> card_description(card_type type)
{
switch (type)
{
case card_type::mixer:
return {"Mixer", "Mixes input colors"};
case card_type::hue_shifter:
return {"Hue shifter", "Shifts the hue of", " input colors"};
case card_type::square_maker:
return {"Squarer", "Turns circles into squares"};
case card_type::crossing:
return {"Bridge", "Allows belts to cross", " without merging"};
case card_type::zoomer:
return {"Grid", "Creates an embedded 3x3 grid", "Zoom using mouse wheel"};
case card_type::eraser:
return {"Eraser", "Erases placed structures"};
}
throw util::unknown_enum_value_exception{type};
}
std::uint64_t make_seed()
{
random::device d;
@ -928,31 +961,24 @@ namespace gmtk
{
if (map_.take_card(*active_card_))
{
bool built = false;
switch (*active_card_)
{
case card_type::mixer:
map_.world.create(
vertex{*selected_},
transformer{transformer_type::mixer}
);
break;
case card_type::hue_shifter:
map_.world.create(
vertex{*selected_},
transformer{transformer_type::hue_shifter}
);
break;
case card_type::square_maker:
map_.world.create(
vertex{*selected_},
transformer{transformer_type::square_maker}
transformer{card_to_transformer(*active_card_).value()}
);
built = true;
break;
case card_type::crossing:
map_.world.create(
vertex{*selected_},
crossing{}
);
built = true;
break;
case card_type::zoomer:
{
@ -967,18 +993,26 @@ namespace gmtk
sink_belt(map_.world, c.right());
sink_belt(map_.world, c.bottom());
sink_belt(map_.world, c.top());
built = true;
}
break;
case card_type::eraser:
break;
}
if (built && tutorial_state_ <= 3)
tutorial_state_ = 4;
}
}
}
else if (selected_card_)
active_card_ = *selected_card_;
else if (selected_item_)
{
item_killing_spree_ = true;
if (tutorial_state_ <= 4)
tutorial_state_ = 5;
}
else if (selected_ && !belt_start_)
belt_start_ = *selected_;
}
@ -1012,13 +1046,22 @@ namespace gmtk
auto & sv = map_.world.get(s).get<path_vertex>();
if (sv.belts_to.contains(t))
{
remove_belt(map_.world, s, t);
if (tutorial_state_ <= 1)
tutorial_state_ = 2;
}
else
{
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);
}
}
if (tutorial_state_ <= 0)
tutorial_state_ = 1;
}
}
belt_start_ = std::nullopt;
@ -1108,6 +1151,9 @@ namespace gmtk
map_.stage += 1;
map_.resource_count = 0;
if (map_.stage > 1 && tutorial_state_ <= 2)
tutorial_state_ = 3;
}
map_.world.apply<vertex const, transformer const>([&](vertex const & v, transformer const & t)
@ -1386,6 +1432,8 @@ namespace gmtk
float view_level = view_stack_.back().level;
float pixel_size = view_box_[1].length() / screen_size_[1];
std::vector<std::string> helper_text;
if (view_transition_)
{
float t = geom::smoothstep(view_transition_->timer * 2.f);
@ -1467,22 +1515,8 @@ namespace gmtk
if (selected_card_ || active_card_)
{
switch (selected_card_.value_or(*active_card_))
{
case card_type::crossing:
case card_type::zoomer:
case card_type::eraser:
break;
case card_type::mixer:
shown_recipies = transformer_type::mixer;
break;
case card_type::hue_shifter:
shown_recipies = transformer_type::hue_shifter;
break;
case card_type::square_maker:
shown_recipies = transformer_type::square_maker;
break;
}
if (auto type = card_to_transformer(selected_card_.value_or(*active_card_)))
shown_recipies = *type;
}
else if (selected_)
{
@ -1496,7 +1530,7 @@ namespace gmtk
float const scale = std::pow(3.f, -1.f - view_level);
float const step = 1.5f * scale / 9.f;
geom::point<float, 2> pen = view_box_.corner(0, 1) + geom::vector{1.f, -1.f} * view_box_[1].length() / 10.f;
geom::point<float, 2> pen = view_box_.corner(0, 1) + geom::vector{18.f, -120.f} * pixel_size + geom::vector{step, - 3.f * step} / 2.f;
for (auto const & recipe : recipies.at(*shown_recipies))
{
int i = 0;
@ -1559,6 +1593,69 @@ 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_))
{
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>())
helper_text = card_description(card_type::crossing);
else if (acc.contains<zoomer>())
helper_text = card_description(card_type::zoomer);
else if (acc.contains<source>())
helper_text = {"Source", "Generates circles"};
else if (acc.contains<lab>())
helper_text = {"Consumer", "Consumes produced items"};
}
if (helper_text.empty())
{
if (tutorial_state_ == 0)
{
helper_text.push_back("Click and drag to add");
helper_text.push_back(" conveyor belts");
}
else if (tutorial_state_ == 1)
{
helper_text.push_back("Drag again to remove belts");
helper_text.push_back(" or switch direction");
}
else if (tutorial_state_ == 2)
{
helper_text.push_back("Deliver items from");
helper_text.push_back("source to consumer");
}
else if (tutorial_state_ == 3)
{
helper_text.push_back("Place a mixer to");
helper_text.push_back(" combine items");
}
else if (tutorial_state_ == 4)
{
helper_text.push_back("Click on items to");
helper_text.push_back(" remove clogging");
}
else if (tutorial_state_ == 5)
{
helper_text.push_back("Let's see how far you can get.");
helper_text.push_back(" Good luck!");
}
}
{
geom::point<float, 2> pen = view_box_.corner(0, 1) + geom::vector{18.f, -24.f} * pixel_size;
float s = 2.f * pixel_size;
for (int i = 0; i < helper_text.size(); ++i)
{
painter_.text(pen, helper_text[i], {.scale = {s, -s}, .x = gfx::painter::x_align::left, .y = gfx::painter::y_align::top, .c = gfx::black});
pen[1] -= 32.f * pixel_size;
}
}
painter_.render(geom::orthographic_camera{view_box_}.transform());
}
@ -1598,6 +1695,8 @@ namespace gmtk
std::optional<card_type> active_card_;
util::hash_map<card_type, float> card_animation_;
int tutorial_state_ = 0;
};
}