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