diff --git a/source/application.cpp b/source/application.cpp index c22b0b9..7aad118 100644 --- a/source/application.cpp +++ b/source/application.cpp @@ -19,86 +19,121 @@ #include #include +#include + namespace gmtk { using namespace psemek; - psemek_declare_enum(resource_type, std::uint32_t, - (stone) - (coal) - (iron_ore) - (copper_ore) - (stone_brick) - (iron_plate) - (copper_plate) - (iron_gear) - (copper_wire) - (inserter) - (electric_circuit) - (red_science_pack) - (green_science_pack) + psemek_declare_enum(color_type, std::uint32_t, + (white) + (black) + (gray) + (red) + (green) + (blue) + (cyan) + (magenta) + (yellow) ) + psemek_declare_enum(shape_type, std::uint32_t, + (circle) + (square) + ) + + struct resource_type + { + color_type color; + shape_type shape; + + friend bool operator == (resource_type const &, resource_type const &) = default; + friend auto operator <=> (resource_type const &, resource_type const &) = default; + }; + + struct resource_hash + { + std::size_t operator()(resource_type const & r) const noexcept + { + return util::hash_all(r.color, r.shape); + } + }; + psemek_declare_enum(transformer_type, std::uint32_t, - (furnace) - (factory) + (mixer) + (square_maker) + (hue_shifter) ) psemek_declare_enum(card_type, std::uint32_t, (crossing) - (furnace) - (factory) + (mixer) + (square_maker) + (hue_shifter) (zoomer) ) - gfx::color_rgba color_of(resource_type c) + gfx::color_rgba color_of(color_type c) { switch (c) { - case resource_type::stone: return {144, 128, 96, 255}; - case resource_type::coal: return {32, 32, 32, 255}; - case resource_type::iron_ore: return {96, 128, 144, 255}; - case resource_type::copper_ore: return {224, 128, 64, 255}; - case resource_type::stone_brick: return color_of(resource_type::stone); - case resource_type::iron_plate: return color_of(resource_type::iron_ore); - case resource_type::copper_plate: return color_of(resource_type::copper_ore); - case resource_type::iron_gear: return color_of(resource_type::iron_ore); - case resource_type::copper_wire: return color_of(resource_type::copper_ore); - case resource_type::inserter: return {224, 192, 64, 255}; - case resource_type::electric_circuit: return {64, 192, 64, 255}; - case resource_type::red_science_pack: return {192, 64, 64, 255}; - case resource_type::green_science_pack: return {64, 192, 64, 255}; + case color_type::white: return {255, 255, 255, 255}; + case color_type::black: return {64, 64, 64, 255}; + case color_type::gray: return {160, 160, 160, 255}; + case color_type::red: return {255, 64, 64, 255}; + case color_type::green: return {64, 255, 64, 255}; + case color_type::blue: return {64, 64, 255, 255}; + case color_type::cyan: return {64, 255, 255, 255}; + case color_type::magenta: return {255, 64, 255, 255}; + case color_type::yellow: return {255, 255, 64, 255}; } throw util::unknown_enum_value_exception{c}; } + gfx::color_rgba color_of(resource_type const & r) + { + return color_of(r.color); + } + struct recipe { - util::hash_set inputs; + boost::container::flat_set inputs; resource_type output; }; static util::hash_map> const recipies { { - transformer_type::furnace, + transformer_type::mixer, { - {{resource_type::coal, resource_type::stone}, resource_type::stone_brick}, - {{resource_type::coal, resource_type::iron_ore}, resource_type::iron_plate}, - {{resource_type::coal, resource_type::copper_ore}, resource_type::copper_plate}, + {{{color_type::white, shape_type::circle}, {color_type::black, shape_type::circle}}, {color_type::gray, shape_type::circle}}, + {{{color_type::white, shape_type::circle}, {color_type::red, shape_type::circle}, {color_type::green, shape_type::circle}}, {color_type::yellow, shape_type::circle}}, + {{{color_type::white, shape_type::circle}, {color_type::red, shape_type::circle}, {color_type::blue, shape_type::circle}}, {color_type::magenta, shape_type::circle}}, + {{{color_type::white, shape_type::circle}, {color_type::green, shape_type::circle}, {color_type::blue, shape_type::circle}}, {color_type::cyan, shape_type::circle}}, }, }, { - transformer_type::factory, + transformer_type::square_maker, { - {{resource_type::iron_plate, resource_type::copper_plate}, resource_type::red_science_pack}, - {{resource_type::iron_plate, resource_type::stone_brick}, resource_type::iron_gear}, - {{resource_type::copper_plate, resource_type::stone_brick}, resource_type::copper_wire}, - {{resource_type::iron_plate, resource_type::copper_wire}, resource_type::electric_circuit}, - {{resource_type::iron_gear, resource_type::copper_plate}, resource_type::inserter}, - {{resource_type::electric_circuit, resource_type::inserter, resource_type::red_science_pack}, resource_type::green_science_pack}, + {{{color_type::gray, shape_type::circle}, {color_type::red, shape_type::circle}}, {color_type::red, shape_type::square}}, + {{{color_type::gray, shape_type::circle}, {color_type::green, shape_type::circle}}, {color_type::green, shape_type::square}}, + {{{color_type::gray, shape_type::circle}, {color_type::blue, shape_type::circle}}, {color_type::blue, shape_type::square}}, + {{{color_type::gray, shape_type::circle}, {color_type::cyan, shape_type::circle}}, {color_type::cyan, shape_type::square}}, + {{{color_type::gray, shape_type::circle}, {color_type::magenta, shape_type::circle}}, {color_type::magenta, shape_type::square}}, + {{{color_type::gray, shape_type::circle}, {color_type::yellow, shape_type::circle}}, {color_type::yellow, shape_type::square}}, + }, + }, + { + transformer_type::hue_shifter, + { + {{{color_type::black, shape_type::circle}, {color_type::red, shape_type::circle}}, {color_type::green, shape_type::circle}}, + {{{color_type::black, shape_type::circle}, {color_type::green, shape_type::circle}}, {color_type::blue, shape_type::circle}}, + {{{color_type::black, shape_type::circle}, {color_type::blue, shape_type::circle}}, {color_type::red, shape_type::circle}}, + {{{color_type::black, shape_type::circle}, {color_type::cyan, shape_type::circle}}, {color_type::magenta, shape_type::circle}}, + {{{color_type::black, shape_type::circle}, {color_type::magenta, shape_type::circle}}, {color_type::yellow, shape_type::circle}}, + {{{color_type::black, shape_type::circle}, {color_type::yellow, shape_type::circle}}, {color_type::cyan, shape_type::circle}}, }, }, }; @@ -332,13 +367,12 @@ namespace gmtk static stage_info stages[] { - {resource_type::stone, 0, {}, {resource_type::stone}}, - {resource_type::stone, 10, {card_type::furnace}, {resource_type::coal}}, - {resource_type::stone_brick, 30, {card_type::furnace}, {resource_type::iron_ore}}, - {resource_type::iron_plate, 30, {card_type::factory, card_type::crossing, card_type::crossing}, {resource_type::copper_ore}}, - {resource_type::red_science_pack, 30, {card_type::furnace, card_type::factory, card_type::crossing, card_type::crossing, card_type::zoomer, card_type::zoomer, card_type::zoomer}, {}}, - {resource_type::inserter, 60, {card_type::factory, card_type::factory, card_type::factory, card_type::factory, card_type::crossing, card_type::crossing, card_type::zoomer, card_type::zoomer, card_type::zoomer}, {resource_type::coal}}, - {resource_type::green_science_pack, 60, {}, {}}, + {{color_type::white, shape_type::circle}, 0, {}, {{color_type::white, shape_type::circle}}}, + {{color_type::white, shape_type::circle}, 10, {card_type::mixer}, {{color_type::black, shape_type::circle}}}, + {{color_type::gray, shape_type::circle}, 30, {card_type::hue_shifter, card_type::crossing}, {{color_type::red, shape_type::circle}}}, + {{color_type::green, shape_type::circle}, 30, {card_type::square_maker, card_type::crossing}, {}}, + {{color_type::green, shape_type::square}, 30, {card_type::hue_shifter, card_type::crossing, card_type::zoomer}, {}}, + {{color_type::blue, shape_type::square}, 30, {card_type::hue_shifter, card_type::crossing}, {}}, }; template @@ -517,10 +551,18 @@ namespace gmtk } else if (auto t = acc.get_if()) { - if (t->type == transformer_type::furnace) - map.put_card(card_type::furnace); - else if (t->type == transformer_type::factory) - map.put_card(card_type::factory); + 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.world.destroy(*entity); @@ -543,7 +585,7 @@ namespace gmtk void draw_grid(geom::box const & box, float view_level, gfx::painter & painter, bool solid = false) { - float const grid_width = 0.05f * std::min(box[0].length() / 3.f, std::pow(3.f, -1.f - view_level)); + float const grid_width = 0.025f * std::min(box[0].length() / 3.f, std::pow(3.f, -1.f - view_level)); gfx::color_rgba color = gfx::black; if (!solid) @@ -573,24 +615,18 @@ namespace gmtk } } - void draw_item(resource_type type, geom::point const & pos, float scale, gfx::painter & painter, bool selected = false) + void draw_item(resource_type const & type, geom::point const & pos, float scale, gfx::painter & painter, bool selected = false) { auto color = color_of(type); + gfx::color_rgba bcolor = selected ? gfx::white : gfx::black; - gfx::color_rgba bcolor = selected ? gfx::red : gfx::black; - - switch (type) + switch (type.shape) { - case resource_type::coal: - case resource_type::stone: - case resource_type::iron_ore: - case resource_type::copper_ore: + case shape_type::circle: painter.circle(pos, 0.075f * scale, bcolor); painter.circle(pos, 0.05f * scale, color); break; - case resource_type::stone_brick: - case resource_type::iron_plate: - case resource_type::copper_plate: + case shape_type::square: { auto box = geom::expand(geom::box::singleton(pos), 0.075f * scale); painter.rect(box, bcolor); @@ -598,30 +634,6 @@ namespace gmtk painter.rect(box, color); } break; - case resource_type::iron_gear: - case resource_type::copper_wire: - case resource_type::inserter: - case resource_type::electric_circuit: - { - 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, c); - first = false; - } - } - break; - case resource_type::red_science_pack: - case resource_type::green_science_pack: - { - auto box = geom::expand(geom::box::singleton(pos), 0.075f * scale); - 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); - } - break; } } @@ -629,25 +641,38 @@ namespace gmtk { auto box = geom::shrink(bbox, bbox[0].length() * 0.2f); - auto p0 = box.corner(0, 0); - auto p1 = box.corner(1, 0); - auto p2 = box.corner(0.8f, 1); - auto p3 = box.corner(0.2f, 1); - - gfx::color_rgba color = {255, 0, 255, 255}; - switch (t.type) + for (int i = 0; i < 2; ++i) { - case transformer_type::furnace: color = color_of(resource_type::stone); break; - case transformer_type::factory: color = color_of(resource_type::iron_ore); break; - } + gfx::color_rgba color = {0, 0, 0, 255}; - painter.triangle(p0, p1, p2, color); - painter.triangle(p0, p2, p3, color); + if (i == 1) + { + color = {255, 255, 255, 255}; + if (t.type == transformer_type::mixer) + box = geom::shrink(bbox, bbox[0].length() * (0.2f + 0.025f * std::sqrt(2.f))); + else + box = geom::shrink(bbox, bbox[0].length() * 0.225f); + } + + switch (t.type) + { + case transformer_type::mixer: + painter.triangle(box.corner(0.f, 0.5f), box.corner(1.f, 0.5f), box.corner(0.5f, 0.f), color); + painter.triangle(box.corner(0.f, 0.5f), box.corner(1.f, 0.5f), box.corner(0.5f, 1.f), color); + break; + case transformer_type::square_maker: + painter.rect(box, color); + break; + case transformer_type::hue_shifter: + painter.circle(box.center(), box[0].length() / 2.f, color, 72); + break; + } + } } void draw_structure(geom::box const & bbox, crossing const &, gfx::painter & painter) { - auto wbox = geom::shrink(bbox, bbox[0].length() * 0.2f); + auto wbox = geom::shrink(bbox, bbox[0].length() * 0.1f); auto sbox = geom::shrink(bbox, bbox[0].length() * 0.3f); gfx::color_rgba color{64, 64, 64, 255}; @@ -663,11 +688,14 @@ namespace gmtk case card_type::crossing: draw_structure(bbox, crossing{}, painter); break; - case card_type::furnace: - draw_structure(bbox, transformer{transformer_type::furnace}, painter); + case card_type::mixer: + draw_structure(bbox, transformer{transformer_type::mixer}, painter); break; - case card_type::factory: - draw_structure(bbox, transformer{transformer_type::factory}, painter); + 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); break; case card_type::zoomer: draw_grid(bbox, -1.f, painter, true); @@ -675,7 +703,7 @@ namespace gmtk } } - void draw(map & map, float view_level, gfx::painter & painter) + void draw_grids(map & map, float view_level, gfx::painter & painter) { draw_grid({{{0.f, 3.f}, {0.f, 3.f}}}, view_level, painter); @@ -683,19 +711,35 @@ namespace gmtk { draw_grid(v.location.bbox(), view_level, painter); }); + } - map.world.apply([&](path_vertex const & vertex) + void draw(map & map, gfx::painter & painter) + { + map.world.apply([&](vertex const & v, crossing const & c) { - for (auto b : vertex.belts_to) - { - auto q = map.world.get(b).get().location; - float w0 = 0.3f * std::pow(3.f, 1.f - vertex.location.level); - float w1 = 0.3f * std::pow(3.f, 1.f - q.level); - gfx::color_rgba c{191, 191, 191, 255}; - painter.line(vertex.location.center(), q.center(), w0, w1, c, c, true); - } + draw_structure(v.location.bbox(), c, painter); }); + for (int i = 0; i < 2; ++i) + map.world.apply([&](path_vertex const & vertex) + { + float w = (i == 0 ? 0.3f : 0.25f); + float w0 = w * std::pow(3.f, 1.f - vertex.location.level); + gfx::color_rgba c{192, 192, 192, 255}; + if (i == 0) + c = {0, 0, 0, 255}; + + if (vertex.location.up().down() == vertex.location && (!vertex.belts_to.empty() || !vertex.belts_from.empty())) + painter.circle(vertex.location.center(), w0 / 2.f, c); + + for (auto b : vertex.belts_to) + { + auto q = map.world.get(b).get().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 & vertex) { for (auto b : vertex.belts_to) @@ -713,15 +757,17 @@ namespace gmtk d *= s * 0.5f; n *= s; - painter.triangle(c - d + n, c - d - n, c + d, {255, 127, 0, 255}); + // gfx::color_rgba color = {255, 128, 0, 255}; + gfx::color_rgba color = {64, 64, 64, 255}; + + painter.triangle(c - d + n, c - d - n, c + d, color); } }); map.world.apply([&](vertex const & v, source const & s) { - // float vs = std::pow(3.f, - v.location.level) * 0.01f; - painter.rect(v.location.bbox(-0.2f), color_of(s.type)); - // painter.text(v.location.center(), "180/m", {.scale = {vs, -vs}, .c = {0, 0, 0, 255}}); + painter.rect(v.location.bbox(-0.2f), gfx::black); + painter.rect(v.location.bbox(-0.225f), color_of(s.type)); }); map.world.apply([&](vertex const & v, transformer const & t) @@ -729,14 +775,10 @@ namespace gmtk draw_structure(v.location.bbox(), t, painter); }); - map.world.apply([&](vertex const & v, crossing const & c) - { - draw_structure(v.location.bbox(), c, painter); - }); - map.world.apply([&](vertex const & v, lab const &) { - painter.rect(v.location.bbox(-0.2f), {128, 192, 255, 255}); + painter.rect(v.location.bbox(-0.2f), {0, 0, 0, 255}); + painter.rect(v.location.bbox(-0.225f), {192, 192, 192, 255}); auto pen = v.location.bbox(-0.4f).corner(0.5f, 1.f); @@ -918,10 +960,10 @@ namespace gmtk { if (selected_ && !map_.world.index().find(*selected_)) { - if (map_.take_card(card_type::furnace)) + if (map_.take_card(card_type::mixer)) map_.world.create( vertex{*selected_}, - transformer{transformer_type::furnace} + transformer{transformer_type::mixer} ); } } @@ -930,10 +972,22 @@ namespace gmtk { if (selected_ && !map_.world.index().find(*selected_)) { - if (map_.take_card(card_type::factory)) + if (map_.take_card(card_type::hue_shifter)) map_.world.create( vertex{*selected_}, - transformer{transformer_type::factory} + transformer{transformer_type::hue_shifter} + ); + } + } + + if (event.down && event.key == app::keycode::H) + { + if (selected_ && !map_.world.index().find(*selected_)) + { + if (map_.take_card(card_type::square_maker)) + map_.world.create( + vertex{*selected_}, + transformer{transformer_type::square_maker} ); } } @@ -1326,13 +1380,15 @@ namespace gmtk view_level = geom::lerp(view_transition_->old.level, view_stack_.back().level, t); } - draw(map_, view_level, painter_); + draw_grids(map_, view_level, painter_); if (selected_) - draw_selection(*selected_, painter_, {255, 128, 128, 255}); + draw_selection(*selected_, painter_, {128, 128, 128, 255}); if (belt_start_) - draw_selection(*belt_start_, painter_, {255, 191, 128, 255}); + draw_selection(*belt_start_, painter_, {64, 64, 64, 255}); + + draw(map_, painter_); { float w = (view_box_[0].length() - view_box_[1].length()) / 2.f; @@ -1412,7 +1468,9 @@ namespace gmtk draw_card(geom::expand(geom::box::singleton(pen), step), type, painter_); - painter_.text(pen, std::to_string(map_.cards.at(type)), {.scale = {vs, -vs}, .c = {0, 0, 0, 255}}); + auto color = (type != card_type::crossing) ? gfx::black : gfx::white; + + painter_.text(pen, std::to_string(map_.cards.at(type)), {.scale = {vs, -vs}, .c = color}); pen[1] -= step * 2.f; } diff --git a/tree.xcf b/tree.xcf new file mode 100644 index 0000000..eb1af11 Binary files /dev/null and b/tree.xcf differ