💿🐜 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.

329 lines
13 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. /*
  2. * Copyright (C) 2020 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 "animation/ease.hpp"
  20. #include "animation/screen-transition.hpp"
  21. #include "configuration.hpp"
  22. #include "debug/logger.hpp"
  23. #include "entity/archetype.hpp"
  24. #include "game/components/cavity-component.hpp"
  25. #include "game/components/copy-transform-component.hpp"
  26. #include "game/components/copy-translation-component.hpp"
  27. #include "game/components/model-component.hpp"
  28. #include "game/components/snap-component.hpp"
  29. #include "game/components/samara-component.hpp"
  30. #include "game/components/terrain-component.hpp"
  31. #include "game/components/tool-component.hpp"
  32. #include "game/components/transform-component.hpp"
  33. #include "game/components/camera-follow-component.hpp"
  34. #include "game/entity-commands.hpp"
  35. #include "game/game-context.hpp"
  36. #include "game/states/game-states.hpp"
  37. #include "math/math.hpp"
  38. #include "nest.hpp"
  39. #include "renderer/material.hpp"
  40. #include "renderer/model.hpp"
  41. #include "renderer/passes/sky-pass.hpp"
  42. #include "resources/resource-manager.hpp"
  43. #include "scene/model-instance.hpp"
  44. #include "scene/scene.hpp"
  45. #include "scene/camera.hpp"
  46. #include "scene/ambient-light.hpp"
  47. #include "scene/directional-light.hpp"
  48. #include "scene/directional-light.hpp"
  49. #include "game/systems/control-system.hpp"
  50. #include "game/systems/camera-system.hpp"
  51. #include "game/systems/render-system.hpp"
  52. #include "game/systems/tool-system.hpp"
  53. #include "game/biome.hpp"
  54. #include "utility/fundamental-types.hpp"
  55. #include "utility/gamma.hpp"
  56. void play_state_enter(game_context* ctx)
  57. {
  58. logger* logger = ctx->logger;
  59. logger->push_task("Entering play state");
  60. // Load biome
  61. if (ctx->option_biome.has_value())
  62. {
  63. ctx->biome = ctx->resource_manager->load<biome>(ctx->option_biome.value() + ".bio");
  64. }
  65. else
  66. {
  67. ctx->biome = ctx->resource_manager->load<biome>("grassland.bio");
  68. }
  69. // Apply biome parameters to scene
  70. ctx->sun_indirect->set_color(ctx->biome->ambient_color);
  71. ctx->sun_indirect->set_intensity(ctx->biome->ambient_intensity);
  72. math::quaternion<float> sun_azimuth_rotation = math::angle_axis(ctx->biome->sun_azimuth, float3{0, 1, 0});
  73. math::quaternion<float> sun_elevation_rotation = math::angle_axis(ctx->biome->sun_elevation, float3{-1, 0, 0});
  74. math::quaternion<float> sun_rotation = math::normalize(sun_azimuth_rotation * sun_elevation_rotation);
  75. ctx->sun_direct->set_rotation(sun_rotation);
  76. ctx->sun_direct->set_color(ctx->biome->sun_color);
  77. ctx->sun_direct->set_intensity(ctx->biome->sun_intensity);
  78. sky_pass* sky_pass = ctx->overworld_sky_pass;
  79. sky_pass->set_enabled(true);
  80. sky_pass->set_sun_angular_radius(ctx->biome->sun_angular_radius);
  81. sky_pass->set_sun_color(ctx->biome->sun_color * ctx->biome->sun_intensity);
  82. sky_pass->set_horizon_color(ctx->biome->horizon_color);
  83. sky_pass->set_zenith_color(ctx->biome->zenith_color);
  84. ctx->tool_system->set_sun_direction(ctx->sun_direct->get_direction());
  85. resource_manager* resource_manager = ctx->resource_manager;
  86. entt::registry& ecs_registry = *ctx->ecs_registry;
  87. // Load entity archetypes
  88. ecs::archetype* ant_hill_archetype = resource_manager->load<ecs::archetype>("ant-hill.ent");
  89. ecs::archetype* maple_tree_archetype = resource_manager->load<ecs::archetype>("maple-tree.ent");
  90. ecs::archetype* nest_archetype = resource_manager->load<ecs::archetype>("harvester-nest.ent");
  91. ecs::archetype* samara_archetype = resource_manager->load<ecs::archetype>("samara.ent");
  92. ecs::archetype* forceps_archetype = resource_manager->load<ecs::archetype>("forceps.ent");
  93. ecs::archetype* lens_archetype = resource_manager->load<ecs::archetype>("lens.ent");
  94. ecs::archetype* brush_archetype = resource_manager->load<ecs::archetype>("brush.ent");
  95. ecs::archetype* marker_archetype = resource_manager->load<ecs::archetype>("marker.ent");
  96. ecs::archetype* container_archetype = resource_manager->load<ecs::archetype>("container.ent");
  97. ecs::archetype* twig_archetype = resource_manager->load<ecs::archetype>("twig.ent");
  98. ecs::archetype* larva_archetype = resource_manager->load<ecs::archetype>("larva.ent");
  99. ecs::archetype* pebble_archetype = resource_manager->load<ecs::archetype>("pebble.ent");
  100. ecs::archetype* flashlight_archetype = resource_manager->load<ecs::archetype>("flashlight.ent");
  101. ecs::archetype* flashlight_light_cone_archetype = resource_manager->load<ecs::archetype>("flashlight-light-cone.ent");
  102. ecs::archetype* lens_light_cone_archetype = resource_manager->load<ecs::archetype>("lens-light-cone.ent");
  103. ecs::archetype* ant_head_archetype = resource_manager->load<ecs::archetype>("ant-head.ent");
  104. ecs::archetype* dandelion_plant_archetype = resource_manager->load<ecs::archetype>("dandelion-plant.ent");
  105. // Create tools
  106. forceps_archetype->assign(ecs_registry, ctx->forceps_entity);
  107. lens_archetype->assign(ecs_registry, ctx->lens_entity);
  108. brush_archetype->assign(ecs_registry, ctx->brush_entity);
  109. marker_archetype->assign(ecs_registry, ctx->marker_entity);
  110. container_archetype->assign(ecs_registry, ctx->container_entity);
  111. twig_archetype->assign(ecs_registry, ctx->twig_entity);
  112. // Create flashlight and light cone, set light cone parent to flashlight, and move both to underworld scene
  113. flashlight_archetype->assign(ecs_registry, ctx->flashlight_entity);
  114. auto flashlight_light_cone = flashlight_light_cone_archetype->create(ecs_registry);
  115. ec::parent(ecs_registry, flashlight_light_cone, ctx->flashlight_entity);
  116. ec::assign_render_layers(ecs_registry, ctx->flashlight_entity, 2);
  117. // Make lens tool's model instance unculled, so its shadow is always visible.
  118. model_instance* lens_model_instance = ctx->render_system->get_model_instance(ctx->lens_entity);
  119. if (lens_model_instance)
  120. {
  121. lens_model_instance->set_culling_mask(&ctx->no_cull);
  122. }
  123. // Create lens light cone and set its parent to lens
  124. auto lens_light_cone = lens_light_cone_archetype->create(ecs_registry);
  125. //ec::bind_transform(ecs_registry, lens_light_cone, ctx->lens_entity);
  126. ec::parent(ecs_registry, lens_light_cone, ctx->lens_entity);
  127. // Hide inactive tools
  128. ec::assign_render_layers(ecs_registry, ctx->forceps_entity, 0);
  129. ec::assign_render_layers(ecs_registry, ctx->brush_entity, 0);
  130. ec::assign_render_layers(ecs_registry, ctx->lens_entity, 0);
  131. ec::assign_render_layers(ecs_registry, ctx->marker_entity, 0);
  132. ec::assign_render_layers(ecs_registry, ctx->container_entity, 0);
  133. ec::assign_render_layers(ecs_registry, ctx->twig_entity, 0);
  134. // Activate brush tool
  135. ctx->tool_system->set_active_tool(ctx->brush_entity);
  136. // Create ant-hill
  137. auto ant_hill_entity = ant_hill_archetype->create(ecs_registry);
  138. ec::place(ecs_registry, ant_hill_entity, {0, 0});
  139. // Generate pebbles
  140. float pebble_radius = 300.0f;
  141. int pebble_count = 100;
  142. for (int i = 0; i < pebble_count; ++i)
  143. {
  144. float x = math::random(-pebble_radius, pebble_radius);
  145. float z = math::random(-pebble_radius, pebble_radius);
  146. auto pebble_entity = ant_head_archetype->create(ecs_registry);
  147. auto& transform = ecs_registry.get<ecs::transform_component>(pebble_entity);
  148. transform.local = math::identity_transform<float>;
  149. transform.local.rotation = math::angle_axis(math::random(0.0f, math::two_pi<float>), {0, 1, 0});
  150. transform.local.scale = float3{1, 1, 1} * math::random(0.75f, 1.25f);
  151. ec::place(ecs_registry, pebble_entity, {x, z});
  152. }
  153. // Create maple tree
  154. auto maple_tree_entity = maple_tree_archetype->create(ecs_registry);
  155. ec::place(ecs_registry, maple_tree_entity, {300, 200});
  156. // Creat nest
  157. auto nest_entity = nest_archetype->create(ecs_registry);
  158. // Create terrain
  159. int terrain_radius = 2;
  160. for (int x = -terrain_radius; x <= terrain_radius; ++x)
  161. {
  162. for (int z = -terrain_radius; z <= terrain_radius; ++z)
  163. {
  164. ecs::terrain_component terrain_component;
  165. terrain_component.subdivisions = TERRAIN_PATCH_RESOLUTION;
  166. terrain_component.x = x;
  167. terrain_component.z = z;
  168. auto terrain_entity = ecs_registry.create();
  169. ecs_registry.assign<ecs::terrain_component>(terrain_entity, terrain_component);
  170. }
  171. }
  172. // Create samaras
  173. for (int i = 0; i < 15; ++i)
  174. {
  175. auto samara_entity = samara_archetype->create(ecs_registry);
  176. auto& transform = ecs_registry.get<ecs::transform_component>(samara_entity);
  177. float zone = 200.0f;
  178. transform.local = math::identity_transform<float>;
  179. transform.local.translation.x = math::random(-zone, zone);
  180. transform.local.translation.y = math::random(50.0f, 150.0f);
  181. transform.local.translation.z = math::random(-zone, zone);
  182. ecs::samara_component samara_component;
  183. samara_component.angle = math::random(0.0f, math::radians(360.0f));
  184. samara_component.direction = math::normalize(float3{math::random(-1.0f, 1.0f), math::random(-1.0f, -5.0f), math::random(-1.0f, 1.0f)});
  185. samara_component.chirality = (math::random(0.0f, 1.0f) < 0.5f) ? -1.0f : 1.0f;
  186. ecs_registry.assign_or_replace<ecs::samara_component>(samara_entity, samara_component);
  187. }
  188. // Setup camera focal point
  189. ecs::transform_component focal_point_transform;
  190. focal_point_transform.local = math::identity_transform<float>;
  191. focal_point_transform.warp = true;
  192. ecs::camera_follow_component focal_point_follow;
  193. ecs::snap_component focal_point_snap;
  194. focal_point_snap.ray = {float3{0, 10000, 0}, float3{0, -1, 0}};
  195. focal_point_snap.warp = false;
  196. focal_point_snap.relative = true;
  197. focal_point_snap.autoremove = false;
  198. ecs_registry.assign_or_replace<ecs::transform_component>(ctx->focal_point_entity, focal_point_transform);
  199. ecs_registry.assign_or_replace<ecs::camera_follow_component>(ctx->focal_point_entity, focal_point_follow);
  200. ecs_registry.assign_or_replace<ecs::snap_component>(ctx->focal_point_entity, focal_point_snap);
  201. // Setup camera
  202. ctx->overworld_camera->look_at({0, 0, 1}, {0, 0, 0}, {0, 1, 0});
  203. ctx->camera_system->set_camera(ctx->overworld_camera);
  204. auto ant_head = ant_head_archetype->create(ecs_registry);
  205. ec::place(ecs_registry, ant_head, {50, 0});
  206. ctx->overworld_scene->update_tweens();
  207. // Allocate a nest
  208. nest* nest = new ::nest();
  209. // Setup initial nest parameters
  210. float tunnel_radius = 1.15f;
  211. nest->set_tunnel_radius(tunnel_radius);
  212. nest::shaft* central_shaft = nest->get_central_shaft();
  213. central_shaft->chirality = 1.0f;
  214. central_shaft->rotation = math::radians(0.0f);
  215. central_shaft->depth = {0.0f, 200.0f};
  216. central_shaft->radius = {15.0f, 15.0f};
  217. central_shaft->pitch = {40.0f, 40.0f};
  218. central_shaft->translation = {{{0.0f, 0.0f}, {0.0f, 0.0f}}};
  219. central_shaft->current_depth = 0.0f;
  220. for (std::size_t i = 0; i < 4; ++i)
  221. {
  222. nest::chamber chamber;
  223. chamber.shaft = central_shaft;
  224. chamber.depth = (i + 1) * 50.0f;
  225. chamber.rotation = math::radians(0.0f);
  226. chamber.inner_radius = 4.0f;
  227. chamber.outer_radius = 10.0f;
  228. central_shaft->chambers.push_back(chamber);
  229. }
  230. // Dig nest shafts
  231. float shift = 0.1f;
  232. for (int i = 0; i < 800; ++i)
  233. {
  234. ecs::cavity_component cavity;
  235. cavity.position = nest->extend_shaft(*nest->get_central_shaft());
  236. cavity.position += float3{math::random(-shift, shift), math::random(-shift, shift), math::random(-shift, shift)};
  237. cavity.radius = tunnel_radius * math::random(1.0f, 1.1f);
  238. ecs_registry.assign<ecs::cavity_component>(ecs_registry.create(), cavity);
  239. }
  240. // Dig nest chambers
  241. /*
  242. for (int i = 0; i < central_shaft->chambers.size(); ++i)
  243. {
  244. for (int j = 0; j < 150; ++j)
  245. {
  246. ecs::cavity_component cavity;
  247. cavity.position = nest->expand_chamber(central_shaft->chambers[i]);
  248. cavity.position += float3{math::random(-shift, shift), math::random(-shift, shift), math::random(-shift, shift)};
  249. cavity.radius = tunnel_radius * math::random(1.0f, 1.1f);
  250. ecs_registry.assign<ecs::cavity_component>(ecs_registry.create(), cavity);
  251. }
  252. }
  253. */
  254. // Place larva in chamber
  255. {
  256. auto larva = larva_archetype->create(ecs_registry);
  257. ec::assign_render_layers(ecs_registry, larva, 1);
  258. ec::warp_to(ecs_registry, larva, {50, 0.1935f, 10});
  259. //auto& transform = ecs_registry.get<ecs::transform_component>(larva_entity);
  260. //transform.transform = math::identity_transform<float>;
  261. //transform.transform.translation = nest->get_shaft_position(*central_shaft, central_shaft->depth[1]);
  262. //transform.transform.translation.y -= 1.0f;
  263. }
  264. auto dandelion_plant = dandelion_plant_archetype->create(ecs_registry);
  265. ec::place(ecs_registry, dandelion_plant, {55, -30});
  266. control_system* control_system = ctx->control_system;
  267. control_system->update(0.0, 0.0);
  268. control_system->set_nest(nest);
  269. // Start fade in
  270. ctx->fade_transition->transition(1.0f, true, ease<float>::in_quad);
  271. logger->pop_task(EXIT_SUCCESS);
  272. std::string biome_name = (*ctx->strings)[ctx->biome->name];
  273. logger->log("Entered biome \"" + biome_name + "\"");
  274. }
  275. void play_state_exit(game_context* ctx)
  276. {
  277. logger* logger = ctx->logger;
  278. logger->push_task("Exiting play state");
  279. logger->pop_task(EXIT_SUCCESS);
  280. }