diff --git a/src/entity/components/select.hpp b/src/entity/components/select.hpp
new file mode 100644
index 0000000..e02b66b
--- /dev/null
+++ b/src/entity/components/select.hpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 Christopher J. Howard
+ *
+ * This file is part of Antkeeper source code.
+ *
+ * Antkeeper source code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper source code. If not, see .
+ */
+
+#ifndef ANTKEEPER_ENTITY_COMPONENT_SELECT_HPP
+#define ANTKEEPER_ENTITY_COMPONENT_SELECT_HPP
+
+namespace entity {
+namespace component {
+
+/// Allows an entity to be selected.
+struct select
+{
+ /// Radius of selection bounds.
+ float radius;
+};
+
+} // namespace component
+} // namespace entity
+
+#endif // ANTKEEPER_ENTITY_COMPONENT_SELECT_HPP
diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp
index 9c5918a..e7941cd 100644
--- a/src/game/bootloader.cpp
+++ b/src/game/bootloader.cpp
@@ -50,7 +50,6 @@
#include "renderer/vertex-attributes.hpp"
#include "renderer/compositor.hpp"
#include "renderer/renderer.hpp"
-#include "resources/config-file.hpp"
#include "resources/resource-manager.hpp"
#include "resources/resource-manager.hpp"
#include "scene/scene.hpp"
@@ -357,7 +356,7 @@ void load_config(game::context* ctx)
logger->push_task("Loading config");
// Load config file
- ctx->config = ctx->resource_manager->load("config.txt");
+ ctx->config = ctx->resource_manager->load("config.json");
if (!ctx->config)
{
logger->pop_task(EXIT_FAILURE);
@@ -376,7 +375,7 @@ void load_strings(game::context* ctx)
build_string_table_map(&ctx->string_table_map, *ctx->string_table);
- ctx->language_code = ctx->config->get("language");
+ ctx->language_code = (*ctx->config)["language"].get();
ctx->language_index = -1;
for (int i = 2; i < (*ctx->string_table)[0].size(); ++i)
{
@@ -397,7 +396,7 @@ void setup_window(game::context* ctx)
logger->push_task("Setting up window");
application* app = ctx->app;
- config_file* config = ctx->config;
+ json* config = ctx->config;
// Set fullscreen or windowed mode
bool fullscreen = true;
@@ -405,8 +404,8 @@ void setup_window(game::context* ctx)
fullscreen = true;
else if (ctx->option_windowed.has_value())
fullscreen = false;
- else if (config->has("fullscreen"))
- fullscreen = (config->get("fullscreen") != 0);
+ else if (config->contains("fullscreen"))
+ fullscreen = (*config)["fullscreen"].get();
app->set_fullscreen(fullscreen);
// Set resolution
@@ -414,13 +413,19 @@ void setup_window(game::context* ctx)
int2 resolution = {display_dimensions[0], display_dimensions[1]};
if (fullscreen)
{
- if (config->has("fullscreen_resolution"))
- resolution = config->get("fullscreen_resolution");
+ if (config->contains("fullscreen_resolution"))
+ {
+ resolution.x = (*config)["fullscreen_resolution"][0].get();
+ resolution.y = (*config)["fullscreen_resolution"][1].get();
+ }
}
else
{
- if (config->has("windowed_resolution"))
- resolution = config->get("windowed_resolution");
+ if (config->contains("windowed_resolution"))
+ {
+ resolution.x = (*config)["windowed_resolution"][0].get();
+ resolution.y = (*config)["windowed_resolution"][1].get();
+ }
}
app->resize_window(resolution.x, resolution.y);
@@ -428,8 +433,8 @@ void setup_window(game::context* ctx)
bool vsync = true;
if (ctx->option_vsync.has_value())
vsync = (ctx->option_vsync.value() != 0);
- else if (config->has("vsync"))
- vsync = (config->get("vsync") != 0);
+ else if (config->contains("vsync"))
+ vsync = (*config)["vsync"].get();
app->set_vsync(vsync);
// Set title
@@ -466,9 +471,9 @@ void setup_rendering(game::context* ctx)
// Create shadow map framebuffer
int shadow_map_resolution = 4096;
- if (ctx->config->has("shadow_map_resolution"))
+ if (ctx->config->contains("shadow_map_resolution"))
{
- shadow_map_resolution = ctx->config->get("shadow_map_resolution");
+ shadow_map_resolution = (*ctx->config)["shadow_map_resolution"].get();
}
ctx->shadow_map_depth_texture = new gl::texture_2d(shadow_map_resolution, shadow_map_resolution, gl::pixel_type::float_32, gl::pixel_format::d);
ctx->shadow_map_depth_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
@@ -846,10 +851,10 @@ void setup_systems(game::context* ctx)
ctx->proteome_system = new entity::system::proteome(*ctx->entity_registry);
// Set time scale
- float time_scale = 60.0f;
- if (ctx->config->has("time_scale"))
+ double time_scale = 60.0;
+ if (ctx->config->contains("time_scale"))
{
- time_scale = ctx->config->get("time_scale");
+ time_scale = (*ctx->config)["time_scale"].get();
}
ctx->orbit_system->set_time_scale(time_scale / seconds_per_day);
diff --git a/src/game/context.hpp b/src/game/context.hpp
index 3432cf9..2b43185 100644
--- a/src/game/context.hpp
+++ b/src/game/context.hpp
@@ -42,6 +42,7 @@
#include
#include
#include
+#include "resources/json.hpp"
// Forward declarations
class animator;
@@ -49,7 +50,6 @@ class application;
class bloom_pass;
class clear_pass;
class compositor;
-class config_file;
class final_pass;
class material;
class material_pass;
@@ -129,8 +129,8 @@ struct context
std::string screenshots_path;
std::string data_package_path;
- // Config
- config_file* config;
+ // Configuration
+ json* config;
// Resources
resource_manager* resource_manager;
diff --git a/src/game/states/forage.cpp b/src/game/states/forage.cpp
index c11592f..95c6a8c 100644
--- a/src/game/states/forage.cpp
+++ b/src/game/states/forage.cpp
@@ -38,6 +38,7 @@ namespace state {
namespace forage {
static void setup_camera(game::context* ctx);
+static void setup_tools(game::context* ctx);
static void setup_controls(game::context* ctx);
void enter(game::context* ctx)
@@ -187,6 +188,54 @@ void setup_camera(game::context* ctx)
ctx->surface_camera->set_exposure(-14.5f);
}
+void setup_tools(game::context* ctx)
+{
+ if (!ctx->entities.count("move_tool"))
+ {
+ entity::id tool_eid = ctx->entity_registry->create();
+ ctx->entities["move_tool"] = tool_eid;
+ }
+
+ if (!ctx->entities.count("paint_tool"))
+ {
+ entity::id tool_eid = ctx->entity_registry->create();
+ ctx->entities["paint_tool"] = tool_eid;
+ }
+
+ if (!ctx->entities.count("flip_tool"))
+ {
+ entity::id tool_eid = ctx->entity_registry->create();
+ ctx->entities["flip_tool"] = tool_eid;
+ }
+
+ if (!ctx->entities.count("poke_tool"))
+ {
+ entity::id tool_eid = ctx->entity_registry->create();
+ ctx->entities["poke_tool"] = tool_eid;
+ }
+
+ if (!ctx->entities.count("inspect_tool"))
+ {
+ entity::id tool_eid = ctx->entity_registry->create();
+ ctx->entities["inspect_tool"] = tool_eid;
+ }
+
+ if (!ctx->entities.count("label_tool"))
+ {
+ entity::id tool_eid = ctx->entity_registry->create();
+ ctx->entities["label_tool"] = tool_eid;
+ }
+
+ if (!ctx->entities.count("wait_tool"))
+ {
+ entity::id tool_eid = ctx->entity_registry->create();
+ ctx->entities["wait_tool"] = tool_eid;
+ }
+
+ // Set move tool as active tool
+ ctx->entities["active_tool"] = ctx->entities["move_tool"];
+}
+
void setup_controls(game::context* ctx)
{
// Get underground camera entity
@@ -209,9 +258,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{
if (move_slow->is_active())
- value *= 0.5f;
+ value *= 0.25f;
if (move_fast->is_active())
- value *= 2.0f;
+ value *= 4.0f;
auto& three_dof = ctx->entity_registry->get(three_dof_eid);
const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@@ -227,9 +276,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{
if (move_slow->is_active())
- value *= 0.5f;
+ value *= 0.25f;
if (move_fast->is_active())
- value *= 2.0f;
+ value *= 4.0f;
auto& three_dof = ctx->entity_registry->get(three_dof_eid);
const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@@ -245,9 +294,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{
if (move_slow->is_active())
- value *= 0.5f;
+ value *= 0.25f;
if (move_fast->is_active())
- value *= 2.0f;
+ value *= 4.0f;
auto& three_dof = ctx->entity_registry->get(three_dof_eid);
const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@@ -263,9 +312,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
{
if (move_slow->is_active())
- value *= 0.5f;
+ value *= 0.25f;
if (move_fast->is_active())
- value *= 2.0f;
+ value *= 4.0f;
auto& three_dof = ctx->entity_registry->get(three_dof_eid);
const math::quaternion yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
@@ -281,9 +330,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
{
if (move_slow->is_active())
- value *= 0.5f;
+ value *= 0.25f;
if (move_fast->is_active())
- value *= 2.0f;
+ value *= 4.0f;
const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f};
entity::command::translate(*ctx->entity_registry, target_eid, movement);
@@ -296,9 +345,9 @@ void setup_controls(game::context* ctx)
[ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
{
if (move_slow->is_active())
- value *= 0.5f;
+ value *= 0.25f;
if (move_fast->is_active())
- value *= 2.0f;
+ value *= 4.0f;
const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f};
entity::command::translate(*ctx->entity_registry, target_eid, movement);
@@ -374,6 +423,39 @@ void setup_controls(game::context* ctx)
three_dof.pitch = std::min(math::radians(90.0f), three_dof.pitch);
}
);
+
+ // Use tool
+ ctx->controls["use_tool"]->set_activated_callback
+ (
+ [ctx]()
+ {
+ if (ctx->entities["active_tool"] == ctx->entities["move_tool"])
+ {
+ // Project mouse position into scene and grab selectable entity
+ auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position();
+ }
+ }
+ );
+
+ ctx->controls["use_tool"]->set_deactivated_callback
+ (
+ [ctx]()
+ {
+ if (ctx->entities["active_tool"] == ctx->entities["move_tool"])
+ {
+
+ }
+ }
+ );
+
+ ctx->controls["use_tool"]->set_active_callback
+ (
+ [ctx](float value)
+ {
+ auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position();
+ ctx->logger->log("tool used (" + std::to_string(mouse_x) + ", " + std::to_string(mouse_y) + ")");
+ }
+ );
}
} // namespace forage
diff --git a/src/game/states/loading.cpp b/src/game/states/loading.cpp
index 131d0cc..8173efa 100644
--- a/src/game/states/loading.cpp
+++ b/src/game/states/loading.cpp
@@ -47,7 +47,6 @@
#include "resources/resource-manager.hpp"
#include "scene/ambient-light.hpp"
#include "scene/directional-light.hpp"
-#include "resources/config-file.hpp"
#include "utility/timestamp.hpp"
namespace game {
@@ -143,11 +142,14 @@ void load_controls(game::context* ctx)
if (!fullscreen)
{
- int2 resolution = ctx->config->get("windowed_resolution");
+ int2 resolution;
+ resolution.x = (*ctx->config)["windowed_resolution"][0].get();
+ resolution.y = (*ctx->config)["windowed_resolution"][1].get();
+
ctx->app->resize_window(resolution.x, resolution.y);
}
- ctx->config->set("fullscreen", (fullscreen) ? 1 : 0);
+ (*ctx->config)["fullscreen"] = fullscreen;
}
);
@@ -288,6 +290,14 @@ void load_controls(game::context* ctx)
ctx->input_event_router->add_mapping(input::mouse_motion_mapping(control, nullptr, input::mouse_motion_axis::positive_y));
ctx->controls["mouse_down"] = control;
}
+
+ // Use tool
+ if (!ctx->controls.count("use_tool"))
+ {
+ input::control* control = new input::control();
+ ctx->input_event_router->add_mapping(input::mouse_button_mapping(control, nullptr, 1));
+ ctx->controls["use_tool"] = control;
+ }
}
void cosmogenesis(game::context* ctx)
diff --git a/src/game/states/nuptial-flight.cpp b/src/game/states/nuptial-flight.cpp
index bf0ed9d..2ba04ff 100644
--- a/src/game/states/nuptial-flight.cpp
+++ b/src/game/states/nuptial-flight.cpp
@@ -29,7 +29,6 @@
#include "renderer/material-property.hpp"
#include "animation/screen-transition.hpp"
#include "animation/ease.hpp"
-#include "resources/config-file.hpp"
#include "resources/resource-manager.hpp"
namespace game {
@@ -102,7 +101,7 @@ void enter(game::context* ctx)
void exit(game::context* ctx)
{
// Resume motion of celestial objects
- const double time_scale = ctx->config->get("time_scale");
+ const double time_scale = (*ctx->config)["time_scale"].get();
ctx->astronomy_system->set_time_scale(time_scale);
ctx->orbit_system->set_time_scale(time_scale);
}
diff --git a/src/resources/config-file-loader.cpp b/src/resources/config-file-loader.cpp
deleted file mode 100644
index 6c5b8e5..0000000
--- a/src/resources/config-file-loader.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2021 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see .
- */
-
-#include "resources/resource-loader.hpp"
-#include "resources/resource-manager.hpp"
-#include "resources/config-file.hpp"
-#include "resources/text-file.hpp"
-
-template <>
-config_file* resource_loader::load(resource_manager* resource_manager, PHYSFS_File* file)
-{
- // Load as text file
- text_file* text = resource_loader::load(resource_manager, file);
-
- config_file* config = new config_file();
- for (const std::string& line: *text)
- {
- if (line[0] == '#')
- continue;
-
- std::size_t delimeter = line.find_first_of('=');
- if (delimeter == std::string::npos)
- continue;
-
- std::string name = line.substr(0, delimeter);
- std::string value = line.substr(delimeter + 1, line.length() - delimeter - 1);
-
- if (name.empty() || value.empty())
- continue;
-
- config->set(name, value);
- }
-
- delete text;
-
- return config;
-}
diff --git a/src/resources/config-file.hpp b/src/resources/config-file.hpp
deleted file mode 100644
index fa59a04..0000000
--- a/src/resources/config-file.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2021 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see .
- */
-
-#ifndef CONFIG_FILE_HPP
-#define CONFIG_FILE_HPP
-
-#include
-#include
-#include
-
-class config_file
-{
-public:
- template
- void set(const std::string& name, const T& value);
-
- template
- T get(const std::string& name) const;
-
- bool has(const std::string& name) const;
-
-private:
- std::unordered_map variables;
-};
-
-template
-void config_file::set(const std::string& name, const T& value)
-{
- std::stringstream stream;
- stream << value;
- variables[name] = stream.str();
-}
-
-template
-T config_file::get(const std::string& name) const
-{
- T value;
- if (auto it = variables.find(name); it != variables.end())
- std::stringstream(it->second) >> value;
- return value;
-}
-
-inline bool config_file::has(const std::string& name) const
-{
- return (variables.find(name) != variables.end());
-}
-
-#endif // CONFIG_FILE_HPP
diff --git a/src/resources/json-loader.cpp b/src/resources/json-loader.cpp
new file mode 100644
index 0000000..cb798a7
--- /dev/null
+++ b/src/resources/json-loader.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 Christopher J. Howard
+ *
+ * This file is part of Antkeeper source code.
+ *
+ * Antkeeper source code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper source code. If not, see .
+ */
+
+#include "resource-loader.hpp"
+#include "resource-manager.hpp"
+#include "json.hpp"
+#include
+
+template <>
+json* resource_loader::load(resource_manager* resource_manager, PHYSFS_File* file)
+{
+ // Read file into buffer
+ std::size_t size = static_cast(PHYSFS_fileLength(file));
+ std::string buffer;
+ buffer.resize(size);
+ PHYSFS_readBytes(file, &buffer[0], size);
+
+ // Parse json from file buffer
+ json* data = new json(json::parse(buffer));
+
+ return data;
+}
diff --git a/src/resources/json.hpp b/src/resources/json.hpp
new file mode 100644
index 0000000..91f26d2
--- /dev/null
+++ b/src/resources/json.hpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 Christopher J. Howard
+ *
+ * This file is part of Antkeeper source code.
+ *
+ * Antkeeper source code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Antkeeper source code is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Antkeeper source code. If not, see .
+ */
+
+#ifndef ANTKEEPER_RESOURCES_JSON_HPP
+#define ANTKEEPER_RESOURCES_JSON_HPP
+
+#include
+
+/// JSON data
+typedef nlohmann::json json;
+
+#endif // ANTKEEPER_RESOURCES_JSON_HPP