jam ready

This commit is contained in:
shweet 2024-08-29 18:06:02 -04:00
parent 9fdde61cac
commit 0a3cc7284c
44 changed files with 464 additions and 241 deletions

View File

@ -14,7 +14,9 @@
typedef enum RendererBuffer typedef enum RendererBuffer
{ {
RENDERER_BUFFER_BACKGROUND, RENDERER_BUFFER_BACKGROUND,
RENDERER_BUFFER_PLANE,
RENDERER_BUFFER_WORLD, RENDERER_BUFFER_WORLD,
RENDERER_BUFFER_OVERLAY,
RENDERER_BUFFER_UI, RENDERER_BUFFER_UI,
RENDERER_BUFFER_META, RENDERER_BUFFER_META,
RENDERER_BUFFER_CURSOR RENDERER_BUFFER_CURSOR

View File

@ -19,4 +19,5 @@ typedef struct Game
Window window; Window window;
Postprocessing postprocessing[RENDERER_BUFFER_COUNT]; Postprocessing postprocessing[RENDERER_BUFFER_COUNT];
bool isPaused; bool isPaused;
bool isMute;
} Game; } Game;

View File

@ -43,7 +43,6 @@ typedef enum ComponentType
COMPONENT_DIALOGUE, COMPONENT_DIALOGUE,
COMPONENT_VALUE_TEXT, COMPONENT_VALUE_TEXT,
COMPONENT_ATLAS, COMPONENT_ATLAS,
COMPONENT_CAMERA_FOCUS,
COMPONENT_COLOR_CHANGE, COMPONENT_COLOR_CHANGE,
COMPONENT_COLOR_MATCH, COMPONENT_COLOR_MATCH,
COMPONENT_SCALE_VALUE, COMPONENT_SCALE_VALUE,

View File

@ -50,7 +50,8 @@ _component_collectible_increment(ComponentCollectible* self, ECS* ecs, EntityID
food = ecs_component_get(ecs, COMPONENT_FOOD, id); food = ecs_component_get(ecs, COMPONENT_FOOD, id);
if (!food) if (!food)
return; return;
food->value -= COMPONENT_COLLECTIBLE_FOOD_VALUE; food->value += COMPONENT_COLLECTIBLE_ROTTEN_FOOD_VALUE;
sound_play(&ecs->resources->sounds[SOUND_BLEH]); sound_play(&ecs->resources->sounds[SOUND_BLEH]);
break; break;
case COLLECTIBLE_AMULET: case COLLECTIBLE_AMULET:
@ -99,7 +100,8 @@ component_collectible_init
size, size,
position, position,
COMPONENT_COLLECTIBLE_HEIGHT_OFFSET, COMPONENT_COLLECTIBLE_HEIGHT_OFFSET,
COMPONENT_COLLECTIBLE_RADIUS COMPONENT_COLLECTIBLE_RADIUS,
true
); );
component_levitate_init component_levitate_init

View File

@ -13,6 +13,7 @@
static const f32 COMPONENT_COLLECTIBLE_HEIGHT_OFFSET = 1000.0f; static const f32 COMPONENT_COLLECTIBLE_HEIGHT_OFFSET = 1000.0f;
static const f32 COMPONENT_COLLECTIBLE_RADIUS = 64.0f; static const f32 COMPONENT_COLLECTIBLE_RADIUS = 64.0f;
static const u32 COMPONENT_COLLECTIBLE_FOOD_VALUE = 1; 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_POWER_VALUE = 10.0f;
static const f32 COMPONENT_COLLECTIBLE_STAMINA_VALUE = 50.0f; static const f32 COMPONENT_COLLECTIBLE_STAMINA_VALUE = 50.0f;
static const u32 COMPONENT_COLLECTIBLE_HOMING_SPEED = 3.0f; static const u32 COMPONENT_COLLECTIBLE_HOMING_SPEED = 3.0f;

View File

