503 lines
11 KiB
C
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);
|
|
|
|
|
|
|
|
}
|