diff --git a/src/STRINGS.h b/src/STRINGS.h index d65065a..845504d 100644 --- a/src/STRINGS.h +++ b/src/STRINGS.h @@ -31,7 +31,7 @@ #define STRING_WINDOW_TITLE "Calamity Cobra in 'A Sweeter Reprise'" -#define STRING_TUTORIAL_TEXT "The Dessert Elemental is restless, and won't be calmed unless she's gotten her fill of goodies! Slaughter foes that come your way with your trusty Snekgun. Fire using left mouse button/space, use right mouse button/R to redirect snakes for additional damage, lock snakes in place with Q and aim them with your mouse for a damage multiplier, and recall all airborne snakes with SHIFT. You can collect goodies with your snakes, too!\n" \ +#define STRING_TUTORIAL_TEXT "The Dessert Elemental is restless, and won't be calmed unless she's gotten her fill of goodies! Slaughter foes that come your way with your trusty Snekgun. Fire using left mouse button/space, use right mouse button/R to redirect snakes for additional damage, lock snakes in place with Q and aim them with your mouse for a damage multiplier, and recall all airborne snakes with TAB. You can collect goodies with your snakes, too!\n" \ "\n" \ "The Sweet Heart she left beats fervently...if you give it a squeeze with the H key, you will gain a goodie multiplier. The more times you push its limits, the better! The next wave of enemies will come right after, though, and the enemies will be more aggressive...so use with great caution!\n" \ "\n" \ diff --git a/src/engine/atlas.c b/src/engine/atlas.c index e9b92d9..d01cd53 100644 --- a/src/engine/atlas.c +++ b/src/engine/atlas.c @@ -25,9 +25,10 @@ atlas_uv_get(Atlas* self, vec2 uvMin, vec2 uvMax) s32 col; s32 row; + /* left to right, top to bottom */ - position[0] = (f32)(self->index % self->size[1]) * self->frameSize[1]; - position[1] = (f32)(self->index / self->size[1]) * self->frameSize[1]; + position[0] = (self->index % self->size[1]) * self->frameSize[1]; + position[1] = (s32)((f32)self->index / self->size[1]) * self->frameSize[1]; uvMin[0] = (f32)position[0] / self->texture.size[0]; uvMin[1] = (f32)position[1] / self->texture.size[1]; diff --git a/src/game/ecs/component/COMPONENT_COMMON.h b/src/game/ecs/component/COMPONENT_COMMON.h index fd3bcf5..06655d5 100644 --- a/src/game/ecs/component/COMPONENT_COMMON.h +++ b/src/game/ecs/component/COMPONENT_COMMON.h @@ -19,6 +19,7 @@ typedef enum ECSComponentType { ECS_COMPONENT_ACTION_ON_DELETE_GIVE_AMMO, + ECS_COMPONENT_ACTION_ON_DELETE_GIVE_REDIRECTS, ECS_COMPONENT_ACTION_ON_DELETE_DROP_GOODIES, ECS_COMPONENT_ENEMY, ECS_COMPONENT_ACTION_SPAWN, @@ -59,6 +60,7 @@ typedef enum ECSComponentType ECS_COMPONENT_BEHAVIOR_APPROACH_AND_SHOOT, ECS_COMPONENT_ACTION_ANGLE, ECS_COMPONENT_ACTION_ON_COMBAT_HIDE, + ECS_COMPONENT_ACTION_ON_RADIUS_HONE, ECS_COMPONENT_ACTION_LOCK, ECS_COMPONENT_ACTION_FOLLOW, ECS_COMPONENT_ACTION_POINT_TO_MOUSE, diff --git a/src/game/ecs/component/action/component_action_delete_on_dead.c b/src/game/ecs/component/action/component_action_delete_on_dead.c index fa710ff..6c48ba1 100644 --- a/src/game/ecs/component/action/component_action_delete_on_dead.c +++ b/src/game/ecs/component/action/component_action_delete_on_dead.c @@ -44,6 +44,9 @@ _dead_sound(ComponentActionDeleteOnDead* self, ECS* ecs) case GAME_ENTITY_CHIP: sound_play(&ecs->game->resources.sounds[SOUND_CHIP_KILL], SOUND_NO_PRIORITY); break; + case GAME_ENTITY_BEANIE: + sound_play(&ecs->game->resources.sounds[SOUND_BEANIE_KILL], SOUND_NO_PRIORITY); + break; case GAME_ENTITY_CRUMBLER: sound_play(&ecs->game->resources.sounds[SOUND_CRUMBLER_KILL], SOUND_NO_PRIORITY); break; diff --git a/src/game/ecs/component/action/component_action_gripped.c b/src/game/ecs/component/action/component_action_gripped.c index c5b8127..7cb21a2 100644 --- a/src/game/ecs/component/action/component_action_gripped.c +++ b/src/game/ecs/component/action/component_action_gripped.c @@ -21,6 +21,7 @@ _component_action_gripped_set(ComponentActionGripped* self, ECS* ecs) ComponentSprite* sprite; ComponentPhysics* physics; ComponentPhysics* gripperPhysics; + ComponentActionKeepInRectangle* actionKeepInRectangle; gripperGameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, self->gripperID); @@ -34,8 +35,12 @@ _component_action_gripped_set(ComponentActionGripped* self, ECS* ecs) gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, self->component.id); physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id); gripperPhysics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->gripperID); + actionKeepInRectangle = ecs_component_get(ecs, ECS_COMPONENT_ACTION_KEEP_IN_RECTANGLE, self->component.id); sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->component.id); + if (actionKeepInRectangle) + actionKeepInRectangle->component.isDisabled = true; + glm_vec3_copy(gripperPhysics->position, physics->position); glm_vec3_copy(gripperPhysics->velocity, physics->velocity); diff --git a/src/game/ecs/component/action/component_action_gripped.h b/src/game/ecs/component/action/component_action_gripped.h index 5c1cb43..841e942 100644 --- a/src/game/ecs/component/action/component_action_gripped.h +++ b/src/game/ecs/component/action/component_action_gripped.h @@ -4,6 +4,7 @@ #include "../../ecs_entity.h" #include "../component_game_object.h" +#include "component_action_keep_in_rectangle.h" #define COMPONENT_ACTION_GRIPPED_TIMER 15 #define COMPONENT_ACTION_GRIPPED_Z_OFFSET -0.001f diff --git a/src/game/ecs/component/action/component_action_lock.c b/src/game/ecs/component/action/component_action_lock.c index 39e5978..964e2c6 100644 --- a/src/game/ecs/component/action/component_action_lock.c +++ b/src/game/ecs/component/action/component_action_lock.c @@ -173,14 +173,15 @@ component_action_lock_unlock(ComponentActionLock* self, ECS* ecs) actionDeleteOnTouchEntity->component.isDisabled = true; + if (self->isLocked) + sound_play(&ecs->game->resources.sounds[SOUND_UNLOCK], SOUND_NO_PRIORITY); + self->isSelected = false; self->isRedirectAngleGiven = false; self->isLocked = false; animationIdle->baseIndex = 0; - sound_play(&ecs->game->resources.sounds[SOUND_UNLOCK], SOUND_NO_PRIORITY); - if (self->isRedirectArrowInit) ecs_entity_delete(ecs, self->redirectArrowID); } diff --git a/src/game/ecs/component/action/component_action_on_delete_drop_goodies.h b/src/game/ecs/component/action/component_action_on_delete_drop_goodies.h index b82402b..d314c77 100644 --- a/src/game/ecs/component/action/component_action_on_delete_drop_goodies.h +++ b/src/game/ecs/component/action/component_action_on_delete_drop_goodies.h @@ -20,7 +20,7 @@ static const s32 GAME_ENTITY_GOODIE_INDEX[GAME_ENTITY_TYPE_COUNT] = -1, 0, 1, - -1, + 11, 2, 3, 4, @@ -30,6 +30,7 @@ static const s32 GAME_ENTITY_GOODIE_INDEX[GAME_ENTITY_TYPE_COUNT] = 8, 9, -1, + 10, -1, -1 }; diff --git a/src/game/ecs/component/action/component_action_on_delete_give_redirects.c b/src/game/ecs/component/action/component_action_on_delete_give_redirects.c new file mode 100644 index 0000000..67cb22a --- /dev/null +++ b/src/game/ecs/component/action/component_action_on_delete_give_redirects.c @@ -0,0 +1,25 @@ +#include "component_action_on_delete_give_redirects.h" + +/* DEPENDENCIES: Redirects, ActEntity */ +/* On deletion, give redirects to the ID belonging to ActEntity. */ + +/* Initializes action on delete give redirects component. */ +void +component_action_on_delete_give_redirects_init(ComponentActionOnDeleteGiveRedirects* self, u32 value) +{ + self->value = value; +} + +/* Ticks aciton on delete give redirects component. */ +void +component_action_on_delete_give_redirects_delete(ComponentActionOnDeleteGiveRedirects* self, ECS* ecs) +{ + ComponentActEntity* actEntity; + ComponentRedirects* redirects; + + actEntity = ecs_component_get(ecs, ECS_COMPONENT_ACT_ENTITY, self->component.id); + redirects = ecs_component_get(ecs, ECS_COMPONENT_REDIRECTS, actEntity->id); + + redirects->value += self->value; + redirects->value = MAX(redirects->value, redirects->max); +} diff --git a/src/game/ecs/component/action/component_action_on_delete_give_redirects.h b/src/game/ecs/component/action/component_action_on_delete_give_redirects.h new file mode 100644 index 0000000..0fab3d1 --- /dev/null +++ b/src/game/ecs/component/action/component_action_on_delete_give_redirects.h @@ -0,0 +1,34 @@ +#pragma once + +#include "../../../GAME_COMMON.h" +#include "../../ecs_entity.h" + +#include "../stat/component_redirects.h" +#include "../stat/component_act_entity.h" + +typedef struct ComponentActionOnDeleteGiveRedirects +{ + ECSComponent component; + u32 value; +} ComponentActionOnDeleteGiveRedirects; + +void component_action_on_delete_give_redirects_init(ComponentActionOnDeleteGiveRedirects* self, u32 value); +void component_action_on_delete_give_redirects_delete(ComponentActionOnDeleteGiveRedirects* self, ECS* ecs); + +static const ECSComponentInfo COMPONENT_ACTION_ON_DELETE_GIVE_REDIRECTS_INFO = +{ + .system = + { + .functions = + { + NULL, + (ECSFunction)component_action_on_delete_give_redirects_delete, + NULL, + NULL + } + }, + .type = ECS_COMPONENT_ACTION_ON_DELETE_GIVE_REDIRECTS, + .size = sizeof(ComponentActionOnDeleteGiveRedirects) +}; + + diff --git a/src/game/ecs/component/action/component_action_on_out_of_bounds_delete.c b/src/game/ecs/component/action/component_action_on_out_of_bounds_delete.c index 8ba4a30..d0338b0 100644 --- a/src/game/ecs/component/action/component_action_on_out_of_bounds_delete.c +++ b/src/game/ecs/component/action/component_action_on_out_of_bounds_delete.c @@ -2,6 +2,21 @@ /* DEPENDENCIES: Physics, ActionOnDeleteDropGoodies */ +static void _out_of_bounds_delete(ComponentActionOnOutOfBoundsDelete* self, ECS* ecs); + +static void +_out_of_bounds_delete(ComponentActionOnOutOfBoundsDelete* self, ECS* ecs) +{ + ComponentActionOnDeleteDropGoodies* actionOnDeleteDropGoodies; + + actionOnDeleteDropGoodies = ecs_component_get(ecs, ECS_COMPONENT_ACTION_ON_DELETE_DROP_GOODIES, self->component.id); + + if (actionOnDeleteDropGoodies) + actionOnDeleteDropGoodies->count = 0; + + ecs_entity_delete(ecs, self->component.id); +} + /* Sets action_on_out_of_bounds_delete component info. */ void component_action_on_out_of_bounds_delete_init(ComponentActionOnOutOfBoundsDelete* self, Rectangle rectangle) @@ -21,14 +36,5 @@ component_action_on_out_of_bounds_delete_tick(ComponentActionOnOutOfBoundsDelete component_physics_rectangle_get(physics, &physicsRectangle); if (!rectangle_collide(&self->rectangle, &physicsRectangle)) - { - ComponentActionOnDeleteDropGoodies* actionOnDeleteDropGoodies; - - actionOnDeleteDropGoodies = ecs_component_get(ecs, ECS_COMPONENT_ACTION_ON_DELETE_DROP_GOODIES, self->component.id); - - if (actionOnDeleteDropGoodies) - actionOnDeleteDropGoodies->component.isDisabled = true; - - ecs_entity_delete(ecs, self->component.id); - } + _out_of_bounds_delete(self, ecs); } diff --git a/src/game/ecs/component/action/component_action_on_radius_hone.c b/src/game/ecs/component/action/component_action_on_radius_hone.c new file mode 100644 index 0000000..597044e --- /dev/null +++ b/src/game/ecs/component/action/component_action_on_radius_hone.c @@ -0,0 +1,94 @@ +#include "component_action_on_radius_hone.h" + +/* DEPENDENCIES: Goodies, ActEntity */ +/* On deletion, give goodies to the ID belonging to ActEntity. */ + +/* Checks for an entity ot hone in onto. */ +static void +_hone_in_check(ComponentActionOnRadiusHone* self, ECS* ecs) +{ + ComponentCircleCollision* circleCollision; + + circleCollision = ecs_component_get(ecs, ECS_COMPONENT_CIRCLE_COLLISION, self->component.id); + + if (circleCollision->collisions.count == 0) + return; + + /* Find the first object of the specified type, and hone in on it. */ + for (s32 i = 0; i < (s32)circleCollision->collisions.count; i++) + { + ComponentGameEntityType* type; + u32 id; + + id = *(u32*)vector_get(&circleCollision->collisions, i); + + type = ecs_component_get(ecs, ECS_COMPONENT_GAME_ENTITY_TYPE, id); + + if (!type) + return; + + if (type->type == self->type) + { + self->targetID = id; + self->isHoming = true; + } + } +} + +/* Hones in on the target. */ +static void +_hone_in(ComponentActionOnRadiusHone* self, ECS* ecs) +{ + ComponentPhysics* physics; + ComponentPhysics* targetPhysics; + f32 angle; + f32 speed; + + targetPhysics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->targetID); + physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id); + + if (!targetPhysics) + return; + + angle = ATAN + ( + targetPhysics->position[0], + physics->position[0], + targetPhysics->position[1], + physics->position[1] + ); + + speed = self->speed * (self->timer * self->multiplier); + + physics->velocity[0] = -cos(angle) * speed; + physics->velocity[1] = -sin(angle) * speed; + + physics->angle = angle; + + self->timer++; +} + +/* Initializes action on touch give goodies component. */ +void +component_action_on_radius_hone_init +( + ComponentActionOnRadiusHone* self, + f32 speed, + f32 multiplier, + GameEntityType type +) +{ + self->speed = speed; + self->multiplier = multiplier; + self->type = type; +} + +/* Ticks aciton on touch give goodies component. */ +void +component_action_on_radius_hone_tick(ComponentActionOnRadiusHone* self, ECS* ecs) +{ + if (self->isHoming) + _hone_in(self, ecs); + else + _hone_in_check(self, ecs); +} diff --git a/src/game/ecs/component/action/component_action_on_radius_hone.h b/src/game/ecs/component/action/component_action_on_radius_hone.h new file mode 100644 index 0000000..9caf4cb --- /dev/null +++ b/src/game/ecs/component/action/component_action_on_radius_hone.h @@ -0,0 +1,46 @@ +#pragma once + +#include "../stat/component_game_entity_type.h" +#include "../component_circle_collision.h" +#include "../component_physics.h" + +typedef struct ComponentActionOnRadiusHone +{ + ECSComponent component; + f32 speed; + f32 multiplier; + GameEntityType type; + u32 targetID; + u32 timer; + bool isHoming; +} ComponentActionOnRadiusHone; + +void +component_action_on_radius_hone_init +( + ComponentActionOnRadiusHone* self, + f32 speed, + f32 multiplier, + GameEntityType type +); + + +void component_action_on_radius_hone_tick(ComponentActionOnRadiusHone* self, ECS* ecs); + +static const ECSComponentInfo COMPONENT_ACTION_ON_RADIUS_HONE_INFO = +{ + .system = + { + .functions = + { + NULL, + NULL, + (ECSFunction)component_action_on_radius_hone_tick, + NULL + } + }, + .type = ECS_COMPONENT_ACTION_ON_RADIUS_HONE, + .size = sizeof(ComponentActionOnRadiusHone) +}; + + diff --git a/src/game/ecs/component/action/component_action_redirect.h b/src/game/ecs/component/action/component_action_redirect.h index ef91499..1d2f00a 100644 --- a/src/game/ecs/component/action/component_action_redirect.h +++ b/src/game/ecs/component/action/component_action_redirect.h @@ -9,7 +9,7 @@ #include "component_action_damage.h" #define COMPONENT_ACTION_REDIRECT_DAMAGE_INCREMENT 1 -#define COMPONENT_ACTION_REDIRECT_DAMAGE_MULTIPLIER 2 +#define COMPONENT_ACTION_REDIRECT_DAMAGE_MULTIPLIER 3 typedef struct ComponentActionRedirect { diff --git a/src/game/ecs/component/action/component_action_spawn.c b/src/game/ecs/component/action/component_action_spawn.c index 4c83d7d..c6ed7af 100644 --- a/src/game/ecs/component/action/component_action_spawn.c +++ b/src/game/ecs/component/action/component_action_spawn.c @@ -13,18 +13,119 @@ static GameEntityType _game_entity_type_get(ComponentActionSpawn* self, ECS* ecs); static void _spawn_timer_set(ComponentActionSpawn* self, ECS* ecs); static void _spawn_entity(ComponentActionSpawn* self, ECS* ecs); -static void _spawn_entity_out_of_bounds_position_get(ComponentActionSpawn* self, ECS* ecs, GameEntityType type, vec3 position, vec2 size, u32 id); +static void _spawn_entity_out_of_bounds_position_get(ComponentActionSpawn* self, ECS* ecs, GameEntityType type, vec3 position, vec2 size, u32 id, SpawnDirection* direction); static void _spawn_entity_in_bounds_position_get(ComponentActionSpawn* self, ECS* ecs, GameEntityType type, vec3 position, vec2 size, u32 id); +static void _alert_no_direction_spawn(ComponentActionSpawn* self, ECS* ecs, vec3 position, IconType type); +static void _alert_direction_spawn(ComponentActionSpawn* self, ECS* ecs, vec3 position, SpawnDirection direction, IconType type); + +/* Spawns an alert notice. */ +static void +_alert_no_direction_spawn(ComponentActionSpawn* self, ECS* ecs, vec3 position, IconType type) +{ + vec3 alertPosition; + vec3 alertIconPosition; + + glm_vec3_copy(position, alertPosition); + + alertPosition[0] = CLAMP(alertPosition[0], COMPONENT_ACTION_SPAWN_ALERT_X_POSITION_MIN, COMPONENT_ACTION_SPAWN_ALERT_X_POSITION_MAX); + alertPosition[1] = CLAMP(alertPosition[1], COMPONENT_ACTION_SPAWN_ALERT_Y_POSITION_MIN, COMPONENT_ACTION_SPAWN_ALERT_Y_POSITION_MAX); + alertPosition[2] = COMPONENT_ACTION_SPAWN_ALERT_Z_OFFSET; + + glm_vec3_copy(alertPosition, alertIconPosition); + + alertIconPosition[1] += COMPONENT_ACTION_SPAWN_ALERT_OFFSET; + + entity_alert_init + ( + ecs, + ecs_entity_add(ecs), + alertPosition + ); + + entity_alert_icon_init + ( + ecs, + ecs_entity_add(ecs), + alertIconPosition, + type + ); +} + +/* Spawns an alert notice. */ +static void +_alert_direction_spawn(ComponentActionSpawn* self, ECS* ecs, vec3 position, SpawnDirection direction, IconType type) +{ + vec3 alertPosition; + vec3 alertIconPosition; + + glm_vec3_copy(position, alertPosition); + + switch (direction) + { + case SPAWN_DIRECTION_NORTH: + case SPAWN_DIRECTION_SOUTH: + alertPosition[0] = position[0]; + break; + case SPAWN_DIRECTION_EAST: + case SPAWN_DIRECTION_WEST: + alertPosition[1] = position[1]; + break; + default: + break; + } + + alertPosition[0] = CLAMP(alertPosition[0], COMPONENT_ACTION_SPAWN_ALERT_X_POSITION_MIN, COMPONENT_ACTION_SPAWN_ALERT_X_POSITION_MAX); + alertPosition[1] = CLAMP(alertPosition[1], COMPONENT_ACTION_SPAWN_ALERT_Y_POSITION_MIN, COMPONENT_ACTION_SPAWN_ALERT_Y_POSITION_MAX); + alertPosition[2] = COMPONENT_ACTION_SPAWN_ALERT_Z_OFFSET; + + glm_vec3_copy(alertPosition, alertIconPosition); + + switch (direction) + { + case SPAWN_DIRECTION_NORTH: + alertIconPosition[1] += COMPONENT_ACTION_SPAWN_ALERT_OFFSET; + break; + case SPAWN_DIRECTION_SOUTH: + alertIconPosition[1] -= COMPONENT_ACTION_SPAWN_ALERT_OFFSET; + break; + case SPAWN_DIRECTION_EAST: + alertIconPosition[0] -= COMPONENT_ACTION_SPAWN_ALERT_OFFSET; + break; + case SPAWN_DIRECTION_WEST: + alertIconPosition[0] += COMPONENT_ACTION_SPAWN_ALERT_OFFSET; + break; + default: + break; + } + + entity_alert_init + ( + ecs, + ecs_entity_add(ecs), + alertPosition + ); + + entity_alert_icon_init + ( + ecs, + ecs_entity_add(ecs), + alertIconPosition, + type + ); +} /* Sets the spawn timer. */ static void _spawn_timer_set(ComponentActionSpawn* self, ECS* ecs) { ComponentLevel* level; + u32 usedLevel; level = ecs_component_get(ecs, ECS_COMPONENT_LEVEL, self->component.id); - self->timer = COMPONENT_ACTION_SPAWN_TIMER_BASE - (COMPONENT_ACTION_SPAWN_TIMER_LEVEL_MULTIPLIER * (level->value - 1)); + usedLevel = level->value + self->levelBonus; + + self->timer = COMPONENT_ACTION_SPAWN_TIMER_BASE - (COMPONENT_ACTION_SPAWN_TIMER_LEVEL_MULTIPLIER * (usedLevel - 1)); self->timer = MIN(self->timer, COMPONENT_ACTION_SPAWN_TIMER_MINIMUM); } @@ -73,13 +174,11 @@ _game_entity_type_get(ComponentActionSpawn* self, ECS* ecs) /* Spawns an entity out of bounds. */ static void -_spawn_entity_out_of_bounds_position_get(ComponentActionSpawn* self, ECS* ecs, GameEntityType type, vec3 position, vec2 size, u32 id) +_spawn_entity_out_of_bounds_position_get(ComponentActionSpawn* self, ECS* ecs, GameEntityType type, vec3 position, vec2 size, u32 id, SpawnDirection* direction) { - SpawnDirection spawnDirection; + *direction = RANDOM_S32(SPAWN_DIRECTION_NORTH, SPAWN_DIRECTION_WEST); - spawnDirection = RANDOM_S32(SPAWN_DIRECTION_NORTH, SPAWN_DIRECTION_WEST); - - switch (spawnDirection) + switch (*direction) { case SPAWN_DIRECTION_NORTH: position[0] = RANDOM_F32(SPAWN_OUT_OF_BOUNDS_RECTANGLE.x - (size[0] * 3), SPAWN_OUT_OF_BOUNDS_RECTANGLE.x + SPAWN_OUT_OF_BOUNDS_RECTANGLE.w + (size[0] * 3)); @@ -131,9 +230,11 @@ _spawn_entity(ComponentActionSpawn* self, ECS* ecs) GameEntityType type; SpawnEntryType spawnEntryType; ComponentLevel* level; + SpawnDirection direction; f32 angle; f32 speed; u32 usedLevel; + IconType iconType; id = ecs_entity_add(ecs); @@ -152,68 +253,56 @@ _spawn_entity(ComponentActionSpawn* self, ECS* ecs) { case GAME_ENTITY_CUPPER: glm_vec2_copy((f32*)CUPPER_SIZE, size); + iconType = ICON_CUPPER; break; - case GAME_ENTITY_CHIP: - glm_vec2_copy((f32*)CHIP_SIZE, size); + case GAME_ENTITY_BEANIE: + glm_vec2_copy((f32*)BEANIE_SIZE, size); + iconType = ICON_BEANIE; break; case GAME_ENTITY_CHIPPER: glm_vec2_copy((f32*)CHIPPER_SIZE, size); + iconType = ICON_CHIPPER; break; case GAME_ENTITY_CUSTARPEDO: glm_vec2_copy((f32*)CUSTARPEDO_SIZE, size); + iconType = ICON_CUSTARPEDO; break; case GAME_ENTITY_CRUMBLER: glm_vec2_copy((f32*)CRUMBLER_SIZE, size); + iconType = ICON_CRUMBLER; break; case GAME_ENTITY_EXCORSANT: glm_vec2_copy((f32*)EXCORSANT_SIZE, size); + iconType = ICON_EXCORSANT; break; default: + iconType = ICON_EMPTY_ONE; break; } switch (spawnEntryType) { case SPAWN_ENTRY_WANDER: - _spawn_entity_out_of_bounds_position_get(self, ecs, type, position, size, id); + _spawn_entity_out_of_bounds_position_get(self, ecs, type, position, size, id, &direction); + _alert_direction_spawn(self, ecs, position, direction, iconType); break; case SPAWN_ENTRY_FALL: case SPAWN_ENTRY_EMERGE: _spawn_entity_in_bounds_position_get(self, ecs, type, position, size, id); + _alert_no_direction_spawn(self, ecs, position, iconType); break; default: break; } + switch (type) { case GAME_ENTITY_CUPPER: entity_cupper_init(ecs, id, position, self->targetID, usedLevel); break; - case GAME_ENTITY_CHIP: - entity_chip_init(ecs, id, position, -1); - - physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, id); - targetPhysics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->targetID); - gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, id); - - angle = ATAN - ( - physics->position[0], - targetPhysics->position[1], - physics->position[1], - targetPhysics->position[1] - ); - - speed = COMPONENT_ACTION_SPAWN_CHIP_SPEED + ((usedLevel - 1) * COMPONENT_ACTION_SPAWN_CHIP_LEVEL_VELOCITY_MULTIPLIER); - - speed = MAX(speed, CHIP_VELOCITY_MAX); - - physics->velocity[0] = cos(angle) * speed; - physics->velocity[1] = sin(angle) * speed; - - gameObject->height = CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_HEIGHT; - + case GAME_ENTITY_BEANIE: + entity_beanie_init(ecs, id, position, self->targetID, usedLevel); break; case GAME_ENTITY_CHIPPER: entity_chipper_init(ecs, id, position, self->targetID, usedLevel); @@ -325,7 +414,15 @@ component_action_spawn_tick(ComponentActionSpawn* self, ECS* ecs) if (self->mercyTimer <= 0) { - ecs_component_list_clear(&ecs->lists[ECS_COMPONENT_ENEMY]); + for (s32 i = 0; i < (s32)ecs->lists[ECS_COMPONENT_ENEMY].components.count; i++) + { + ComponentEnemy* enemy; + + enemy = ecs_component_from_index_get(ecs, ECS_COMPONENT_ENEMY, i); + + ecs_entity_delete(ecs, enemy->component.id); + } + self->mercyTimer = COMPONENT_ACTION_SPAWN_MERCY_TIMER_MAX; } } @@ -341,7 +438,6 @@ component_action_spawn_tick(ComponentActionSpawn* self, ECS* ecs) return; } - if (self->timer <= 0) { if (self->combatTimer > 0) diff --git a/src/game/ecs/component/action/component_action_spawn.h b/src/game/ecs/component/action/component_action_spawn.h index e7358d5..8a0b2c8 100644 --- a/src/game/ecs/component/action/component_action_spawn.h +++ b/src/game/ecs/component/action/component_action_spawn.h @@ -4,8 +4,7 @@ #include "../../ecs_entity.h" #include "../stat/component_wave.h" - -#include "../../entity/play/entity_chip.h" +#include "../../entity/play/entity_beanie.h" #include "../../entity/play/entity_cupper.h" #include "../../entity/play/entity_custarpedo.h" #include "../../entity/play/entity_crumbler.h" @@ -13,13 +12,21 @@ #include "../../entity/play/entity_excorsant.h" #include "../stat/component_level.h" -#define COMPONENT_ACTION_SPAWN_TIMER_BASE 100 -#define COMPONENT_ACTION_SPAWN_TIMER_LEVEL_MULTIPLIER 10 -#define COMPONENT_ACTION_SPAWN_TIMER_MINIMUM 20 -#define COMPONENT_ACTION_SPAWN_MERCY_TIMER_MAX 1800 +#include "../../entity/play/entity_alert.h" +#include "../../entity/play/entity_alert_icon.h" -#define COMPONENT_ACTION_SPAWN_CHIP_SPEED 10 -#define COMPONENT_ACTION_SPAWN_CHIP_LEVEL_VELOCITY_MULTIPLIER 1.5 +#define COMPONENT_ACTION_SPAWN_TIMER_BASE 100 +#define COMPONENT_ACTION_SPAWN_TIMER_LEVEL_MULTIPLIER 5 +#define COMPONENT_ACTION_SPAWN_TIMER_MINIMUM 50 +#define COMPONENT_ACTION_SPAWN_MERCY_TIMER_MAX 600 +#define COMPONENT_ACTION_SPAWN_ALERT_OFFSET 64.0f +#define COMPONENT_ACTION_SPAWN_ALERT_Z_OFFSET 0.01f +#define COMPONENT_ACTION_SPAWN_ALERT_X_POSITION_MIN 64.0f +#define COMPONENT_ACTION_SPAWN_ALERT_X_POSITION_MAX 1856.0f +#define COMPONENT_ACTION_SPAWN_ALERT_Y_POSITION_MIN 64.0f +#define COMPONENT_ACTION_SPAWN_ALERT_Y_POSITION_MAX 1016.0f + +static const vec3 COMPONENT_ACTION_SPAWN_ALERT_ICON_POSITION_OFFSET = {0.0f, 64.0f, 0.01f}; #define SPAWN_DIRECTION_COUNT SPAWN_WEST + 1 typedef enum SpawnDirection @@ -100,6 +107,7 @@ static const SpawnRarityType SPAWN_GAME_ENTITY_RARITY_TYPES[GAME_ENTITY_TYPE_COU SPAWN_RARITY_UNCOMMON, SPAWN_RARITY_RARE, SPAWN_RARITY_NONE, + SPAWN_RARITY_COMMON, SPAWN_RARITY_NONE, SPAWN_RARITY_NONE }; @@ -120,6 +128,7 @@ static const SpawnEntryType SPAWN_GAME_ENTITY_ENTRY_TYPES[GAME_ENTITY_TYPE_COUNT SPAWN_ENTRY_FALL, SPAWN_ENTRY_WANDER, SPAWN_ENTRY_NONE, + SPAWN_ENTRY_WANDER, SPAWN_ENTRY_NONE, SPAWN_ENTRY_NONE }; diff --git a/src/game/ecs/component/action/component_action_wave.c b/src/game/ecs/component/action/component_action_wave.c index 7f439ca..d00a938 100644 --- a/src/game/ecs/component/action/component_action_wave.c +++ b/src/game/ecs/component/action/component_action_wave.c @@ -41,7 +41,7 @@ _wave_add(ComponentActionWave* self, ECS* ecs) _timer_set(self, ecs); - self->timer += SPAWN_WAVES[self->index].timer; + self->timer += actionSpawn->combatTimer; } /* Runs on add wave. */ diff --git a/src/game/ecs/component/action/component_action_wave.h b/src/game/ecs/component/action/component_action_wave.h index bdf0740..b40eb05 100644 --- a/src/game/ecs/component/action/component_action_wave.h +++ b/src/game/ecs/component/action/component_action_wave.h @@ -21,18 +21,18 @@ static const GameEntityType WAVE_FIVE_ENEMIES[2] = { GAME_ENTITY_CUPPER, GAME_ static const GameEntityType WAVE_SIX_ENEMIES[2] = { GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER }; static const GameEntityType WAVE_SEVEN_ENEMIES[3] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER }; static const GameEntityType WAVE_EIGHT_ENEMIES[3] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER }; -static const GameEntityType WAVE_NINE_ENEMIES[1] = { GAME_ENTITY_CHIP }; -static const GameEntityType WAVE_TEN_ENEMIES[4] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER, GAME_ENTITY_CHIP }; +static const GameEntityType WAVE_NINE_ENEMIES[1] = { GAME_ENTITY_BEANIE}; +static const GameEntityType WAVE_TEN_ENEMIES[4] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER, GAME_ENTITY_BEANIE}; static const GameEntityType WAVE_ELEVEN_ENEMIES[1] = { GAME_ENTITY_CUSTARPEDO }; static const GameEntityType WAVE_TWELVE_ENEMIES[2] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CUSTARPEDO }; static const GameEntityType WAVE_THIRTEEN_ENEMIES[2] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CUSTARPEDO }; static const GameEntityType WAVE_FOURTEEN_ENEMIES[2] = { GAME_ENTITY_CRUMBLER, GAME_ENTITY_CUSTARPEDO }; -static const GameEntityType WAVE_FIFTEEN_ENEMIES[2] = { GAME_ENTITY_CHIP, GAME_ENTITY_CUSTARPEDO }; +static const GameEntityType WAVE_FIFTEEN_ENEMIES[2] = { GAME_ENTITY_BEANIE, GAME_ENTITY_CUSTARPEDO }; static const GameEntityType WAVE_SIXTEEN_ENEMIES[1] = { GAME_ENTITY_EXCORSANT }; static const GameEntityType WAVE_SEVENTEEN_ENEMIES[2] = { GAME_ENTITY_CUPPER, GAME_ENTITY_EXCORSANT }; static const GameEntityType WAVE_EIGHTEEN_ENEMIES[2] = { GAME_ENTITY_CHIPPER, GAME_ENTITY_EXCORSANT }; static const GameEntityType WAVE_NINETEEN_ENEMIES[2] = { GAME_ENTITY_CRUMBLER, GAME_ENTITY_EXCORSANT }; -static const GameEntityType WAVE_TWENTY_ENEMIES[2] = { GAME_ENTITY_CHIP, GAME_ENTITY_EXCORSANT }; +static const GameEntityType WAVE_TWENTY_ENEMIES[2] = { GAME_ENTITY_BEANIE, GAME_ENTITY_EXCORSANT }; static const GameEntityType WAVE_TWENTY_ONE_ENEMIES[2] = { GAME_ENTITY_CUSTARPEDO, GAME_ENTITY_EXCORSANT }; static const GameEntityType WAVE_TWENTY_TWO_ENEMIES[3] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CUSTARPEDO, GAME_ENTITY_EXCORSANT }; static const GameEntityType WAVE_TWENTY_THREE_ENEMIES[4] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CUSTARPEDO, GAME_ENTITY_EXCORSANT }; @@ -41,8 +41,8 @@ static const GameEntityType WAVE_TWENTY_FIVE_ENEMIES[3] = { GAME_ENTITY_CUPPER, static const GameEntityType WAVE_TWENTY_SIX_ENEMIES[1] = { GAME_ENTITY_CUSTARPEDO }; static const GameEntityType WAVE_TWENTY_SEVEN_ENEMIES[1] = { GAME_ENTITY_EXCORSANT }; static const GameEntityType WAVE_TWENTY_EIGHT_ENEMIES[5] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER, GAME_ENTITY_CUSTARPEDO, GAME_ENTITY_EXCORSANT }; -static const GameEntityType WAVE_TWENTY_NINE_ENEMIES[1] = { GAME_ENTITY_CHIP }; -static const GameEntityType WAVE_THIRTY_ENEMIES[6] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER, GAME_ENTITY_CHIP, GAME_ENTITY_CUSTARPEDO, GAME_ENTITY_EXCORSANT }; +static const GameEntityType WAVE_TWENTY_NINE_ENEMIES[1] = { GAME_ENTITY_BEANIE}; +static const GameEntityType WAVE_THIRTY_ENEMIES[6] = { GAME_ENTITY_CUPPER, GAME_ENTITY_CHIPPER, GAME_ENTITY_CRUMBLER, GAME_ENTITY_BEANIE, GAME_ENTITY_CUSTARPEDO, GAME_ENTITY_EXCORSANT }; static const SpawnWave SPAWN_WAVES[COMPONENT_ACTION_WAVE_COUNT] = { diff --git a/src/game/ecs/component/behavior/component_behavior_boomerang.c b/src/game/ecs/component/behavior/component_behavior_boomerang.c index d6b2a7d..d2a846e 100644 --- a/src/game/ecs/component/behavior/component_behavior_boomerang.c +++ b/src/game/ecs/component/behavior/component_behavior_boomerang.c @@ -102,9 +102,6 @@ component_behavior_boomerang_init levelTimer = timer - (COMPONENT_BEHAVIOR_BOOMERANG_LEVEL_TIMER_MULTIPLIER * (level->value - 1)); - printf("LEVEL: %i\n", level->value); - printf("LEVEL TIMER: %i\n", levelTimer); - levelTimer = MIN(levelTimer, COMPONENT_BEHAVIOR_BOOMERANG_TIMER_MAX); self->speed = speed; @@ -112,8 +109,6 @@ component_behavior_boomerang_init self->timerMax = levelTimer; self->timer = self->timerMax; self->targetID = targetID; - - printf("TIMER MAX: %i\n", self->timerMax); } /* Sets behavior_boomerang component info. */ diff --git a/src/game/ecs/component/control/component_control_player.c b/src/game/ecs/component/control/component_control_player.c index 0e5f3df..c6434ba 100644 --- a/src/game/ecs/component/control/component_control_player.c +++ b/src/game/ecs/component/control/component_control_player.c @@ -10,12 +10,14 @@ component_control_player_init ECS* ecs, f32 speed, f32 angleThreshold, - f32 shootCooldown, + u32 shootCooldown, + u32 recallCooldown, u32 spawnID ) { ComponentControlMove* controlMove; ComponentControlRedirect* controlRedirect; + ComponentControlRecall* controlRecall; ComponentControlShoot* controlShoot; ComponentControlHeart* controlHeart; @@ -23,11 +25,13 @@ component_control_player_init controlRedirect = ecs_component_get(ecs, ECS_COMPONENT_CONTROL_REDIRECT, self->component.id); controlShoot = ecs_component_get(ecs, ECS_COMPONENT_CONTROL_SHOOT, self->component.id); controlHeart = ecs_component_get(ecs, ECS_COMPONENT_CONTROL_HEART, self->component.id); + controlRecall = ecs_component_get(ecs, ECS_COMPONENT_CONTROL_RECALL, self->component.id); component_control_move_init(controlMove, speed); component_control_redirect_init(controlRedirect, angleThreshold); component_control_shoot_init(controlShoot, shootCooldown); component_control_heart_init(controlHeart, spawnID); + component_control_recall_init(controlRecall, recallCooldown); } /* Ticks control_player component. */ diff --git a/src/game/ecs/component/control/component_control_player.h b/src/game/ecs/component/control/component_control_player.h index 5cd55cc..bb63625 100644 --- a/src/game/ecs/component/control/component_control_player.h +++ b/src/game/ecs/component/control/component_control_player.h @@ -25,7 +25,8 @@ component_control_player_init ECS* ecs, f32 speed, f32 angleThreshold, - f32 shootCooldown, + u32 shootCooldown, + u32 redirectCooldown, u32 spawnID ); diff --git a/src/game/ecs/component/control/component_control_recall.c b/src/game/ecs/component/control/component_control_recall.c index 5ca16ea..14e716a 100644 --- a/src/game/ecs/component/control/component_control_recall.c +++ b/src/game/ecs/component/control/component_control_recall.c @@ -31,6 +31,10 @@ _component_control_recall(ComponentControlRecall* self, ECS* ecs) component_action_return(actionReturn, ecs); } } + + self->cooldown = self->cooldownMax; + + sound_play(&ecs->game->resources.sounds[SOUND_RECALL], SOUND_NO_PRIORITY); } /* Initializes control recall component. */ diff --git a/src/game/ecs/component/entity/component_pickup.c b/src/game/ecs/component/entity/component_pickup.c index 3a2764d..a6344c1 100644 --- a/src/game/ecs/component/entity/component_pickup.c +++ b/src/game/ecs/component/entity/component_pickup.c @@ -27,11 +27,15 @@ component_pickup_init ComponentPhysics* physics; ComponentActionDeleteOnTouchGameEntityType* actionDeleteOnTouchGameEntityType; ComponentActionDeleteOnTimer* actionDeleteOnTimer; + ComponentActionOnRadiusHone* actionOnRadiusHone; + ComponentCircleCollision* circleCollision; gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, self->component.id); physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id); actionDeleteOnTimer = ecs_component_get(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, self->component.id); + actionOnRadiusHone = ecs_component_get(ecs, ECS_COMPONENT_ACTION_ON_RADIUS_HONE, self->component.id); actionDeleteOnTouchGameEntityType = ecs_component_get(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE, self->component.id); + circleCollision = ecs_component_get(ecs, ECS_COMPONENT_CIRCLE_COLLISION, self->component.id); component_game_object_atlas_init ( @@ -58,6 +62,16 @@ component_pickup_init component_action_delete_on_timer_init(actionDeleteOnTimer, time); + component_circle_collision_init(circleCollision, ecs, COMPONENT_PICKUP_CIRCLE_COLLISION_RADIUS); + + component_action_on_radius_hone_init + ( + actionOnRadiusHone, + COMPONENT_PICKUP_ON_RADIUS_HONE_SPEED, + COMPONENT_PICKUP_ON_RADIUS_HONE_MULTIPLIER, + COMPONENT_PICKUP_ON_RADIUS_HONE_GAME_ENTITY_TYPE + ); + self->fadeThreshold = fadeThreshold; } @@ -71,6 +85,8 @@ component_pickup_add(ComponentPickup* self, ECS* ecs) ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, self->component.id); ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE, self->component.id); ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, self->component.id); + ecs_component_add(ecs, ECS_COMPONENT_CIRCLE_COLLISION, self->component.id); + ecs_component_add(ecs, ECS_COMPONENT_ACTION_ON_RADIUS_HONE, self->component.id); ecs_component_add(ecs, ECS_COMPONENT_ACTION_GRIPPED, self->component.id); @@ -88,6 +104,8 @@ component_pickup_delete(ComponentPickup* self, ECS* ecs) ecs_component_delete(ecs, ECS_COMPONENT_ANIMATION_COLOR_CHANGE, self->component.id); ecs_component_delete(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, self->component.id); ecs_component_delete(ecs, ECS_COMPONENT_ACTION_GRIPPED, self->component.id); + ecs_component_delete(ecs, ECS_COMPONENT_CIRCLE_COLLISION, self->component.id); + ecs_component_delete(ecs, ECS_COMPONENT_ACTION_ON_RADIUS_HONE, self->component.id); } /* Ticks pickup. */ diff --git a/src/game/ecs/component/entity/component_pickup.h b/src/game/ecs/component/entity/component_pickup.h index 45a34bc..26531b5 100644 --- a/src/game/ecs/component/entity/component_pickup.h +++ b/src/game/ecs/component/entity/component_pickup.h @@ -6,6 +6,7 @@ #include "../component_game_object.h" #include "../animation/component_animation_color_change.h" #include "../action/component_action_delete_on_touch_game_entity_type.h" +#include "../action/component_action_on_radius_hone.h" #include "../action/component_action_delete_on_timer.h" #include "../action/component_action_gripped.h" @@ -15,6 +16,11 @@ #define COMPONENT_PICKUP_GAME_OBJECT_IS_SOLID false #define COMPONENT_PICKUP_GAME_OBJECT_IS_AFFECTED_BY_GRAVITY true #define COMPONENT_PICKUP_GAME_OBJECT_IS_BOUNCE true +#define COMPONENT_PICKUP_CIRCLE_COLLISION_RADIUS 150.0f +#define COMPONENT_PICKUP_ON_RADIUS_HONE_SPEED 1 +#define COMPONENT_PICKUP_ON_RADIUS_HONE_MULTIPLIER 1.15 +#define COMPONENT_PICKUP_ON_RADIUS_HONE_GAME_ENTITY_TYPE GAME_ENTITY_PLAYER +#define COMPONENT_PICKUP_ON_RADIUS_HONE_VELOCITY_MAX 20 typedef struct ComponentPickup { diff --git a/src/game/ecs/component/hud/component_shop_button.c b/src/game/ecs/component/hud/component_shop_button.c index e494678..871fc1b 100644 --- a/src/game/ecs/component/hud/component_shop_button.c +++ b/src/game/ecs/component/hud/component_shop_button.c @@ -332,4 +332,6 @@ component_shop_button_tick(ComponentShopButton* self, ECS* ecs) shopItem->isBought = true; self->isUpdate = true; } + + button->state = BUTTON_UNSELECTED; } diff --git a/src/game/ecs/component/stat/component_fatness.c b/src/game/ecs/component/stat/component_fatness.c index f50ce35..b4fa513 100644 --- a/src/game/ecs/component/stat/component_fatness.c +++ b/src/game/ecs/component/stat/component_fatness.c @@ -10,8 +10,6 @@ _fatness_set(ComponentFatness* self, ECS* ecs) animationIdle = ecs_component_get(ecs, ECS_COMPONENT_ANIMATION_IDLE, self->component.id); heart = ecs_component_get(ecs, ECS_COMPONENT_HEART, self->heartID); - printf("%i\n", self->value); - animationIdle->baseIndex = (self->value * 2); heart->multiplierBonus = self->value; @@ -36,19 +34,21 @@ component_fatness_tick(ComponentFatness* self, ECS* ecs) self->previousValue = self->value; - for (s32 i = 0; i < (s32)self->thresholdCount; i++) + for (s32 i = self->thresholdCount; i > 0; i--) { u32 value; value = self->thresholds[i]; - if (goodies->value > value) + if (goodies->value >= value) { self->value = i + 1; + _fatness_set(self, ecs); if (self->value > self->previousValue) sound_play(&ecs->game->resources.sounds[SOUND_GROW], SOUND_SPECIAL); + return; } } diff --git a/src/game/ecs/component/stat/component_game_entity_type.h b/src/game/ecs/component/stat/component_game_entity_type.h index 970f57b..28ee1fb 100644 --- a/src/game/ecs/component/stat/component_game_entity_type.h +++ b/src/game/ecs/component/stat/component_game_entity_type.h @@ -20,6 +20,7 @@ typedef enum GameEntityType GAME_ENTITY_CREPER, GAME_ENTITY_GUM_MK_II, GAME_ENTITY_GUMBALL, + GAME_ENTITY_BEANIE, GAME_ENTITY_ELEMENTAL, GAME_ENTITY_GOODIE } GameEntityType; diff --git a/src/game/ecs/component/stat/component_heart.c b/src/game/ecs/component/stat/component_heart.c index d8d6407..d90fd34 100644 --- a/src/game/ecs/component/stat/component_heart.c +++ b/src/game/ecs/component/stat/component_heart.c @@ -1,7 +1,33 @@ #include "component_heart.h" +static void _state_set(ComponentHeart* self, ECS* ecs); +static void _multiplier_update(ComponentHeart* self, ECS* ecs); + +static void +_multiplier_update(ComponentHeart* self, ECS* ecs) +{ + ComponentGoodies* goodies; + + goodies = ecs_component_get(ecs, ECS_COMPONENT_GOODIES, self->component.id); + + if (self->concurrentUses > 1) + { + self->multiplier = self->uses + 1; + self->multiplier += pow(self->concurrentUses, 2); + self->multiplier *= self->multiplierBonus + 1; + } + else + { + self->multiplier = self->uses + 1; + self->multiplier *= self->multiplierBonus + 1; + } + + if (goodies) + goodies->multiplier = self->multiplier; +} + /* Determines current heart state. */ -void +static void _state_set(ComponentHeart* self, ECS* ecs) { HeartState previousState; @@ -28,17 +54,6 @@ _state_set(ComponentHeart* self, ECS* ecs) void component_heart_tick(ComponentHeart* self, ECS* ecs) { - ComponentGoodies* goodies; - - goodies = ecs_component_get(ecs, ECS_COMPONENT_GOODIES, self->component.id); - - if (self->concurrentUses > 1) - self->multiplier = (self->uses + pow(self->concurrentUses, 2)) * (self->multiplierBonus + 1); - else - self->multiplier = (self->uses + 1) * (self->multiplierBonus + 1); - - if (goodies) - goodies->multiplier = self->multiplier; - + _multiplier_update(self, ecs); _state_set(self, ecs); } diff --git a/src/game/ecs/component/stat/component_shop_item.c b/src/game/ecs/component/stat/component_shop_item.c index 19a4a1c..29799b1 100644 --- a/src/game/ecs/component/stat/component_shop_item.c +++ b/src/game/ecs/component/stat/component_shop_item.c @@ -13,6 +13,8 @@ _shop_item_bought(ComponentShopItem* self, ECS* ecs) ComponentSprite* sprite; vec3 position; + self->isBought = false; + goodies = ecs_component_get(ecs, ECS_COMPONENT_GOODIES, self->affectedID); if (self->type == SHOP_ITEM_FEED) @@ -25,11 +27,15 @@ _shop_item_bought(ComponentShopItem* self, ECS* ecs) position[1] -= sprite->size[1]; position[2] += COMPONENT_SHOP_ITEM_ICON_NOTICE_Z_OFFSET; - if (goodies->value < self->price && self->type != SHOP_ITEM_FEED) - return; - - if (goodies->value == 0 && self->type == SHOP_ITEM_FEED) + if + ( + (goodies->value < self->price && self->type != SHOP_ITEM_FEED) || + (goodies->value == 0 && self->type == SHOP_ITEM_FEED) + ) + { + sound_play(&ecs->game->resources.sounds[SOUND_ERROR], SOUND_NO_PRIORITY); return; + } switch (self->type) { @@ -51,7 +57,10 @@ _shop_item_bought(ComponentShopItem* self, ECS* ecs) case SHOP_ITEM_HEALTH: health = ecs_component_get(ecs, ECS_COMPONENT_HEALTH, self->affectedID); if (health->value >= health->max) + { + sound_play(&ecs->game->resources.sounds[SOUND_ERROR], SOUND_NO_PRIORITY); return; + } health->value++; entity_icon_notice_init(ecs, ecs_entity_add(ecs), position, ICON_HEALTH); break; @@ -64,7 +73,6 @@ _shop_item_bought(ComponentShopItem* self, ECS* ecs) break; } - self->isBought = false; if (self->type == SHOP_ITEM_FEED) { diff --git a/src/game/ecs/ecs.h b/src/game/ecs/ecs.h index 75aeaa7..89fb7d6 100644 --- a/src/game/ecs/ecs.h +++ b/src/game/ecs/ecs.h @@ -14,8 +14,10 @@ #include "component/action/component_action_on_combat_hide.h" #include "component/action/component_action_on_delete_drop_goodies.h" #include "component/action/component_action_on_delete_give_ammo.h" +#include "component/action/component_action_on_delete_give_redirects.h" #include "component/action/component_action_on_touch_give_goodies.h" #include "component/action/component_action_on_out_of_bounds_delete.h" +#include "component/action/component_action_on_radius_hone.h" #include "component/action/component_action_redirect.h" #include "component/action/component_action_point_to_mouse.h" #include "component/action/component_action_return.h" @@ -88,6 +90,7 @@ typedef struct DrawEntry static const ECSComponentInfo ECS_COMPONENT_INFO[ECS_COMPONENT_COUNT] = { COMPONENT_ACTION_ON_DELETE_GIVE_AMMO_INFO, + COMPONENT_ACTION_ON_DELETE_GIVE_REDIRECTS_INFO, COMPONENT_ACTION_ON_DELETE_DROP_GOODIES_INFO, COMPONENT_ENEMY_INFO, COMPONENT_ACTION_SPAWN_INFO, @@ -128,6 +131,7 @@ static const ECSComponentInfo ECS_COMPONENT_INFO[ECS_COMPONENT_COUNT] = COMPONENT_BEHAVIOR_APPROACH_AND_SHOOT_INFO, COMPONENT_ACTION_ANGLE_INFO, COMPONENT_ACTION_ON_COMBAT_HIDE_INFO, + COMPONENT_ACTION_ON_RADIUS_HONE_INFO, COMPONENT_ACTION_LOCK_INFO, COMPONENT_ACTION_FOLLOW_INFO, COMPONENT_ACTION_POINT_TO_MOUSE_INFO, diff --git a/src/game/ecs/entity/play/entity_alert.c b/src/game/ecs/entity/play/entity_alert.c new file mode 100644 index 0000000..22c6893 --- /dev/null +++ b/src/game/ecs/entity/play/entity_alert.c @@ -0,0 +1,43 @@ +#include "entity_alert.h" + +/* Initializes a alert entity. */ +void +entity_alert_init(ECS* ecs, u32 id, vec3 position) +{ + ComponentActionDeleteOnTimer* actionDeleteOnTimer; + ComponentAnimationColorChange* animationColorChange; + ComponentSprite* sprite; + + sprite = ecs_component_add(ecs, ECS_COMPONENT_SPRITE, id); + actionDeleteOnTimer = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, id); + animationColorChange = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_COLOR_CHANGE, id); + + component_sprite_atlas_init + ( + sprite, + ecs->game->resources.textures[TEXTURE_ICONS], + (s32*)ICON_FRAME_SIZE, + (s32*)ICON_ATLAS_SIZE, + (f32*)ENTITY_ALERT_SIZE, + position + ); + + component_action_delete_on_timer_init + ( + actionDeleteOnTimer, + ENTITY_ALERT_TIMER + ); + + component_animation_color_change_init + ( + animationColorChange, + (f32*)COLOR_TRANSPARENT, + (f32*)COLOR_OPAQUE, + ENTITY_ALERT_TIMER, + ANIMATION_COLOR_CHANGE_MODE_STICK + ); + + sprite->atlas.index = ICON_ALERT; + + sound_play(&ecs->game->resources.sounds[SOUND_ALERT], SOUND_NO_PRIORITY); +} diff --git a/src/game/ecs/entity/play/entity_alert.h b/src/game/ecs/entity/play/entity_alert.h new file mode 100644 index 0000000..80be3b4 --- /dev/null +++ b/src/game/ecs/entity/play/entity_alert.h @@ -0,0 +1,13 @@ +#pragma once + +#include "../../component/action/component_action_delete_on_timer.h" +#include "../../component/animation/component_animation_color_change.h" +#include "../../ecs_component.h" + +#include "entity_icon.h" + +#define ENTITY_ALERT_TIMER 60 + +static const vec2 ENTITY_ALERT_SIZE = {64.0f, 64.0f}; + +void entity_alert_init(ECS* ecs, u32 id, vec3 position); diff --git a/src/game/ecs/entity/play/entity_alert_icon.c b/src/game/ecs/entity/play/entity_alert_icon.c new file mode 100644 index 0000000..b300b58 --- /dev/null +++ b/src/game/ecs/entity/play/entity_alert_icon.c @@ -0,0 +1,41 @@ +#include "entity_alert_icon.h" + +/* Initializes a alert icon entity. */ +void +entity_alert_icon_init(ECS* ecs, u32 id, vec3 position, IconType type) +{ + ComponentActionDeleteOnTimer* actionDeleteOnTimer; + ComponentAnimationColorChange* animationColorChange; + ComponentSprite* sprite; + + sprite = ecs_component_add(ecs, ECS_COMPONENT_SPRITE, id); + actionDeleteOnTimer = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TIMER, id); + animationColorChange = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_COLOR_CHANGE, id); + + component_sprite_atlas_init + ( + sprite, + ecs->game->resources.textures[TEXTURE_ICONS], + (s32*)ICON_FRAME_SIZE, + (s32*)ICON_ATLAS_SIZE, + (f32*)ENTITY_ALERT_ICON_SIZE, + position + ); + + component_action_delete_on_timer_init + ( + actionDeleteOnTimer, + ENTITY_ALERT_ICON_TIMER + ); + + component_animation_color_change_init + ( + animationColorChange, + (f32*)COLOR_TRANSPARENT, + (f32*)COLOR_OPAQUE, + ENTITY_ALERT_ICON_TIMER, + ANIMATION_COLOR_CHANGE_MODE_STICK + ); + + sprite->atlas.index = type; +} diff --git a/src/game/ecs/entity/play/entity_alert_icon.h b/src/game/ecs/entity/play/entity_alert_icon.h new file mode 100644 index 0000000..9a5b1c6 --- /dev/null +++ b/src/game/ecs/entity/play/entity_alert_icon.h @@ -0,0 +1,13 @@ +#pragma once + +#include "../../component/action/component_action_delete_on_timer.h" +#include "../../component/animation/component_animation_color_change.h" +#include "../../ecs_component.h" + +#include "entity_icon.h" + +#define ENTITY_ALERT_ICON_TIMER 60 + +static const vec2 ENTITY_ALERT_ICON_SIZE = {64.0f, 64.0f}; + +void entity_alert_icon_init(ECS* ecs, u32 id, vec3 position, IconType type); diff --git a/src/game/ecs/entity/play/entity_beanie.c b/src/game/ecs/entity/play/entity_beanie.c new file mode 100644 index 0000000..a8a0934 --- /dev/null +++ b/src/game/ecs/entity/play/entity_beanie.c @@ -0,0 +1,81 @@ +#include "entity_beanie.h" + +/* Initializes a beanie entity. */ +void +entity_beanie_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level) +{ + ComponentEnemy* enemy; + ComponentActionDeleteOnTouchGameEntityType* actionDeleteOnTouchGameEntityType; + ComponentAnimationRotate* animationRotate; + ComponentSprite* sprite; + ComponentGameEntityType* gameEntityType; + ComponentPhysics* physics; + ComponentPhysics* targetPhysics; + ComponentGameObject* gameObject; + f32 speed; + f32 angle; + + enemy = ecs_component_add(ecs, ECS_COMPONENT_ENEMY, id); + actionDeleteOnTouchGameEntityType = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE, id); + animationRotate = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_ROTATE, id); + gameEntityType = ecs_component_add(ecs, ECS_COMPONENT_GAME_ENTITY_TYPE, id); + + component_enemy_init + ( + enemy, + ecs, + ecs->game->resources.textures[TEXTURE_BEANIE], + (s32*)BEANIE_FRAME_SIZE, + (s32*)BEANIE_ATLAS_SIZE, + (f32*)BEANIE_SIZE, + (f32*)BEANIE_PHYSICS_SIZE, + position, + BEANIE_FRICTION, + BEANIE_VELOCITY_MAX, + BEANIE_HEALTH, + BEANIE_IS_BOUNCE, + BEANIE_IS_AFFECTED_BY_GRAVITY, + BEANIE_IS_SOLID, + BEANIE_GOODIE_COUNT, + 1 + ); + + sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, id); + + component_action_delete_on_touch_game_entity_type_init + ( + actionDeleteOnTouchGameEntityType, + BEANIE_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE + ); + + component_game_entity_type_init + ( + gameEntityType, + GAME_ENTITY_BEANIE + ); + + component_animation_rotate_init(animationRotate, BEANIE_ROTATION_SPEED); + + sprite->rotation = RANDOM_F32(0, TAU); + + physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, id); + targetPhysics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, targetID); + gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, id); + + angle = ATAN + ( + physics->position[0], + targetPhysics->position[1], + physics->position[1], + targetPhysics->position[1] + ); + + speed = BEANIE_SPEED + ((level - 1) * BEANIE_LEVEL_VELOCITY_MULTIPLIER); + + speed = MAX(speed, BEANIE_VELOCITY_MAX); + + physics->velocity[0] = cos(angle) * speed; + physics->velocity[1] = sin(angle) * speed; + + gameObject->height = BEANIE_HEIGHT; +} diff --git a/src/game/ecs/entity/play/entity_beanie.h b/src/game/ecs/entity/play/entity_beanie.h new file mode 100644 index 0000000..0750091 --- /dev/null +++ b/src/game/ecs/entity/play/entity_beanie.h @@ -0,0 +1,30 @@ +#pragma once + +#include "../../component/action/component_action_delete_on_touch_game_entity_type.h" +#include "../../component/animation/component_animation_rotate.h" +#include "../../component/component_physics.h" +#include "../../component/component_game_object.h" +#include "../../component/entity/component_enemy.h" +#include "../../component/stat/component_game_entity_type.h" +#include "../../ecs_component.h" + +#define BEANIE_HEALTH 1 +#define BEANIE_FRICTION 1 +#define BEANIE_VELOCITY_MAX 10 +#define BEANIE_IS_AFFECTED_BY_GRAVITY false +#define BEANIE_IS_BOUNCE false +#define BEANIE_IS_SOLID false +#define BEANIE_GOODIE_COUNT 1 +#define BEANIE_ROTATION_SPEED 0.05 +#define BEANIE_SPEED 10 +#define BEANIE_LEVEL_VELOCITY_MULTIPLIER 1.5 +#define BEANIE_HEIGHT 30 + +#define BEANIE_ACTION_DELETE_ON_TOUCH_GAME_ENTITY_TYPE GAME_ENTITY_PLAYER + +static const ivec2 BEANIE_FRAME_SIZE = {512, 512}; +static const ivec2 BEANIE_ATLAS_SIZE = {1, 1}; +static const vec2 BEANIE_SIZE = {60.0f, 60.0f}; +static const vec2 BEANIE_PHYSICS_SIZE = {30.0f, 10.0f}; + +void entity_beanie_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level); diff --git a/src/game/ecs/entity/play/entity_chip.h b/src/game/ecs/entity/play/entity_chip.h index d617817..0fd3779 100644 --- a/src/game/ecs/entity/play/entity_chip.h +++ b/src/game/ecs/entity/play/entity_chip.h @@ -9,7 +9,7 @@ #define CHIP_SPEED 1 #define CHIP_HEALTH 1 #define CHIP_FRICTION 1 -#define CHIP_VELOCITY_MAX 30 +#define CHIP_VELOCITY_MAX 10 #define CHIP_IS_AFFECTED_BY_GRAVITY false #define CHIP_IS_BOUNCE false #define CHIP_IS_SOLID false diff --git a/src/game/ecs/entity/play/entity_chipper.h b/src/game/ecs/entity/play/entity_chipper.h index 78e6f49..ea69e42 100644 --- a/src/game/ecs/entity/play/entity_chipper.h +++ b/src/game/ecs/entity/play/entity_chipper.h @@ -9,7 +9,7 @@ #include "entity_chip.h" -#define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_DISTANCE 750.0f +#define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_DISTANCE 500.0f #define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_HEIGHT 10.0f #define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_OFFSET 30.0f #define CHIPPER_BEHAVIOR_APPROACH_AND_SHOOT_PROJECTILE_SPEED 10.0f diff --git a/src/game/ecs/entity/play/entity_crumbler.h b/src/game/ecs/entity/play/entity_crumbler.h index 7d2672a..dc339fe 100644 --- a/src/game/ecs/entity/play/entity_crumbler.h +++ b/src/game/ecs/entity/play/entity_crumbler.h @@ -10,17 +10,17 @@ #define CRUMBLER_IS_AFFECTED_BY_GRAVITY true #define CRUMBLER_FRICTION 0 #define CRUMBLER_VELOCITY_MAX 0 -#define CRUMBLER_HEALTH_MAX 10 +#define CRUMBLER_HEALTH_MAX 15 #define CRUMBLER_GOODIE_COUNT 5 #define CRUMBLER_HEIGHT COMPONENT_GAME_OBJECT_HEIGHT_MAX #define CRUMBLER_GRAVITY -0.1f #define CRUMBLER_LEVEL_GRAVITY_MULTIPLIER -0.01f -#define CRUMBLER_GRAVITY_MAX -0.2f +#define CRUMBLER_GRAVITY_MAX -0.3f #define CRUMBLER_DAMAGE_HEIGHT 100.0f static const ivec2 CRUMBLER_FRAME_SIZE = {512, 512}; static const ivec2 CRUMBLER_ATLAS_SIZE = {1, 3}; -static const vec2 CRUMBLER_SIZE = {200.0f, 200.0f}; -static const vec2 CRUMBLER_PHYSICS_SIZE = {150.0f, 50.0f}; +static const vec2 CRUMBLER_SIZE = {300.0f, 300.0f}; +static const vec2 CRUMBLER_PHYSICS_SIZE = {225.0f, 75.0f}; void entity_crumbler_init(ECS* ecs, u32 id, vec3 position, u32 level); diff --git a/src/game/ecs/entity/play/entity_cupper.h b/src/game/ecs/entity/play/entity_cupper.h index f0f686e..ea85c44 100644 --- a/src/game/ecs/entity/play/entity_cupper.h +++ b/src/game/ecs/entity/play/entity_cupper.h @@ -23,6 +23,6 @@ static const ivec2 CUPPER_FRAME_SIZE = {512, 512}; static const ivec2 CUPPER_ATLAS_SIZE = {1, 4}; static const vec2 CUPPER_SIZE = {100.0f, 100.0f}; -static const vec2 CUPPER_PHYSICS_SIZE = {60.0f, 20.0f}; +static const vec2 CUPPER_PHYSICS_SIZE = {75.0f, 25.0f}; void entity_cupper_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level); diff --git a/src/game/ecs/entity/play/entity_custarpedo.h b/src/game/ecs/entity/play/entity_custarpedo.h index b0a4507..86cbb01 100644 --- a/src/game/ecs/entity/play/entity_custarpedo.h +++ b/src/game/ecs/entity/play/entity_custarpedo.h @@ -12,16 +12,16 @@ #define CUSTARPEDO_IS_AFFECTED_BY_GRAVITY false #define CUSTARPEDO_BEHAVIOR_CHASE_SPEED 5 #define CUSTARPEDO_FRICTION 1 -#define CUSTARPEDO_VELOCITY_MAX 30 +#define CUSTARPEDO_VELOCITY_MAX 35 #define CUSTARPEDO_HEALTH_MAX 2 #define CUSTARPEDO_GOODIE_COUNT 1 #define CUSTARPEDO_HEIGHT 30 #define CUSTARPEDO_ANIMATION_IDLE_BASE_INDEX 0 -#define CUSTARPEDO_ANIMATION_IDLE_TIMER 30 +#define CUSTARPEDO_ANIMATION_IDLE_TIMER 5 static const ivec2 CUSTARPEDO_FRAME_SIZE = {512, 512}; static const ivec2 CUSTARPEDO_ATLAS_SIZE = {8, 2}; -static const vec2 CUSTARPEDO_SIZE = {100.0f, 100.0f}; -static const vec2 CUSTARPEDO_PHYSICS_SIZE = {60.0f, 20.0f}; +static const vec2 CUSTARPEDO_SIZE = {150.0f, 150.0f}; +static const vec2 CUSTARPEDO_PHYSICS_SIZE = {90.0f, 30.0f}; void entity_custarpedo_init(ECS* ecs, u32 id, vec3 position, u32 targetID, u32 level); diff --git a/src/game/ecs/entity/play/entity_elemental.h b/src/game/ecs/entity/play/entity_elemental.h index 258a72d..9a66939 100644 --- a/src/game/ecs/entity/play/entity_elemental.h +++ b/src/game/ecs/entity/play/entity_elemental.h @@ -33,8 +33,8 @@ #define ELEMENTAL_FATNESS_THRESHOLD_COUNT 4 static const ivec2 ELEMENTAL_FRAME_SIZE = {1024, 1024}; -static const ivec2 ELEMENTAL_ATLAS_SIZE = {1, 8}; -static const vec2 ELEMENTAL_SIZE = {300.0f, 300.0f}; +static const ivec2 ELEMENTAL_ATLAS_SIZE = {1, 10}; +static const vec2 ELEMENTAL_SIZE = {600.0f, 600.0f}; static const vec2 ELEMENTAL_PHYSICS_SIZE = {120.0f, 40.0f}; static const u32 ELEMENTAL_FATNESS_THRESHOLDS[ELEMENTAL_FATNESS_THRESHOLD_COUNT] = diff --git a/src/game/ecs/entity/play/entity_goodie.c b/src/game/ecs/entity/play/entity_goodie.c index 062cc85..4740bf0 100644 --- a/src/game/ecs/entity/play/entity_goodie.c +++ b/src/game/ecs/entity/play/entity_goodie.c @@ -6,9 +6,11 @@ entity_goodie_init(ECS* ecs, u32 id, vec3 position, vec3 velocity, f32 height) { ComponentPickup* pickup; ComponentActionOnTouchGiveGoodies* actionOnTouchGiveGoodies; + ComponentActionKeepInRectangle* actionKeepInRectangle; pickup = ecs_component_add(ecs, ECS_COMPONENT_PICKUP, id); actionOnTouchGiveGoodies = ecs_component_add(ecs, ECS_COMPONENT_ACTION_ON_TOUCH_GIVE_GOODIES, id); + actionKeepInRectangle = ecs_component_add(ecs, ECS_COMPONENT_ACTION_KEEP_IN_RECTANGLE, id); component_pickup_init ( @@ -31,6 +33,7 @@ entity_goodie_init(ECS* ecs, u32 id, vec3 position, vec3 velocity, f32 height) ); component_action_on_touch_give_goodies_init(actionOnTouchGiveGoodies, GOODIE_PICKUP_VALUE); + component_action_keep_in_rectangle_init(actionKeepInRectangle, GOODIE_ACTION_KEEP_IN_RECTANGLE); ComponentGameEntityType* gameEntityType; gameEntityType = ecs_component_add(ecs, ECS_COMPONENT_GAME_ENTITY_TYPE, id); diff --git a/src/game/ecs/entity/play/entity_goodie.h b/src/game/ecs/entity/play/entity_goodie.h index 29b7373..63b895d 100644 --- a/src/game/ecs/entity/play/entity_goodie.h +++ b/src/game/ecs/entity/play/entity_goodie.h @@ -4,6 +4,7 @@ #include "../../component/entity/component_pickup.h" #include "../../component/action/component_action_on_touch_give_goodies.h" #include "../../component/stat/component_game_entity_type.h" +#include "../../component/action/component_action_keep_in_rectangle.h" #define GOODIE_FRICTION 0.95 #define GOODIE_VELOCITY_MAX 50 @@ -14,7 +15,8 @@ static const vec2 GOODIE_SIZE = {64.0f, 64.0f}; static const ivec2 GOODIE_FRAME_SIZE = {512, 512}; -static const ivec2 GOODIE_ATLAS_SIZE = {1, 10}; +static const ivec2 GOODIE_ATLAS_SIZE = {1, 12}; static const vec2 GOODIE_PHYSICS_SIZE = {60.0f, 20.0f}; +static const Rectangle GOODIE_ACTION_KEEP_IN_RECTANGLE = {0.0f, 0.0f, 1920.0f, 1080.0f}; void entity_goodie_init(ECS* ecs, u32 id, vec3 position, vec3 velocity, f32 height); diff --git a/src/game/ecs/entity/play/entity_icon.h b/src/game/ecs/entity/play/entity_icon.h index 0c382dc..675ff1d 100644 --- a/src/game/ecs/entity/play/entity_icon.h +++ b/src/game/ecs/entity/play/entity_icon.h @@ -35,10 +35,20 @@ typedef enum IconType ICON_NEAPOLITOTEM = 26, ICON_EZ_ACHE = 27, ICON_CREPER = 28, - ICON_GUM_MK_II = 30 + ICON_GUM_MK_II = 29, + ICON_CHIP = 30, + ICON_BEANIE = 31, + ICON_ALERT = 32, + ICON_EMPTY_ONE = 33, + ICON_EMPTY_TWO = 34, + ICON_EMPTY_THREE = 35, + ICON_EMPTY_FOUR = 36, + ICON_EMPTY_FIVE = 37, + ICON_EMPTY_SIX = 38, + ICON_EMPTY_SEVEM = 39 } IconType; static const ivec2 ICON_FRAME_SIZE = {512, 512}; -static const ivec2 ICON_ATLAS_SIZE = {3, 10}; +static const ivec2 ICON_ATLAS_SIZE = {4, 10}; void entity_icon_init(ECS* ecs, u32 id, vec3 position, vec2 size, IconType type); diff --git a/src/game/ecs/entity/play/entity_player.c b/src/game/ecs/entity/play/entity_player.c index fccfa7b..dbdf1f6 100644 --- a/src/game/ecs/entity/play/entity_player.c +++ b/src/game/ecs/entity/play/entity_player.c @@ -71,6 +71,7 @@ entity_player_init(ECS* ecs, u32 id, vec3 position, u32 spawnID) PLAYER_CONTROL_MOVE_SPEED, PLAYER_CONTROL_REDIRECT_ANGLE_THRESHOLD, PLAYER_CONTROL_SHOOT_COOLDOWN, + PLAYER_CONTROL_RECALL_COOLDOWN, spawnID ); diff --git a/src/game/ecs/entity/play/entity_player.h b/src/game/ecs/entity/play/entity_player.h index b9d53a0..48e7831 100644 --- a/src/game/ecs/entity/play/entity_player.h +++ b/src/game/ecs/entity/play/entity_player.h @@ -30,9 +30,10 @@ #define PLAYER_ACTION_SHOOT_HEIGHT 60.0f #define PLAYER_ACTION_SHOOT_OFFSET 150.0f #define PLAYER_CONTROL_SHOOT_COOLDOWN 12 -#define PLAYER_CONTROL_REDIRECT_ANGLE_THRESHOLD 20 // Degrees +#define PLAYER_CONTROL_RECALL_COOLDOWN 60 +#define PLAYER_CONTROL_REDIRECT_ANGLE_THRESHOLD 15 // Degrees #define PLAYER_AMMO_START 1 -#define PLAYER_HEALTH_MAX 3 +#define PLAYER_HEALTH_MAX 5 #define PLAYER_REDIRECTS_START 1 #define PLAYER_GAME_ENTITY_TYPE GAME_ENTITY_PLAYER #define PLAYER_ALLEGIANCE ALLEGIANCE_PLAYER diff --git a/src/game/ecs/entity/play/entity_puff.h b/src/game/ecs/entity/play/entity_puff.h index de694ae..17ff52a 100644 --- a/src/game/ecs/entity/play/entity_puff.h +++ b/src/game/ecs/entity/play/entity_puff.h @@ -7,6 +7,5 @@ #define ENTITY_PUFF_TIMER 15 static const vec3 ENTITY_PUFF_MOVE_VELOCITY = {0.0f, -1.0f, 0.0f}; -static const vec2 ENTITY_PUFF_SIZE = {64.0f, 64.0f}; void entity_puff_init(ECS* ecs, u32 id, vec3 position, vec2 size); diff --git a/src/game/ecs/entity/play/entity_shop_item_health.h b/src/game/ecs/entity/play/entity_shop_item_health.h index 33b1e26..97f8f0c 100644 --- a/src/game/ecs/entity/play/entity_shop_item_health.h +++ b/src/game/ecs/entity/play/entity_shop_item_health.h @@ -3,7 +3,7 @@ #include "../../ecs_component.h" #include "../../component/stat/component_shop_item.h" -#define ENTITY_SHOP_ITEM_HEALTH_PRICE 250 -#define ENTITY_SHOP_ITEM_HEALTH_EXPONENT 3 +#define ENTITY_SHOP_ITEM_HEALTH_PRICE 100 +#define ENTITY_SHOP_ITEM_HEALTH_EXPONENT 2 void entity_shop_item_health_init(ECS* ecs, u32 id, u32 affectedID, u32 affectedID2); diff --git a/src/game/ecs/entity/play/entity_snake.c b/src/game/ecs/entity/play/entity_snake.c index c30b72f..5fe8d5f 100644 --- a/src/game/ecs/entity/play/entity_snake.c +++ b/src/game/ecs/entity/play/entity_snake.c @@ -9,6 +9,7 @@ entity_snake_init(ECS* ecs, u32 id, vec3 position, u32 sender) ComponentActionRedirect* actionRedirect; ComponentActionLock* actionLock; ComponentActionOnDeleteGiveAmmo* actionOnDeleteGiveAmmo; + ComponentActionOnDeleteGiveRedirects* actionOnDeleteGiveRedirects; ComponentActionDamage* actionDamage; ComponentAllegiance* allegiance; ComponentAnimationIdle* animationIdle; @@ -17,6 +18,7 @@ entity_snake_init(ECS* ecs, u32 id, vec3 position, u32 sender) actionReturn = ecs_component_add(ecs, ECS_COMPONENT_ACTION_RETURN, id); actionRedirect = ecs_component_add(ecs, ECS_COMPONENT_ACTION_REDIRECT, id); actionOnDeleteGiveAmmo = ecs_component_add(ecs, ECS_COMPONENT_ACTION_ON_DELETE_GIVE_AMMO, id); + actionOnDeleteGiveRedirects = ecs_component_add(ecs, ECS_COMPONENT_ACTION_ON_DELETE_GIVE_REDIRECTS, id); actionDamage = ecs_component_add(ecs, ECS_COMPONENT_ACTION_DAMAGE, id); actionLock = ecs_component_add(ecs, ECS_COMPONENT_ACTION_LOCK, id); animationIdle = ecs_component_add(ecs, ECS_COMPONENT_ANIMATION_IDLE, id); @@ -56,6 +58,7 @@ entity_snake_init(ECS* ecs, u32 id, vec3 position, u32 sender) component_action_redirect_init(actionRedirect, SNAKE_ACTION_REDIRECT_MULTIPLIER, sender); component_action_lock_init(actionLock, SNAKE_ACTION_LOCK_COOLDOWN, SNAKE_ACTION_LOCK_SELECT_RADIUS, sender); component_action_on_delete_give_ammo_init(actionOnDeleteGiveAmmo, SNAKE_ACTION_ON_DELETE_GIVE_AMMO_VALUE); + component_action_on_delete_give_redirects_init(actionOnDeleteGiveRedirects, SNAKE_ACTION_ON_DELETE_GIVE_REDIRECTS_VALUE); component_animation_idle_init(animationIdle, SNAKE_ANIMATION_IDLE_BASE_INDEX, SNAKE_ANIMATION_IDLE_TIMER); component_action_damage_init ( diff --git a/src/game/ecs/entity/play/entity_snake.h b/src/game/ecs/entity/play/entity_snake.h index 27e1ba5..cb6fb1e 100644 --- a/src/game/ecs/entity/play/entity_snake.h +++ b/src/game/ecs/entity/play/entity_snake.h @@ -7,6 +7,7 @@ #include "../../component/action/component_action_angle.h" #include "../../component/animation/component_animation_idle.h" #include "../../component/action/component_action_on_delete_give_ammo.h" +#include "../../component/action/component_action_on_delete_give_redirects.h" #include "../../component/action/component_action_lock.h" #include "../../component/action/component_action_damage.h" #include "../../component/action/component_action_grip.h" @@ -25,18 +26,19 @@ #define SNAKE_ACTION_DAMAGE_TIMER 60 #define SNAKE_ACTION_RETURN_MULTIPLIER 1.15 #define SNAKE_ACTION_ON_DELETE_GIVE_AMMO_VALUE 1 -#define SNAKE_ACTION_REDIRECT_MULTIPLIER 1.05 +#define SNAKE_ACTION_ON_DELETE_GIVE_REDIRECTS_VALUE 1 +#define SNAKE_ACTION_REDIRECT_MULTIPLIER 1.25 #define SNAKE_ALLEGIANCE ALLEGIANCE_PLAYER #define SNAKE_ACTION_DAMAGE_TYPE ALLEGIANCE_PLAYER #define SNAKE_ACTION_DAMAGE_ATTACK_TYPE ALLEGIANCE_ENEMY -#define SNAKE_ACTION_LOCK_SELECT_RADIUS 100.0f +#define SNAKE_ACTION_LOCK_SELECT_RADIUS 125.0f #define SNAKE_ACTION_LOCK_COOLDOWN 300 #define SNAKE_GAME_OBJECT_IS_AFFECTED_BY_GRAVITY false #define SNAKE_GAME_OBJECT_IS_BOUNCE false #define SNAKE_GAME_OBJECT_IS_SOLID false static const vec2 SNAKE_SIZE = {100.0f, 100.0f}; -static const vec2 SNAKE_PHYSICS_SIZE = {60.0f, 20.0f}; +static const vec2 SNAKE_PHYSICS_SIZE = {75.0f, 25.0f}; static const ivec2 SNAKE_ATLAS_SIZE = {9, 2}; static const ivec2 SNAKE_FRAME_SIZE = {512, 512}; diff --git a/src/game/input/input.h b/src/game/input/input.h index a53a55f..6108280 100644 --- a/src/game/input/input.h +++ b/src/game/input/input.h @@ -170,11 +170,10 @@ static const MouseInputEntry INPUT_MOUSE_LOCK_ENTRY = .count = INPUT_LOCK_MOUSE_BUTTON_COUNT }; -#define INPUT_RECALL_KEY_COUNT 2 +#define INPUT_RECALL_KEY_COUNT 1 static const KeyboardKeyType INPUT_RECALL_KEYS[INPUT_RECALL_KEY_COUNT] = { - KEYBOARD_KEY_LSHIFT, - KEYBOARD_KEY_RSHIFT + KEYBOARD_KEY_TAB, }; static const KeyboardInputEntry INPUT_KEYBOARD_RECALL_ENTRY = diff --git a/src/game/resource/RESOURCE_COMMON.h b/src/game/resource/RESOURCE_COMMON.h index d6e4d1e..2ff3ae8 100644 --- a/src/game/resource/RESOURCE_COMMON.h +++ b/src/game/resource/RESOURCE_COMMON.h @@ -62,6 +62,7 @@ typedef enum TextureType TEXTURE_SNAKE, TEXTURE_CHIP, TEXTURE_GUMBALL, + TEXTURE_BEANIE, TEXTURE_GOODIES } TextureType; @@ -94,6 +95,7 @@ static const char* TEXTURE_PATHS[TEXTURE_COUNT] = "res/gfx/play/snake.png", "res/gfx/play/chip.png", "res/gfx/play/gumball.png", + "res/gfx/play/beanie.png", "res/gfx/play/goodies.png" }; @@ -143,6 +145,7 @@ typedef enum SoundType SOUND_SELECT, SOUND_BLEEP, SOUND_SNAKE_SHOOT, + SOUND_RECALL, SOUND_PLAYER_HURT, SOUND_PLAYER_KILL, SOUND_HURT, @@ -154,6 +157,8 @@ typedef enum SoundType SOUND_GROW, SOUND_HEART, SOUND_UPGRADE, + SOUND_ERROR, + SOUND_ALERT, SOUND_CUPPER_HOP, SOUND_CUPPER_KILL, SOUND_CHIPPER_KILL, @@ -166,6 +171,7 @@ typedef enum SoundType SOUND_CUSTARPEDO_KILL, SOUND_EXCORSANT_SPIN, SOUND_EXCORSANT_KILL, + SOUND_BEANIE_KILL, SOUND_EZ_ACHE_READY } SoundType; @@ -174,6 +180,7 @@ static const char* SOUND_PATHS[SOUND_COUNT] = "res/sound/select.ogg", "res/sound/bleep.ogg", "res/sound/snakeShoot.ogg", + "res/sound/recall.ogg", "res/sound/playerHurt.ogg", "res/sound/playerKill.ogg", "res/sound/hurt.ogg", @@ -185,6 +192,8 @@ static const char* SOUND_PATHS[SOUND_COUNT] = "res/sound/grow.ogg", "res/sound/heart.ogg", "res/sound/upgrade.ogg", + "res/sound/error.ogg", + "res/sound/alert.ogg", "res/sound/cupperHop.ogg", "res/sound/cupperKill.ogg", "res/sound/chipperKill.ogg", @@ -197,6 +206,7 @@ static const char* SOUND_PATHS[SOUND_COUNT] = "res/sound/custarpedoKill.ogg", "res/sound/excorsantSpin.ogg", "res/sound/excorsantKill.ogg", + "res/sound/beanieKill.ogg", "res/sound/ezAcheReady.ogg", }; diff --git a/src/game/state/play/play.h b/src/game/state/play/play.h index a42d41e..67b6d3d 100644 --- a/src/game/state/play/play.h +++ b/src/game/state/play/play.h @@ -32,7 +32,7 @@ static const ShaderType PLAY_SHADERS[PLAY_SHADER_COUNT] = SHADER_COLOR_QUAD }; -#define PLAY_TEXTURE_COUNT 25 +#define PLAY_TEXTURE_COUNT 26 static const TextureType PLAY_TEXTURES[PLAY_TEXTURE_COUNT] = { TEXTURE_STATE_FADE, @@ -59,6 +59,7 @@ static const TextureType PLAY_TEXTURES[PLAY_TEXTURE_COUNT] = TEXTURE_SNAKE, TEXTURE_CHIP, TEXTURE_GUMBALL, + TEXTURE_BEANIE, TEXTURE_GOODIES }; @@ -73,12 +74,13 @@ static const FontType PLAY_FONTS[PLAY_FONT_COUNT] = FONT_TUTORIAL }; -#define PLAY_SOUND_COUNT 27 +#define PLAY_SOUND_COUNT 30 static const SoundType PLAY_SOUNDS[PLAY_SOUND_COUNT] = { SOUND_SELECT, SOUND_BLEEP, SOUND_SNAKE_SHOOT, + SOUND_RECALL, SOUND_PLAYER_HURT, SOUND_PLAYER_KILL, SOUND_HURT, @@ -90,6 +92,8 @@ static const SoundType PLAY_SOUNDS[PLAY_SOUND_COUNT] = SOUND_GROW, SOUND_HEART, SOUND_UPGRADE, + SOUND_ERROR, + SOUND_ALERT, SOUND_CUPPER_HOP, SOUND_CUPPER_KILL, SOUND_CHIPPER_KILL,