@ -135,7 +135,8 @@ component_world_object_init
vec2 size, vec2 size,
vec3 position, vec3 position,
f32 heightOffset, f32 heightOffset,
f32 radius f32 radius,
bool isShadow
) )
{ {
component_game_object_init component_game_object_init
@ -165,20 +166,27 @@ component_world_object_init
COMPONENT_WORLD_OBJECT_FRICTION COMPONENT_WORLD_OBJECT_FRICTION
); );
self->shadowID = entity_sprite_add self->isShadow = isShadow;
(
ecs,
&ecs->resources->textures[TEXTURE_SHADOW],
COMPONENT_WORLD_OBJECT_BUFFER,
COMPONENT_WORLD_OBJECT_ORIGIN,
(f32*)size,
(f32*)position
);
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->heightOffset = heightOffset;
self->isGravityAffected = true; self->isGravityAffected = true;
_component_world_object_shadow_set(self, ecs);
_component_world_object_height_offset_set(self, ecs); _component_world_object_height_offset_set(self, ecs);
_component_world_object_circle_collider_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_tick(ComponentWorldObject* self, ECS* ecs)
{ {
_component_world_object_depth_set(self, 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_height_offset_set(self, ecs);
_component_world_object_bounds_set(self, ecs); _component_world_object_bounds_set(self, ecs);
_component_world_object_direction_set(self, ecs); _component_world_object_direction_set(self, ecs);

View File

@ -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_DEPTH_MAX = 0.2f;
static const f32 COMPONENT_WORLD_OBJECT_GRAVITY = 1.0f; 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 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 #define COMPONENT_WORLD_OBJECT_ORIGIN ORIGIN_CENTER
@ -29,6 +29,7 @@ typedef struct ComponentWorldObject
Direction direction; Direction direction;
bool isAirborne; bool isAirborne;
bool isGravityAffected; bool isGravityAffected;
bool isShadow;
} ComponentWorldObject; } ComponentWorldObject;
void void
@ -40,7 +41,8 @@ component_world_object_init
vec2 size, vec2 size,
vec3 position, vec3 position,
f32 heightOffset, f32 heightOffset,
f32 radius f32 radius,
bool isShadow
); );
void component_world_object_add(ComponentWorldObject* self, ECS* ecs); void component_world_object_add(ComponentWorldObject* self, ECS* ecs);

View File

@ -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;
}

View File

@ -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)
};

View File

@ -27,7 +27,6 @@
#include "component/utility/component_timer.h" #include "component/utility/component_timer.h"
#include "component/utility/component_delete_on_timer.h" #include "component/utility/component_delete_on_timer.h"
#include "component/visual/component_atlas.h" #include "component/visual/component_atlas.h"
#include "component/visual/component_camera_focus.h"
#include "component/visual/component_dialogue.h" #include "component/visual/component_dialogue.h"
#include "component/visual/component_drop_shadow.h" #include "component/visual/component_drop_shadow.h"
#include "component/visual/component_color_change.h" #include "component/visual/component_color_change.h"
@ -84,7 +83,6 @@ static const struct ComponentInfo COMPONENT_INFO[COMPONENT_COUNT] =
COMPONENT_DIALOGUE_INFO, COMPONENT_DIALOGUE_INFO,
COMPONENT_VALUE_TEXT_INFO, COMPONENT_VALUE_TEXT_INFO,
COMPONENT_ATLAS_INFO, COMPONENT_ATLAS_INFO,
COMPONENT_CAMERA_FOCUS_INFO,
COMPONENT_COLOR_CHANGE_INFO, COMPONENT_COLOR_CHANGE_INFO,
COMPONENT_COLOR_MATCH_INFO, COMPONENT_COLOR_MATCH_INFO,
COMPONENT_SCALE_VALUE_INFO, COMPONENT_SCALE_VALUE_INFO,

View File

@ -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;
}

View File

@ -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);

View File

@ -21,7 +21,8 @@ entity_player_add(ECS* ecs, const vec3 position)
PLAYER_SIZE, PLAYER_SIZE,
position, position,
PLAYER_HEIGHT_OFFSET, PLAYER_HEIGHT_OFFSET,
PLAYER_RADIUS PLAYER_RADIUS,
true
); );
worldObject->angle = PLAYER_ANGLE; worldObject->angle = PLAYER_ANGLE;
@ -35,14 +36,6 @@ entity_player_add(ECS* ecs, const vec3 position)
PLAYER_ATLAS_INDEX 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 component_stamina_init
( (
ecs_component_get(ecs, COMPONENT_STAMINA, id), ecs_component_get(ecs, COMPONENT_STAMINA, id),

View File

@ -10,7 +10,6 @@
#include "../../component/game/component_collect.h" #include "../../component/game/component_collect.h"
#include "../../component/game/component_stamina.h" #include "../../component/game/component_stamina.h"
#include "../../component/game/component_world_object.h" #include "../../component/game/component_world_object.h"
#include "../../component/visual/component_camera_focus.h"
static const TextureType PLAYER_TEXTURE = TEXTURE_PLAYER; static const TextureType PLAYER_TEXTURE = TEXTURE_PLAYER;
static const vec2 PLAYER_SIZE = {384.0f, 256.0f}; 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_STAMINA_GAIN = 0.1f;
static const f32 PLAYER_POWER_MAX = 100.0f; static const f32 PLAYER_POWER_MAX = 100.0f;
static const f32 PLAYER_POWER_GAIN = 0.01f; 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_FRAME_SIZE = {96, 64};
static const ivec2 PLAYER_ATLAS_SIZE = {4, 5}; 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_WORLD_OBJECT,
COMPONENT_ATLAS, COMPONENT_ATLAS,
COMPONENT_CAMERA_FOCUS,
COMPONENT_COLLECT, COMPONENT_COLLECT,
COMPONENT_FOOD, COMPONENT_FOOD,
COMPONENT_POWER, COMPONENT_POWER,

View File

@ -17,7 +17,8 @@ entity_target_add(ECS* ecs, const vec3 position, u32 threshold, u32 stage, Entit
TARGET_SIZE, TARGET_SIZE,
position, position,
TARGET_HEIGHT_OFFSET, TARGET_HEIGHT_OFFSET,
TARGET_RADIUS TARGET_RADIUS,
true
); );
component_atlas_init component_atlas_init

View File

@ -3,7 +3,7 @@
#include "../visual/entity_sprite.h" #include "../visual/entity_sprite.h"
#include "../../component/visual/component_scale_value.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_MIN_SIZE = {0.0f, 32.0f};
static const vec2 ENTITY_METER_FILL_MAX_SIZE = {200.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}; static const vec2 ENTITY_METER_SIZE = {206.0f, 38.0f};

View File

@ -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;
}

View File

@ -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
};

View File

@ -40,6 +40,16 @@ _game_tick(Game* self)
if (event_press(&self->input.event, EVENT_QUIT)) if (event_press(&self->input.event, EVENT_QUIT))
_game_quit(self); _game_quit(self);
if (control_pressed(&self->control, CONTROL_MUTE))
{
self->isMute = !self->isMute;
if (self->isMute)
music_pause();
else
music_resume();
}
} }
static void static void

View File

@ -14,6 +14,8 @@ static const ivec2 BUFFER_SIZES[RENDERER_BUFFER_COUNT] =
{ {
{1280, 720}, {1280, 720},
{6400, 3600}, {6400, 3600},
{6400, 3600},
{6400, 3600},
{1280, 720}, {1280, 720},
{1280, 720}, {1280, 720},
{1280, 720} {1280, 720}

View File

@ -50,6 +50,9 @@ control_tick(Control* self, Input* input)
if (input->keyboard.current[KEYBOARD_KEY_ESCAPE]) if (input->keyboard.current[KEYBOARD_KEY_ESCAPE])
self->current[CONTROL_ESCAPE] = true; self->current[CONTROL_ESCAPE] = true;
if (input->keyboard.current[KEYBOARD_KEY_M])
self->current[CONTROL_MUTE] = true;
} }
bool bool

View File

@ -2,7 +2,7 @@
#include "input.h" #include "input.h"
#define CONTROL_COUNT CONTROL_ESCAPE + 1 #define CONTROL_COUNT CONTROL_MUTE + 1
typedef enum ControlType typedef enum ControlType
{ {
CONTROL_NONE, CONTROL_NONE,
@ -20,7 +20,8 @@ typedef enum ControlType
CONTROL_MAGNET, CONTROL_MAGNET,
CONTROL_PAUSE, CONTROL_PAUSE,
CONTROL_RETRY, CONTROL_RETRY,
CONTROL_ESCAPE CONTROL_ESCAPE,
CONTROL_MUTE
} ControlType; } ControlType;
typedef struct Control typedef struct Control

View File

@ -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 typedef enum TextureType
{ {
TEXTURE_DEFAULT, TEXTURE_DEFAULT,
@ -48,6 +48,7 @@ typedef enum TextureType
TEXTURE_COLLECTIBLE, TEXTURE_COLLECTIBLE,
TEXTURE_SMOKE, TEXTURE_SMOKE,
TEXTURE_TRAP, TEXTURE_TRAP,
TEXTURE_FOLIAGE,
TEXTURE_CUTSCENE_ONE_SCENE_ONE, TEXTURE_CUTSCENE_ONE_SCENE_ONE,
TEXTURE_CUTSCENE_ONE_SCENE_TWO, TEXTURE_CUTSCENE_ONE_SCENE_TWO,
TEXTURE_CUTSCENE_ONE_SCENE_THREE, TEXTURE_CUTSCENE_ONE_SCENE_THREE,
@ -88,7 +89,9 @@ typedef enum TextureType
TEXTURE_CUTSCENE_FINAL_SCENE_ELEVEN, TEXTURE_CUTSCENE_FINAL_SCENE_ELEVEN,
TEXTURE_CUTSCENE_FINAL_SCENE_TWELVE, TEXTURE_CUTSCENE_FINAL_SCENE_TWELVE,
TEXTURE_CUTSCENE_FINAL_SCENE_THIRTEEN, TEXTURE_CUTSCENE_FINAL_SCENE_THIRTEEN,
TEXTURE_ENDING TEXTURE_ENDING,
TEXTURE_ENDING_TWO,
TEXTURE_ENDING_THREE,
} TextureType; } TextureType;
static const char* TEXTURE_PATHS[TEXTURE_COUNT] = static const char* TEXTURE_PATHS[TEXTURE_COUNT] =
@ -111,47 +114,50 @@ static const char* TEXTURE_PATHS[TEXTURE_COUNT] =
"res/gfx/collectible.png", "res/gfx/collectible.png",
"res/gfx/smoke.png", "res/gfx/smoke.png",
"res/gfx/trap.png", "res/gfx/trap.png",
"res/gfx/cutscene/c1s1.png", "res/gfx/foliage.png",
"res/gfx/cutscene/c1s2.png", "res/gfx/cutscene/c01s01.png",
"res/gfx/cutscene/c1s3.png", "res/gfx/cutscene/c01s02.png",
"res/gfx/cutscene/c1s4.png", "res/gfx/cutscene/c01s03.png",
"res/gfx/cutscene/c2s1.png", "res/gfx/cutscene/c01s04.png",
"res/gfx/cutscene/c2s2.png", "res/gfx/cutscene/c02s01.png",
"res/gfx/cutscene/c2s3.png", "res/gfx/cutscene/c02s02.png",
"res/gfx/cutscene/c2s4.png", "res/gfx/cutscene/c02s03.png",
"res/gfx/cutscene/c2s5.png", "res/gfx/cutscene/c02s04.png",
"res/gfx/cutscene/c3s1.png", "res/gfx/cutscene/c02s05.png",
"res/gfx/cutscene/c3s2.png", "res/gfx/cutscene/c03s01.png",
"res/gfx/cutscene/c3s3.png", "res/gfx/cutscene/c03s02.png",
"res/gfx/cutscene/c3s4.png", "res/gfx/cutscene/c03s03.png",
"res/gfx/cutscene/c3s5.png", "res/gfx/cutscene/c03s04.png",
"res/gfx/cutscene/c3s6.png", "res/gfx/cutscene/c03s05.png",
"res/gfx/cutscene/c4s1.png", "res/gfx/cutscene/c03s06.png",
"res/gfx/cutscene/c4s2.png", "res/gfx/cutscene/c04s01.png",
"res/gfx/cutscene/c4s3.png", "res/gfx/cutscene/c04s02.png",
"res/gfx/cutscene/c4s4.png", "res/gfx/cutscene/c04s03.png",
"res/gfx/cutscene/c4s5.png", "res/gfx/cutscene/c04s04.png",
"res/gfx/cutscene/c4s6.png", "res/gfx/cutscene/c04s05.png",
"res/gfx/cutscene/c5s1.png", "res/gfx/cutscene/c04s06.png",
"res/gfx/cutscene/c5s2.png", "res/gfx/cutscene/c05s01.png",
"res/gfx/cutscene/c5s3.png", "res/gfx/cutscene/c05s02.png",
"res/gfx/cutscene/c5s4.png", "res/gfx/cutscene/c05s03.png",
"res/gfx/cutscene/c5s5.png", "res/gfx/cutscene/c05s04.png",
"res/gfx/cutscene/c5s6.png", "res/gfx/cutscene/c05s05.png",
"res/gfx/cutscene/c6s1.png", "res/gfx/cutscene/c05s06.png",
"res/gfx/cutscene/c6s2.png", "res/gfx/cutscene/c06s01.png",
"res/gfx/cutscene/c6s3.png", "res/gfx/cutscene/c06s02.png",
"res/gfx/cutscene/c6s4.png", "res/gfx/cutscene/c06s03.png",
"res/gfx/cutscene/c6s5.png", "res/gfx/cutscene/c06s04.png",
"res/gfx/cutscene/c6s6.png", "res/gfx/cutscene/c06s05.png",
"res/gfx/cutscene/c6s7.png", "res/gfx/cutscene/c06s06.png",
"res/gfx/cutscene/c6s8.png", "res/gfx/cutscene/c06s07.png",
"res/gfx/cutscene/c6s9.png", "res/gfx/cutscene/c06s08.png",
"res/gfx/cutscene/c6s10.png", "res/gfx/cutscene/c06s09.png",
"res/gfx/cutscene/c6s11.png", "res/gfx/cutscene/c06s10.png",
"res/gfx/cutscene/c6s12.png", "res/gfx/cutscene/c06s11.png",
"res/gfx/cutscene/c6s13.png", "res/gfx/cutscene/c06s12.png",
"res/gfx/cutscene/ending.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 #define FONT_COUNT FONT_BIG + 1

View File

@ -28,6 +28,8 @@ typedef enum StateType
STATE_CUTSCENE_FIVE, STATE_CUTSCENE_FIVE,
STATE_CUTSCENE_FINAL, STATE_CUTSCENE_FINAL,
STATE_ENDING, STATE_ENDING,
STATE_ENDING_TWO,
STATE_ENDING_THREE,
STATE_LEVEL_ONE, STATE_LEVEL_ONE,
STATE_LEVEL_TWO, STATE_LEVEL_TWO,
STATE_LEVEL_THREE, STATE_LEVEL_THREE,

View File

@ -99,6 +99,7 @@ cutscene_tick(Cutscene* self)
} }
_cutscene_dialogue_set(self); _cutscene_dialogue_set(self);
_cutscene_sprite_set(self);
} }
if (control_released(self->ecs->control, CONTROL_ACTION_TERTIARY)) if (control_released(self->ecs->control, CONTROL_ACTION_TERTIARY))

View File

