Wip
This commit is contained in:
parent
52091cc52e
commit
de3aefac44
1 changed files with 72 additions and 170 deletions
|
|
@ -10,6 +10,7 @@
|
|||
#include <psemek/util/clock.hpp>
|
||||
#include <psemek/geom/box.hpp>
|
||||
#include <psemek/geom/camera.hpp>
|
||||
#include <psemek/geom/contains.hpp>
|
||||
#include <psemek/ecs/container.hpp>
|
||||
#include <psemek/ecs/declare_uuid.hpp>
|
||||
|
||||
|
|
@ -74,28 +75,6 @@ namespace gmtk
|
|||
resource_type output;
|
||||
};
|
||||
|
||||
static util::hash_map<transformer_type, util::hash_map<resource_type, int>> const construction_recipe
|
||||
{
|
||||
{
|
||||
transformer_type::furnace,
|
||||
{
|
||||
{resource_type::stone, 30},
|
||||
},
|
||||
},
|
||||
{
|
||||
transformer_type::factory,
|
||||
{
|
||||
{resource_type::stone_brick, 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
|
||||
{
|
||||
{
|
||||
|
|
@ -205,14 +184,6 @@ namespace gmtk
|
|||
resource_type type;
|
||||
};
|
||||
|
||||
struct build_site
|
||||
{
|
||||
psemek_ecs_declare_uuid("build_site")
|
||||
|
||||
std::optional<transformer_type> type; // null means zoomer
|
||||
util::hash_map<resource_type, int> 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<resource_type, int> 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<resource_type> existing_tasks;
|
||||
int task_count = 0;
|
||||
map.world.apply<task const>([&](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<bool>(rng) ? -1 : 3;
|
||||
if (random::uniform<bool>(rng))
|
||||
std::swap(x, y);
|
||||
|
||||
if (map.world.index<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, build_site const>([&](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, transformer const>([&](vertex const & v, transformer const & t)
|
||||
{
|
||||
draw_transformer(v.location, t.type, false);
|
||||
});
|
||||
|
||||
map.world.apply<vertex const, task const>([&](vertex const & v, task const & t)
|
||||
map.world.apply<vertex const, lab const>([&](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>([&](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<index>().find(*selected_))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
{
|
||||
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<index>().find(*selected_))
|
||||
{
|
||||
auto acc = map_.world.get(*entity);
|
||||
if (!acc.contains<source>() && !acc.contains<task>() && !acc.contains<zoomer>())
|
||||
if (!acc.contains<source>() && !acc.contains<lab>() && !acc.contains<zoomer>())
|
||||
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<vertex const, build_site>([&](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<build_site>(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, transformer const>([&](vertex const & v, transformer const & t)
|
||||
{
|
||||
boost::container::flat_map<resource_type, location> has_inputs;
|
||||
|
|
@ -1038,17 +926,9 @@ namespace gmtk
|
|||
|
||||
if (auto cell = map_.world.index<index>().find(i.start.up()))
|
||||
{
|
||||
if (auto t = map_.world.get(*cell).get_if<build_site>())
|
||||
if (auto l = map_.world.get(*cell).get_if<lab>())
|
||||
{
|
||||
t->resources[i.type] += 1;
|
||||
map_.world.destroy(entity);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto t = map_.world.get(*cell).get_if<task>())
|
||||
{
|
||||
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<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<index>().find(p.up()))
|
||||
if (map_.world.get(*entity).contains<zoomer>())
|
||||
break;
|
||||
|
||||
selected_ = std::nullopt;
|
||||
break;
|
||||
|
||||
// TODO:
|
||||
selected_ = selected_->up();
|
||||
}
|
||||
}
|
||||
else if (!within_grid(p))
|
||||
if (auto entity = map_.world.index<index>().find(p))
|
||||
selected_ = p;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue