diff --git a/src/engine/renderer.h b/src/engine/renderer.h index abdb1dc..7ccdb99 100644 --- a/src/engine/renderer.h +++ b/src/engine/renderer.h @@ -14,7 +14,9 @@ typedef enum RendererBuffer { RENDERER_BUFFER_BACKGROUND, + RENDERER_BUFFER_PLANE, RENDERER_BUFFER_WORLD, + RENDERER_BUFFER_OVERLAY, RENDERER_BUFFER_UI, RENDERER_BUFFER_META, RENDERER_BUFFER_CURSOR diff --git a/src/game/GAME_COMMON.h b/src/game/GAME_COMMON.h index 90139b5..973b005 100644 --- a/src/game/GAME_COMMON.h +++ b/src/game/GAME_COMMON.h @@ -19,4 +19,5 @@ typedef struct Game Window window; Postprocessing postprocessing[RENDERER_BUFFER_COUNT]; bool isPaused; + bool isMute; } Game; diff --git a/src/game/ecs/component/COMPONENT_COMMON.h b/src/game/ecs/component/COMPONENT_COMMON.h index 60a1c27..9a55ce7 100644 --- a/src/game/ecs/component/COMPONENT_COMMON.h +++ b/src/game/ecs/component/COMPONENT_COMMON.h @@ -43,7 +43,6 @@ typedef enum ComponentType COMPONENT_DIALOGUE, COMPONENT_VALUE_TEXT, COMPONENT_ATLAS, - COMPONENT_CAMERA_FOCUS, COMPONENT_COLOR_CHANGE, COMPONENT_COLOR_MATCH, COMPONENT_SCALE_VALUE, diff --git a/src/game/ecs/component/game/component_collectible.c b/src/game/ecs/component/game/component_collectible.c index b2a9c80..0184389 100644 --- a/src/game/ecs/component/game/component_collectible.c +++ b/src/game/ecs/component/game/component_collectible.c @@ -50,7 +50,8 @@ _component_collectible_increment(ComponentCollectible* self, ECS* ecs, EntityID food = ecs_component_get(ecs, COMPONENT_FOOD, id); if (!food) return; - food->value -= COMPONENT_COLLECTIBLE_FOOD_VALUE; + food->value += COMPONENT_COLLECTIBLE_ROTTEN_FOOD_VALUE; + sound_play(&ecs->resources->sounds[SOUND_BLEH]); break; case COLLECTIBLE_AMULET: @@ -99,7 +100,8 @@ component_collectible_init size, position, COMPONENT_COLLECTIBLE_HEIGHT_OFFSET, - COMPONENT_COLLECTIBLE_RADIUS + COMPONENT_COLLECTIBLE_RADIUS, + true ); component_levitate_init diff --git a/src/game/ecs/component/game/component_collectible.h b/src/game/ecs/component/game/component_collectible.h index 06bea9b..9007feb 100644 --- a/src/game/ecs/component/game/component_collectible.h +++ b/src/game/ecs/component/game/component_collectible.h @@ -13,6 +13,7 @@ static const f32 COMPONENT_COLLECTIBLE_HEIGHT_OFFSET = 1000.0f; static const f32 COMPONENT_COLLECTIBLE_RADIUS = 64.0f; static const u32 COMPONENT_COLLECTIBLE_FOOD_VALUE = 1; +static const u32 COMPONENT_COLLECTIBLE_ROTTEN_FOOD_VALUE = -5; static const f32 COMPONENT_COLLECTIBLE_POWER_VALUE = 10.0f; static const f32 COMPONENT_COLLECTIBLE_STAMINA_VALUE = 50.0f; static const u32 COMPONENT_COLLECTIBLE_HOMING_SPEED = 3.0f; diff --git a/src/game/ecs/component/game/component_world_object.c b/src/game/ecs/component/game/component_world_object.c index cb4d303..487ec4c 100644 --- a/src/game/ecs/component/game/component_world_object.c +++ b/src/game/ecs/component/game/component_world_object.c @@ -135,7 +135,8 @@ component_world_object_init vec2 size, vec3 position, f32 heightOffset, - f32 radius + f32 radius, + bool isShadow ) { component_game_object_init @@ -165,20 +166,27 @@ component_world_object_init COMPONENT_WORLD_OBJECT_FRICTION ); - self->shadowID = entity_sprite_add - ( - ecs, - &ecs->resources->textures[TEXTURE_SHADOW], - COMPONENT_WORLD_OBJECT_BUFFER, - COMPONENT_WORLD_OBJECT_ORIGIN, - (f32*)size, - (f32*)position - ); + self->isShadow = isShadow; + if (self->isShadow) + { + self->shadowID = entity_sprite_add + ( + ecs, + &ecs->resources->textures[TEXTURE_SHADOW], + COMPONENT_WORLD_OBJECT_BUFFER, + COMPONENT_WORLD_OBJECT_ORIGIN, + (f32*)size, + (f32*)position + ); + + _component_world_object_shadow_set(self, ecs); + } + + self->heightOffset = heightOffset; self->isGravityAffected = true; - _component_world_object_shadow_set(self, ecs); _component_world_object_height_offset_set(self, ecs); _component_world_object_circle_collider_set(self, ecs); } @@ -205,7 +213,10 @@ void component_world_object_tick(ComponentWorldObject* self, ECS* ecs) { _component_world_object_depth_set(self, ecs); - _component_world_object_shadow_set(self, ecs); + + if (self->isShadow) + _component_world_object_shadow_set(self, ecs); + _component_world_object_height_offset_set(self, ecs); _component_world_object_bounds_set(self, ecs); _component_world_object_direction_set(self, ecs); diff --git a/src/game/ecs/component/game/component_world_object.h b/src/game/ecs/component/game/component_world_object.h index 0312c36..eae187e 100644 --- a/src/game/ecs/component/game/component_world_object.h +++ b/src/game/ecs/component/game/component_world_object.h @@ -15,7 +15,7 @@ static const f32 COMPONENT_WORLD_OBJECT_DEPTH_MIN = 0.1f; static const f32 COMPONENT_WORLD_OBJECT_DEPTH_MAX = 0.2f; static const f32 COMPONENT_WORLD_OBJECT_GRAVITY = 1.0f; static const vec3 COMPONENT_WORLD_OBJECT_VELOCITY_MAX = {100.0f, 100.0f, 100.0f}; -static const vec4 COMPONENT_WORLD_OBJECT_BOUNDS = {250.0f, 250.0f, 6300.0f, 3100.0f}; +static const vec4 COMPONENT_WORLD_OBJECT_BOUNDS = {250.0f, 250.0f, 6150.0f, 3200.0f}; #define COMPONENT_WORLD_OBJECT_ORIGIN ORIGIN_CENTER @@ -29,6 +29,7 @@ typedef struct ComponentWorldObject Direction direction; bool isAirborne; bool isGravityAffected; + bool isShadow; } ComponentWorldObject; void @@ -40,7 +41,8 @@ component_world_object_init vec2 size, vec3 position, f32 heightOffset, - f32 radius + f32 radius, + bool isShadow ); void component_world_object_add(ComponentWorldObject* self, ECS* ecs); diff --git a/src/game/ecs/component/visual/component_camera_focus.c b/src/game/ecs/component/visual/component_camera_focus.c deleted file mode 100644 index b9db4f6..0000000 --- a/src/game/ecs/component/visual/component_camera_focus.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "component_camera_focus.h" - -void -component_camera_focus_tick(ComponentCameraFocus* self, ECS* ecs) -{ - ComponentPhysics* physics; - vec3 position; - //f32 velocityPercent; - //vec2 positionPercent; - - physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->entityID); - - if (!physics) - return; - - glm_vec3_copy(physics->position, position); - - /* - positionPercent[0] = (physics->position[0] + (physics->velocity[0] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER)) / self->camera->orthographic.size[0]; - positionPercent[1] = (physics->position[1] + (physics->velocity[1] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER)) / self->camera->orthographic.size[1]; - */ - - /* - position[0] += physics->velocity[0] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER; - position[1] += physics->velocity[1] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER; - */ - - position[0] -= self->camera->orthographic.size[0] / 2; - position[1] -= self->camera->orthographic.size[1] / 2; - - /* - position[0] += (physics->position[0]) - ((self->camera->orthographic.size[0] / 4) * (1 - self->camera->zoom)); - position[1] += (physics->position[1]) - ((self->camera->orthographic.size[1] / 4) * (1 - self->camera->zoom)); - */ - - position[2] = 0.0f; - - //velocityPercent = 0.0f; - - /* - if (fabs(physics->velocity[0]) >= fabs(physics->velocity[1])) - velocityPercent = fabs(physics->velocity[0]) / physics->velocityMax[0]; - else if (fabs(physics->velocity[1]) > fabs(physics->velocity[0])) - velocityPercent = fabs(physics->velocity[1]) / physics->velocityMax[1]; - - self->camera->zoom = COMPONENT_CAMERA_FOCUS_ZOOM_MIN; - self->camera->zoom += (velocityPercent * (COMPONENT_CAMERA_FOCUS_ZOOM_MAX - COMPONENT_CAMERA_FOCUS_ZOOM_MIN)); - */ - - //glm_vec3_print(position, stderr); - - camera_position_set(self->camera, position); -} - -void -component_camera_focus_init -( - ComponentCameraFocus* self, - ECS* ecs, - Camera* camera, - u32 entityID -) -{ - self->camera = camera; - self->entityID = entityID; -} diff --git a/src/game/ecs/component/visual/component_camera_focus.h b/src/game/ecs/component/visual/component_camera_focus.h deleted file mode 100644 index 24f02c6..0000000 --- a/src/game/ecs/component/visual/component_camera_focus.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "../physics/component_physics.h" - -static const f32 COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER = 10.0f; -static const f32 COMPONENT_CAMERA_FOCUS_VELOCITY_ZOOM_MULTIPLIER = 0.1f; -static const f32 COMPONENT_CAMERA_FOCUS_ZOOM_MAX = 0.40f; -static const f32 COMPONENT_CAMERA_FOCUS_ZOOM_MIN = 0.25f; - -typedef struct ComponentCameraFocus -{ - Component component; - Camera* camera; - EntityID entityID; -} ComponentCameraFocus; - -void component_camera_focus_tick(ComponentCameraFocus* self, ECS* ecs); - -void -component_camera_focus_init -( - ComponentCameraFocus* self, - ECS* ecs, - Camera* camera, - EntityID entityID -); - -static const ComponentInfo COMPONENT_CAMERA_FOCUS_INFO = -{ - .system = - { - .functions = - { - NULL, - NULL, - (ECSFunction)component_camera_focus_tick, - NULL, - NULL - } - }, - .type = COMPONENT_CAMERA_FOCUS, - .size = sizeof(ComponentCameraFocus) -}; diff --git a/src/game/ecs/ecs.h b/src/game/ecs/ecs.h index 635a13d..962055a 100644 --- a/src/game/ecs/ecs.h +++ b/src/game/ecs/ecs.h @@ -27,7 +27,6 @@ #include "component/utility/component_timer.h" #include "component/utility/component_delete_on_timer.h" #include "component/visual/component_atlas.h" -#include "component/visual/component_camera_focus.h" #include "component/visual/component_dialogue.h" #include "component/visual/component_drop_shadow.h" #include "component/visual/component_color_change.h" @@ -84,7 +83,6 @@ static const struct ComponentInfo COMPONENT_INFO[COMPONENT_COUNT] = COMPONENT_DIALOGUE_INFO, COMPONENT_VALUE_TEXT_INFO, COMPONENT_ATLAS_INFO, - COMPONENT_CAMERA_FOCUS_INFO, COMPONENT_COLOR_CHANGE_INFO, COMPONENT_COLOR_MATCH_INFO, COMPONENT_SCALE_VALUE_INFO, diff --git a/src/game/ecs/entity/game/entity_foliage.c b/src/game/ecs/entity/game/entity_foliage.c new file mode 100644 index 0000000..9773a29 --- /dev/null +++ b/src/game/ecs/entity/game/entity_foliage.c @@ -0,0 +1,22 @@ +#include "entity_foliage.h" + +EntityID +entity_foliage_add(ECS* ecs, const vec3 position, FoliageType type) +{ + EntityID id; + + id = entity_sprite_atlas_add + ( + ecs, + &ecs->resources->textures[TEXTURE_FOLIAGE], + RENDERER_BUFFER_WORLD, + ORIGIN_CENTER, + ENTITY_FOLIAGE_SIZE, + position, + ENTITY_FOLIAGE_ATLAS_FRAME_SIZE, + ENTITY_FOLIAGE_ATLAS_SIZE, + (u32)type + ); + + return id; +} diff --git a/src/game/ecs/entity/game/entity_foliage.h b/src/game/ecs/entity/game/entity_foliage.h new file mode 100644 index 0000000..89cc0d2 --- /dev/null +++ b/src/game/ecs/entity/game/entity_foliage.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../visual/entity_sprite_atlas.h" + +#define FOLIAGE_TYPE_COUNT 6 +typedef enum FoliageType +{ + FOLIAGE_BIG_PILE, + FOLIAGE_SMALL_PILE, + FOLIAGE_BIG_ROCK, + FOLIAGE_SMALL_ROCK, + FOLIAGE_BIG_GRASS, + FOLIAGE_SMALL_GRASS +} FoliageType; + +static const vec2 ENTITY_FOLIAGE_SIZE = {128.0f, 128.0f}; +static const ivec2 ENTITY_FOLIAGE_ATLAS_FRAME_SIZE = {32, 32}; +static const ivec2 ENTITY_FOLIAGE_ATLAS_SIZE = {1, 6}; + +EntityID entity_foliage_add(ECS* ecs, const vec3 position, FoliageType type); diff --git a/src/game/ecs/entity/game/entity_player.c b/src/game/ecs/entity/game/entity_player.c index 22b0eb7..cb42f37 100644 --- a/src/game/ecs/entity/game/entity_player.c +++ b/src/game/ecs/entity/game/entity_player.c @@ -21,7 +21,8 @@ entity_player_add(ECS* ecs, const vec3 position) PLAYER_SIZE, position, PLAYER_HEIGHT_OFFSET, - PLAYER_RADIUS + PLAYER_RADIUS, + true ); worldObject->angle = PLAYER_ANGLE; @@ -35,14 +36,6 @@ entity_player_add(ECS* ecs, const vec3 position) PLAYER_ATLAS_INDEX ); - component_camera_focus_init - ( - ecs_component_get(ecs, COMPONENT_CAMERA_FOCUS, id), - ecs, - &ecs->renderer->camera[RENDERER_BUFFER_WORLD], - id - ); - component_stamina_init ( ecs_component_get(ecs, COMPONENT_STAMINA, id), diff --git a/src/game/ecs/entity/game/entity_player.h b/src/game/ecs/entity/game/entity_player.h index 2854166..6aa0dc4 100644 --- a/src/game/ecs/entity/game/entity_player.h +++ b/src/game/ecs/entity/game/entity_player.h @@ -10,7 +10,6 @@ #include "../../component/game/component_collect.h" #include "../../component/game/component_stamina.h" #include "../../component/game/component_world_object.h" -#include "../../component/visual/component_camera_focus.h" static const TextureType PLAYER_TEXTURE = TEXTURE_PLAYER; static const vec2 PLAYER_SIZE = {384.0f, 256.0f}; @@ -20,7 +19,7 @@ static const f32 PLAYER_STAMINA_MAX = 100.0f; static const f32 PLAYER_STAMINA_GAIN = 0.1f; static const f32 PLAYER_POWER_MAX = 100.0f; static const f32 PLAYER_POWER_GAIN = 0.01f; -static const f32 PLAYER_COLLECT_RADIUS = 300.0f; +static const f32 PLAYER_COLLECT_RADIUS = 250.0f; static const ivec2 PLAYER_ATLAS_FRAME_SIZE = {96, 64}; static const ivec2 PLAYER_ATLAS_SIZE = {4, 5}; @@ -34,7 +33,6 @@ static const ComponentType ENTITY_PLAYER_DEPENDENCIES[ENTITY_PLAYER_DEPENDENCY_C { COMPONENT_WORLD_OBJECT, COMPONENT_ATLAS, - COMPONENT_CAMERA_FOCUS, COMPONENT_COLLECT, COMPONENT_FOOD, COMPONENT_POWER, diff --git a/src/game/ecs/entity/game/entity_target.c b/src/game/ecs/entity/game/entity_target.c index 5c43784..3635aea 100644 --- a/src/game/ecs/entity/game/entity_target.c +++ b/src/game/ecs/entity/game/entity_target.c @@ -17,7 +17,8 @@ entity_target_add(ECS* ecs, const vec3 position, u32 threshold, u32 stage, Entit TARGET_SIZE, position, TARGET_HEIGHT_OFFSET, - TARGET_RADIUS + TARGET_RADIUS, + true ); component_atlas_init diff --git a/src/game/ecs/entity/ui/entity_meter.h b/src/game/ecs/entity/ui/entity_meter.h index 96381a8..ce024a6 100644 --- a/src/game/ecs/entity/ui/entity_meter.h +++ b/src/game/ecs/entity/ui/entity_meter.h @@ -3,7 +3,7 @@ #include "../visual/entity_sprite.h" #include "../../component/visual/component_scale_value.h" -static const vec3 ENTITY_METER_FILL_OFFSET = {2.0f, 2.0f, 0.001f}; +static const vec3 ENTITY_METER_FILL_OFFSET = {3.0f, 3.0f, 0.001f}; static const vec2 ENTITY_METER_FILL_MIN_SIZE = {0.0f, 32.0f}; static const vec2 ENTITY_METER_FILL_MAX_SIZE = {200.0f, 32.0f}; static const vec2 ENTITY_METER_SIZE = {206.0f, 38.0f}; diff --git a/src/game/ecs/entity/visual/entity_text_queue_entry.c b/src/game/ecs/entity/visual/entity_text_queue_entry.c new file mode 100644 index 0000000..45a624f --- /dev/null +++ b/src/game/ecs/entity/visual/entity_text_queue_entry.c @@ -0,0 +1,37 @@ +#include "entity_text_queue_entry.h" + +EntityID +entity_text_queue_entry_add +( + ECS* ecs, + Font* font, + RendererBuffer buffer, + const char* string, + const vec3 position, + u32 wrap, + u32 timer +) +{ + EntityID id; + + id = entity_text_add + ( + ecs, + font, + buffer, + string, + position, + wrap + ); + + ecs_components_add(ecs, ENTITY_TEXT_QUEUE_ENTRY_DEPENDENCIES, ENTITY_TEXT_QUEUE_ENTRY_DEPENDENCY_COUNT, id); + + component_delete_on_timer_init + ( + ecs_component_get(ecs, COMPONENT_DELETE_ON_TIMER, id), + ecs, + timer + ); + + return id; +} diff --git a/src/game/ecs/entity/visual/entity_text_queue_entry.h b/src/game/ecs/entity/visual/entity_text_queue_entry.h new file mode 100644 index 0000000..029d55b --- /dev/null +++ b/src/game/ecs/entity/visual/entity_text_queue_entry.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../../component/visual/component_color_change.h" +#include "../../component/utility/component_delete_on_timer.h" +#include "entity_text.h" + +EntityID +entity_text_queue_entry_add +( + ECS* ecs, + Font* font, + RendererBuffer buffer, + const char* string, + const vec3 position, + u32 wrap, + u32 timer +); + +#define ENTITY_TEXT_QUEUE_ENTRY_DEPENDENCY_COUNT 1 +static const ComponentType ENTITY_TEXT_QUEUE_ENTRY_DEPENDENCIES[ENTITY_TEXT_QUEUE_ENTRY_DEPENDENCY_COUNT] = +{ + COMPONENT_DELETE_ON_TIMER +}; diff --git a/src/game/game.c b/src/game/game.c index 836d626..46dfb29 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -40,6 +40,16 @@ _game_tick(Game* self) if (event_press(&self->input.event, EVENT_QUIT)) _game_quit(self); + + if (control_pressed(&self->control, CONTROL_MUTE)) + { + self->isMute = !self->isMute; + + if (self->isMute) + music_pause(); + else + music_resume(); + } } static void diff --git a/src/game/game.h b/src/game/game.h index 44a350f..113bf65 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -14,6 +14,8 @@ static const ivec2 BUFFER_SIZES[RENDERER_BUFFER_COUNT] = { {1280, 720}, {6400, 3600}, + {6400, 3600}, + {6400, 3600}, {1280, 720}, {1280, 720}, {1280, 720} diff --git a/src/game/input/control.c b/src/game/input/control.c index 1820f38..bc1efd0 100644 --- a/src/game/input/control.c +++ b/src/game/input/control.c @@ -50,6 +50,9 @@ control_tick(Control* self, Input* input) if (input->keyboard.current[KEYBOARD_KEY_ESCAPE]) self->current[CONTROL_ESCAPE] = true; + + if (input->keyboard.current[KEYBOARD_KEY_M]) + self->current[CONTROL_MUTE] = true; } bool diff --git a/src/game/input/control.h b/src/game/input/control.h index 33913bd..e275a6a 100644 --- a/src/game/input/control.h +++ b/src/game/input/control.h @@ -2,7 +2,7 @@ #include "input.h" -#define CONTROL_COUNT CONTROL_ESCAPE + 1 +#define CONTROL_COUNT CONTROL_MUTE + 1 typedef enum ControlType { CONTROL_NONE, @@ -20,7 +20,8 @@ typedef enum ControlType CONTROL_MAGNET, CONTROL_PAUSE, CONTROL_RETRY, - CONTROL_ESCAPE + CONTROL_ESCAPE, + CONTROL_MUTE } ControlType; typedef struct Control diff --git a/src/game/resource/RESOURCE_COMMON.h b/src/game/resource/RESOURCE_COMMON.h index a128356..2a488e9 100644 --- a/src/game/resource/RESOURCE_COMMON.h +++ b/src/game/resource/RESOURCE_COMMON.h @@ -27,7 +27,7 @@ static const ShaderPaths SHADER_PATHS[SHADER_COUNT] = } }; -#define TEXTURE_COUNT TEXTURE_ENDING + 1 +#define TEXTURE_COUNT TEXTURE_ENDING_THREE + 1 typedef enum TextureType { TEXTURE_DEFAULT, @@ -48,6 +48,7 @@ typedef enum TextureType TEXTURE_COLLECTIBLE, TEXTURE_SMOKE, TEXTURE_TRAP, + TEXTURE_FOLIAGE, TEXTURE_CUTSCENE_ONE_SCENE_ONE, TEXTURE_CUTSCENE_ONE_SCENE_TWO, TEXTURE_CUTSCENE_ONE_SCENE_THREE, @@ -88,7 +89,9 @@ typedef enum TextureType TEXTURE_CUTSCENE_FINAL_SCENE_ELEVEN, TEXTURE_CUTSCENE_FINAL_SCENE_TWELVE, TEXTURE_CUTSCENE_FINAL_SCENE_THIRTEEN, - TEXTURE_ENDING + TEXTURE_ENDING, + TEXTURE_ENDING_TWO, + TEXTURE_ENDING_THREE, } TextureType; static const char* TEXTURE_PATHS[TEXTURE_COUNT] = @@ -111,47 +114,50 @@ static const char* TEXTURE_PATHS[TEXTURE_COUNT] = "res/gfx/collectible.png", "res/gfx/smoke.png", "res/gfx/trap.png", - "res/gfx/cutscene/c1s1.png", - "res/gfx/cutscene/c1s2.png", - "res/gfx/cutscene/c1s3.png", - "res/gfx/cutscene/c1s4.png", - "res/gfx/cutscene/c2s1.png", - "res/gfx/cutscene/c2s2.png", - "res/gfx/cutscene/c2s3.png", - "res/gfx/cutscene/c2s4.png", - "res/gfx/cutscene/c2s5.png", - "res/gfx/cutscene/c3s1.png", - "res/gfx/cutscene/c3s2.png", - "res/gfx/cutscene/c3s3.png", - "res/gfx/cutscene/c3s4.png", - "res/gfx/cutscene/c3s5.png", - "res/gfx/cutscene/c3s6.png", - "res/gfx/cutscene/c4s1.png", - "res/gfx/cutscene/c4s2.png", - "res/gfx/cutscene/c4s3.png", - "res/gfx/cutscene/c4s4.png", - "res/gfx/cutscene/c4s5.png", - "res/gfx/cutscene/c4s6.png", - "res/gfx/cutscene/c5s1.png", - "res/gfx/cutscene/c5s2.png", - "res/gfx/cutscene/c5s3.png", - "res/gfx/cutscene/c5s4.png", - "res/gfx/cutscene/c5s5.png", - "res/gfx/cutscene/c5s6.png", - "res/gfx/cutscene/c6s1.png", - "res/gfx/cutscene/c6s2.png", - "res/gfx/cutscene/c6s3.png", - "res/gfx/cutscene/c6s4.png", - "res/gfx/cutscene/c6s5.png", - "res/gfx/cutscene/c6s6.png", - "res/gfx/cutscene/c6s7.png", - "res/gfx/cutscene/c6s8.png", - "res/gfx/cutscene/c6s9.png", - "res/gfx/cutscene/c6s10.png", - "res/gfx/cutscene/c6s11.png", - "res/gfx/cutscene/c6s12.png", - "res/gfx/cutscene/c6s13.png", - "res/gfx/cutscene/ending.png" + "res/gfx/foliage.png", + "res/gfx/cutscene/c01s01.png", + "res/gfx/cutscene/c01s02.png", + "res/gfx/cutscene/c01s03.png", + "res/gfx/cutscene/c01s04.png", + "res/gfx/cutscene/c02s01.png", + "res/gfx/cutscene/c02s02.png", + "res/gfx/cutscene/c02s03.png", + "res/gfx/cutscene/c02s04.png", + "res/gfx/cutscene/c02s05.png", + "res/gfx/cutscene/c03s01.png", + "res/gfx/cutscene/c03s02.png", + "res/gfx/cutscene/c03s03.png", + "res/gfx/cutscene/c03s04.png", + "res/gfx/cutscene/c03s05.png", + "res/gfx/cutscene/c03s06.png", + "res/gfx/cutscene/c04s01.png", + "res/gfx/cutscene/c04s02.png", + "res/gfx/cutscene/c04s03.png", + "res/gfx/cutscene/c04s04.png", + "res/gfx/cutscene/c04s05.png", + "res/gfx/cutscene/c04s06.png", + "res/gfx/cutscene/c05s01.png", + "res/gfx/cutscene/c05s02.png", + "res/gfx/cutscene/c05s03.png", + "res/gfx/cutscene/c05s04.png", + "res/gfx/cutscene/c05s05.png", + "res/gfx/cutscene/c05s06.png", + "res/gfx/cutscene/c06s01.png", + "res/gfx/cutscene/c06s02.png", + "res/gfx/cutscene/c06s03.png", + "res/gfx/cutscene/c06s04.png", + "res/gfx/cutscene/c06s05.png", + "res/gfx/cutscene/c06s06.png", + "res/gfx/cutscene/c06s07.png", + "res/gfx/cutscene/c06s08.png", + "res/gfx/cutscene/c06s09.png", + "res/gfx/cutscene/c06s10.png", + "res/gfx/cutscene/c06s11.png", + "res/gfx/cutscene/c06s12.png", + "res/gfx/cutscene/c06s13.png", + "res/gfx/cutscene/ending.png", + "res/gfx/cutscene/ending2.png", + "res/gfx/cutscene/ending3.png", }; #define FONT_COUNT FONT_BIG + 1 diff --git a/src/game/state/STATE_COMMON.h b/src/game/state/STATE_COMMON.h index f71274b..4e2841f 100644 --- a/src/game/state/STATE_COMMON.h +++ b/src/game/state/STATE_COMMON.h @@ -28,6 +28,8 @@ typedef enum StateType STATE_CUTSCENE_FIVE, STATE_CUTSCENE_FINAL, STATE_ENDING, + STATE_ENDING_TWO, + STATE_ENDING_THREE, STATE_LEVEL_ONE, STATE_LEVEL_TWO, STATE_LEVEL_THREE, diff --git a/src/game/state/cutscene/cutscene.c b/src/game/state/cutscene/cutscene.c index 4060218..0b55d44 100644 --- a/src/game/state/cutscene/cutscene.c +++ b/src/game/state/cutscene/cutscene.c @@ -99,6 +99,7 @@ cutscene_tick(Cutscene* self) } _cutscene_dialogue_set(self); + _cutscene_sprite_set(self); } if (control_released(self->ecs->control, CONTROL_ACTION_TERTIARY)) diff --git a/src/game/state/cutscene/cutscene.h b/src/game/state/cutscene/cutscene.h index dfbfc95..02c2a64 100644 --- a/src/game/state/cutscene/cutscene.h +++ b/src/game/state/cutscene/cutscene.h @@ -9,7 +9,7 @@ static const u32 CUTSCENE_SKIP_TEXT_TIMER = 300; static const s32 CUTSCENE_SKIP_TEXT_WRAP = -1; static const u32 CUTSCENE_DIALOGUE_SPEED = 2; static const vec3 CUTSCENE_SPRITE_POSITION = {640.0f, 250.0f, 0.0f}; -static const vec2 CUTSCENE_SPRITE_SIZE = {720.0f, 360.0f}; +static const vec2 CUTSCENE_SPRITE_SIZE = {640.0f, 360.0f}; #define CUTSCENE_BUFFER RENDERER_BUFFER_UI diff --git a/src/game/state/ending/ENDING_COMMON.h b/src/game/state/ending/ENDING_COMMON.h index f93b85f..29bc8d2 100644 --- a/src/game/state/ending/ENDING_COMMON.h +++ b/src/game/state/ending/ENDING_COMMON.h @@ -4,11 +4,20 @@ #include "../../ecs/entity/visual/entity_sprite.h" #include "../../ecs/entity/ui/entity_cursor.h" +#define ENDING_COUNT ENDING_THREE + 1 +typedef enum EndingType +{ + ENDING_ONE, + ENDING_TWO, + ENDING_THREE +} EndingType; + typedef struct Ending { ECS* ecs; EntityID cursor; EntityID text; + EntityID tipText; EntityID bg; bool isFinished; } Ending; diff --git a/src/game/state/ending/ending.c b/src/game/state/ending/ending.c index d0ebf62..eae6a92 100644 --- a/src/game/state/ending/ending.c +++ b/src/game/state/ending/ending.c @@ -1,8 +1,11 @@ #include "ending.h" void -ending_init(Ending* self, ECS* ecs) +ending_init(Ending* self, ECS* ecs, EndingType type) { + Texture* texture; + const char* tipString; + memset(self, '\0', sizeof(Ending)); self->ecs = ecs; @@ -19,17 +22,45 @@ ending_init(Ending* self, ECS* ecs) -1 ); + + switch (type) + { + case ENDING_ONE: + default: + texture = &ecs->resources->textures[TEXTURE_ENDING]; + break; + case ENDING_TWO: + texture = &ecs->resources->textures[TEXTURE_ENDING_TWO]; + break; + case ENDING_THREE: + texture = &ecs->resources->textures[TEXTURE_ENDING_THREE]; + break; + }; + + + tipString = STRING_ENDING_TIP_TEXT[type]; + + self->tipText = entity_text_add + ( + ecs, + &ecs->resources->fonts[FONT_SMALL], + RENDERER_BUFFER_UI, + tipString, + ENDING_TIP_TEXT_POSITION, + -1 + ); + self->bg = entity_sprite_add ( ecs, - &ecs->resources->textures[TEXTURE_ENDING], + texture, RENDERER_BUFFER_BACKGROUND, ORIGIN_TOP_LEFT, ENDING_BG_SIZE, ENDING_BG_POSITION ); - music_play(&self->ecs->resources->music[MUSIC_VICTORY], true); + music_play(&self->ecs->resources->music[MUSIC_WIND], true); } void diff --git a/src/game/state/ending/ending.h b/src/game/state/ending/ending.h index f22a525..f7e3560 100644 --- a/src/game/state/ending/ending.h +++ b/src/game/state/ending/ending.h @@ -6,8 +6,17 @@ static vec3 ENDING_TEXT_POSITION = {25.0f, 650.0f, 0.0f}; static vec2 ENDING_BG_SIZE = {1280.0f, 720.0f}; static vec3 ENDING_BG_POSITION = {0.0f, 0.0f, 0.0f}; +static vec3 ENDING_TIP_TEXT_POSITION = {25.0f, 25.0f, 0.0f}; + +static const char* STRING_ENDING_TIP_TEXT[ENDING_COUNT] = +{ + "OK ending! Earn better medals to get a better ending!", + "Good ending! Earn better medals to get a better ending!", + "Best ending! Congratulations!", +}; + #define STRING_ENDING_TEXT "THE END" -void ending_init(Ending* self, ECS* ecs); +void ending_init(Ending* self, ECS* ecs, EndingType type); void ending_tick(Ending* self); void ending_free(Ending* self); diff --git a/src/game/state/level/LEVEL_COMMON.h b/src/game/state/level/LEVEL_COMMON.h index 4038f7c..1dedc9f 100644 --- a/src/game/state/level/LEVEL_COMMON.h +++ b/src/game/state/level/LEVEL_COMMON.h @@ -5,6 +5,7 @@ #include "../../ecs/entity/ui/entity_medal.h" #include "../../ecs/entity/visual/entity_value_text.h" #include "../../ecs/entity/game/entity_player.h" +#include "../../ecs/entity/game/entity_foliage.h" #include "../../ecs/entity/game/entity_target.h" #include "../../ecs/entity/game/entity_collectible_amulet.h" #include "../../ecs/entity/game/entity_collectible_stamina.h" @@ -16,6 +17,9 @@ #include "../../ecs/entity/utility/entity_timer.h" #include "../../ecs/entity/visual/entity_dialogue.h" #include "../../ecs/entity/visual/entity_text_disappearing.h" +#include "../../ecs/entity/visual/entity_text_queue_entry.h" + +static const vec4 LEVEL_SUNSET_COLOR = {0.15f, 0.10f, 0.10f, 1.0f}; #define LEVEL_TUTORIAL_TEXT_COUNT 3 @@ -57,9 +61,11 @@ typedef struct LevelSettings u32 eventTime; vec4 colorCover; u32 collectibleMax; + u32 seedStart; bool isPower; bool isEvent; bool isAmulet; + bool isSunset; bool isPowerForesight; bool isPowerCancel; bool isPowerMagnet; @@ -88,6 +94,8 @@ typedef struct Level s32 timeToMedal; s32 timerValue; u32 levelValue; + u32 eventSeed; + u32 collectibleSeed; LevelMedal nextMedal; LevelEvent event; LevelEvent nextEvent; diff --git a/src/game/state/level/collectible_spawn.c b/src/game/state/level/collectible_spawn.c index 87a28d9..bfb57cc 100644 --- a/src/game/state/level/collectible_spawn.c +++ b/src/game/state/level/collectible_spawn.c @@ -407,6 +407,8 @@ _level_collectibles_spawn(Level* self) vector_init(&spawns, sizeof(u32)); + srand(self->collectibleSeed); + collectibleCount = 0; while (collectibleCount <= self->settings.collectibleMax) @@ -524,6 +526,8 @@ _level_collectibles_spawn(Level* self) vector_free(&spawns); sound_play(&self->ecs->resources->sounds[SOUND_APPEAR]); + + self->collectibleSeed++; } void diff --git a/src/game/state/level/collectible_spawn.h b/src/game/state/level/collectible_spawn.h index 4e9e6cb..b7389fd 100644 --- a/src/game/state/level/collectible_spawn.h +++ b/src/game/state/level/collectible_spawn.h @@ -4,7 +4,7 @@ #define LEVEL_COLLECTIBLE_SPAWN_MAX 50 -static const vec4 LEVEL_COLLECTIBLE_SPAWN_BOUNDS = {350.0f, 350.0f, 6300.0f, 3000.0f}; +static const vec4 LEVEL_COLLECTIBLE_SPAWN_BOUNDS = {350.0f, 350.0f, 6100.0f, 3000.0f}; static const f32 LEVEL_COLLECTIBLE_SPAWN_MERCY_TIMER = 600; static const u32 LEVEL_COLLECTIBLE_SPAWN_MERCY_COUNT = 5; diff --git a/src/game/state/level/event.c b/src/game/state/level/event.c index e31de8f..d4dfa41 100644 --- a/src/game/state/level/event.c +++ b/src/game/state/level/event.c @@ -410,7 +410,11 @@ _level_event_set(Level* self) _level_event_timer_init(self); - self->nextEvent = LEVEL_EVENT_STICKY_TRAPS;//RANDOM_S32(LEVEL_EVENT_NONE, LEVEL_EVENT_COUNT - 1); + self->eventSeed++; + + srand(self->eventSeed); + + self->nextEvent = RANDOM_S32(LEVEL_EVENT_NONE, LEVEL_EVENT_COUNT - 1); } void @@ -424,7 +428,11 @@ level_event_init(Level* self) eventTimer->component.isDisabled = true; - self->nextEvent = LEVEL_EVENT_STICKY_TRAPS; //RANDOM_S32(LEVEL_EVENT_NONE, LEVEL_EVENT_COUNT - 1); + self->eventSeed = self->settings.seedStart; + + srand(self->eventSeed); + + self->nextEvent = RANDOM_S32(LEVEL_EVENT_NONE, LEVEL_EVENT_COUNT - 1); } void diff --git a/src/game/state/level/event.h b/src/game/state/level/event.h index 06e9738..029d878 100644 --- a/src/game/state/level/event.h +++ b/src/game/state/level/event.h @@ -4,7 +4,7 @@ #include "ui.h" #define LEVEL_EVENT_OUT_OF_BREATH_STAMINA_MULTIPLIER 0.5f -#define LEVEL_EVENT_VIM_AND_VIGOR_STAMINA_MAX 10000.0f +#define LEVEL_EVENT_VIM_AND_VIGOR_STAMINA_MAX 99999.0f #define LEVEL_EVENT_ANCHOR_ARMS_FOOD_MAX 50 #define LEVEL_EVENT_BUTTERFINGERS_FOOD_MAX 10 #define LEVEL_EVENT_GLUTTONY_FOOD_MULTIPLIER 2; diff --git a/src/game/state/level/level.c b/src/game/state/level/level.c index ac182f9..d9771a9 100644 --- a/src/game/state/level/level.c +++ b/src/game/state/level/level.c @@ -4,6 +4,45 @@ static void _level_entity_init(Level* self); static void _level_finish(Level* self); static void _level_finish_text_add(Level* self); static void _level_finish_amulet_spawn(Level* self); +//static void _level_foliage_spawn(Level* self); + +/* +static void +_level_foliage_spawn(Level* self) +{ + s32 foliageCount; + + foliageCount = RANDOM_S32(LEVEL_FOLIAGE_COUNT_MIN, LEVEL_FOLIAGE_COUNT_MAX); + + for (s32 i = 0; i < foliageCount; i++) + { + FoliageType type; + vec3 position; + bool isInRectangle; + + glm_vec3_zero(position); + + type = (FoliageType)RANDOM_S32(0, FOLIAGE_TYPE_COUNT - 1); + + isInRectangle = true; + + while(isInRectangle) + { + vec2 testPosition; + + position[0] = RANDOM_F32(LEVEL_FOLIAGE_SPAWN_BOUNDS[0], LEVEL_FOLIAGE_SPAWN_BOUNDS[2]); + position[1] = RANDOM_F32(LEVEL_FOLIAGE_SPAWN_BOUNDS[1], LEVEL_FOLIAGE_SPAWN_BOUNDS[3]); + + testPosition[0] = position[0]; + testPosition[1] = position[1]; + + isInRectangle = rectangle_has_point(&LEVEL_FOLIAGE_SPAWN_NO_NO_RECTANGLE, testPosition); + } + + entity_foliage_add(self->ecs, position, type); + } +} +*/ static void _level_finish_text_add(Level* self) @@ -71,7 +110,6 @@ _level_finish_text_add(Level* self) level_text_queue_clear(self); level_text_queue_add(self, string); - } static void @@ -181,7 +219,7 @@ _level_entity_init(Level* self) ( self->ecs, &self->ecs->resources->textures[TEXTURE_GAME_PLANE], - RENDERER_BUFFER_WORLD, + RENDERER_BUFFER_PLANE, ORIGIN_TOP_LEFT, (f32*)LEVEL_PLANE_SIZE, (f32*)LEVEL_PLANE_POSITION @@ -235,6 +273,9 @@ level_init(Level* self, ECS* ecs, LevelSettings settings, u32 levelValue) self->levelValue = levelValue; self->isCountdownDone = false; + self->collectibleSeed = self->settings.seedStart; + self->eventSeed = self->settings.seedStart; + _level_entity_init(self); if (self->settings.isEvent) @@ -247,7 +288,12 @@ level_init(Level* self, ECS* ecs, LevelSettings settings, u32 levelValue) level_collectible_spawn_init(self); + if (self->settings.isSunset) + glm_vec4_copy(LEVEL_SUNSET_COLOR, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].color); + + glm_vec4_copy(settings.colorCover, self->ecs->postprocessing[RENDERER_BUFFER_PLANE].colorCover); glm_vec4_copy(settings.colorCover, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].colorCover); + glm_vec4_copy(settings.colorCover, self->ecs->postprocessing[RENDERER_BUFFER_OVERLAY].colorCover); glm_vec4_copy(settings.colorCover, self->ecs->postprocessing[RENDERER_BUFFER_BACKGROUND].colorCover); music_play(&self->ecs->resources->music[MUSIC_WIND], true); @@ -279,8 +325,14 @@ level_tick(Level* self) self->isCountdownDone ) { + ComponentText* text; + + text = ecs_component_get(self->ecs, COMPONENT_TEXT, self->timerUI); + if (timer->value % SECOND_TICK == 0) sound_play(&self->ecs->resources->sounds[SOUND_LOW_TIMER_TICK]); + + glm_vec4_copy(LEVEL_EVENT_TIMER_LOW_TICK_THRESHOLD_COLOR, text->color); } if (!timer->isFinished) diff --git a/src/game/state/level/level.h b/src/game/state/level/level.h index 7bbf7f7..d366903 100644 --- a/src/game/state/level/level.h +++ b/src/game/state/level/level.h @@ -6,13 +6,17 @@ #include "tutorial.h" #include "pause.h" +#define LEVEL_FOLIAGE_COUNT_MIN 10 +#define LEVEL_FOLIAGE_COUNT_MAX 20 + static const vec3 LEVEL_TRAP_POSITION = {2500.0f, 1000.0f, 0.0f}; static const vec3 LEVEL_PLAYER_POSITION = {3275.0f, 2400.0f, 0.0f}; static const vec3 LEVEL_TARGET_POSITION = {3275.0f, 1625.0f, 0.0f}; static const vec3 LEVEL_PLANE_POSITION = {250.0f, 250.0f, 1.0f}; -static const vec3 LEVEL_PLANE_SIZE = {6300.0f, 3100.0f, 0.0f}; -static const vec3 LEVEL_BG_POSITION = {0.0f, 00.0f, 1.0f}; +static const vec3 LEVEL_PLANE_SIZE = {5925.0f, 3100.0f, 0.0f}; +static const vec3 LEVEL_BG_POSITION = {0.0f, 0.0f, 1.0f}; static const vec3 LEVEL_BG_SIZE = {1280.0f, 720.0f, 0.0f}; +static const vec4 LEVEL_EVENT_TIMER_LOW_TICK_THRESHOLD_COLOR = {1.0f, 0.0f, 0.0f, 1.0f}; static const f32 LEVEL_FINISH_TEXT_VALUE = 60; static const vec3 LEVEL_FINISH_TEXT_POSITION = {600.0f, 300.0f, 0.0f}; diff --git a/src/game/state/level/pause.c b/src/game/state/level/pause.c index 1a03745..af63919 100644 --- a/src/game/state/level/pause.c +++ b/src/game/state/level/pause.c @@ -44,8 +44,15 @@ level_pause(Level* self) self->ecs->isFunctionDisabled[ECS_FUNCTION_TICK] = true; self->ecs->isFunctionDisabled[ECS_FUNCTION_UPDATE] = true; - glm_vec3_copy(LEVEL_PAUSE_COLOR, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].color); + glm_vec3_copy(LEVEL_PAUSE_COLOR, self->ecs->postprocessing[RENDERER_BUFFER_PLANE].color); + + if (self->settings.isSunset) + glm_vec3_copy(BLACK, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].color); + else + glm_vec3_copy(LEVEL_PAUSE_COLOR, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].color); + glm_vec3_copy(LEVEL_PAUSE_COLOR, self->ecs->postprocessing[RENDERER_BUFFER_BACKGROUND].color); + glm_vec3_copy(LEVEL_PAUSE_COLOR, self->ecs->postprocessing[RENDERER_BUFFER_OVERLAY].color); } void @@ -63,8 +70,15 @@ level_unpause(Level* self) self->ecs->isFunctionDisabled[ECS_FUNCTION_TICK] = false; self->ecs->isFunctionDisabled[ECS_FUNCTION_UPDATE] = false; - glm_vec3_copy(OPAQUE, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].color); + glm_vec3_copy(OPAQUE, self->ecs->postprocessing[RENDERER_BUFFER_PLANE].color); + + if (self->settings.isSunset) + glm_vec3_copy(BLACK, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].color); + else + glm_vec3_copy(OPAQUE, self->ecs->postprocessing[RENDERER_BUFFER_WORLD].color); + glm_vec3_copy(OPAQUE, self->ecs->postprocessing[RENDERER_BUFFER_BACKGROUND].color); + glm_vec3_copy(OPAQUE, self->ecs->postprocessing[RENDERER_BUFFER_OVERLAY].color); } void diff --git a/src/game/state/level/text_queue.c b/src/game/state/level/text_queue.c index 7924390..fce2d7d 100644 --- a/src/game/state/level/text_queue.c +++ b/src/game/state/level/text_queue.c @@ -67,7 +67,7 @@ level_text_queue_add(Level* self, const char* string) { EntityID id; - id = entity_text_disappearing_add + id = entity_text_queue_entry_add ( self->ecs, &self->ecs->resources->fonts[FONT_SMALL], diff --git a/src/game/state/level/text_queue.h b/src/game/state/level/text_queue.h index c8afe73..1e30bcd 100644 --- a/src/game/state/level/text_queue.h +++ b/src/game/state/level/text_queue.h @@ -2,7 +2,7 @@ #include "LEVEL_COMMON.h" -static const f32 LEVEL_TEXT_QUEUE_TIMER = 1500; +static const f32 LEVEL_TEXT_QUEUE_TIMER = 900; static const vec3 LEVEL_TEXT_QUEUE_POSITION = {25.0f, 675.0f, 0.0f}; void level_text_queue_set(Level* self); diff --git a/src/game/state/level/ui.c b/src/game/state/level/ui.c index aacb5f1..8a507a3 100644 --- a/src/game/state/level/ui.c +++ b/src/game/state/level/ui.c @@ -175,5 +175,27 @@ level_ui_init(Level* self) void level_ui_tick(Level* self) { + ComponentFood* food; + _level_ui_threshold_tick(self); + + food = ecs_component_get(self->ecs, COMPONENT_FOOD, self->player); + + if (food->value >= food->max) + { + ComponentText* text; + + text = ecs_component_get(self->ecs, COMPONENT_TEXT, self->playerFoodUI); + + glm_vec4_copy(LEVEL_PLAYER_FOOD_UI_MAX_COLOR, text->color); + } + else + { + ComponentText* text; + + text = ecs_component_get(self->ecs, COMPONENT_TEXT, self->playerFoodUI); + + glm_vec4_copy(OPAQUE, text->color); + } + } diff --git a/src/game/state/level/ui.h b/src/game/state/level/ui.h index 5f3c988..a739a17 100644 --- a/src/game/state/level/ui.h +++ b/src/game/state/level/ui.h @@ -10,6 +10,7 @@ static const vec3 LEVEL_THRESHOLD_UI_POSITION = {1200.0f, 64.0f, 0.0f}; static const vec3 LEVEL_MEDAL_POSITION = {1175.0f, 75.0f, 0.0f}; static const vec3 LEVEL_TIMER_POSITION = {600.0f, 32.0f, 0.0f}; static const vec3 LEVEL_EVENT_TIMER_POSITION = {575.0f, 64.0f, 0.0f}; +static const vec4 LEVEL_PLAYER_FOOD_UI_MAX_COLOR = {1.0f, 0.0f, 0.0f, 1.0f}; #define LEVEL_TIMER_FORMAT "%i'%02i\"%02i" #define LEVEL_EVENT_TIMER_FORMAT "Event: %i'%02i\"%02i" diff --git a/src/game/state/state.c b/src/game/state/state.c index cfb83c9..62dd152 100644 --- a/src/game/state/state.c +++ b/src/game/state/state.c @@ -34,10 +34,10 @@ _state_level_tick(State* self, LevelType type) self->levelData[type + 1].status = LEVEL_STATUS_UNLOCKED; } - if (type < LEVEL_FIVE) - _state_set(self, STATE_TITLE); - else + if (type == LEVEL_FIVE && self->states.level.isComplete) _state_set(self, STATE_CUTSCENE_FINAL); + else + _state_set(self, STATE_TITLE); } } @@ -75,7 +75,13 @@ _state_set(State* self, StateType type) cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_FINAL); break; case STATE_ENDING: - ending_init(&self->states.ending, self->ecs); + ending_init(&self->states.ending, self->ecs, ENDING_ONE); + break; + case STATE_ENDING_TWO: + ending_init(&self->states.ending, self->ecs, ENDING_TWO); + break; + case STATE_ENDING_THREE: + ending_init(&self->states.ending, self->ecs, ENDING_THREE); break; case STATE_LEVEL_ONE: level_init(&self->states.level, self->ecs, LEVEL_SETTINGS[LEVEL_ONE], LEVEL_ONE); @@ -133,6 +139,8 @@ state_free(State* self) cutscene_free(&self->states.cutscene); break; case STATE_ENDING: + case STATE_ENDING_TWO: + case STATE_ENDING_THREE: ending_free(&self->states.ending); default: break; @@ -149,6 +157,10 @@ state_change(State* self, StateType type) void state_tick(State* self) { + u32 endingPoints; + + endingPoints = 0; + if (self->isChanging) { self->isChanging = false; @@ -223,9 +235,22 @@ state_tick(State* self) cutscene_tick(&self->states.cutscene); if (self->states.cutscene.isFinished) - _state_set(self, STATE_ENDING); + { + for (s32 i = 0; i < LEVEL_COUNT; i++) + endingPoints += self->levelData[i].status; + + if (endingPoints >= LEVEL_STATUS_GOLD * LEVEL_COUNT) + _state_set(self, STATE_ENDING_THREE); + else if (endingPoints >= (LEVEL_STATUS_SILVER * LEVEL_COUNT)) + _state_set(self, STATE_ENDING_TWO); + else + _state_set(self, STATE_ENDING); + } + break; case STATE_ENDING: + case STATE_ENDING_TWO: + case STATE_ENDING_THREE: ending_tick(&self->states.ending); if (self->states.ending.isFinished) diff --git a/src/game/state/state.h b/src/game/state/state.h index 73b6c96..44ad91b 100644 --- a/src/game/state/state.h +++ b/src/game/state/state.h @@ -7,7 +7,7 @@ static const Scene CUTSCENE_ONE_SCENES[CUTSCENE_ONE_COUNT] = { { .texture = TEXTURE_CUTSCENE_ONE_SCENE_ONE, - .string = "In an far off patch of unknown wilderness, there has been an unexpected period of abundance. It is as if full meals grow from the ground like weeds in a garden." + .string = "In an far off patch of unknown wilderness, there has been an unexpected period of abundance. It is as if full meals grow from the ground like weeds in a garden. Or...perhaps, they do." }, { .texture = TEXTURE_CUTSCENE_ONE_SCENE_TWO, @@ -28,7 +28,7 @@ static const Scene CUTSCENE_TWO_SCENES[CUTSCENE_TWO_COUNT] = { { .texture = TEXTURE_CUTSCENE_TWO_SCENE_ONE, - .string = "The first expeditions had been a resounding success. The frilled matriarch has spent her time lounging and indulging in the delights her slave had brought her. It even began to reflect on her physique." + .string = "The first expeditions had been a resounding success. The frilled matriarch has spent her time lounging and indulging in the delights her servant had brought her. It even began to reflect on her physique." }, { .texture = TEXTURE_CUTSCENE_TWO_SCENE_TWO, @@ -36,7 +36,7 @@ static const Scene CUTSCENE_TWO_SCENES[CUTSCENE_TWO_COUNT] = }, { .texture = TEXTURE_CUTSCENE_TWO_SCENE_THREE, - .string = "...but, its objective was more important than anything else." + .string = "...but, its objective was more important than anything else!!" }, { .texture = TEXTURE_CUTSCENE_TWO_SCENE_FOUR, @@ -53,7 +53,7 @@ static const Scene CUTSCENE_THREE_SCENES[CUTSCENE_THREE_COUNT] = { { .texture = TEXTURE_CUTSCENE_THREE_SCENE_ONE, - .string = "While scrounging for more foodstuffs, in the dense thicket, the frilled runt uncovers a golden trinket that illuminates the creature's face in an unearthly turquoise." + .string = "While scrounging for more foodstuffs, in the dense thicket, the frilled runt uncovers a golden trinket that illuminates an unearthly turquoise." }, { .texture = TEXTURE_CUTSCENE_THREE_SCENE_TWO, @@ -82,11 +82,11 @@ static const Scene CUTSCENE_FOUR_SCENES[CUTSCENE_FOUR_COUNT] = { { .texture = TEXTURE_CUTSCENE_FOUR_SCENE_ONE, - .string = "It seemed that the amulet's power was strengthening. Suddenly, the creature could feel things before they were set to happen. It predicted that its growing mistress would ask fo-" + .string = "It seemed that the amulet's power was strengthening. Suddenly, the creature could feel things before they were set to happen. It predicted that its mistress would ask fo-" }, { .texture = TEXTURE_CUTSCENE_FOUR_SCENE_TWO, - .string = "\"Servant! Fetch more food for your famished mistress!\"" + .string = "\"Servant! Fetch more food for your famished matriarch!\"" }, { .texture = TEXTURE_CUTSCENE_FOUR_SCENE_THREE, @@ -94,11 +94,11 @@ static const Scene CUTSCENE_FOUR_SCENES[CUTSCENE_FOUR_COUNT] = }, { .texture = TEXTURE_CUTSCENE_FOUR_SCENE_FOUR, - .string = "...and so it did. The amulet glowed that brilliant turquoise as it did...could the amulet also use its power to dispel or change the events happening around the creature?" + .string = "...and indeed, it happened. The amulet glowed that brilliant turquoise as this occurred...could the amulet also use its power to dispel or change the events happening around the creature?" }, { .texture = TEXTURE_CUTSCENE_FOUR_SCENE_FIVE, - .string = "It seemed that the amulet's power was only growing, and so too was the frilled runt's...what other secrets might it hold?" + .string = "It seemed that the amulet's abilities were increasing, The frilled runt's power continued to grow. What other secrets might it hold?" }, { .texture = TEXTURE_CUTSCENE_FOUR_SCENE_SIX, @@ -112,7 +112,7 @@ static const Scene CUTSCENE_FIVE_SCENES[CUTSCENE_FIVE_COUNT] = { { .texture = TEXTURE_CUTSCENE_FIVE_SCENE_ONE, - .string = "The frilled runt, having wieleded the amulet's magick, had begun to master it. That magick seeped through the creature, indispensible like blood." + .string = "The frilled runt, having wieleded the amulet's magick, had begun to master it. That magick flowed through its veins like blood." }, { .texture = TEXTURE_CUTSCENE_FIVE_SCENE_TWO, @@ -124,15 +124,15 @@ static const Scene CUTSCENE_FIVE_SCENES[CUTSCENE_FIVE_COUNT] = }, { .texture = TEXTURE_CUTSCENE_FIVE_SCENE_FOUR, - .string = "As the frilled monarch finished gorging upon a morsel, it catches her single prized laborer deep in thought." + .string = "As the frilled monarch finished gorging upon a morsel, it catches her single prized laborer caught in...this episode." }, { .texture = TEXTURE_CUTSCENE_FIVE_SCENE_FIVE, - .string = "\"My dear servant! Fetch me more food to feed my growing belly!\" she beams excitedly, her thick digits sunk into her now-voluminous yellow flesh." + .string = "\"My dear s-servant! Please, continue feeding me; I insist.\" she escapes her trance, her thick digits sunk into her now-voluminous yellow flesh." }, { .texture = TEXTURE_CUTSCENE_FIVE_SCENE_SIX, - .string = "With the help of the amulet, a new feeling twinged through the creature's body. With its increasing strength, it seemed anything was possible. Perhaps it would best to just...play along with this charade! Until...until..." + .string = "A new feeling twinged through the creature's body. With its increasing powers, it seemed anything was possible. Godhood, even. For now, it would be best to play along with this charade... until... until..." } }; @@ -145,7 +145,7 @@ static const Scene CUTSCENE_FINAL_SCENES[CUTSCENE_FINAL_COUNT] = }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_TWO, - .string = "Unfortunately for the gluttonous reptile, her body had acquired so much flesh, that her encumbered muscles could not heave her rotund rear end off the ground." + .string = "Unfortunately for the gluttonous reptile, her body had acquired so much flesh, that her encumbered muscles could not heave her rotund rear end off of her throne." }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_THREE, @@ -161,35 +161,35 @@ static const Scene CUTSCENE_FINAL_SCENES[CUTSCENE_FINAL_COUNT] = }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_SIX, - .string = "Her little friend was, indeed, starving, and had been for a while. As a pang of hunger struck, so did a pang of that strange, alien sense of negativity.. " + .string = "Her little friend was, indeed, starving, and had been for a while. As a pang of hunger struck, so did a pang of that unfamilar, powerful...hatred." }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_SEVEN, - .string = "\"Surely, you could've eaten some of the food yourself! And... I saw you with that golden trinket. It's got quite the power, does it?\"" + .string = "\"Surely, you could've eaten some of the food yourself! And... I saw you with that golden trinket. It's got quite the power, doesn't it?\"" }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_EIGHT, - .string = "That golden trinket had stirred those feelings. It had also stirred untold, growing power. A lesser creature would fell the useless, blubbery monarch and usurp her throne using its mighty magicks then and there." + .string = "That golden trinket had amplified those feelings. It had also stirred untold, growing power. One could fell the useless, blubbery monarch and usurp her throne using its mighty magicks then and there." }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_NINE, - .string = "But...the runt was not a lesser creature. That amulet also granted...wisdom; a sense of reality. The mistress was flawed, but as she was served, she began to appreciate the tireless efforts of her companion. She belived the runt should not suffer." + .string = "But...the runt was not so shortsighted. The mistress was flawed, but what would the runt do without her? She gave it purpose, meaning. What would the runt rule over if it chose to unleash this power? Its starvation had only been an invention, festered by blind devotion, and amplified by the power of the amulet." }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_TEN, - .string = "Perhaps things were better when that trinket did not grant the creature these pointed feelings. The past was in the past. The frilled runt only had one gift left to relinquish...the amulet, dedicating its power to the greatest leader it knew." + .string = "That amulet had intoxicated the little runt with visions. With its wisdom though, it helped the runt realize it is best for one to know their role; doing the most good with what they are, than being something they are not; like...a god. The runt chose to gift the trinket to the one more equipped to lead." }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_ELEVEN, - .string = "The power present in the creature's body soon transferred to that of the frilled monarch. \"Now, my little friend...perhaps I should use this amulet's power to feed you as much as you did me!" + .string = "The power present in the creature's body soon transferred to that of the frilled monarch. \"Now, my little friend...perhaps I should use this trinket's power to spoil you as much as you did me!" }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_TWELVE, - .string = "..!" + .string = "\"..!\"" }, { .texture = TEXTURE_CUTSCENE_FINAL_SCENE_THIRTEEN, - .string = "The clouds recede as the two enjoy the abundance...together! Perhaps...a little too much!" + .string = "A turquoise light in the sky gleams as the two enjoy the abundance...together! Perhaps...a little too much!" }, }; @@ -232,14 +232,16 @@ static const SceneCollection CUTSCENE_FINAL = static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] = { { - .medalThresholds = {100, 200, 300}, + .medalThresholds = {200, 275, 325}, .time = 7200, .colorCover = {-0.05f, -0.05f, -0.05f, 0.0f}, .collectibleMax = 30, .eventTime = 0, + .seedStart = 0xFACEFEED, .isPower = false, .isEvent = false, .isAmulet = false, + .isSunset = false, .isPowerForesight = false, .isPowerCancel = false, .isPowerMagnet = false, @@ -258,14 +260,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] = .isTutorialFinal = false }, { - .medalThresholds = {150, 300, 450}, + .medalThresholds = {300, 500, 600}, .time = 10800, - .colorCover = {0.0f, 0.0f, 0.0f, 0.0f}, + .colorCover = {-0.10f, -0.10f, -0.05f, 0.0f}, .collectibleMax = 35, .eventTime = 1800, + .seedStart = 0xABADBABE, .isPower = false, .isEvent = true, .isAmulet = true, + .isSunset = false, .isPowerForesight = false, .isPowerCancel = false, .isPowerMagnet = false, @@ -284,14 +288,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] = .isTutorialFinal = false }, { - .medalThresholds = {300, 400, 500}, + .medalThresholds = {400, 550, 625}, .time = 10800, - .colorCover = {0.05f, 0.05f, 0.05f, 0.0f}, + .colorCover = {0.15f, 0.05f, 0.00f, 0.0f}, .collectibleMax = 40, .eventTime = 1500, + .seedStart = 0x0B00B135, .isPower = true, .isEvent = true, .isAmulet = false, + .isSunset = false, .isPowerForesight = false, .isPowerCancel = false, .isPowerMagnet = false, @@ -310,14 +316,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] = .isTutorialFinal = false }, { - .medalThresholds = {400, 500, 600}, + .medalThresholds = {500, 600, 700}, .time = 10800, - .colorCover = {0.1f, 0.05f, 0.0f, 0.0f}, + .colorCover = {0.3f, 0.15f, 0.0f, 0.0f}, .collectibleMax = 45, .eventTime = 1200, + .seedStart = 0xDEADD00D, .isPower = true, .isEvent = true, .isAmulet = false, + .isSunset = true, .isPowerForesight = true, .isPowerCancel = true, .isPowerMagnet = false, @@ -336,14 +344,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] = .isTutorialFinal = false }, { - .medalThresholds = {500, 750, 1000}, + .medalThresholds = {750, 900, 1150}, .time = 18000, - .colorCover = {-0.025f, -0.00f, -0.025f, 0.0f}, + .colorCover = {-0.25f, -0.50f, -0.10f, 0.0f}, .collectibleMax = 50, .eventTime = 900, + .seedStart = 0xDEADBEEF, .isPower = true, .isEvent = true, .isAmulet = false, + .isSunset = false, .isPowerForesight = true, .isPowerCancel = true, .isPowerMagnet = false, @@ -371,7 +381,7 @@ static const LevelData LEVEL_DATA_DEFAULT[LEVEL_COUNT] = .time = -1 }, { - .status = LEVEL_STATUS_UNLOCKED, + .status = LEVEL_STATUS_LOCKED, .score = -1, .time = -1 }, diff --git a/src/game/state/title/title.h b/src/game/state/title/title.h index b7f4bfb..1e370af 100644 --- a/src/game/state/title/title.h +++ b/src/game/state/title/title.h @@ -5,7 +5,7 @@ #define TITLE_LEVEL_SELECT_BUTTON_X_OFFSET (ENTITY_LEVEL_SELECT_BUTTON_SIZE[0] + (ENTITY_LEVEL_SELECT_BUTTON_SIZE[0] / 2)) #define TITLE_LEVEL_DATA_TEXT_X_OFFSET (TITLE_LEVEL_SELECT_BUTTON_X_OFFSET) -#define STRING_TITLE_CREDITS "WeightGaming Gain Jam 2024 (Theme: \"Unexpected Outcomes\") | Design, Programming Sound, Art by Shweet | Music by FraynVGM\nCharacters, graphics, music, sound, script licensed under CC0 | Source code licensed under GPLv3" +#define STRING_TITLE_CREDITS "WeightGaming Gain Jam 2024 (Theme: \"Unexpected Outcomes\") | Design, Programming, Sound, Art by Shweet | Music by FraynVGM\nCharacters, graphics, music, sound, script licensed under CC0 | Source code licensed under GPLv3" #define STRING_TITLE_LEVEL_SELECT "Select level..." #define STRING_TITLE_LEVEL_DATA_UNINITIALIZED "Time: -\'--\"--\nScore: ---"