@ -9,7 +9,7 @@ static const u32 CUTSCENE_SKIP_TEXT_TIMER = 300;
static const s32 CUTSCENE_SKIP_TEXT_WRAP = -1; static const s32 CUTSCENE_SKIP_TEXT_WRAP = -1;
static const u32 CUTSCENE_DIALOGUE_SPEED = 2; static const u32 CUTSCENE_DIALOGUE_SPEED = 2;
static const vec3 CUTSCENE_SPRITE_POSITION = {640.0f, 250.0f, 0.0f}; 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 #define CUTSCENE_BUFFER RENDERER_BUFFER_UI

View File

@ -4,11 +4,20 @@
#include "../../ecs/entity/visual/entity_sprite.h" #include "../../ecs/entity/visual/entity_sprite.h"
#include "../../ecs/entity/ui/entity_cursor.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 typedef struct Ending
{ {
ECS* ecs; ECS* ecs;
EntityID cursor; EntityID cursor;
EntityID text; EntityID text;
EntityID tipText;
EntityID bg; EntityID bg;
bool isFinished; bool isFinished;
} Ending; } Ending;

View File

@ -1,8 +1,11 @@
#include "ending.h" #include "ending.h"
void 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)); memset(self, '\0', sizeof(Ending));
self->ecs = ecs; self->ecs = ecs;
@ -19,17 +22,45 @@ ending_init(Ending* self, ECS* ecs)
-1 -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 self->bg = entity_sprite_add
( (
ecs, ecs,
&ecs->resources->textures[TEXTURE_ENDING], texture,
RENDERER_BUFFER_BACKGROUND, RENDERER_BUFFER_BACKGROUND,
ORIGIN_TOP_LEFT, ORIGIN_TOP_LEFT,
ENDING_BG_SIZE, ENDING_BG_SIZE,
ENDING_BG_POSITION ENDING_BG_POSITION
); );
music_play(&self->ecs->resources->music[MUSIC_VICTORY], true); music_play(&self->ecs->resources->music[MUSIC_WIND], true);
} }
void void

View File

@ -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 vec2 ENDING_BG_SIZE = {1280.0f, 720.0f};
static vec3 ENDING_BG_POSITION = {0.0f, 0.0f, 0.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" #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_tick(Ending* self);
void ending_free(Ending* self); void ending_free(Ending* self);

View File

@ -5,6 +5,7 @@
#include "../../ecs/entity/ui/entity_medal.h" #include "../../ecs/entity/ui/entity_medal.h"
#include "../../ecs/entity/visual/entity_value_text.h" #include "../../ecs/entity/visual/entity_value_text.h"
#include "../../ecs/entity/game/entity_player.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_target.h"
#include "../../ecs/entity/game/entity_collectible_amulet.h" #include "../../ecs/entity/game/entity_collectible_amulet.h"
#include "../../ecs/entity/game/entity_collectible_stamina.h" #include "../../ecs/entity/game/entity_collectible_stamina.h"
@ -16,6 +17,9 @@
#include "../../ecs/entity/utility/entity_timer.h" #include "../../ecs/entity/utility/entity_timer.h"
#include "../../ecs/entity/visual/entity_dialogue.h" #include "../../ecs/entity/visual/entity_dialogue.h"
#include "../../ecs/entity/visual/entity_text_disappearing.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 #define LEVEL_TUTORIAL_TEXT_COUNT 3
@ -57,9 +61,11 @@ typedef struct LevelSettings
u32 eventTime; u32 eventTime;
vec4 colorCover; vec4 colorCover;
u32 collectibleMax; u32 collectibleMax;
u32 seedStart;
bool isPower; bool isPower;
bool isEvent; bool isEvent;
bool isAmulet; bool isAmulet;
bool isSunset;
bool isPowerForesight; bool isPowerForesight;
bool isPowerCancel; bool isPowerCancel;
bool isPowerMagnet; bool isPowerMagnet;
@ -88,6 +94,8 @@ typedef struct Level
s32 timeToMedal; s32 timeToMedal;
s32 timerValue; s32 timerValue;
u32 levelValue; u32 levelValue;
u32 eventSeed;
u32 collectibleSeed;
LevelMedal nextMedal; LevelMedal nextMedal;
LevelEvent event; LevelEvent event;
LevelEvent nextEvent; LevelEvent nextEvent;

View File

@ -407,6 +407,8 @@ _level_collectibles_spawn(Level* self)
vector_init(&spawns, sizeof(u32)); vector_init(&spawns, sizeof(u32));
srand(self->collectibleSeed);
collectibleCount = 0; collectibleCount = 0;
while (collectibleCount <= self->settings.collectibleMax) while (collectibleCount <= self->settings.collectibleMax)
@ -524,6 +526,8 @@ _level_collectibles_spawn(Level* self)
vector_free(&spawns); vector_free(&spawns);
sound_play(&self->ecs->resources->sounds[SOUND_APPEAR]); sound_play(&self->ecs->resources->sounds[SOUND_APPEAR]);
self->collectibleSeed++;
} }
void void

