Files
frillrun/src/game/state/level/event.c
2024-08-30 01:18:18 -04:00

503 lines
11 KiB
C

#include "event.h"
void _level_event_foresight(Level* self);
void _level_event_cancel(Level* self);
void _level_event_extend(Level* self);
void _level_event_magnet(Level* self);
void _level_event_invigorate(Level* self);
void _level_event_power_player_color_change_init(Level* self);
void _level_event_sticky_traps_set(Level* self);
void _level_event_sticky_traps_clear(Level* self);
void _level_event_queue_init(Level* self);
void
_level_event_queue_init(Level* self)
{
/*
random_seed_set(self->eventSeed);
for (s32 i = 0; i < LEVEL_EVENT_COUNT; i++)
{
LevelEvent event;
event = (LevelEvent)i;
vector_push(&self->eventQueue, &event);
}
*/
}
void
_level_event_power_player_color_change_init(Level* self)
{
ComponentColorChange* colorChange;
colorChange = ecs_component_get(self->ecs, COMPONENT_COLOR_CHANGE, self->player);
component_color_change_init
(
colorChange,
self->ecs,
LEVEL_EVENT_PLAYER_POWER_COLOR,
TRANSPARENT,
LEVEL_EVENT_PLAYER_POWER_COLOR_CHANGE_TIME,
true,
false
);
}
void
_level_event_foresight(Level* self)
{
level_text_queue_add(self, STRING_LEVEL_EVENT_FORESIGHTS[self->nextEvent]);
sound_play(&self->ecs->resources->sounds[SOUND_FORESIGHT]);
_level_event_power_player_color_change_init(self);
}
void
_level_event_cancel(Level* self)
{
self->nextEvent = LEVEL_EVENT_NONE;
level_text_queue_add(self, STRING_LEVEL_EVENT_CANCEL);
sound_play(&self->ecs->resources->sounds[SOUND_CANCEL]);
_level_event_power_player_color_change_init(self);
}
void
_level_event_extend(Level* self)
{
ComponentTimer* eventTimer;
eventTimer = ecs_component_get(self->ecs, COMPONENT_TIMER, self->eventTimer);
eventTimer->value += LEVEL_EVENT_POWER_EXTEND_TIME;
level_text_queue_add(self, STRING_LEVEL_EVENT_EXTEND);
sound_play(&self->ecs->resources->sounds[SOUND_EXTEND]);
_level_event_power_player_color_change_init(self);
}
void
_level_event_magnet(Level* self)
{
ComponentCollect* collect;
collect = ecs_component_get(self->ecs, COMPONENT_COLLECT, self->player);
collect->circle.radius = LEVEL_EVENT_POWER_MAGNET_RADIUS;
sound_play(&self->ecs->resources->sounds[SOUND_MAGNET]);
self->isMagnet = true;
level_text_queue_add(self, STRING_LEVEL_EVENT_MAGNET);
_level_event_power_player_color_change_init(self);
}
void
_level_event_invigorate(Level* self)
{
ComponentStamina* stamina;
stamina = ecs_component_get(self->ecs, COMPONENT_STAMINA, self->player);
stamina->value = stamina->max;
level_text_queue_add(self, STRING_LEVEL_EVENT_INVIGORATE);
sound_play(&self->ecs->resources->sounds[SOUND_INVIGORATE]);
_level_event_power_player_color_change_init(self);
}
void
_level_event_sticky_traps_set(Level* self)
{
s32 stickyTrapsCount;
stickyTrapsCount = random_s32_in_range(LEVEL_EVENT_STICKY_TRAPS_MIN, LEVEL_EVENT_STICKY_TRAPS_MAX);
for (s32 i = 0; i < stickyTrapsCount; i++)
{
vec3 position;
u32 id;
bool isInRectangle;
ComponentPhysics* physics;
vec3 smokePosition;
glm_vec3_zero(position);
isInRectangle = true;
while(isInRectangle)
{
vec2 testPosition;
position[0] = random_f32_in_range(LEVEL_EVENT_STICKY_TRAPS_BOUNDS[0], LEVEL_EVENT_STICKY_TRAPS_BOUNDS[2]);
position[1] = random_f32_in_range(LEVEL_EVENT_STICKY_TRAPS_BOUNDS[1], LEVEL_EVENT_STICKY_TRAPS_BOUNDS[3]);
testPosition[0] = position[0];
testPosition[1] = position[1];
isInRectangle = rectangle_has_point(&LEVEL_EVENT_STICKY_TRAPS_NO_NO_RECTANGLE, testPosition);
}
id = entity_trap_add
(
self->ecs,
position
);
physics = ecs_component_get(self->ecs, COMPONENT_PHYSICS, id);
glm_vec3_copy(physics->position, smokePosition);
smokePosition[2] += ENTITY_TRAP_SMOKE_Z_OFFSET;
entity_smoke_big_add
(
self->ecs,
smokePosition
);
}
sound_play(&self->ecs->resources->sounds[SOUND_APPEAR]);
}
void
_level_event_sticky_traps_clear(Level* self)
{
for (s32 i = 0; i < (s32)self->ecs->lists[COMPONENT_PLANE_OBJECT].components.count; i++)
{
ComponentPlaneObject* planeObject;
ComponentPhysics* physics;
vec3 smokePosition;
planeObject = (ComponentPlaneObject*)vector_get(&self->ecs->lists[COMPONENT_PLANE_OBJECT].components, i);
physics = ecs_component_get(self->ecs, COMPONENT_PHYSICS, planeObject->component.id);
glm_vec3_copy(physics->position, smokePosition);
smokePosition[2] += ENTITY_TRAP_SMOKE_Z_OFFSET;
entity_smoke_big_add
(
self->ecs,
smokePosition
);
ecs_entity_delete(self->ecs, planeObject->component.id);
i--;
}
sound_play(&self->ecs->resources->sounds[SOUND_APPEAR]);
}
void
_level_event_power_tick(Level* self)
{
if (self->isMagnet)
{
ComponentCollect* collect;
collect = ecs_component_get(self->ecs, COMPONENT_COLLECT, self->player);
collect->circle.radius = PLAYER_COLLECT_RADIUS;
self->isMagnet = false;
}
if (self->settings.isPowerForesight)
{
if (control_released(self->ecs->control, CONTROL_FORESIGHT))
{
ComponentPower* power;
power = ecs_component_get(self->ecs, COMPONENT_POWER, self->player);
if (power->value >= LEVEL_EVENT_FORESIGHT_POWER)
{
_level_event_foresight(self);
power->value -= LEVEL_EVENT_FORESIGHT_POWER;
}
}
}
if (self->settings.isPowerCancel)
{
if (control_released(self->ecs->control, CONTROL_CANCEL))
{
ComponentPower* power;
power = ecs_component_get(self->ecs, COMPONENT_POWER, self->player);
if (power->value >= LEVEL_EVENT_CANCEL_POWER)
{
_level_event_cancel(self);
power->value -= LEVEL_EVENT_CANCEL_POWER;
}
}
}
if (self->settings.isPowerExtend)
{
if (control_released(self->ecs->control, CONTROL_EXTEND))
{
ComponentPower* power;
power = ecs_component_get(self->ecs, COMPONENT_POWER, self->player);
if (power->value >= LEVEL_EVENT_EXTEND_POWER)
{
_level_event_extend(self);
power->value -= LEVEL_EVENT_EXTEND_POWER;
}
}
}
if (self->settings.isPowerMagnet)
{
if (control_released(self->ecs->control, CONTROL_MAGNET))
{
ComponentPower* power;
power = ecs_component_get(self->ecs, COMPONENT_POWER, self->player);
if (power->value >= LEVEL_EVENT_MAGNET_POWER)
{
_level_event_magnet(self);
power->value -= LEVEL_EVENT_MAGNET_POWER;
}
}
}
if (self->settings.isPowerInvigorate)
{
if (control_released(self->ecs->control, CONTROL_INVIGORATE))
{
ComponentPower* power;
power = ecs_component_get(self->ecs, COMPONENT_POWER, self->player);
if (power->value >= LEVEL_EVENT_INVIGORATE_POWER)
{
_level_event_invigorate(self);
power->value -= LEVEL_EVENT_INVIGORATE_POWER;
}
}
}
}
void
level_event_handle(Level* self)
{
ComponentStamina* playerStamina;
ComponentPower* playerPower;
ComponentFood* playerFood;
ComponentFood* targetFood;
switch (self->event)
{
case LEVEL_EVENT_ROTTEN_FOOD:
self->isRottenFood = true;
break;
case LEVEL_EVENT_STICKY_TRAPS:
_level_event_sticky_traps_set(self);
break;
case LEVEL_EVENT_BUTTERFINGERS:
playerFood = ecs_component_get(self->ecs, COMPONENT_FOOD, self->player);
playerFood->max = LEVEL_EVENT_BUTTERFINGERS_FOOD_MAX;
playerFood->value = MAX(playerFood->value, LEVEL_EVENT_BUTTERFINGERS_FOOD_MAX);
break;
case LEVEL_EVENT_OUT_OF_BREATH:
playerStamina = ecs_component_get(self->ecs, COMPONENT_STAMINA, self->player);
playerStamina->max = PLAYER_STAMINA_MAX * LEVEL_EVENT_OUT_OF_BREATH_STAMINA_MULTIPLIER;
break;
case LEVEL_EVENT_POWER_LEECH:
playerPower = ecs_component_get(self->ecs, COMPONENT_POWER, self->player);
playerPower->value = 0.0f;
break;
case LEVEL_EVENT_VIM_AND_VIGOR:
playerStamina = ecs_component_get(self->ecs, COMPONENT_STAMINA, self->player);
playerStamina->value = LEVEL_EVENT_VIM_AND_VIGOR_STAMINA_MAX;
playerStamina->max = LEVEL_EVENT_VIM_AND_VIGOR_STAMINA_MAX;
break;
case LEVEL_EVENT_GLUTTONY:
targetFood = ecs_component_get(self->ecs, COMPONENT_FOOD, self->target);
targetFood->multiplier = LEVEL_EVENT_GLUTTONY_FOOD_MULTIPLIER;
break;
case LEVEL_EVENT_ANCHOR_ARMS:
playerFood = ecs_component_get(self->ecs, COMPONENT_FOOD, self->player);
playerFood->max = LEVEL_EVENT_ANCHOR_ARMS_FOOD_MAX;
break;
case LEVEL_EVENT_NONE:
default:
break;
}
}
void
level_event_return(Level* self)
{
ComponentStamina* playerStamina;
ComponentPower* playerPower;
ComponentFood* playerFood;
ComponentFood* targetFood;
switch (self->event)
{
case LEVEL_EVENT_ROTTEN_FOOD:
self->isRottenFood = false;
break;
case LEVEL_EVENT_STICKY_TRAPS:
_level_event_sticky_traps_clear(self);
break;
case LEVEL_EVENT_ANCHOR_ARMS:
case LEVEL_EVENT_BUTTERFINGERS:
playerFood = ecs_component_get(self->ecs, COMPONENT_FOOD, self->player);
playerFood->max = PLAYER_FOOD_MAX;
break;
case LEVEL_EVENT_VIM_AND_VIGOR:
playerStamina = ecs_component_get(self->ecs, COMPONENT_STAMINA, self->player);
playerStamina->value = PLAYER_STAMINA_MAX;
playerStamina->max = PLAYER_STAMINA_MAX;
break;
case LEVEL_EVENT_OUT_OF_BREATH:
playerStamina = ecs_component_get(self->ecs, COMPONENT_STAMINA, self->player);
playerStamina->max = PLAYER_STAMINA_MAX;
break;
case LEVEL_EVENT_GLUTTONY:
targetFood = ecs_component_get(self->ecs, COMPONENT_FOOD, self->target);
targetFood->multiplier = TARGET_FOOD_MULTIPLIER;
break;
case LEVEL_EVENT_NONE:
case LEVEL_EVENT_POWER_LEECH:
default:
break;
}
}
void
level_event_choose(Level* self)
{
/*
u32 index;
LevelEvent* event;
*/
/*
index = (u32)random_s32_in_range(0, self->eventQueue.count);
event = (LevelEvent*)vector_get(&self->eventQueue, index);
self->nextEvent = *event;
vector_remove(&self->eventQueue, index);
if (self->eventQueue.count <= 0)
_level_event_queue_init(self);
*/
self->nextEvent = (LevelEvent)random_s32_in_range(0, LEVEL_EVENT_COUNT);
self->eventSeed++;
random_seed_set(self->eventSeed);
}
void
_level_event_timer_init(Level* self)
{
ecs_entity_delete(self->ecs, self->eventTimer);
self->eventTimer = entity_timer_add
(
self->ecs,
self->settings.eventTime
);
level_ui_event_timer_init(self);
}
void
_level_event_set(Level* self)
{
char* string;
LevelEvent event;
level_event_return(self);
if (self->nextEvent == LEVEL_EVENT_POWER_LEECH && !self->settings.isPower)
self->nextEvent = LEVEL_EVENT_NONE;
self->event = self->nextEvent;
string = STRING_LEVEL_EVENTS[self->nextEvent];
sound_play(&self->ecs->resources->sounds[SOUND_EVENT]);
level_text_queue_add(self, string);
level_event_handle(self);
_level_event_timer_init(self);
level_event_choose(self);
}
void
level_event_init(Level* self)
{
ComponentTimer* eventTimer;
vector_init(&self->eventQueue, sizeof(EventType));
_level_event_timer_init(self);
eventTimer = ecs_component_get(self->ecs, COMPONENT_TIMER, self->eventTimer);
eventTimer->component.isDisabled = true;
self->eventSeed = self->settings.seedStart;
random_seed_set(self->eventSeed);
}
void
level_event_tick(Level* self)
{
ComponentTimer* eventTimer;
eventTimer = ecs_component_get(self->ecs, COMPONENT_TIMER, self->eventTimer);
if (eventTimer->isFinished)
_level_event_set(self);
_level_event_power_tick(self);
}
void
level_event_free(Level* self)
{
vector_free(&self->eventQueue);
}