diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7faddc1..8b94016 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 3.7)
-
option(VERSION_STRING "Project version string" "0.0.0")
project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX)
diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp
index 1428736..7057132 100644
--- a/src/ai/ai.hpp
+++ b/src/ai/ai.hpp
@@ -23,6 +23,7 @@
/// Artificial intelligence (AI)
namespace ai {}
-#include "behavior-tree.hpp"
+#include "bt/bt.hpp"
+#include "steering/steering.hpp"
#endif // ANTKEEPER_AI_HPP
diff --git a/src/game/state/brood.hpp b/src/ai/bt/bt.hpp
similarity index 68%
rename from src/game/state/brood.hpp
rename to src/ai/bt/bt.hpp
index 1658aae..6a4dd01 100644
--- a/src/game/state/brood.hpp
+++ b/src/ai/bt/bt.hpp
@@ -17,23 +17,20 @@
* along with Antkeeper source code. If not, see .
*/
-#ifndef ANTKEEPER_GAME_STATE_BROOD_HPP
-#define ANTKEEPER_GAME_STATE_BROOD_HPP
+#ifndef ANTKEEPER_AI_BT_HPP
+#define ANTKEEPER_AI_BT_HPP
-#include "game/context.hpp"
+#include
+#include
-namespace game {
-namespace state {
+namespace ai {
-/// Brood game state functions.
-namespace brood {
+/// Behavior tree (BT)
+namespace bt {}
-void enter(game::context* ctx);
-void exit(game::context* ctx);
+} // namespace ai
-} // namespace brood
+#include "ai/bt/node.hpp"
+#include "ai/bt/status.hpp"
-} // namespace state
-} // namespace game
-
-#endif // ANTKEEPER_GAME_STATE_BROOD_HPP
+#endif // ANTKEEPER_AI_BT_HPP
diff --git a/src/ai/behavior-tree.hpp b/src/ai/bt/node.hpp
similarity index 90%
rename from src/ai/behavior-tree.hpp
rename to src/ai/bt/node.hpp
index be00e37..9697057 100644
--- a/src/ai/behavior-tree.hpp
+++ b/src/ai/bt/node.hpp
@@ -17,25 +17,14 @@
* along with Antkeeper source code. If not, see .
*/
-#ifndef ANTKEEPER_AI_BEHAVIOR_TREE_HPP
-#define ANTKEEPER_AI_BEHAVIOR_TREE_HPP
+#ifndef ANTKEEPER_AI_BT_NODE_HPP
+#define ANTKEEPER_AI_BT_NODE_HPP
-#include
-#include
+#include "ai/bt/status.hpp"
namespace ai {
-
-/// Behavior tree (BT)
namespace bt {
-/// Behavior tree node return status enumerations.
-enum class status
-{
- failure, ///< Indicates a node's execution failed.
- success, ///< Indicates a node's execution succeed.
- running ///< Indicates a node's execution has not finished.
-};
-
/**
* Abstract base class for behavior tree nodes.
*
@@ -48,17 +37,18 @@ struct node
typedef T context_type;
/**
- * Executes a node's functionality and returns its status.
+ * Executes a node's function and returns its status.
*
* @param context Context data on which the node will operate.
*/
virtual status execute(context_type& context) const = 0;
};
-/// A node with no children.
+/// Behavior tree node with no children.
template
using leaf_node = node;
+
/// A node with exactly one child.
template
struct decorator_node: node
@@ -193,4 +183,4 @@ status selector::execute(context_type& context) const
} // namespace bt
} // namespace ai
-#endif // ANTKEEPER_AI_BEHAVIOR_TREE_HPP
+#endif // ANTKEEPER_AI_BT_NODE_HPP
diff --git a/src/game/state/forage.hpp b/src/ai/bt/status.hpp
similarity index 64%
rename from src/game/state/forage.hpp
rename to src/ai/bt/status.hpp
index b6068e5..e8417af 100644
--- a/src/game/state/forage.hpp
+++ b/src/ai/bt/status.hpp
@@ -17,23 +17,26 @@
* along with Antkeeper source code. If not, see .
*/
-#ifndef ANTKEEPER_GAME_STATE_FORAGE_HPP
-#define ANTKEEPER_GAME_STATE_FORAGE_HPP
-
-#include "game/context.hpp"
-
-namespace game {
-namespace state {
-
-/// Forage game state functions.
-namespace forage {
-
-void enter(game::context* ctx);
-void exit(game::context* ctx);
-
-} // namespace forage
-
-} // namespace state
-} // namespace game
-
-#endif // ANTKEEPER_GAME_STATE_FORAGE_HPP
+#ifndef ANTKEEPER_AI_BT_STATUS_HPP
+#define ANTKEEPER_AI_BT_STATUS_HPP
+
+namespace ai {
+namespace bt {
+
+/// Behavior tree node return status enumerations.
+enum class status
+{
+ /// Indicates a node's execution has failed.
+ failure,
+
+ /// Indicates a node's execution has succeeded.
+ success,
+
+ /// Indicates a node's execution has not finished.
+ running
+};
+
+} // namespace bt
+} // namespace ai
+
+#endif // ANTKEEPER_AI_BT_STATUS_HPP
diff --git a/src/ai/steering/behavior/wander.cpp b/src/ai/steering/behavior/wander.cpp
index f412a46..6eb8592 100644
--- a/src/ai/steering/behavior/wander.cpp
+++ b/src/ai/steering/behavior/wander.cpp
@@ -46,18 +46,14 @@ float3 wander_2d(const agent& agent, float noise, float distance, float radius,
return seek(agent, center + offset);
}
-/*
-float3 wander_3d(const agent& agent, float distance, float radius, float delta, float& theta, float& phi)
+float3 wander_3d(const agent& agent, float noise, float distance, float radius, float& theta, float& phi)
{
// Shift wander angles
- theta += random(-delta, delta);
- phi += random(-delta, delta);
+ theta += math::random(-noise, noise);
+ phi += math::random(-noise, noise);
// Calculate center of wander sphere
- float3 center = agent.position;
- const float speed_squared = math::dot(agent.velocity, agent.velocity);
- if (speed_squared)
- center += (agent.velocity / std::sqrt(speed_squared)) * distance;
+ const float3 center = agent.position + agent.forward * distance;
// Convert spherical coordinates to Cartesian point on wander sphere
const float r_cos_theta = radius * std::cos(theta);
@@ -71,7 +67,6 @@ float3 wander_3d(const agent& agent, float distance, float radius, float delta,
// Seek toward point on wander sphere
return seek(agent, center + offset);
}
-*/
} // namespace behavior
} // namespace steering
diff --git a/src/ai/steering/behavior/wander.hpp b/src/ai/steering/behavior/wander.hpp
index ea0f840..8b2b939 100644
--- a/src/ai/steering/behavior/wander.hpp
+++ b/src/ai/steering/behavior/wander.hpp
@@ -47,13 +47,12 @@ float3 wander_2d(const agent& agent, float noise, float distance, float radius,
* @param distance Distance to the wander sphere.
* @param radius Radius of the wander sphere.
* @param delta Maximum angle offset.
- * @param theta Polar wander angle, in radians.
- * @param phi Azimuthal wander angle, in radians.
- * @param[in,out] Wander angle, in radians.
+ * @param[in,out] theta Polar wander angle, in radians.
+ * @param[in,out] phi Azimuthal wander angle, in radians.
*
* @return Wander force.
*/
-//float3 wander_3d(const agent& agent, float distance, float radius, float delta, float& theta, float& phi);
+float3 wander_3d(const agent& agent, float noise, float distance, float radius, float& theta, float& phi);
} // namespace behavior
} // namespace steering
diff --git a/src/ai/steering/steering.hpp b/src/ai/steering/steering.hpp
index 71694a2..07b0c7c 100644
--- a/src/ai/steering/steering.hpp
+++ b/src/ai/steering/steering.hpp
@@ -29,6 +29,11 @@ namespace ai {
*/
namespace steering {}
+#include "ai/steering/agent.hpp"
+#include "ai/steering/behavior/flee.hpp"
+#include "ai/steering/behavior/seek.hpp"
+#include "ai/steering/behavior/wander.hpp"
+
} // namespace ai
#endif // ANTKEEPER_AI_STEERING_HPP
diff --git a/src/entity/components/steering.hpp b/src/entity/components/steering.hpp
index d8eb520..1fe34dd 100644
--- a/src/entity/components/steering.hpp
+++ b/src/entity/components/steering.hpp
@@ -30,17 +30,23 @@ struct steering
/// Steering agent.
ai::steering::agent agent;
+ // Wander behavior
float wander_weight;
float wander_noise;
float wander_distance;
float wander_radius;
float wander_angle;
+ float wander_angle2;
+ // Seek behavior
float seek_weight;
float3 seek_target;
+ // Flee behavior
float flee_weight;
- float weight_sum;
+
+ /// Sum of steering behavior weights
+ float sum_weights;
};
} // namespace component
diff --git a/src/entity/ebt.hpp b/src/entity/ebt.hpp
index eeb1da0..7b79008 100644
--- a/src/entity/ebt.hpp
+++ b/src/entity/ebt.hpp
@@ -20,7 +20,7 @@
#ifndef ANTKEEPER_ENTITY_EBT_HPP
#define ANTKEEPER_ENTITY_EBT_HPP
-#include "ai/behavior-tree.hpp"
+#include "ai/bt/bt.hpp"
#include "entity/id.hpp"
#include "entity/registry.hpp"
diff --git a/src/entity/systems/steering.cpp b/src/entity/systems/steering.cpp
index 939d031..94b0c07 100644
--- a/src/entity/systems/steering.cpp
+++ b/src/entity/systems/steering.cpp
@@ -47,7 +47,8 @@ void steering::update(double t, double dt)
float3 force = {0, 0, 0};
if (steering.wander_weight)
{
- force += ai::steering::behavior::wander_2d(agent, steering.wander_noise * dt, steering.wander_distance, steering.wander_radius, steering.wander_angle) * steering.wander_weight;
+ //force += ai::steering::behavior::wander_2d(agent, steering.wander_noise * dt, steering.wander_distance, steering.wander_radius, steering.wander_angle) * steering.wander_weight;
+ force += ai::steering::behavior::wander_3d(agent, steering.wander_noise * dt, steering.wander_distance, steering.wander_radius, steering.wander_angle, steering.wander_angle2) * steering.wander_weight;
}
if (steering.seek_weight)
{
@@ -55,7 +56,8 @@ void steering::update(double t, double dt)
}
// Normalize force
- force /= steering.weight_sum;
+ if (steering.sum_weights)
+ force /= steering.sum_weights;
// Accelerate
agent.acceleration = force / agent.mass;
diff --git a/src/game/state/boot.cpp b/src/game/state/boot.cpp
index ff4d268..5254e58 100644
--- a/src/game/state/boot.cpp
+++ b/src/game/state/boot.cpp
@@ -493,7 +493,7 @@ void boot::setup_rendering()
ctx.sky_pass = new render::sky_pass(ctx.rasterizer, ctx.hdr_framebuffer, ctx.resource_manager);
ctx.sky_pass->set_enabled(false);
- ctx.sky_pass->set_magnification(10.0f);
+ ctx.sky_pass->set_magnification(3.0f);
ctx.app->get_event_dispatcher()->subscribe(ctx.sky_pass);
ctx.ground_pass = new render::ground_pass(ctx.rasterizer, ctx.hdr_framebuffer, ctx.resource_manager);
diff --git a/src/game/state/brood.cpp b/src/game/state/brood.cpp
deleted file mode 100644
index d774a1f..0000000
--- a/src/game/state/brood.cpp
+++ /dev/null
@@ -1,399 +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 "game/state/brood.hpp"
-#include "entity/archetype.hpp"
-#include "entity/commands.hpp"
-#include "entity/components/observer.hpp"
-#include "entity/components/camera.hpp"
-#include "entity/components/terrain.hpp"
-#include "entity/components/transform.hpp"
-#include "entity/components/chamber.hpp"
-#include "entity/components/constraints/spring-to.hpp"
-#include "entity/components/constraints/three-dof.hpp"
-#include "entity/components/constraint-stack.hpp"
-#include "animation/screen-transition.hpp"
-#include "animation/ease.hpp"
-#include "resources/resource-manager.hpp"
-#include "render/passes/sky-pass.hpp"
-#include "application.hpp"
-#include
-
-namespace game {
-namespace state {
-namespace brood {
-
-static void setup_nest(game::context* ctx);
-static void setup_ants(game::context* ctx);
-static void setup_camera(game::context* ctx);
-static void setup_controls(game::context* ctx);
-
-void enter(game::context* ctx)
-{
- setup_nest(ctx);
- setup_ants(ctx);
- setup_camera(ctx);
- setup_controls(ctx);
-
- ctx->underground_ambient_light->set_intensity(1.0f);
-
- // Create larva
- {
- entity::archetype* larva_archetype = ctx->resource_manager->load("ant-larva.ent");
- auto larva_eid = larva_archetype->create(*ctx->entity_registry);
- entity::command::warp_to(*ctx->entity_registry, larva_eid, {0.0f, 0.0f, 0.0f});
- entity::command::assign_render_layers(*ctx->entity_registry, larva_eid, 0b1);
- }
-
- // Create cocoon
- {
- entity::archetype* cocoon_archetype = ctx->resource_manager->load("ant-cocoon.ent");
- auto cocoon_eid = cocoon_archetype->create(*ctx->entity_registry);
- entity::command::warp_to(*ctx->entity_registry, cocoon_eid, {-50, 0.1935f, 0});
- entity::command::assign_render_layers(*ctx->entity_registry, cocoon_eid, 0b1);
- }
-
- // Reset tweening
- ctx->underground_scene->update_tweens();
-
- // Start fade in
- ctx->fade_transition->transition(1.0f, true, ease::in_quad);
-}
-
-void exit(game::context* ctx)
-{}
-
-void setup_nest(game::context* ctx)
-{
- // Create nest central shaft entity
- if (!ctx->entities.count("shaft"))
- {
- entity::id shaft_eid = ctx->entity_registry->create();
- ctx->entities["shaft"] = shaft_eid;
-
- entity::component::transform transform;
- transform.local = math::transform::identity;
- transform.world = transform.local;
- transform.warp = true;
-
- ctx->entity_registry->assign(shaft_eid, transform);
- }
-
- // Create nest lobby chamber entity
- if (!ctx->entities.count("lobby"))
- {
- entity::id lobby_eid = ctx->entity_registry->create();
- ctx->entities["lobby"] = lobby_eid;
-
- entity::component::chamber chamber;
- chamber.shaft_eid = ctx->entities["shaft"];
- chamber.distance = 10.0f;
- chamber.previous_chamber_eid = entt::null;
- chamber.next_chamber_eid = entt::null;
- }
-}
-
-void setup_ants(game::context* ctx)
-{
- // Create queen ant entity
- if (!ctx->entities.count("queen"))
- {
- entity::id queen_eid = ctx->entity_registry->create();
- ctx->entities["queen"] = queen_eid;
- }
-}
-
-void setup_camera(game::context* ctx)
-{
- // Switch to underground camera
- ctx->surface_camera->set_active(false);
- ctx->underground_camera->set_active(true);
-
- // Create underground camera entity
- if (!ctx->entities.count("underground_cam"))
- {
- // Create camera target entity
- entity::id target_eid = ctx->entity_registry->create();
- ctx->entities["underground_cam_target"] = target_eid;
- {
- // Transform
- entity::component::transform target_transform;
- target_transform.local = math::transform::identity;
- target_transform.world = target_transform.local;
- target_transform.warp = true;
- ctx->entity_registry->assign(target_eid, target_transform);
- }
-
- // Create camera entity
- entity::id camera_eid = ctx->entity_registry->create();
- ctx->entities["underground_cam"] = camera_eid;
-
- // Create camera transform component
- entity::component::transform transform;
- transform.local = math::transform::identity;
- transform.world = transform.local;
- transform.warp = true;
- ctx->entity_registry->assign(camera_eid, transform);
-
- // Create camera camera component
- entity::component::camera camera;
- camera.object = ctx->underground_camera;
- ctx->entity_registry->assign(camera_eid, camera);
-
- // Create camera 3DOF constraint entity
- entity::id three_dof_constraint_eid = ctx->entity_registry->create();
- ctx->entities["underground_cam_3dof"] = three_dof_constraint_eid;
- {
- // Create 3DOF to constraint
- entity::component::constraint::three_dof three_dof;
- three_dof.yaw = 0.0f;
- three_dof.pitch = 0.0f;
- three_dof.roll = 0.0f;
- ctx->entity_registry->assign(three_dof_constraint_eid, three_dof);
-
- // Create constraint stack node component
- entity::component::constraint_stack_node node;
- node.active = true;
- node.weight = 1.0f;
- node.next = entt::null;
- ctx->entity_registry->assign(three_dof_constraint_eid, node);
- }
-
- // Create camera spring to constraint entity
- entity::id spring_constraint_eid = ctx->entity_registry->create();
- {
- // Create spring to constraint
- entity::component::constraint::spring_to spring;
- spring.target = target_eid;
- spring.translation = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 1.0f, math::two_pi};
- spring.translation.w = hz_to_rads(8.0f);
-
- spring.spring_translation = true;
- spring.spring_rotation = false;
- ctx->entity_registry->assign(spring_constraint_eid, spring);
-
- // Create constraint stack node component
- entity::component::constraint_stack_node node;
- node.active = true;
- node.weight = 1.0f;
- node.next = three_dof_constraint_eid;
- ctx->entity_registry->assign(spring_constraint_eid, node);
- }
-
- // Create camera constraint stack component
- entity::component::constraint_stack constraint_stack;
- constraint_stack.head = spring_constraint_eid;
- ctx->entity_registry->assign(camera_eid, constraint_stack);
- }
-
- ctx->underground_camera->set_exposure(0.0f);
-}
-
-void setup_controls(game::context* ctx)
-{
- // Get underground camera entity
- entity::id camera_eid = ctx->entities["underground_cam"];
- entity::id target_eid = ctx->entities["underground_cam_target"];
- entity::id three_dof_eid = ctx->entities["underground_cam_3dof"];
-
- const float dolly_speed = 20.0f;
- const float truck_speed = dolly_speed;
- const float pedestal_speed = 30.0f;
- const float pan_speed = math::radians(8.0f);
- const float tilt_speed = pan_speed;
-
- const input::control* move_slow = ctx->controls["move_slow"];
- const input::control* move_fast = ctx->controls["move_fast"];
- const input::control* mouse_rotate = ctx->controls["mouse_rotate"];
-
- ctx->controls["dolly_forward"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.5f;
- if (move_fast->is_active())
- value *= 2.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});
-
- const float3 movement = {0.0f, 0.0f, -truck_speed * value * (1.0f / 60.0f)};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Dolly backward
- ctx->controls["dolly_backward"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.5f;
- if (move_fast->is_active())
- value *= 2.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});
-
- const float3 movement = {0.0f, 0.0f, truck_speed * value * (1.0f / 60.0f)};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Truck right
- ctx->controls["truck_right"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.5f;
- if (move_fast->is_active())
- value *= 2.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});
-
- const float3 movement = {truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Truck left
- ctx->controls["truck_left"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.5f;
- if (move_fast->is_active())
- value *= 2.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});
-
- const float3 movement = {-truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Pedestal up
- ctx->controls["pedestal_up"]->set_active_callback
- (
- [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.5f;
- if (move_fast->is_active())
- value *= 2.0f;
-
- const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f};
- entity::command::translate(*ctx->entity_registry, target_eid, movement);
- }
- );
-
- // Pedestal down
- ctx->controls["pedestal_down"]->set_active_callback
- (
- [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.5f;
- if (move_fast->is_active())
- value *= 2.0f;
-
- const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f};
- entity::command::translate(*ctx->entity_registry, target_eid, movement);
- }
- );
-
- // Mouse rotate
- ctx->controls["mouse_rotate"]->set_activated_callback
- (
- [&ctx]()
- {
- ctx->app->set_relative_mouse_mode(true);
- }
- );
- ctx->controls["mouse_rotate"]->set_deactivated_callback
- (
- [&ctx]()
- {
- ctx->app->set_relative_mouse_mode(false);
- }
- );
-
- // Pan left
- ctx->controls["pan_left_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, pan_speed, mouse_rotate](float value)
- {
- if (!mouse_rotate->is_active())
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.yaw += pan_speed * value * (1.0f / 60.0f);
- }
- );
-
- // Pan right
- ctx->controls["pan_right_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, pan_speed, mouse_rotate](float value)
- {
- if (!mouse_rotate->is_active())
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.yaw -= pan_speed * value * (1.0f / 60.0f);
- }
- );
-
- // Tilt up
- ctx->controls["tilt_up_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, tilt_speed, mouse_rotate](float value)
- {
- if (!mouse_rotate->is_active())
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.pitch -= tilt_speed * value * (1.0f / 60.0f);
- three_dof.pitch = std::max(math::radians(-90.0f), three_dof.pitch);
- }
- );
-
- // Tilt down
- ctx->controls["tilt_down_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, tilt_speed, mouse_rotate](float value)
- {
- if (!mouse_rotate->is_active())
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.pitch += tilt_speed * value * (1.0f / 60.0f);
- three_dof.pitch = std::min(math::radians(90.0f), three_dof.pitch);
- }
- );
-}
-
-} // namespace brood
-} // namespace state
-} // namespace game
diff --git a/src/game/state/forage.cpp b/src/game/state/forage.cpp
deleted file mode 100644
index e95510b..0000000
--- a/src/game/state/forage.cpp
+++ /dev/null
@@ -1,530 +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 "game/state/forage.hpp"
-#include "entity/archetype.hpp"
-#include "entity/commands.hpp"
-#include "entity/components/observer.hpp"
-#include "entity/components/terrain.hpp"
-#include "entity/components/transform.hpp"
-#include "entity/components/celestial-body.hpp"
-#include "entity/components/tool.hpp"
-#include "entity/systems/astronomy.hpp"
-#include "animation/screen-transition.hpp"
-#include "animation/ease.hpp"
-#include "resources/resource-manager.hpp"
-#include "entity/components/camera.hpp"
-#include "entity/components/constraints/spring-to.hpp"
-#include "entity/components/constraints/three-dof.hpp"
-#include "entity/components/constraint-stack.hpp"
-#include "application.hpp"
-#include "game/tools.hpp"
-
-namespace game {
-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)
-{
- setup_camera(ctx);
- setup_tools(ctx);
- setup_controls(ctx);
-
- // Find planet EID by name
- entity::id planet_eid = ctx->entities["planet"];
-
- // Create biome terrain component
- entity::component::terrain biome_terrain;
- biome_terrain.max_lod = 18;
- biome_terrain.patch_material = ctx->resource_manager->load("desert-terrain.mtl");
- biome_terrain.elevation = [](double, double) -> double
- {
- return 0.0;
- };
-
- // Replace planet terrain component with biome terrain component
- ctx->entity_registry->replace(planet_eid, biome_terrain);
-
- // Create observer
- entity::id observer_eid = ctx->entity_registry->create();
- {
- entity::component::observer observer;
- observer.reference_body_eid = planet_eid;
- observer.elevation = 0.0;
- observer.latitude = 0.0;
- observer.longitude = 0.0;
- observer.camera = ctx->surface_camera;
- ctx->entity_registry->assign(observer_eid, observer);
-
- // Set reference location of astronomy system
- //ctx->astronomy_system->set_reference_body(planet_eid);
- ctx->astronomy_system->set_observer_location(double3{observer.elevation, observer.latitude, observer.longitude});
- }
-
- // Create larva
- {
- entity::archetype* larva_archetype = ctx->resource_manager->load("ant-larva.ent");
- auto larva_eid = larva_archetype->create(*ctx->entity_registry);
- entity::command::warp_to(*ctx->entity_registry, larva_eid, {50, 0.1935f, 0});
- entity::command::assign_render_layers(*ctx->entity_registry, larva_eid, 0b10);
- }
-
- // Create cocoon
- {
- entity::archetype* cocoon_archetype = ctx->resource_manager->load("ant-cocoon.ent");
- auto cocoon_eid = cocoon_archetype->create(*ctx->entity_registry);
- entity::command::warp_to(*ctx->entity_registry, cocoon_eid, {-50, 0.1935f, 0});
- entity::command::assign_render_layers(*ctx->entity_registry, cocoon_eid, 0b10);
- }
-
- // Create moon
- {
- entity::archetype* moon_archetype = ctx->resource_manager->load("moon.ent");
- auto moon_eid = moon_archetype->create(*ctx->entity_registry);
- entity::command::warp_to(*ctx->entity_registry, moon_eid, {50.0f, 50.0f, 50.0f});
- entity::command::assign_render_layers(*ctx->entity_registry, moon_eid, 0b10);
- entity::command::set_scale(*ctx->entity_registry, moon_eid, float3{1.0f, 1.0f, 1.0f} * 10.0f);
- }
-
- ctx->surface_scene->update_tweens();
-
- // Start fade in
- ctx->fade_transition->transition(1.0f, true, ease::in_quad);
-}
-
-void exit(game::context* ctx)
-{}
-
-void setup_camera(game::context* ctx)
-{
- // Switch to surface camera
- ctx->underground_camera->set_active(false);
- ctx->surface_camera->set_active(true);
-
- // Create surface camera entity
- if (!ctx->entities.count("surface_cam"))
- {
- // Create camera target entity
- entity::id target_eid = ctx->entity_registry->create();
- ctx->entities["surface_cam_target"] = target_eid;
- {
- // Transform
- entity::component::transform target_transform;
- target_transform.local = math::transform::identity;
- target_transform.world = target_transform.local;
- target_transform.warp = true;
- ctx->entity_registry->assign(target_eid, target_transform);
- }
-
- // Create camera entity
- entity::id camera_eid = ctx->entity_registry->create();
- ctx->entities["surface_cam"] = camera_eid;
-
- // Create camera transform component
- entity::component::transform transform;
- transform.local = math::transform::identity;
- transform.world = transform.local;
- transform.warp = true;
- ctx->entity_registry->assign(camera_eid, transform);
-
- // Create camera camera component
- entity::component::camera camera;
- camera.object = ctx->surface_camera;
- ctx->entity_registry->assign(camera_eid, camera);
-
- // Create camera 3DOF constraint entity
- entity::id three_dof_constraint_eid = ctx->entity_registry->create();
- ctx->entities["surface_cam_3dof"] = three_dof_constraint_eid;
- {
- // Create 3DOF to constraint
- entity::component::constraint::three_dof three_dof;
- three_dof.yaw = 0.0f;
- three_dof.pitch = 0.0f;
- three_dof.roll = 0.0f;
- ctx->entity_registry->assign(three_dof_constraint_eid, three_dof);
-
- // Create constraint stack node component
- entity::component::constraint_stack_node node;
- node.active = true;
- node.weight = 1.0f;
- node.next = entt::null;
- ctx->entity_registry->assign(three_dof_constraint_eid, node);
- }
-
- // Create camera spring to constraint entity
- entity::id spring_constraint_eid = ctx->entity_registry->create();
- {
- // Create spring to constraint
- entity::component::constraint::spring_to spring;
- spring.target = target_eid;
- spring.translation = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 1.0f, math::two_pi};
- spring.translation.w = hz_to_rads(8.0f);
-
- spring.spring_translation = true;
- spring.spring_rotation = false;
- ctx->entity_registry->assign(spring_constraint_eid, spring);
-
- // Create constraint stack node component
- entity::component::constraint_stack_node node;
- node.active = true;
- node.weight = 1.0f;
- node.next = three_dof_constraint_eid;
- ctx->entity_registry->assign(spring_constraint_eid, node);
- }
-
- // Create camera constraint stack component
- entity::component::constraint_stack constraint_stack;
- constraint_stack.head = spring_constraint_eid;
- ctx->entity_registry->assign(camera_eid, constraint_stack);
- }
-
- ctx->surface_camera->set_exposure(-14.5f);
-}
-
-void setup_tools(game::context* ctx)
-{
- ctx->entities["camera_tool"] = build_camera_tool(*ctx);
- ctx->entities["time_tool"] = build_time_tool(*ctx);
-
- // Set active tool
- ctx->entities["active_tool"] = ctx->entities["time_tool"];
-}
-
-void setup_controls(game::context* ctx)
-{
- // Get underground camera entity
- entity::id camera_eid = ctx->entities["surface_cam"];
- entity::id target_eid = ctx->entities["surface_cam_target"];
- entity::id three_dof_eid = ctx->entities["surface_cam_3dof"];
-
- const float dolly_speed = 20.0f;
- const float truck_speed = dolly_speed;
- const float pedestal_speed = 30.0f;
- float mouse_tilt_sensitivity = 1.0f;
- float mouse_pan_sensitivity = 1.0f;
- bool mouse_invert_tilt = false;
- bool mouse_invert_pan = false;
- float gamepad_tilt_sensitivity = 1.0f;
- float gamepad_pan_sensitivity = 1.0f;
- bool gamepad_invert_tilt = false;
- bool gamepad_invert_pan = false;
- bool mouse_look_toggle = false;
- ctx->mouse_look = false;
-
- if (ctx->config->contains("mouse_tilt_sensitivity"))
- mouse_tilt_sensitivity = math::radians((*ctx->config)["mouse_tilt_sensitivity"].get());
- if (ctx->config->contains("mouse_pan_sensitivity"))
- mouse_pan_sensitivity = math::radians((*ctx->config)["mouse_pan_sensitivity"].get());
- if (ctx->config->contains("mouse_invert_tilt"))
- mouse_invert_tilt = math::radians((*ctx->config)["mouse_invert_tilt"].get());
- if (ctx->config->contains("mouse_invert_pan"))
- mouse_invert_pan = math::radians((*ctx->config)["mouse_invert_pan"].get());
- if (ctx->config->contains("mouse_look_toggle"))
- mouse_look_toggle = math::radians((*ctx->config)["mouse_look_toggle"].get());
-
- if (ctx->config->contains("gamepad_tilt_sensitivity"))
- gamepad_tilt_sensitivity = math::radians((*ctx->config)["gamepad_tilt_sensitivity"].get());
- if (ctx->config->contains("gamepad_pan_sensitivity"))
- gamepad_pan_sensitivity = math::radians((*ctx->config)["gamepad_pan_sensitivity"].get());
- if (ctx->config->contains("gamepad_invert_tilt"))
- gamepad_invert_tilt = math::radians((*ctx->config)["gamepad_invert_tilt"].get());
- if (ctx->config->contains("gamepad_invert_pan"))
- gamepad_invert_pan = math::radians((*ctx->config)["gamepad_invert_pan"].get());
-
- const input::control* move_slow = ctx->controls["move_slow"];
- const input::control* move_fast = ctx->controls["move_fast"];
- const input::control* mouse_look = ctx->controls["mouse_look"];
-
- float mouse_tilt_factor = mouse_tilt_sensitivity * (mouse_invert_tilt ? -1.0f : 1.0f);
- float mouse_pan_factor = mouse_pan_sensitivity * (mouse_invert_pan ? -1.0f : 1.0f);
- float gamepad_tilt_factor = gamepad_tilt_sensitivity * (gamepad_invert_tilt ? -1.0f : 1.0f);
- float gamepad_pan_factor = gamepad_pan_sensitivity * (gamepad_invert_pan ? -1.0f : 1.0f);
-
- ctx->controls["dolly_forward"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.25f;
- if (move_fast->is_active())
- 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});
-
- const float3 movement = {0.0f, 0.0f, -truck_speed * value * (1.0f / 60.0f)};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Dolly backward
- ctx->controls["dolly_backward"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.25f;
- if (move_fast->is_active())
- 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});
-
- const float3 movement = {0.0f, 0.0f, truck_speed * value * (1.0f / 60.0f)};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Truck right
- ctx->controls["truck_right"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.25f;
- if (move_fast->is_active())
- 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});
-
- const float3 movement = {truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Truck left
- ctx->controls["truck_left"]->set_active_callback
- (
- [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.25f;
- if (move_fast->is_active())
- 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});
-
- const float3 movement = {-truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
- entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
- }
- );
-
- // Pedestal up
- ctx->controls["pedestal_up"]->set_active_callback
- (
- [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.25f;
- if (move_fast->is_active())
- 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);
- }
- );
-
- // Pedestal down
- ctx->controls["pedestal_down"]->set_active_callback
- (
- [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
- {
- if (move_slow->is_active())
- value *= 0.25f;
- if (move_fast->is_active())
- 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);
- }
- );
-
- // Mouse rotate
- ctx->controls["mouse_look"]->set_activated_callback
- (
- [ctx, mouse_look_toggle]()
- {
- if (mouse_look_toggle)
- ctx->mouse_look = !ctx->mouse_look;
- else
- ctx->mouse_look = true;
-
- ctx->app->set_relative_mouse_mode(ctx->mouse_look);
- }
- );
- ctx->controls["mouse_look"]->set_deactivated_callback
- (
- [ctx, mouse_look_toggle]()
- {
- if (!mouse_look_toggle)
- {
- ctx->mouse_look = false;
- ctx->app->set_relative_mouse_mode(false);
- }
- }
- );
-
- // Pan left
- ctx->controls["pan_left_gamepad"]->set_active_callback
- (
- [ctx, three_dof_eid, gamepad_pan_factor](float value)
- {
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.yaw += gamepad_pan_factor * value * (1.0f / 60.0f);
- }
- );
- ctx->controls["pan_left_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, mouse_pan_factor](float value)
- {
- if (!ctx->mouse_look)
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.yaw += mouse_pan_factor * value * (1.0f / 60.0f);
- }
- );
-
- // Pan right
- ctx->controls["pan_right_gamepad"]->set_active_callback
- (
- [ctx, three_dof_eid, gamepad_pan_factor](float value)
- {
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.yaw -= gamepad_pan_factor * value * (1.0f / 60.0f);
- }
- );
- ctx->controls["pan_right_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, mouse_pan_factor](float value)
- {
- if (!ctx->mouse_look)
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.yaw -= mouse_pan_factor * value * (1.0f / 60.0f);
- }
- );
-
- // Tilt up
- ctx->controls["tilt_up_gamepad"]->set_active_callback
- (
- [ctx, three_dof_eid, gamepad_tilt_factor](float value)
- {
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.pitch -= gamepad_tilt_factor * value * (1.0f / 60.0f);
- three_dof.pitch = std::max(math::radians(-90.0f), three_dof.pitch);
- }
- );
- ctx->controls["tilt_up_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, mouse_tilt_factor](float value)
- {
- if (!ctx->mouse_look)
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.pitch -= mouse_tilt_factor * value * (1.0f / 60.0f);
- three_dof.pitch = std::max(math::radians(-90.0f), three_dof.pitch);
- }
- );
-
- // Tilt down
- ctx->controls["tilt_down_gamepad"]->set_active_callback
- (
- [ctx, three_dof_eid, gamepad_tilt_factor](float value)
- {
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.pitch += gamepad_tilt_factor * value * (1.0f / 60.0f);
- three_dof.pitch = std::min(math::radians(90.0f), three_dof.pitch);
- }
- );
- ctx->controls["tilt_down_mouse"]->set_active_callback
- (
- [ctx, three_dof_eid, mouse_tilt_factor](float value)
- {
- if (!ctx->mouse_look)
- return;
-
- auto& three_dof = ctx->entity_registry->get(three_dof_eid);
- three_dof.pitch += mouse_tilt_factor * value * (1.0f / 60.0f);
- 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.count("active_tool"))
- {
- entity::id tool_eid = ctx->entities["active_tool"];
- const auto& tool = ctx->entity_registry->get(tool_eid);
- if (tool.activated)
- tool.activated();
- }
- }
- );
- ctx->controls["use_tool"]->set_deactivated_callback
- (
- [&ctx]()
- {
- if (ctx->entities.count("active_tool"))
- {
- entity::id tool_eid = ctx->entities["active_tool"];
- const auto& tool = ctx->entity_registry->get(tool_eid);
- if (tool.deactivated)
- tool.deactivated();
- }
- }
- );
- ctx->controls["use_tool"]->set_active_callback
- (
- [&ctx](float value)
- {
- if (ctx->entities.count("active_tool"))
- {
- entity::id tool_eid = ctx->entities["active_tool"];
- const auto& tool = ctx->entity_registry->get(tool_eid);
- if (tool.active)
- tool.active();
- }
- }
- );
-
- /*
- 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) + ")");
-
- entity::id planet_eid = ctx->entities["planet"];
- entity::component::celestial_body& body = ctx->entity_registry->get(planet_eid);
- body.axial_tilt += math::radians(30.0f) * 1.0f / 60.0f;
- */
-}
-
-} // namespace forage
-} // namespace state
-} // namespace game
diff --git a/src/game/state/main-menu.cpp b/src/game/state/main-menu.cpp
index 39d68bc..62e67d9 100644
--- a/src/game/state/main-menu.cpp
+++ b/src/game/state/main-menu.cpp
@@ -20,7 +20,6 @@
#include "game/state/main-menu.hpp"
#include "game/state/options-menu.hpp"
#include "game/state/extras-menu.hpp"
-#include "game/state/forage.hpp"
#include "game/state/nuptial-flight.hpp"
#include "game/menu.hpp"
#include "render/passes/clear-pass.hpp"
diff --git a/src/game/state/nuptial-flight.cpp b/src/game/state/nuptial-flight.cpp
index 544b44b..d12f782 100644
--- a/src/game/state/nuptial-flight.cpp
+++ b/src/game/state/nuptial-flight.cpp
@@ -113,7 +113,7 @@ nuptial_flight::nuptial_flight(game::context& ctx):
game::world::set_time_scale(ctx, 60.0);
// Create boids
- for (int i = 0; i < 20; ++i)
+ for (int i = 0; i < 50; ++i)
{
entity::id boid_eid = ctx.entity_registry->create();
@@ -134,10 +134,10 @@ nuptial_flight::nuptial_flight(game::context& ctx):
// Create steering component
entity::component::steering steering;
steering.agent.mass = 1.0f;
- steering.agent.position = {0, 0, 0};
+ steering.agent.position = {0, 100, 0};
steering.agent.velocity = {0, 0, 0};
steering.agent.acceleration = {0, 0, 0};
- steering.agent.max_force = 2.5f;
+ steering.agent.max_force = 4.0f;
steering.agent.max_speed = 5.0f;
steering.agent.max_speed_squared = steering.agent.max_speed * steering.agent.max_speed;
steering.agent.orientation = math::quaternion::identity;
@@ -146,18 +146,19 @@ nuptial_flight::nuptial_flight(game::context& ctx):
steering.wander_weight = 1.0f;
steering.wander_noise = math::radians(2000.0f);
steering.wander_distance = 10.0f;
- steering.wander_radius = 5.0f;
+ steering.wander_radius = 8.0f;
steering.wander_angle = 0.0f;
+ steering.wander_angle2 = 0.0f;
steering.seek_weight = 0.2f;
- steering.seek_target = {0, 0, 0};
+ steering.seek_target = {0, 100, 0};
steering.flee_weight = 0.0f;
- steering.weight_sum = steering.wander_weight + steering.seek_weight + steering.flee_weight;
+ steering.sum_weights = steering.wander_weight + steering.seek_weight + steering.flee_weight;
ctx.entity_registry->assign(boid_eid, steering);
}
}
// Load biome
- game::load::biome(ctx, "lab.bio");
+ game::load::biome(ctx, "desert-scrub.bio");
// Setup and enable sky and ground passes
ctx.sky_pass->set_enabled(true);