diff --git a/CMakeLists.txt b/CMakeLists.txt index d4aa351..bc40e61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2-static SDL2::SDL2main CONFIG) find_package(OpenAL REQUIRED CONFIG) find_library(physfs REQUIRED NAMES physfs-static PATHS "${CMAKE_PREFIX_PATH}/lib") + # Determine dependencies set(STATIC_LIBS dr_wav diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp new file mode 100644 index 0000000..1428736 --- /dev/null +++ b/src/ai/ai.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_AI_HPP +#define ANTKEEPER_AI_HPP + +/// Artificial intelligence (AI) +namespace ai {} + +#include "behavior-tree.hpp" + +#endif // ANTKEEPER_AI_HPP diff --git a/src/game/behavior/behavior-tree.hpp b/src/ai/behavior-tree.hpp similarity index 96% rename from src/game/behavior/behavior-tree.hpp rename to src/ai/behavior-tree.hpp index 88d34b0..be00e37 100644 --- a/src/game/behavior/behavior-tree.hpp +++ b/src/ai/behavior-tree.hpp @@ -17,13 +17,16 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_BEHAVIOR_TREE_HPP -#define ANTKEEPER_BEHAVIOR_TREE_HPP +#ifndef ANTKEEPER_AI_BEHAVIOR_TREE_HPP +#define ANTKEEPER_AI_BEHAVIOR_TREE_HPP #include #include -namespace behavior_tree { +namespace ai { + +/// Behavior tree (BT) +namespace bt { /// Behavior tree node return status enumerations. enum class status @@ -187,7 +190,7 @@ status selector::execute(context_type& context) const return status::failure; } -} // namespace behavior_tree - -#endif // ANTKEEPER_BEHAVIOR_TREE_HPP +} // namespace bt +} // namespace ai +#endif // ANTKEEPER_AI_BEHAVIOR_TREE_HPP diff --git a/src/ecs/components/behavior-component.hpp b/src/ecs/components/behavior-component.hpp index 2463357..cb33d0a 100644 --- a/src/ecs/components/behavior-component.hpp +++ b/src/ecs/components/behavior-component.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_ECS_BEHAVIOR_COMPONENT_HPP #define ANTKEEPER_ECS_BEHAVIOR_COMPONENT_HPP -#include "game/behavior/ebt.hpp" +#include "ecs/ebt.hpp" namespace ecs { diff --git a/src/game/behavior/ebt.cpp b/src/ecs/ebt.cpp similarity index 96% rename from src/game/behavior/ebt.cpp rename to src/ecs/ebt.cpp index b532945..41c1044 100644 --- a/src/game/behavior/ebt.cpp +++ b/src/ecs/ebt.cpp @@ -17,12 +17,11 @@ * along with Antkeeper source code. If not, see . */ -#include "game/behavior/ebt.hpp" +#include "ecs/ebt.hpp" #include "ecs/components/transform-component.hpp" #include -using namespace ecs; - +namespace ecs { namespace ebt { status print(context& context, const std::string& text) @@ -51,4 +50,4 @@ bool is_carrying_food(const context& context) } } // namespace ebt - +} // namespace ecs diff --git a/src/game/behavior/ebt.hpp b/src/ecs/ebt.hpp similarity index 54% rename from src/game/behavior/ebt.hpp rename to src/ecs/ebt.hpp index 5b89edd..8edfcfb 100644 --- a/src/game/behavior/ebt.hpp +++ b/src/ecs/ebt.hpp @@ -17,17 +17,16 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_EBT_HPP -#define ANTKEEPER_EBT_HPP +#ifndef ANTKEEPER_ECS_EBT_HPP +#define ANTKEEPER_ECS_EBT_HPP -#include "game/behavior/behavior-tree.hpp" -#include +#include "ai/behavior-tree.hpp" +#include "ecs/entity.hpp" +#include "ecs/registry.hpp" -/// Entity Behavior Tree +namespace ecs { -/** - * The `ebt` namespace defines Entity Behavior Tree (EBT) nodes and an EBT context, on which EBT nodes operate. - */ +/// Entity behavior tree (EBT) nodes and context. namespace ebt { /** @@ -35,22 +34,22 @@ namespace ebt { */ struct context { - entt::registry* registry; - entt::entity entity; + ecs::registry* registry; + ecs::entity entity; }; -typedef behavior_tree::status status; -typedef behavior_tree::node node; -typedef behavior_tree::leaf_node leaf_node; -typedef behavior_tree::decorator_node decorator_node; -typedef behavior_tree::composite_node composite_node; -typedef behavior_tree::action action; -typedef behavior_tree::condition condition; -typedef behavior_tree::inverter inverter; -typedef behavior_tree::repeater repeater; -typedef behavior_tree::succeeder succeeder; -typedef behavior_tree::sequence sequence; -typedef behavior_tree::selector selector; +typedef ai::bt::status status; +typedef ai::bt::node node; +typedef ai::bt::leaf_node leaf_node; +typedef ai::bt::decorator_node decorator_node; +typedef ai::bt::composite_node composite_node; +typedef ai::bt::action action; +typedef ai::bt::condition condition; +typedef ai::bt::inverter inverter; +typedef ai::bt::repeater repeater; +typedef ai::bt::succeeder succeeder; +typedef ai::bt::sequence sequence; +typedef ai::bt::selector selector; // Actions status print(context& context, const std::string& text); @@ -61,6 +60,7 @@ status warp_to(context& context, float x, float y, float z); bool is_carrying_food(const context& context); } // namespace ebt +} // namespace ecs -#endif // ANTKEEPER_EBT_HPP +#endif // ANTKEEPER_ECS_EBT_HPP diff --git a/src/resources/behavior-tree-loader.cpp b/src/resources/behavior-tree-loader.cpp index 2cff377..b0a88ce 100644 --- a/src/resources/behavior-tree-loader.cpp +++ b/src/resources/behavior-tree-loader.cpp @@ -19,7 +19,7 @@ #include "resource-loader.hpp" #include "resource-manager.hpp" -#include "game/behavior/ebt.hpp" +#include "ecs/ebt.hpp" #include #include #include @@ -43,7 +43,7 @@ void parse_argument(std::string& value, const std::string& string) } template -std::function pack_function(T (*function)(ebt::context&, Args...), std::list argv) +std::function pack_function(T (*function)(ecs::ebt::context&, Args...), std::list argv) { //if (argv.size() != sizeof...(Args)) @@ -60,18 +60,18 @@ std::function pack_function(T (*function)(ebt::conte } return std::bind( - [function, arguments](ebt::context& context) -> ebt::status + [function, arguments](ecs::ebt::context& context) -> ecs::ebt::status { return std::apply(function, std::tuple_cat(std::make_tuple(context), arguments)); }, std::placeholders::_1); } -static ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager); -static void load_node_child(ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager); -static void load_node_children(ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager); +static ecs::ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager); +static void load_node_child(ecs::ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager); +static void load_node_children(ecs::ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager); -static ebt::node* load_action_node(const nlohmann::json& json, resource_manager* resource_manager) +static ecs::ebt::node* load_action_node(const nlohmann::json& json, resource_manager* resource_manager) { // Get function name auto function_it = json.find("function"); @@ -85,31 +85,31 @@ static ebt::node* load_action_node(const nlohmann::json& json, resource_manager* for (auto it = arguments_it.value().cbegin(); it != arguments_it.value().cend(); ++it) arguments.push_back(it.value().get()); - ebt::action* action_node = new ebt::action(); - if (function_name == "print") action_node->function = pack_function(ebt::print, arguments); - else if (function_name == "print_eid") action_node->function = pack_function(ebt::print_eid, arguments); - else if (function_name == "warp_to") action_node->function = pack_function(ebt::warp_to, arguments); + ecs::ebt::action* action_node = new ecs::ebt::action(); + if (function_name == "print") action_node->function = pack_function(ecs::ebt::print, arguments); + else if (function_name == "print_eid") action_node->function = pack_function(ecs::ebt::print_eid, arguments); + else if (function_name == "warp_to") action_node->function = pack_function(ecs::ebt::warp_to, arguments); return action_node; } -static ebt::node* load_selector_node(const nlohmann::json& json, resource_manager* resource_manager) +static ecs::ebt::node* load_selector_node(const nlohmann::json& json, resource_manager* resource_manager) { - ebt::selector* selector_node = new ebt::selector(); + ecs::ebt::selector* selector_node = new ecs::ebt::selector(); load_node_children(selector_node, json, resource_manager); return selector_node; } -static ebt::node* load_sequence_node(const nlohmann::json& json, resource_manager* resource_manager) +static ecs::ebt::node* load_sequence_node(const nlohmann::json& json, resource_manager* resource_manager) { - ebt::sequence* sequence_node = new ebt::sequence(); + ecs::ebt::sequence* sequence_node = new ecs::ebt::sequence(); load_node_children(sequence_node, json, resource_manager); return sequence_node; } -static ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager) +static ecs::ebt::node* load_node(const nlohmann::json::const_iterator& json, resource_manager* resource_manager) { - static const std::map> node_loaders = + static const std::map> node_loaders = { {"action", &load_action_node}, {"selector", &load_selector_node}, @@ -125,24 +125,24 @@ static ebt::node* load_node(const nlohmann::json::const_iterator& json, resource return node_loader->second(json.value(), resource_manager); } -static void load_node_child(ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager) +static void load_node_child(ecs::ebt::decorator_node* node, const nlohmann::json& json, resource_manager* resource_manager) { auto it = json.find("child"); node->child = load_node(it.value().cbegin(), resource_manager); } -static void load_node_children(ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager) +static void load_node_children(ecs::ebt::composite_node* node, const nlohmann::json& json, resource_manager* resource_manager) { auto children_it = json.find("children"); for (auto it = children_it.value().cbegin(); it != children_it.value().cend(); ++it) { - ebt::node* child = load_node(it.value().begin(), resource_manager); + ecs::ebt::node* child = load_node(it.value().begin(), resource_manager); node->children.push_back(child); } } template <> -ebt::node* resource_loader::load(resource_manager* resource_manager, PHYSFS_File* file) +ecs::ebt::node* resource_loader::load(resource_manager* resource_manager, PHYSFS_File* file) { // Read file into buffer std::size_t size = static_cast(PHYSFS_fileLength(file)); @@ -155,7 +155,7 @@ ebt::node* resource_loader::load(resource_manager* resource_manager, if (json.size() != 1) { - throw std::runtime_error("resource_loader::load(): Behavior tree must have exactly one root node."); + throw std::runtime_error("resource_loader::load(): Behavior tree must have exactly one root node."); } return load_node(json.cbegin(), resource_manager); diff --git a/src/resources/entity-archetype-loader.cpp b/src/resources/entity-archetype-loader.cpp index 8539541..0ea713f 100644 --- a/src/resources/entity-archetype-loader.cpp +++ b/src/resources/entity-archetype-loader.cpp @@ -31,7 +31,7 @@ #include "ecs/components/marker-component.hpp" #include "ecs/components/brush-component.hpp" #include "ecs/archetype.hpp" -#include "game/behavior/ebt.hpp" +#include "ecs/ebt.hpp" #include #include @@ -46,7 +46,7 @@ static bool load_behavior_component(archetype& archetype, resource_manager& reso std::string filename = parameters[1]; behavior_component component; - component.behavior_tree = resource_manager.load(filename); + component.behavior_tree = resource_manager.load(filename); if (!component.behavior_tree) { std::string message = std::string("load_behavior_component(): Failed to load behavior tree \"") + filename + std::string("\"");