Visual style tweaks

This commit is contained in:
Nikita Lisitsa 2024-08-19 15:13:44 +03:00
parent 528a8b4385
commit b22005ff54
2 changed files with 194 additions and 136 deletions

View file

@ -19,86 +19,121 @@
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
#include <map>
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<resource_type> inputs;
boost::container::flat_set<resource_type> inputs;
resource_type output;
};
static util::hash_map<transformer_type, std::vector<recipe>> 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 <typename Component, util::uuid UUID>
@ -517,10 +551,18 @@ namespace gmtk
}
else if (auto t = acc.get_if<transformer>())
{
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<float, 2> 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<float, 2> const & pos, float scale, gfx::painter & painter, bool selected = false)
void draw_item(resource_type const & 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::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<float, 2>::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<float, 2>::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<float, 2> 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>([&](path_vertex const & vertex)
void draw(map & map, gfx::painter & painter)
{
map.world.apply<vertex const, crossing const>([&](vertex const & v, crossing const & c)
{
for (auto b : vertex.belts_to)
{
auto q = map.world.get(b).get<path_vertex const>().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>([&](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<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)
{
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, source const>([&](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, transformer const>([&](vertex const & v, transformer const & t)
@ -729,14 +775,10 @@ namespace gmtk
draw_structure(v.location.bbox(), t, painter);
});
map.world.apply<vertex const, crossing const>([&](vertex const & v, crossing const & c)
{
draw_structure(v.location.bbox(), c, painter);
});
map.world.apply<vertex const, lab const>([&](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<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<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<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<float>(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<float, 2>::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;
}

BIN
tree.xcf Normal file

Binary file not shown.