View File

@ -4,7 +4,7 @@
#define LEVEL_COLLECTIBLE_SPAWN_MAX 50 #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 f32 LEVEL_COLLECTIBLE_SPAWN_MERCY_TIMER = 600;
static const u32 LEVEL_COLLECTIBLE_SPAWN_MERCY_COUNT = 5; static const u32 LEVEL_COLLECTIBLE_SPAWN_MERCY_COUNT = 5;

View File

@ -410,7 +410,11 @@ _level_event_set(Level* self)
_level_event_timer_init(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 void
@ -424,7 +428,11 @@ level_event_init(Level* self)
eventTimer->component.isDisabled = true; 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 void

View File

@ -4,7 +4,7 @@
#include "ui.h" #include "ui.h"
#define LEVEL_EVENT_OUT_OF_BREATH_STAMINA_MULTIPLIER 0.5f #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_ANCHOR_ARMS_FOOD_MAX 50
#define LEVEL_EVENT_BUTTERFINGERS_FOOD_MAX 10 #define LEVEL_EVENT_BUTTERFINGERS_FOOD_MAX 10
#define LEVEL_EVENT_GLUTTONY_FOOD_MULTIPLIER 2; #define LEVEL_EVENT_GLUTTONY_FOOD_MULTIPLIER 2;

View File

@ -4,6 +4,45 @@ static void _level_entity_init(Level* self);
static void _level_finish(Level* self); static void _level_finish(Level* self);
static void _level_finish_text_add(Level* self); static void _level_finish_text_add(Level* self);
static void _level_finish_amulet_spawn(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 static void
_level_finish_text_add(Level* self) _level_finish_text_add(Level* self)
@ -71,7 +110,6 @@ _level_finish_text_add(Level* self)
level_text_queue_clear(self); level_text_queue_clear(self);
level_text_queue_add(self, string); level_text_queue_add(self, string);
} }
static void static void
@ -181,7 +219,7 @@ _level_entity_init(Level* self)
( (
self->ecs, self->ecs,
&self->ecs->resources->textures[TEXTURE_GAME_PLANE], &self->ecs->resources->textures[TEXTURE_GAME_PLANE],
RENDERER_BUFFER_WORLD, RENDERER_BUFFER_PLANE,
ORIGIN_TOP_LEFT, ORIGIN_TOP_LEFT,
(f32*)LEVEL_PLANE_SIZE, (f32*)LEVEL_PLANE_SIZE,
(f32*)LEVEL_PLANE_POSITION (f32*)LEVEL_PLANE_POSITION
@ -235,6 +273,9 @@ level_init(Level* self, ECS* ecs, LevelSettings settings, u32 levelValue)
self->levelValue = levelValue; self->levelValue = levelValue;
self->isCountdownDone = false; self->isCountdownDone = false;
self->collectibleSeed = self->settings.seedStart;
self->eventSeed = self->settings.seedStart;
_level_entity_init(self); _level_entity_init(self);
if (self->settings.isEvent) if (self->settings.isEvent)
@ -247,7 +288,12 @@ level_init(Level* self, ECS* ecs, LevelSettings settings, u32 levelValue)
level_collectible_spawn_init(self); 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_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); glm_vec4_copy(settings.colorCover, self->ecs->postprocessing[RENDERER_BUFFER_BACKGROUND].colorCover);
music_play(&self->ecs->resources->music[MUSIC_WIND], true); music_play(&self->ecs->resources->music[MUSIC_WIND], true);
@ -279,8 +325,14 @@ level_tick(Level* self)
self->isCountdownDone self->isCountdownDone
) )
{ {
ComponentText* text;
text = ecs_component_get(self->ecs, COMPONENT_TEXT, self->timerUI);
if (timer->value % SECOND_TICK == 0) if (timer->value % SECOND_TICK == 0)
sound_play(&self->ecs->resources->sounds[SOUND_LOW_TIMER_TICK]); 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) if (!timer->isFinished)

View File

@ -6,13 +6,17 @@
#include "tutorial.h" #include "tutorial.h"
#include "pause.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_TRAP_POSITION = {2500.0f, 1000.0f, 0.0f};
static const vec3 LEVEL_PLAYER_POSITION = {3275.0f, 2400.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_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_POSITION = {250.0f, 250.0f, 1.0f};
static const vec3 LEVEL_PLANE_SIZE = {6300.0f, 3100.0f, 0.0f}; static const vec3 LEVEL_PLANE_SIZE = {5925.0f, 3100.0f, 0.0f};
static const vec3 LEVEL_BG_POSITION = {0.0f, 00.0f, 1.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 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 f32 LEVEL_FINISH_TEXT_VALUE = 60;
static const vec3 LEVEL_FINISH_TEXT_POSITION = {600.0f, 300.0f, 0.0f}; static const vec3 LEVEL_FINISH_TEXT_POSITION = {600.0f, 300.0f, 0.0f};

View File

@ -44,8 +44,15 @@ level_pause(Level* self)
self->ecs->isFunctionDisabled[ECS_FUNCTION_TICK] = true; self->ecs->isFunctionDisabled[ECS_FUNCTION_TICK] = true;
self->ecs->isFunctionDisabled[ECS_FUNCTION_UPDATE] = 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_BACKGROUND].color);
glm_vec3_copy(LEVEL_PAUSE_COLOR, self->ecs->postprocessing[RENDERER_BUFFER_OVERLAY].color);
} }
void void
@ -63,8 +70,15 @@ level_unpause(Level* self)
self->ecs->isFunctionDisabled[ECS_FUNCTION_TICK] = false; self->ecs->isFunctionDisabled[ECS_FUNCTION_TICK] = false;
self->ecs->isFunctionDisabled[ECS_FUNCTION_UPDATE] = 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_BACKGROUND].color);
glm_vec3_copy(OPAQUE, self->ecs->postprocessing[RENDERER_BUFFER_OVERLAY].color);
} }
void void

