💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

463 lines
14 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "game/states/forage.hpp"
  20. #include "entity/archetype.hpp"
  21. #include "entity/commands.hpp"
  22. #include "entity/components/observer.hpp"
  23. #include "entity/components/terrain.hpp"
  24. #include "entity/components/transform.hpp"
  25. #include "entity/systems/astronomy.hpp"
  26. #include "animation/screen-transition.hpp"
  27. #include "animation/ease.hpp"
  28. #include "resources/resource-manager.hpp"
  29. #include "entity/components/camera.hpp"
  30. #include "entity/components/constraints/spring-to.hpp"
  31. #include "entity/components/constraints/three-dof.hpp"
  32. #include "entity/components/constraint-stack.hpp"
  33. #include "application.hpp"
  34. namespace game {
  35. namespace state {
  36. namespace forage {
  37. static void setup_camera(game::context* ctx);
  38. static void setup_tools(game::context* ctx);
  39. static void setup_controls(game::context* ctx);
  40. void enter(game::context* ctx)
  41. {
  42. setup_camera(ctx);
  43. setup_controls(ctx);
  44. // Find planet EID by name
  45. entity::id planet_eid = ctx->entities["planet"];
  46. // Create biome terrain component
  47. entity::component::terrain biome_terrain;
  48. biome_terrain.max_lod = 18;
  49. biome_terrain.patch_material = ctx->resource_manager->load<material>("desert-terrain.mtl");
  50. biome_terrain.elevation = [](double, double) -> double
  51. {
  52. return 0.0;
  53. };
  54. // Replace planet terrain component with biome terrain component
  55. ctx->entity_registry->replace<entity::component::terrain>(planet_eid, biome_terrain);
  56. // Create observer
  57. entity::id observer_eid = ctx->entity_registry->create();
  58. {
  59. entity::component::observer observer;
  60. observer.reference_body_eid = planet_eid;
  61. observer.elevation = 0.0;
  62. observer.latitude = 0.0;
  63. observer.longitude = 0.0;
  64. observer.camera = ctx->surface_camera;
  65. ctx->entity_registry->assign<entity::component::observer>(observer_eid, observer);
  66. // Set reference location of astronomy system
  67. ctx->astronomy_system->set_reference_body(planet_eid);
  68. ctx->astronomy_system->set_observer_location(double3{observer.elevation, observer.latitude, observer.longitude});
  69. }
  70. // Create larva
  71. {
  72. entity::archetype* larva_archetype = ctx->resource_manager->load<entity::archetype>("ant-larva.ent");
  73. auto larva_eid = larva_archetype->create(*ctx->entity_registry);
  74. entity::command::warp_to(*ctx->entity_registry, larva_eid, {50, 0.1935f, 0});
  75. entity::command::assign_render_layers(*ctx->entity_registry, larva_eid, 0b10);
  76. }
  77. // Create cocoon
  78. {
  79. entity::archetype* cocoon_archetype = ctx->resource_manager->load<entity::archetype>("ant-cocoon.ent");
  80. auto cocoon_eid = cocoon_archetype->create(*ctx->entity_registry);
  81. entity::command::warp_to(*ctx->entity_registry, cocoon_eid, {-50, 0.1935f, 0});
  82. entity::command::assign_render_layers(*ctx->entity_registry, cocoon_eid, 0b10);
  83. }
  84. ctx->surface_scene->update_tweens();
  85. // Start fade in
  86. ctx->fade_transition->transition(1.0f, true, ease<float>::in_quad);
  87. }
  88. void exit(game::context* ctx)
  89. {}
  90. void setup_camera(game::context* ctx)
  91. {
  92. // Switch to surface camera
  93. ctx->underground_camera->set_active(false);
  94. ctx->surface_camera->set_active(true);
  95. // Create surface camera entity
  96. if (!ctx->entities.count("surface_cam"))
  97. {
  98. // Create camera target entity
  99. entity::id target_eid = ctx->entity_registry->create();
  100. ctx->entities["surface_cam_target"] = target_eid;
  101. {
  102. // Transform
  103. entity::component::transform target_transform;
  104. target_transform.local = math::identity_transform<float>;
  105. target_transform.world = target_transform.local;
  106. target_transform.warp = true;
  107. ctx->entity_registry->assign<entity::component::transform>(target_eid, target_transform);
  108. }
  109. // Create camera entity
  110. entity::id camera_eid = ctx->entity_registry->create();
  111. ctx->entities["surface_cam"] = camera_eid;
  112. // Create camera transform component
  113. entity::component::transform transform;
  114. transform.local = math::identity_transform<float>;
  115. transform.world = transform.local;
  116. transform.warp = true;
  117. ctx->entity_registry->assign<entity::component::transform>(camera_eid, transform);
  118. // Create camera camera component
  119. entity::component::camera camera;
  120. camera.object = ctx->surface_camera;
  121. ctx->entity_registry->assign<entity::component::camera>(camera_eid, camera);
  122. // Create camera 3DOF constraint entity
  123. entity::id three_dof_constraint_eid = ctx->entity_registry->create();
  124. ctx->entities["surface_cam_3dof"] = three_dof_constraint_eid;
  125. {
  126. // Create 3DOF to constraint
  127. entity::component::constraint::three_dof three_dof;
  128. three_dof.yaw = 0.0f;
  129. three_dof.pitch = 0.0f;
  130. three_dof.roll = 0.0f;
  131. ctx->entity_registry->assign<entity::component::constraint::three_dof>(three_dof_constraint_eid, three_dof);
  132. // Create constraint stack node component
  133. entity::component::constraint_stack_node node;
  134. node.active = true;
  135. node.weight = 1.0f;
  136. node.next = entt::null;
  137. ctx->entity_registry->assign<entity::component::constraint_stack_node>(three_dof_constraint_eid, node);
  138. }
  139. // Create camera spring to constraint entity
  140. entity::id spring_constraint_eid = ctx->entity_registry->create();
  141. {
  142. // Create spring to constraint
  143. entity::component::constraint::spring_to spring;
  144. spring.target = target_eid;
  145. 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<float>};
  146. spring.translation.w = hz_to_rads(8.0f);
  147. spring.spring_translation = true;
  148. spring.spring_rotation = false;
  149. ctx->entity_registry->assign<entity::component::constraint::spring_to>(spring_constraint_eid, spring);
  150. // Create constraint stack node component
  151. entity::component::constraint_stack_node node;
  152. node.active = true;
  153. node.weight = 1.0f;
  154. node.next = three_dof_constraint_eid;
  155. ctx->entity_registry->assign<entity::component::constraint_stack_node>(spring_constraint_eid, node);
  156. }
  157. // Create camera constraint stack component
  158. entity::component::constraint_stack constraint_stack;
  159. constraint_stack.head = spring_constraint_eid;
  160. ctx->entity_registry->assign<entity::component::constraint_stack>(camera_eid, constraint_stack);
  161. }
  162. ctx->surface_camera->set_exposure(-14.5f);
  163. }
  164. void setup_tools(game::context* ctx)
  165. {
  166. if (!ctx->entities.count("move_tool"))
  167. {
  168. entity::id tool_eid = ctx->entity_registry->create();
  169. ctx->entities["move_tool"] = tool_eid;
  170. }
  171. if (!ctx->entities.count("paint_tool"))
  172. {
  173. entity::id tool_eid = ctx->entity_registry->create();
  174. ctx->entities["paint_tool"] = tool_eid;
  175. }
  176. if (!ctx->entities.count("flip_tool"))
  177. {
  178. entity::id tool_eid = ctx->entity_registry->create();
  179. ctx->entities["flip_tool"] = tool_eid;
  180. }
  181. if (!ctx->entities.count("poke_tool"))
  182. {
  183. entity::id tool_eid = ctx->entity_registry->create();
  184. ctx->entities["poke_tool"] = tool_eid;
  185. }
  186. if (!ctx->entities.count("inspect_tool"))
  187. {
  188. entity::id tool_eid = ctx->entity_registry->create();
  189. ctx->entities["inspect_tool"] = tool_eid;
  190. }
  191. if (!ctx->entities.count("label_tool"))
  192. {
  193. entity::id tool_eid = ctx->entity_registry->create();
  194. ctx->entities["label_tool"] = tool_eid;
  195. }
  196. if (!ctx->entities.count("wait_tool"))
  197. {
  198. entity::id tool_eid = ctx->entity_registry->create();
  199. ctx->entities["wait_tool"] = tool_eid;
  200. }
  201. // Set move tool as active tool
  202. ctx->entities["active_tool"] = ctx->entities["move_tool"];
  203. }
  204. void setup_controls(game::context* ctx)
  205. {
  206. // Get underground camera entity
  207. entity::id camera_eid = ctx->entities["surface_cam"];
  208. entity::id target_eid = ctx->entities["surface_cam_target"];
  209. entity::id three_dof_eid = ctx->entities["surface_cam_3dof"];
  210. const float dolly_speed = 20.0f;
  211. const float truck_speed = dolly_speed;
  212. const float pedestal_speed = 30.0f;
  213. const float pan_speed = math::radians(8.0f);
  214. const float tilt_speed = pan_speed;
  215. const input::control* move_slow = ctx->controls["move_slow"];
  216. const input::control* move_fast = ctx->controls["move_fast"];
  217. const input::control* mouse_rotate = ctx->controls["mouse_rotate"];
  218. ctx->controls["dolly_forward"]->set_active_callback
  219. (
  220. [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
  221. {
  222. if (move_slow->is_active())
  223. value *= 0.25f;
  224. if (move_fast->is_active())
  225. value *= 4.0f;
  226. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  227. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  228. const float3 movement = {0.0f, 0.0f, -truck_speed * value * (1.0f / 60.0f)};
  229. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  230. }
  231. );
  232. // Dolly backward
  233. ctx->controls["dolly_backward"]->set_active_callback
  234. (
  235. [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
  236. {
  237. if (move_slow->is_active())
  238. value *= 0.25f;
  239. if (move_fast->is_active())
  240. value *= 4.0f;
  241. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  242. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  243. const float3 movement = {0.0f, 0.0f, truck_speed * value * (1.0f / 60.0f)};
  244. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  245. }
  246. );
  247. // Truck right
  248. ctx->controls["truck_right"]->set_active_callback
  249. (
  250. [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
  251. {
  252. if (move_slow->is_active())
  253. value *= 0.25f;
  254. if (move_fast->is_active())
  255. value *= 4.0f;
  256. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  257. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  258. const float3 movement = {truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
  259. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  260. }
  261. );
  262. // Truck left
  263. ctx->controls["truck_left"]->set_active_callback
  264. (
  265. [ctx, target_eid, three_dof_eid, truck_speed, move_slow, move_fast](float value)
  266. {
  267. if (move_slow->is_active())
  268. value *= 0.25f;
  269. if (move_fast->is_active())
  270. value *= 4.0f;
  271. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  272. const math::quaternion<float> yaw = math::angle_axis(three_dof.yaw, {0.0f, 1.0f, 0.0f});
  273. const float3 movement = {-truck_speed * value * (1.0f / 60.0f), 0.0f, 0.0f};
  274. entity::command::translate(*ctx->entity_registry, target_eid, yaw * movement);
  275. }
  276. );
  277. // Pedestal up
  278. ctx->controls["pedestal_up"]->set_active_callback
  279. (
  280. [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
  281. {
  282. if (move_slow->is_active())
  283. value *= 0.25f;
  284. if (move_fast->is_active())
  285. value *= 4.0f;
  286. const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f};
  287. entity::command::translate(*ctx->entity_registry, target_eid, movement);
  288. }
  289. );
  290. // Pedestal down
  291. ctx->controls["pedestal_down"]->set_active_callback
  292. (
  293. [ctx, target_eid, pedestal_speed, move_slow, move_fast](float value)
  294. {
  295. if (move_slow->is_active())
  296. value *= 0.25f;
  297. if (move_fast->is_active())
  298. value *= 4.0f;
  299. const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f};
  300. entity::command::translate(*ctx->entity_registry, target_eid, movement);
  301. }
  302. );
  303. // Mouse rotate
  304. ctx->controls["mouse_rotate"]->set_activated_callback
  305. (
  306. [ctx]()
  307. {
  308. ctx->app->set_relative_mouse_mode(true);
  309. }
  310. );
  311. ctx->controls["mouse_rotate"]->set_deactivated_callback
  312. (
  313. [ctx]()
  314. {
  315. ctx->app->set_relative_mouse_mode(false);
  316. }
  317. );
  318. // Pan left
  319. ctx->controls["mouse_left"]->set_active_callback
  320. (
  321. [ctx, three_dof_eid, pan_speed, mouse_rotate](float value)
  322. {
  323. if (!mouse_rotate->is_active())
  324. return;
  325. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  326. three_dof.yaw += pan_speed * value * (1.0f / 60.0f);
  327. }
  328. );
  329. // Pan right
  330. ctx->controls["mouse_right"]->set_active_callback
  331. (
  332. [ctx, three_dof_eid, pan_speed, mouse_rotate](float value)
  333. {
  334. if (!mouse_rotate->is_active())
  335. return;
  336. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  337. three_dof.yaw -= pan_speed * value * (1.0f / 60.0f);
  338. }
  339. );
  340. // Tilt up
  341. ctx->controls["mouse_up"]->set_active_callback
  342. (
  343. [ctx, three_dof_eid, tilt_speed, mouse_rotate](float value)
  344. {
  345. if (!mouse_rotate->is_active())
  346. return;
  347. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  348. three_dof.pitch -= tilt_speed * value * (1.0f / 60.0f);
  349. three_dof.pitch = std::max<float>(math::radians(-90.0f), three_dof.pitch);
  350. }
  351. );
  352. // Tilt down
  353. ctx->controls["mouse_down"]->set_active_callback
  354. (
  355. [ctx, three_dof_eid, tilt_speed, mouse_rotate](float value)
  356. {
  357. if (!mouse_rotate->is_active())
  358. return;
  359. auto& three_dof = ctx->entity_registry->get<entity::component::constraint::three_dof>(three_dof_eid);
  360. three_dof.pitch += tilt_speed * value * (1.0f / 60.0f);
  361. three_dof.pitch = std::min<float>(math::radians(90.0f), three_dof.pitch);
  362. }
  363. );
  364. // Use tool
  365. ctx->controls["use_tool"]->set_activated_callback
  366. (
  367. [ctx]()
  368. {
  369. if (ctx->entities["active_tool"] == ctx->entities["move_tool"])
  370. {
  371. // Project mouse position into scene and grab selectable entity
  372. auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position();
  373. }
  374. }
  375. );
  376. ctx->controls["use_tool"]->set_deactivated_callback
  377. (
  378. [ctx]()
  379. {
  380. if (ctx->entities["active_tool"] == ctx->entities["move_tool"])
  381. {
  382. }
  383. }
  384. );
  385. ctx->controls["use_tool"]->set_active_callback
  386. (
  387. [ctx](float value)
  388. {
  389. auto [mouse_x, mouse_y] = ctx->app->get_mouse()->get_current_position();
  390. ctx->logger->log("tool used (" + std::to_string(mouse_x) + ", " + std::to_string(mouse_y) + ")");
  391. }
  392. );
  393. }
  394. } // namespace forage
  395. } // namespace state
  396. } // namespace game