diff --git a/source/application.cpp b/source/application.cpp index 155308b..67a783d 100644 --- a/source/application.cpp +++ b/source/application.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -74,28 +75,6 @@ namespace gmtk resource_type output; }; - static util::hash_map> const construction_recipe - { - { - transformer_type::furnace, - { - {resource_type::stone, 30}, - }, - }, - { - transformer_type::factory, - { - {resource_type::stone_brick, 30}, - }, - }, - }; - - static util::hash_map const zoomer_construction_recipe - { - {resource_type::iron_plate, 30}, - {resource_type::copper_plate, 30}, - }; - static util::hash_map> const recipies { { @@ -205,14 +184,6 @@ namespace gmtk resource_type type; }; - struct build_site - { - psemek_ecs_declare_uuid("build_site") - - std::optional type; // null means zoomer - util::hash_map resources = {}; - }; - struct transformer { psemek_ecs_declare_uuid("transformer") @@ -287,13 +258,11 @@ namespace gmtk friend auto operator <=> (timestamp const & x, timestamp const & y) = default; }; - struct task + struct lab { - psemek_ecs_declare_uuid("task") + psemek_ecs_declare_uuid("lab") - resource_type type; - - int count = 0; + util::hash_map count = {}; }; struct map @@ -421,47 +390,6 @@ namespace gmtk sink(world, c, m); } - void generate_next_task(random::generator & rng, map & map) - { - resource_type type; - - util::hash_set existing_tasks; - int task_count = 0; - map.world.apply([&](task const & task) - { - existing_tasks.insert(task.type); - task_count += 1; - }); - - while (true) - { - type = random::uniform_from(rng, resource_type_values()); - if (task_count >= 3) - break; - - if (!existing_tasks.contains(type)) - break; - } - - while (true) - { - int x = random::uniform(rng, 0, 2); - int y = random::uniform(rng) ? -1 : 3; - if (random::uniform(rng)) - std::swap(x, y); - - if (map.world.index().find({0, {x, y}})) - continue; - - map.world.create( - vertex{{0, {x, y}}}, - task{type} - ); - - break; - } - } - map starting_map(random::generator & rng) { map result; @@ -475,7 +403,7 @@ namespace gmtk ); result.world.create( - vertex{{0, {0, 3}}}, + vertex{{0, {-1, 2}}}, source{resource_type::iron_ore} ); @@ -485,13 +413,13 @@ namespace gmtk ); result.world.create( - vertex{{0, {2, 3}}}, + vertex{{0, {3, 2}}}, source{resource_type::copper_ore} ); result.world.create( vertex{{0, {1, -1}}}, - task{resource_type::red_science_pack} + lab{} ); (void)rng; @@ -592,40 +520,27 @@ namespace gmtk painter.triangle(p0, p2, p3, color); }; - map.world.apply([&](vertex const & v, build_site const & t) - { - if (t.type) - draw_transformer(v.location, *t.type, true); - else - draw_grid(v.location, view_level, painter, true); - - float vs = std::pow(3.f, - v.location.level) * 0.01f; - auto text_bbox = v.location.bbox(-0.4f); - auto pen = text_bbox.corner(0.5f, 1.f); - - auto & recipe = t.type ? construction_recipe.at(*t.type) : zoomer_construction_recipe; - - for (auto const & p : recipe) - { - int have = t.resources.contains(p.first) ? t.resources.at(p.first) : 0; - int need = p.second; - - painter.text(pen, std::format("{}/{}", have, need), {.scale = {vs, -vs}, .c = color_of(p.first)}); - - pen[1] -= 12.f * vs; - } - }); - map.world.apply([&](vertex const & v, transformer const & t) { draw_transformer(v.location, t.type, false); }); - map.world.apply([&](vertex const & v, task const & t) + map.world.apply([&](vertex const & v, lab const & l) { + painter.rect(v.location.bbox(-0.2f), {128, 192, 255, 255}); + + auto pen = v.location.bbox(-0.4f).corner(0.5f, 1.f); + float vs = std::pow(3.f, - v.location.level) * 0.01f; - painter.rect(v.location.bbox(-0.2f), color_of(t.type)); - painter.text(v.location.center(), std::format("{}", t.count), {.scale = {vs, -vs}, .c = {0, 0, 0, 255}}); + + for (auto type : {resource_type::red_science_pack, resource_type::green_science_pack}) + { + if (l.count.contains(type)) + { + painter.text(pen, std::to_string(l.count.at(type)), {.scale = {vs, -vs}, .c = color_of(type)}); + pen[1] -= 12.f * vs; + } + } }); map.world.apply([&](item const & i) @@ -729,13 +644,26 @@ namespace gmtk if (event.down && event.button == app::mouse_button::left) { if (selected_ && !view_transition_) + { + bool transitioned = false; + if (auto entity = map_.world.index().find(*selected_)) if (map_.world.get(*entity).contains()) { view_transition_ = {view_stack_.back()}; view_stack_.push_back(*selected_); selected_ = std::nullopt; + transitioned = true; } + + if (!transitioned && 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.down && event.button == app::mouse_button::right) @@ -794,8 +722,8 @@ namespace gmtk } } } - belt_start_ = std::nullopt; } + belt_start_ = std::nullopt; } if (event.down && event.key == app::keycode::F) @@ -804,7 +732,7 @@ namespace gmtk { map_.world.create( vertex{*selected_}, - build_site{transformer_type::furnace} + transformer{transformer_type::furnace} ); } } @@ -815,7 +743,7 @@ namespace gmtk { map_.world.create( vertex{*selected_}, - build_site{transformer_type::factory} + transformer{transformer_type::factory} ); } } @@ -826,8 +754,15 @@ namespace gmtk { map_.world.create( vertex{*selected_}, - build_site{std::nullopt} + 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()); } } @@ -838,16 +773,11 @@ namespace gmtk if (auto entity = map_.world.index().find(*selected_)) { auto acc = map_.world.get(*entity); - if (!acc.contains() && !acc.contains() && !acc.contains()) + if (!acc.contains() && !acc.contains() && !acc.contains()) map_.world.destroy(*entity); } } } - - if (event.down && event.key == app::keycode::SPACE) - { - generate_next_task(rng_, map_); - } } bool running() const override @@ -890,48 +820,6 @@ namespace gmtk ); } - map_.world.apply([&](ecs::handle entity, vertex const & v, build_site & b) - { - bool built = true; - auto & recipe = b.type ? construction_recipe.at(*b.type) : zoomer_construction_recipe; - for (auto const & p : recipe) - { - if (!b.resources.contains(p.first)) - { - built = false; - break; - } - - if (b.resources.at(p.first) < p.second) - { - built = false; - break; - } - } - - if (built) - { - auto type = b.type; - auto l = v.location; - map_.world.detach(entity); - if (type) - { - map_.world.attach(entity, transformer{*type}); - } - else - { - map_.world.attach(entity, zoomer{}); - - auto c = l.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()); - } - } - }); - map_.world.apply([&](vertex const & v, transformer const & t) { boost::container::flat_map has_inputs; @@ -1038,17 +926,9 @@ namespace gmtk if (auto cell = map_.world.index().find(i.start.up())) { - if (auto t = map_.world.get(*cell).get_if()) + if (auto l = map_.world.get(*cell).get_if()) { - t->resources[i.type] += 1; - map_.world.destroy(entity); - return; - } - - if (auto t = map_.world.get(*cell).get_if()) - { - if (t->type == i.type) - t->count += 1; + l->count[i.type] += 1; map_.world.destroy(entity); return; } @@ -1124,10 +1004,32 @@ namespace gmtk location p{1 + l.level, {std::floor(m[0]), std::floor(m[1])}}; - if (p.coords[0] >= 3 * l.coords[0] && p.coords[0] < 3 * l.coords[0] + 3 && p.coords[1] >= 3 * l.coords[1] && p.coords[1] < 3 * l.coords[1] + 3) + 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 (auto entity = map_.world.index().find(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().find(p.up())) + if (map_.world.get(*entity).contains()) + break; + + selected_ = std::nullopt; + break; + + // TODO: + selected_ = selected_->up(); + } + } + else if (!within_grid(p)) + if (auto entity = map_.world.index().find(p)) + selected_ = p; } }