View File

@ -67,7 +67,7 @@ level_text_queue_add(Level* self, const char* string)
{ {
EntityID id; EntityID id;
id = entity_text_disappearing_add id = entity_text_queue_entry_add
( (
self->ecs, self->ecs,
&self->ecs->resources->fonts[FONT_SMALL], &self->ecs->resources->fonts[FONT_SMALL],

View File

@ -2,7 +2,7 @@
#include "LEVEL_COMMON.h" #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}; static const vec3 LEVEL_TEXT_QUEUE_POSITION = {25.0f, 675.0f, 0.0f};
void level_text_queue_set(Level* self); void level_text_queue_set(Level* self);

View File

@ -175,5 +175,27 @@ level_ui_init(Level* self)
void void
level_ui_tick(Level* self) level_ui_tick(Level* self)
{ {
ComponentFood* food;
_level_ui_threshold_tick(self); _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);
}
} }

View File

@ -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_MEDAL_POSITION = {1175.0f, 75.0f, 0.0f};
static const vec3 LEVEL_TIMER_POSITION = {600.0f, 32.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 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_TIMER_FORMAT "%i'%02i\"%02i"
#define LEVEL_EVENT_TIMER_FORMAT "Event: %i'%02i\"%02i" #define LEVEL_EVENT_TIMER_FORMAT "Event: %i'%02i\"%02i"

View File

@ -34,10 +34,10 @@ _state_level_tick(State* self, LevelType type)
self->levelData[type + 1].status = LEVEL_STATUS_UNLOCKED; self->levelData[type + 1].status = LEVEL_STATUS_UNLOCKED;
} }
if (type < LEVEL_FIVE) if (type == LEVEL_FIVE && self->states.level.isComplete)
_state_set(self, STATE_TITLE);
else
_state_set(self, STATE_CUTSCENE_FINAL); _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); cutscene_init(&self->states.cutscene, self->ecs, CUTSCENE_FINAL);
break; break;
case STATE_ENDING: 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; break;
case STATE_LEVEL_ONE: case STATE_LEVEL_ONE:
level_init(&self->states.level, self->ecs, LEVEL_SETTINGS[LEVEL_ONE], 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); cutscene_free(&self->states.cutscene);
break; break;
case STATE_ENDING: case STATE_ENDING:
case STATE_ENDING_TWO:
case STATE_ENDING_THREE:
ending_free(&self->states.ending); ending_free(&self->states.ending);
default: default:
break; break;
@ -149,6 +157,10 @@ state_change(State* self, StateType type)
void void
state_tick(State* self) state_tick(State* self)
{ {
u32 endingPoints;
endingPoints = 0;
if (self->isChanging) if (self->isChanging)
{ {
self->isChanging = false; self->isChanging = false;
@ -223,9 +235,22 @@ state_tick(State* self)
cutscene_tick(&self->states.cutscene); cutscene_tick(&self->states.cutscene);
if (self->states.cutscene.isFinished) 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; break;
case STATE_ENDING: case STATE_ENDING:
case STATE_ENDING_TWO:
case STATE_ENDING_THREE:
ending_tick(&self->states.ending); ending_tick(&self->states.ending);
if (self->states.ending.isFinished) if (self->states.ending.isFinished)

View File

@ -7,7 +7,7 @@ static const Scene CUTSCENE_ONE_SCENES[CUTSCENE_ONE_COUNT] =
{ {
{ {
.texture = TEXTURE_CUTSCENE_ONE_SCENE_ONE, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .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, .texture = TEXTURE_CUTSCENE_FINAL_SCENE_TWELVE,
.string = "..!" .string = "\"..!\""
}, },
{ {
.texture = TEXTURE_CUTSCENE_FINAL_SCENE_THIRTEEN, .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] = static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] =
{ {
{ {
.medalThresholds = {100, 200, 300}, .medalThresholds = {200, 275, 325},
.time = 7200, .time = 7200,
.colorCover = {-0.05f, -0.05f, -0.05f, 0.0f}, .colorCover = {-0.05f, -0.05f, -0.05f, 0.0f},
.collectibleMax = 30, .collectibleMax = 30,
.eventTime = 0, .eventTime = 0,
.seedStart = 0xFACEFEED,
.isPower = false, .isPower = false,
.isEvent = false, .isEvent = false,
.isAmulet = false, .isAmulet = false,
.isSunset = false,
.isPowerForesight = false, .isPowerForesight = false,
.isPowerCancel = false, .isPowerCancel = false,
.isPowerMagnet = false, .isPowerMagnet = false,
@ -258,14 +260,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] =
.isTutorialFinal = false .isTutorialFinal = false
}, },
{ {
.medalThresholds = {150, 300, 450}, .medalThresholds = {300, 500, 600},
.time = 10800, .time = 10800,
.colorCover = {0.0f, 0.0f, 0.0f, 0.0f}, .colorCover = {-0.10f, -0.10f, -0.05f, 0.0f},
.collectibleMax = 35, .collectibleMax = 35,
.eventTime = 1800, .eventTime = 1800,
.seedStart = 0xABADBABE,
.isPower = false, .isPower = false,
.isEvent = true, .isEvent = true,
.isAmulet = true, .isAmulet = true,
.isSunset = false,
.isPowerForesight = false, .isPowerForesight = false,
.isPowerCancel = false, .isPowerCancel = false,
.isPowerMagnet = false, .isPowerMagnet = false,
@ -284,14 +288,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] =
.isTutorialFinal = false .isTutorialFinal = false
}, },
{ {
.medalThresholds = {300, 400, 500}, .medalThresholds = {400, 550, 625},
.time = 10800, .time = 10800,
.colorCover = {0.05f, 0.05f, 0.05f, 0.0f}, .colorCover = {0.15f, 0.05f, 0.00f, 0.0f},
.collectibleMax = 40, .collectibleMax = 40,
.eventTime = 1500, .eventTime = 1500,
.seedStart = 0x0B00B135,
.isPower = true, .isPower = true,
.isEvent = true, .isEvent = true,
.isAmulet = false, .isAmulet = false,
.isSunset = false,
.isPowerForesight = false, .isPowerForesight = false,
.isPowerCancel = false, .isPowerCancel = false,
.isPowerMagnet = false, .isPowerMagnet = false,
@ -310,14 +316,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] =
.isTutorialFinal = false .isTutorialFinal = false
}, },
{ {
.medalThresholds = {400, 500, 600}, .medalThresholds = {500, 600, 700},
.time = 10800, .time = 10800,
.colorCover = {0.1f, 0.05f, 0.0f, 0.0f}, .colorCover = {0.3f, 0.15f, 0.0f, 0.0f},
.collectibleMax = 45, .collectibleMax = 45,
.eventTime = 1200, .eventTime = 1200,
.seedStart = 0xDEADD00D,
.isPower = true, .isPower = true,
.isEvent = true, .isEvent = true,
.isAmulet = false, .isAmulet = false,
.isSunset = true,
.isPowerForesight = true, .isPowerForesight = true,
.isPowerCancel = true, .isPowerCancel = true,
.isPowerMagnet = false, .isPowerMagnet = false,
@ -336,14 +344,16 @@ static const LevelSettings LEVEL_SETTINGS[LEVEL_COUNT] =
.isTutorialFinal = false .isTutorialFinal = false
}, },
{ {
.medalThresholds = {500, 750, 1000}, .medalThresholds = {750, 900, 1150},
.time = 18000, .time = 18000,
.colorCover = {-0.025f, -0.00f, -0.025f, 0.0f}, .colorCover = {-0.25f, -0.50f, -0.10f, 0.0f},
.collectibleMax = 50, .collectibleMax = 50,
.eventTime = 900, .eventTime = 900,
.seedStart = 0xDEADBEEF,
.isPower = true, .isPower = true,
.isEvent = true, .isEvent = true,
.isAmulet = false, .isAmulet = false,
.isSunset = false,
.isPowerForesight = true, .isPowerForesight = true,
.isPowerCancel = true, .isPowerCancel = true,
.isPowerMagnet = false, .isPowerMagnet = false,
@ -371,7 +381,7 @@ static const LevelData LEVEL_DATA_DEFAULT[LEVEL_COUNT] =
.time = -1 .time = -1
}, },
{ {
.status = LEVEL_STATUS_UNLOCKED, .status = LEVEL_STATUS_LOCKED,
.score = -1, .score = -1,
.time = -1 .time = -1
}, },

View File

@ -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_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 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_SELECT "Select level..."
#define STRING_TITLE_LEVEL_DATA_UNINITIALIZED "Time: -\'--\"--\nScore: ---" #define STRING_TITLE_LEVEL_DATA_UNINITIALIZED "Time: -\'--\"--\nScore: ---"