Factorio-like gameplay wip

This commit is contained in:
Nikita Lisitsa 2024-08-18 23:17:43 +03:00
parent 9bfbe69df9
commit 52091cc52e

View file

@ -18,7 +18,6 @@
#include <boost/container/flat_set.hpp>
#include <boost/container/flat_map.hpp>
#include <deque>
#include <format>
namespace gmtk
@ -34,7 +33,12 @@ namespace gmtk
(stone_brick)
(iron_plate)
(copper_plate)
(iron_gear)
(copper_wire)
(inserter)
(electric_circuit)
(red_science_pack)
(green_science_pack)
)
psemek_declare_enum(transformer_type, std::uint32_t,
@ -53,7 +57,12 @@ namespace gmtk
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, 160, 64, 255};
case resource_type::electric_circuit: return {64, 160, 0, 255};
case resource_type::red_science_pack: return {192, 64, 64, 255};
case resource_type::green_science_pack: return {64, 192, 64, 255};
}
throw util::unknown_enum_value_exception{c};
@ -77,11 +86,16 @@ namespace gmtk
transformer_type::factory,
{
{resource_type::stone_brick, 30},
{resource_type::iron_plate, 30},
},
},
};
static util::hash_map<resource_type, int> const zoomer_construction_recipe
{
{resource_type::iron_plate, 30},
{resource_type::copper_plate, 30},
};
static util::hash_map<transformer_type, std::vector<recipe>> const recipies
{
{
@ -96,6 +110,11 @@ namespace gmtk
transformer_type::factory,
{
{{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::green_science_pack},
},
},
};
@ -190,7 +209,7 @@ namespace gmtk
{
psemek_ecs_declare_uuid("build_site")
transformer_type type;
std::optional<transformer_type> type; // null means zoomer
util::hash_map<resource_type, int> resources = {};
};
@ -480,7 +499,7 @@ namespace gmtk
return result;
}
void draw_grid(location origin, float view_level, gfx::painter & painter)
void draw_grid(location origin, float view_level, gfx::painter & painter, bool in_construction)
{
origin.level += 1;
origin.coords[0] *= 3;
@ -490,20 +509,24 @@ namespace gmtk
auto box = origin.bbox();
auto color = gfx::black.as_color_rgba();
if (in_construction)
color[3] = 127;
for (int x = 0; x <= 3; ++x)
{
painter.line(box.corner(x, 0), box.corner(x, 3), grid_width, gfx::black, true);
painter.line(box.corner(0, x), box.corner(3, x), grid_width, gfx::black, true);
painter.line(box.corner(x, 0), box.corner(x, 3), grid_width, color, true);
painter.line(box.corner(0, x), box.corner(3, x), grid_width, color, true);
}
}
void draw(map & map, float view_level, gfx::painter & painter)
{
draw_grid({-1, {0, 0}}, view_level, painter);
draw_grid({-1, {0, 0}}, view_level, painter, false);
map.world.apply<vertex const, zoomer const>([&](vertex const & v, zoomer const &)
{
draw_grid(v.location, view_level, painter);
draw_grid(v.location, view_level, painter, false);
});
map.world.apply<path_vertex const>([&](path_vertex const & vertex)
@ -571,13 +594,18 @@ namespace gmtk
map.world.apply<vertex const, build_site const>([&](vertex const & v, build_site const & t)
{
draw_transformer(v.location, t.type, true);
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);
for (auto const & p : construction_recipe.at(t.type))
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;
@ -638,7 +666,22 @@ 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})
{
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, first ? gfx::black : color);
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), {0, 0, 0, 255});
@ -783,15 +826,8 @@ namespace gmtk
{
map_.world.create(
vertex{*selected_},
zoomer{}
build_site{std::nullopt}
);
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());
}
}
@ -854,10 +890,11 @@ namespace gmtk
);
}
map_.world.apply<build_site>([&](ecs::handle entity, build_site & b)
map_.world.apply<vertex const, build_site>([&](ecs::handle entity, vertex const & v, build_site & b)
{
bool built = true;
for (auto const & p : construction_recipe.at(b.type))
auto & recipe = b.type ? construction_recipe.at(*b.type) : zoomer_construction_recipe;
for (auto const & p : recipe)
{
if (!b.resources.contains(p.first))
{
@ -875,8 +912,23 @@ namespace gmtk
if (built)
{
auto type = b.type;
auto l = v.location;
map_.world.detach<build_site>(entity);
map_.world.attach(entity, transformer{type});
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());
}
}
});