first commit

This commit is contained in:
2024-08-24 00:47:58 -04:00
commit f6ef842a28
400 changed files with 43479 additions and 0 deletions

22
src/game/GAME_COMMON.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include "state/state.h"
#include "../engine/tick.h"
#include "../engine/sdl.h"
#include "render/buffer.h"
typedef struct Game
{
ECS ecs;
Input input;
Control control;
Renderer renderer;
Resources resources;
State state;
Tick tick;
Window window;
Postprocessing postprocessing[RENDERER_BUFFER_COUNT];
bool isPaused;
} Game;

66
src/game/ecs/ECS_COMMON.h Normal file
View File

@ -0,0 +1,66 @@
#pragma once
#include "component/COMPONENT_COMMON.h"
#include "../../engine/vector.h"
#define ECS_FUNCTION_COUNT ECS_FUNCTION_DRAW + 1
typedef enum ECSFunctionType
{
ECS_FUNCTION_ADD,
ECS_FUNCTION_DELETE,
ECS_FUNCTION_TICK,
ECS_FUNCTION_UPDATE,
ECS_FUNCTION_DRAW
} ECSFunctionType;
typedef struct ECS ECS;
typedef struct Control Control;
typedef struct Input Input;
typedef struct Renderer Renderer;
typedef struct Postprocessing Postprocessing;
typedef struct Resources Resources;
typedef u32 EntityID;
typedef void (*ECSFunction)(void*, ECS*);
typedef struct ECSSystem
{
ECSFunction functions[ECS_FUNCTION_COUNT];
} ECSSystem;
typedef struct Component
{
EntityID id;
bool isDisabled;
bool isFunctionDisabled[ECS_FUNCTION_COUNT];
} Component;
typedef struct ComponentInfo
{
ECSSystem system;
ComponentType type;
size_t size;
} ComponentInfo;
typedef struct ComponentList
{
ECS* ecs;
ECSSystem system;
ComponentType type;
Vector components;
} ComponentList;
typedef struct ECS
{
Input* input;
Control* control;
Renderer* renderer;
Resources* resources;
Postprocessing* postprocessing;
ComponentList lists[COMPONENT_COUNT];
bool isFunctionDisabled[ECS_FUNCTION_COUNT];
bool isLog;
EntityID nextID;
} ECS;

View File

@ -0,0 +1,52 @@
#pragma once
#include "../../../COMMON.h"
#define COMPONENT_COUNT COMPONENT_PULSATE + 1
typedef enum ComponentType
{
/* Utility */
COMPONENT_TIMER,
COMPONENT_COUNTER,
COMPONENT_DELETE_ON_TIMER,
/* Physics */
COMPONENT_PHYSICS,
COMPONENT_COPY_MOUSE_POSITION,
COMPONENT_CIRCLE_COLLIDER,
/* Game */
COMPONENT_GAME_OBJECT,
COMPONENT_PLANE_OBJECT,
COMPONENT_WORLD_OBJECT,
COMPONENT_SOLID,
COMPONENT_LEVITATE,
COMPONENT_COLLIDE_SLOW,
COMPONENT_COLLECTIBLE,
COMPONENT_COLLECT,
COMPONENT_HOMING,
COMPONENT_FOOD,
COMPONENT_THRESHOLD,
COMPONENT_TAKE_FOOD,
COMPONENT_STAGE,
COMPONENT_STAMINA,
COMPONENT_POWER,
COMPONENT_PLAYER_CONTROL,
/* Animation */
COMPONENT_ANIMATION,
COMPONENT_ANIMATION_PLAYER,
COMPONENT_ANIMATION_TARGET,
/* UI */
COMPONENT_BUTTON,
/* Visual */
COMPONENT_DROP_SHADOW,
COMPONENT_TEXTURE_QUAD,
COMPONENT_TEXT,
COMPONENT_DIALOGUE,
COMPONENT_VALUE_TEXT,
COMPONENT_ATLAS,
COMPONENT_CAMERA_FOCUS,
COMPONENT_COLOR_CHANGE,
COMPONENT_COLOR_MATCH,
COMPONENT_SCALE_VALUE,
COMPONENT_ROTATE,
COMPONENT_PULSATE
} ComponentType;

View File

@ -0,0 +1,87 @@
#include "component_animation.h"
void _component_animation_frame_set(ComponentAnimation* self, ECS* ecs);
void
_component_animation_frame_set(ComponentAnimation* self, ECS* ecs)
{
ComponentTimer* timer;
if (self->isFinished)
return;
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timer);
if (timer->isFinished)
{
ComponentAtlas* atlas;
if (self->frame >= self->animation.count)
{
if (!self->animation.isLoop)
{
self->isFinished = true;
return;
}
self->frame = 0;
}
atlas = ecs_component_get(ecs, COMPONENT_ATLAS, self->component.id);
atlas->index = self->animation.frameIndices[self->frame];
component_timer_init(timer, ecs, self->animation.length);
self->frame++;
}
}
void
component_animation_add(ComponentAnimation* self, ECS* ecs)
{
ComponentTimer* timer;
self->timer = entity_timer_add(ecs, -1);
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timer);
timer->component.isDisabled = true;
}
void
component_animation_delete(ComponentAnimation* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->timer);
}
void
component_animation_set(ComponentAnimation* self, ECS* ecs, Animation* animation)
{
ComponentTimer* timer;
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timer);
memcpy(&self->animation, animation, sizeof(Animation));
self->frame = 0;
self->isFinished = false;
component_timer_init(timer, ecs, self->animation.length);
timer->component.isDisabled = false;
timer->isFinished = true;
_component_animation_frame_set(self, ecs);
}
void
component_animation_init(ComponentAnimation* self, ECS* ecs, Animation* animation)
{
component_animation_set(self, ecs, animation);
}
void
component_animation_tick(ComponentAnimation* self, ECS* ecs)
{
_component_animation_frame_set(self, ecs);
}

View File

@ -0,0 +1,44 @@
#pragma once
#include "../../entity/utility/entity_timer.h"
#include "../../component/visual/component_atlas.h"
typedef struct Animation
{
u32* frameIndices;
u32 count;
u32 length;
bool isLoop;
} Animation;
typedef struct ComponentAnimation
{
Component component;
EntityID timer;
u32 frame;
bool isFinished;
Animation animation;
} ComponentAnimation;
void component_animation_add(ComponentAnimation* self, ECS* ecs);
void component_animation_delete(ComponentAnimation* self, ECS* ecs);
void component_animation_tick(ComponentAnimation* self, ECS* ecs);
void component_animation_set(ComponentAnimation* self, ECS* ecs, Animation* animation);
void component_animation_init(ComponentAnimation* self, ECS* ecs, Animation* animation);
static const ComponentInfo COMPONENT_ANIMATION_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_animation_add,
(ECSFunction)component_animation_delete,
(ECSFunction)component_animation_tick,
NULL,
NULL
}
},
.type = COMPONENT_ANIMATION,
.size = sizeof(ComponentAnimation)
};

View File

@ -0,0 +1,87 @@
#include "component_animation_player.h"
void _component_animation_player_set(ComponentAnimationPlayer* self, ECS* ecs, AnimationPlayerType type);
void _component_animation_player_determine(ComponentAnimationPlayer* self, ECS* ecs);
void
_component_animation_player_set(ComponentAnimationPlayer* self, ECS* ecs, AnimationPlayerType type)
{
ComponentAnimation* animation;
if (type == self->type)
return;
self->type = type;
animation = ecs_component_get(ecs, COMPONENT_ANIMATION, self->component.id);
component_animation_set(animation, ecs, &ANIMATION_PLAYER_STRUCTS[type]);
}
void
_component_animation_player_determine(ComponentAnimationPlayer* self, ECS* ecs)
{
AnimationPlayerType type;
ComponentWorldObject* worldObject;
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
type = (AnimationPlayerType)(self->action + ((ANIMATION_PLAYER_ACTION_COUNT) * worldObject->direction));
_component_animation_player_set(self, ecs, type);
}
void
component_animation_player_init(ComponentAnimationPlayer* self, ECS* ecs, AnimationPlayerType type)
{
self->type = -1;
self->action = ANIMATION_PLAYER_ACTION_IDLE;
_component_animation_player_set(self, ecs, type);
}
void
component_animation_player_tick(ComponentAnimationPlayer* self, ECS* ecs)
{
ComponentWorldObject* worldObject;
ComponentPlayerControl* playerControl;
ComponentPhysics* physics;
ComponentAnimation* animation;
ComponentTimer* animationTimer;
f32 nextPositionDistance;
s32 newTimer;
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
if (worldObject->isAirborne && self->action == ANIMATION_PLAYER_ACTION_LUNGE)
return;
playerControl = ecs_component_get(ecs, COMPONENT_PLAYER_CONTROL, self->component.id);
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
self->action = ANIMATION_PLAYER_ACTION_IDLE;
if (playerControl->isLunge)
{
self->action = ANIMATION_PLAYER_ACTION_LUNGE;
sound_play(&ecs->resources->sounds[SOUND_LUNGE + RANDOM_S32(0, SOUND_LUNGE_COUNT - 1)]);
}
else if (physics->isMoving)
{
self->action = ANIMATION_PLAYER_ACTION_RUN;
animation = ecs_component_get(ecs, COMPONENT_ANIMATION, self->component.id);
animationTimer = ecs_component_get(ecs, COMPONENT_TIMER, animation->timer);
nextPositionDistance = component_physics_next_position_distance_get(physics, ecs);
newTimer = ANIMATION_PLAYER_RUN_TIMER - (s32)((nextPositionDistance / ANIMATION_PLAYER_RUN_DISTANCE_MAX) * ANIMATION_PLAYER_RUN_TIMER);
newTimer = MIN(newTimer, (s32)ANIMATION_PLAYER_RUN_TIMER_MIN);
if (animationTimer->value > (s32)ANIMATION_PLAYER_RUN_TIMER_MIN)
animationTimer->value = (s32)(CLAMP((s32)animationTimer->value, (s32)ANIMATION_PLAYER_RUN_TIMER_MIN, (s32)newTimer));
}
_component_animation_player_determine(self, ecs);
}

View File

@ -0,0 +1,199 @@
#pragma once
#include "component_animation.h"
#include "../game/component_world_object.h"
#include "../game/component_player_control.h"
static const f32 ANIMATION_PLAYER_RUN_DISTANCE_MAX = 50.0f;
static const u32 ANIMATION_PLAYER_RUN_TIMER = 20;
static const u32 ANIMATION_PLAYER_RUN_TIMER_MIN = 5;
#define ANIMATION_PLAYER_COUNT ANIMATION_PLAYER_LUNGE_DOWN + 1
typedef enum AnimationPlayerType
{
ANIMATION_PLAYER_IDLE_LEFT,
ANIMATION_PLAYER_RUN_LEFT,
ANIMATION_PLAYER_LUNGE_LEFT,
ANIMATION_PLAYER_IDLE_RIGHT,
ANIMATION_PLAYER_RUN_RIGHT,
ANIMATION_PLAYER_LUNGE_RIGHT,
ANIMATION_PLAYER_IDLE_UP,
ANIMATION_PLAYER_RUN_UP,
ANIMATION_PLAYER_LUNGE_UP,
ANIMATION_PLAYER_IDLE_DOWN,
ANIMATION_PLAYER_RUN_DOWN,
ANIMATION_PLAYER_LUNGE_DOWN
} AnimationPlayerType;
#define ANIMATION_PLAYER_ACTION_COUNT (ANIMATION_PLAYER_ACTION_LUNGE + 1)
typedef enum AnimationPlayerActionType
{
ANIMATION_PLAYER_ACTION_IDLE,
ANIMATION_PLAYER_ACTION_RUN,
ANIMATION_PLAYER_ACTION_LUNGE
} AnimationPlayerActionType;
#define ANIMATION_PLAYER_IDLE_LEFT_COUNT 1
static const u32 ANIMATION_PLAYER_IDLE_LEFT_FRAME_INDICES[ANIMATION_PLAYER_IDLE_LEFT_COUNT] = {0};
static const struct Animation ANIMATION_PLAYER_IDLE_LEFT_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_IDLE_LEFT_FRAME_INDICES,
.count = ANIMATION_PLAYER_IDLE_LEFT_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_PLAYER_RUN_LEFT_COUNT 3
static const u32 ANIMATION_PLAYER_RUN_LEFT_FRAME_INDICES[ANIMATION_PLAYER_RUN_LEFT_COUNT] = {1, 2, 3};
static const struct Animation ANIMATION_PLAYER_RUN_LEFT_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_RUN_LEFT_FRAME_INDICES,
.count = ANIMATION_PLAYER_RUN_LEFT_COUNT,
.length = 20,
.isLoop = true
};
#define ANIMATION_PLAYER_LUNGE_LEFT_COUNT 1
static const u32 ANIMATION_PLAYER_LUNGE_LEFT_FRAME_INDICES[ANIMATION_PLAYER_LUNGE_LEFT_COUNT] = {4};
static const struct Animation ANIMATION_PLAYER_LUNGE_LEFT_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_LUNGE_LEFT_FRAME_INDICES,
.count = ANIMATION_PLAYER_LUNGE_LEFT_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_PLAYER_IDLE_RIGHT_COUNT 1
static const u32 ANIMATION_PLAYER_IDLE_RIGHT_FRAME_INDICES[ANIMATION_PLAYER_IDLE_RIGHT_COUNT] = {5};
static const struct Animation ANIMATION_PLAYER_IDLE_RIGHT_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_IDLE_RIGHT_FRAME_INDICES,
.count = ANIMATION_PLAYER_IDLE_RIGHT_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_PLAYER_RUN_RIGHT_COUNT 3
static const u32 ANIMATION_PLAYER_RUN_RIGHT_FRAME_INDICES[ANIMATION_PLAYER_RUN_RIGHT_COUNT] = {6, 7, 8};
static const struct Animation ANIMATION_PLAYER_RUN_RIGHT_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_RUN_RIGHT_FRAME_INDICES,
.count = ANIMATION_PLAYER_RUN_RIGHT_COUNT,
.length = 20,
.isLoop = true
};
#define ANIMATION_PLAYER_LUNGE_RIGHT_COUNT 1
static const u32 ANIMATION_PLAYER_LUNGE_RIGHT_FRAME_INDICES[ANIMATION_PLAYER_LUNGE_RIGHT_COUNT] = {9};
static const struct Animation ANIMATION_PLAYER_LUNGE_RIGHT_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_LUNGE_RIGHT_FRAME_INDICES,
.count = ANIMATION_PLAYER_LUNGE_RIGHT_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_PLAYER_IDLE_UP_COUNT 1
static const u32 ANIMATION_PLAYER_IDLE_UP_FRAME_INDICES[ANIMATION_PLAYER_IDLE_UP_COUNT] = {10};
static const struct Animation ANIMATION_PLAYER_IDLE_UP_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_IDLE_UP_FRAME_INDICES,
.count = ANIMATION_PLAYER_IDLE_UP_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_PLAYER_RUN_UP_COUNT 3
static const u32 ANIMATION_PLAYER_RUN_UP_FRAME_INDICES[ANIMATION_PLAYER_RUN_UP_COUNT] = {11, 12, 13};
static const struct Animation ANIMATION_PLAYER_RUN_UP_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_RUN_UP_FRAME_INDICES,
.count = ANIMATION_PLAYER_RUN_UP_COUNT,
.length = 20,
.isLoop = true
};
#define ANIMATION_PLAYER_LUNGE_UP_COUNT 1
static const u32 ANIMATION_PLAYER_LUNGE_UP_FRAME_INDICES[ANIMATION_PLAYER_LUNGE_UP_COUNT] = {14};
static const struct Animation ANIMATION_PLAYER_LUNGE_UP_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_LUNGE_UP_FRAME_INDICES,
.count = ANIMATION_PLAYER_LUNGE_UP_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_PLAYER_IDLE_DOWN_COUNT 1
static const u32 ANIMATION_PLAYER_IDLE_DOWN_FRAME_INDICES[ANIMATION_PLAYER_IDLE_DOWN_COUNT] = {15};
static const struct Animation ANIMATION_PLAYER_IDLE_DOWN_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_IDLE_DOWN_FRAME_INDICES,
.count = ANIMATION_PLAYER_IDLE_DOWN_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_PLAYER_RUN_DOWN_COUNT 3
static const u32 ANIMATION_PLAYER_RUN_DOWN_FRAME_INDICES[ANIMATION_PLAYER_RUN_DOWN_COUNT] = {16, 17, 18};
static const struct Animation ANIMATION_PLAYER_RUN_DOWN_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_RUN_DOWN_FRAME_INDICES,
.count = ANIMATION_PLAYER_RUN_DOWN_COUNT,
.length = 20,
.isLoop = true
};
#define ANIMATION_PLAYER_LUNGE_DOWN_COUNT 1
static const u32 ANIMATION_PLAYER_LUNGE_DOWN_FRAME_INDICES[ANIMATION_PLAYER_LUNGE_DOWN_COUNT] = {19};
static const struct Animation ANIMATION_PLAYER_LUNGE_DOWN_STRUCT =
{
.frameIndices = (u32*)ANIMATION_PLAYER_LUNGE_DOWN_FRAME_INDICES,
.count = ANIMATION_PLAYER_LUNGE_DOWN_COUNT,
.length = 0,
.isLoop = true
};
static const struct Animation ANIMATION_PLAYER_STRUCTS[ANIMATION_PLAYER_COUNT] =
{
ANIMATION_PLAYER_IDLE_LEFT_STRUCT,
ANIMATION_PLAYER_RUN_LEFT_STRUCT,
ANIMATION_PLAYER_LUNGE_LEFT_STRUCT,
ANIMATION_PLAYER_IDLE_RIGHT_STRUCT,
ANIMATION_PLAYER_RUN_RIGHT_STRUCT,
ANIMATION_PLAYER_LUNGE_RIGHT_STRUCT,
ANIMATION_PLAYER_IDLE_UP_STRUCT,
ANIMATION_PLAYER_RUN_UP_STRUCT,
ANIMATION_PLAYER_LUNGE_UP_STRUCT,
ANIMATION_PLAYER_IDLE_DOWN_STRUCT,
ANIMATION_PLAYER_RUN_DOWN_STRUCT,
ANIMATION_PLAYER_LUNGE_DOWN_STRUCT
};
typedef struct ComponentAnimationPlayer
{
Component component;
AnimationPlayerType type;
AnimationPlayerActionType action;
} ComponentAnimationPlayer;
void component_animation_player_init(ComponentAnimationPlayer* self, ECS* ecs, AnimationPlayerType type);
void component_animation_player_tick(ComponentAnimationPlayer* self, ECS* ecs);
static const ComponentInfo COMPONENT_ANIMATION_PLAYER_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_animation_player_tick,
NULL,
NULL
}
},
.type = COMPONENT_ANIMATION_PLAYER,
.size = sizeof(ComponentAnimationPlayer)
};

View File

@ -0,0 +1,107 @@
#include "component_animation_target.h"
void _component_animation_target_set(ComponentAnimationTarget* self, ECS* ecs, AnimationTargetType type);
void _component_animation_target_determine(ComponentAnimationTarget* self, ECS* ecs);
void
_component_animation_target_set(ComponentAnimationTarget* self, ECS* ecs, AnimationTargetType type)
{
ComponentAnimation* animation;
if (type == self->type)
return;
self->type = type;
animation = ecs_component_get(ecs, COMPONENT_ANIMATION, self->component.id);
component_animation_set(animation, ecs, &ANIMATION_TARGET_STRUCTS[type]);
}
void
_component_animation_target_determine(ComponentAnimationTarget* self, ECS* ecs)
{
ComponentStage* stage;
AnimationTargetType type;
stage = ecs_component_get(ecs, COMPONENT_STAGE, self->component.id);
type = (AnimationTargetType)(self->action + ((ANIMATION_TARGET_ACTION_COUNT) * stage->value));
_component_animation_target_set(self, ecs, type);
}
void
component_animation_target_init(ComponentAnimationTarget* self, ECS* ecs, AnimationTargetType type, EntityID playerID)
{
self->type = -1;
self->action = ANIMATION_TARGET_ACTION_IDLE;
self->playerID = playerID;
_component_animation_target_set(self, ecs, type);
}
void
component_animation_target_tick(ComponentAnimationTarget* self, ECS* ecs)
{
ComponentFood* playerFood;
ComponentTakeFood* takeFood;
ComponentAnimation* animation;
animation = ecs_component_get(ecs, COMPONENT_ANIMATION, self->component.id);
if
(
(self->action == ANIMATION_TARGET_ACTION_GULP || self->action == ANIMATION_TARGET_ACTION_BURP) &&
!animation->isFinished
)
return;
if (self->action == ANIMATION_TARGET_ACTION_GULP && animation->isFinished)
{
self->action = ANIMATION_TARGET_ACTION_BURP;
sound_play(&ecs->resources->sounds[SOUND_BURP + RANDOM_S32(0, SOUND_BURP_COUNT - 1)]);
_component_animation_target_determine(self, ecs);
return;
}
playerFood = ecs_component_get(ecs, COMPONENT_FOOD, self->playerID);
takeFood = ecs_component_get(ecs, COMPONENT_TAKE_FOOD, self->component.id);
if (self->action == ANIMATION_TARGET_ACTION_BURP && animation->isFinished)
{
sound_play(&ecs->resources->sounds[SOUND_GURGLE + RANDOM_S32(0, SOUND_GURGLE_COUNT - 1)]);
takeFood->component.isDisabled = false;
}
self->action = ANIMATION_TARGET_ACTION_IDLE;
if (takeFood->isTakeFood)
{
self->action = ANIMATION_TARGET_ACTION_GULP;
takeFood->isTakeFood = false;
takeFood->component.isDisabled = true;
sound_play(&ecs->resources->sounds[SOUND_GULP + RANDOM_S32(0, SOUND_GULP_COUNT - 1)]);
}
else if (playerFood->value > 0)
{
ComponentPhysics* playerPhysics;
ComponentPhysics* physics;
f32 distance;
playerPhysics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->playerID);
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
distance = DISTANCE_2D(playerPhysics->position[0], physics->position[0], playerPhysics->position[1], physics->position[1]);
if (distance <= ANIMATION_TARGET_POINT_RADIUS && !self->isPointDisabled)
self->action = ANIMATION_TARGET_ACTION_POINT;
}
_component_animation_target_determine(self, ecs);
}

View File

@ -0,0 +1,296 @@
#pragma once
#include "component_animation.h"
#include "../game/component_food.h"
#include "../game/component_take_food.h"
#include "../game/component_stage.h"
#include "../game/component_world_object.h"
static const f32 ANIMATION_TARGET_POINT_RADIUS = 1500.0f;
#define ANIMATION_TARGET_COUNT (ANIMATION_TARGET_BURP_STAGE_FIVE + 1)
typedef enum AnimationTargetType
{
ANIMATION_TARGET_IDLE_STAGE_ONE,
ANIMATION_TARGET_POINT_STAGE_ONE,
ANIMATION_TARGET_GULP_STAGE_ONE,
ANIMATION_TARGET_BURP_STAGE_ONE,
ANIMATION_TARGET_IDLE_STAGE_TWO,
ANIMATION_TARGET_POINT_STAGE_TWO,
ANIMATION_TARGET_GULP_STAGE_TWO,
ANIMATION_TARGET_BURP_STAGE_TWO,
ANIMATION_TARGET_IDLE_STAGE_THREE,
ANIMATION_TARGET_POINT_STAGE_THREE,
ANIMATION_TARGET_GULP_STAGE_THREE,
ANIMATION_TARGET_BURP_STAGE_THREE,
ANIMATION_TARGET_IDLE_STAGE_FOUR,
ANIMATION_TARGET_POINT_STAGE_FOUR,
ANIMATION_TARGET_GULP_STAGE_FOUR,
ANIMATION_TARGET_BURP_STAGE_FOUR,
ANIMATION_TARGET_IDLE_STAGE_FIVE,
ANIMATION_TARGET_POINT_STAGE_FIVE,
ANIMATION_TARGET_GULP_STAGE_FIVE,
ANIMATION_TARGET_BURP_STAGE_FIVE
} AnimationTargetType;
#define ANIMATION_TARGET_ACTION_COUNT (ANIMATION_TARGET_ACTION_BURP + 1)
typedef enum AnimationTargetActionType
{
ANIMATION_TARGET_ACTION_IDLE,
ANIMATION_TARGET_ACTION_POINT,
ANIMATION_TARGET_ACTION_GULP,
ANIMATION_TARGET_ACTION_BURP
} AnimationTargetActionType;
#define ANIMATION_TARGET_IDLE_STAGE_ONE_COUNT 2
static const u32 ANIMATION_TARGET_IDLE_STAGE_ONE_FRAME_INDICES[ANIMATION_TARGET_IDLE_STAGE_ONE_COUNT] = {0, 1};
static const struct Animation ANIMATION_TARGET_IDLE_STAGE_ONE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_IDLE_STAGE_ONE_FRAME_INDICES,
.count = ANIMATION_TARGET_IDLE_STAGE_ONE_COUNT,
.length = 30,
.isLoop = true
};
#define ANIMATION_TARGET_POINT_STAGE_ONE_COUNT 1
static const u32 ANIMATION_TARGET_POINT_STAGE_ONE_FRAME_INDICES[ANIMATION_TARGET_POINT_STAGE_ONE_COUNT] = {2};
static const struct Animation ANIMATION_TARGET_POINT_STAGE_ONE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_POINT_STAGE_ONE_FRAME_INDICES,
.count = ANIMATION_TARGET_POINT_STAGE_ONE_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_TARGET_GULP_STAGE_ONE_COUNT 1
static const u32 ANIMATION_TARGET_GULP_STAGE_ONE_FRAME_INDICES[ANIMATION_TARGET_GULP_STAGE_ONE_COUNT] = {3};
static const struct Animation ANIMATION_TARGET_GULP_STAGE_ONE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_GULP_STAGE_ONE_FRAME_INDICES,
.count = ANIMATION_TARGET_GULP_STAGE_ONE_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_BURP_STAGE_ONE_COUNT 1
static const u32 ANIMATION_TARGET_BURP_STAGE_ONE_FRAME_INDICES[ANIMATION_TARGET_BURP_STAGE_ONE_COUNT] = {4};
static const struct Animation ANIMATION_TARGET_BURP_STAGE_ONE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_BURP_STAGE_ONE_FRAME_INDICES,
.count = ANIMATION_TARGET_BURP_STAGE_ONE_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_IDLE_STAGE_TWO_COUNT 2
static const u32 ANIMATION_TARGET_IDLE_STAGE_TWO_FRAME_INDICES[ANIMATION_TARGET_IDLE_STAGE_TWO_COUNT] = {5, 6};
static const struct Animation ANIMATION_TARGET_IDLE_STAGE_TWO_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_IDLE_STAGE_TWO_FRAME_INDICES,
.count = ANIMATION_TARGET_IDLE_STAGE_TWO_COUNT,
.length = 30,
.isLoop = true
};
#define ANIMATION_TARGET_POINT_STAGE_TWO_COUNT 1
static const u32 ANIMATION_TARGET_POINT_STAGE_TWO_FRAME_INDICES[ANIMATION_TARGET_POINT_STAGE_TWO_COUNT] = {7};
static const struct Animation ANIMATION_TARGET_POINT_STAGE_TWO_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_POINT_STAGE_TWO_FRAME_INDICES,
.count = ANIMATION_TARGET_POINT_STAGE_TWO_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_TARGET_GULP_STAGE_TWO_COUNT 1
static const u32 ANIMATION_TARGET_GULP_STAGE_TWO_FRAME_INDICES[ANIMATION_TARGET_GULP_STAGE_TWO_COUNT] = {8};
static const struct Animation ANIMATION_TARGET_GULP_STAGE_TWO_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_GULP_STAGE_TWO_FRAME_INDICES,
.count = ANIMATION_TARGET_GULP_STAGE_TWO_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_BURP_STAGE_TWO_COUNT 1
static const u32 ANIMATION_TARGET_BURP_STAGE_TWO_FRAME_INDICES[ANIMATION_TARGET_BURP_STAGE_TWO_COUNT] = {9};
static const struct Animation ANIMATION_TARGET_BURP_STAGE_TWO_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_BURP_STAGE_TWO_FRAME_INDICES,
.count = ANIMATION_TARGET_BURP_STAGE_TWO_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_IDLE_STAGE_THREE_COUNT 2
static const u32 ANIMATION_TARGET_IDLE_STAGE_THREE_FRAME_INDICES[ANIMATION_TARGET_IDLE_STAGE_THREE_COUNT] = {10, 11};
static const struct Animation ANIMATION_TARGET_IDLE_STAGE_THREE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_IDLE_STAGE_THREE_FRAME_INDICES,
.count = ANIMATION_TARGET_IDLE_STAGE_THREE_COUNT,
.length = 30,
.isLoop = true
};
#define ANIMATION_TARGET_POINT_STAGE_THREE_COUNT 1
static const u32 ANIMATION_TARGET_POINT_STAGE_THREE_FRAME_INDICES[ANIMATION_TARGET_POINT_STAGE_THREE_COUNT] = {12};
static const struct Animation ANIMATION_TARGET_POINT_STAGE_THREE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_POINT_STAGE_THREE_FRAME_INDICES,
.count = ANIMATION_TARGET_POINT_STAGE_THREE_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_TARGET_GULP_STAGE_THREE_COUNT 1
static const u32 ANIMATION_TARGET_GULP_STAGE_THREE_FRAME_INDICES[ANIMATION_TARGET_GULP_STAGE_THREE_COUNT] = {13};
static const struct Animation ANIMATION_TARGET_GULP_STAGE_THREE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_GULP_STAGE_THREE_FRAME_INDICES,
.count = ANIMATION_TARGET_GULP_STAGE_THREE_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_BURP_STAGE_THREE_COUNT 1
static const u32 ANIMATION_TARGET_BURP_STAGE_THREE_FRAME_INDICES[ANIMATION_TARGET_BURP_STAGE_THREE_COUNT] = {14};
static const struct Animation ANIMATION_TARGET_BURP_STAGE_THREE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_BURP_STAGE_THREE_FRAME_INDICES,
.count = ANIMATION_TARGET_BURP_STAGE_THREE_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_IDLE_STAGE_FOUR_COUNT 2
static const u32 ANIMATION_TARGET_IDLE_STAGE_FOUR_FRAME_INDICES[ANIMATION_TARGET_IDLE_STAGE_FOUR_COUNT] = {15, 16};
static const struct Animation ANIMATION_TARGET_IDLE_STAGE_FOUR_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_IDLE_STAGE_FOUR_FRAME_INDICES,
.count = ANIMATION_TARGET_IDLE_STAGE_FOUR_COUNT,
.length = 30,
.isLoop = true
};
#define ANIMATION_TARGET_POINT_STAGE_FOUR_COUNT 1
static const u32 ANIMATION_TARGET_POINT_STAGE_FOUR_FRAME_INDICES[ANIMATION_TARGET_POINT_STAGE_FOUR_COUNT] = {17};
static const struct Animation ANIMATION_TARGET_POINT_STAGE_FOUR_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_POINT_STAGE_FOUR_FRAME_INDICES,
.count = ANIMATION_TARGET_POINT_STAGE_FOUR_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_TARGET_GULP_STAGE_FOUR_COUNT 1
static const u32 ANIMATION_TARGET_GULP_STAGE_FOUR_FRAME_INDICES[ANIMATION_TARGET_GULP_STAGE_FOUR_COUNT] = {18};
static const struct Animation ANIMATION_TARGET_GULP_STAGE_FOUR_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_GULP_STAGE_FOUR_FRAME_INDICES,
.count = ANIMATION_TARGET_GULP_STAGE_FOUR_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_BURP_STAGE_FOUR_COUNT 1
static const u32 ANIMATION_TARGET_BURP_STAGE_FOUR_FRAME_INDICES[ANIMATION_TARGET_BURP_STAGE_FOUR_COUNT] = {19};
static const struct Animation ANIMATION_TARGET_BURP_STAGE_FOUR_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_BURP_STAGE_FOUR_FRAME_INDICES,
.count = ANIMATION_TARGET_BURP_STAGE_FOUR_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_IDLE_STAGE_FIVE_COUNT 2
static const u32 ANIMATION_TARGET_IDLE_STAGE_FIVE_FRAME_INDICES[ANIMATION_TARGET_IDLE_STAGE_FIVE_COUNT] = {20, 21};
static const struct Animation ANIMATION_TARGET_IDLE_STAGE_FIVE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_IDLE_STAGE_FIVE_FRAME_INDICES,
.count = ANIMATION_TARGET_IDLE_STAGE_FIVE_COUNT,
.length = 30,
.isLoop = true
};
#define ANIMATION_TARGET_POINT_STAGE_FIVE_COUNT 1
static const u32 ANIMATION_TARGET_POINT_STAGE_FIVE_FRAME_INDICES[ANIMATION_TARGET_POINT_STAGE_FIVE_COUNT] = {22};
static const struct Animation ANIMATION_TARGET_POINT_STAGE_FIVE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_POINT_STAGE_FIVE_FRAME_INDICES,
.count = ANIMATION_TARGET_POINT_STAGE_FIVE_COUNT,
.length = 0,
.isLoop = true
};
#define ANIMATION_TARGET_GULP_STAGE_FIVE_COUNT 1
static const u32 ANIMATION_TARGET_GULP_STAGE_FIVE_FRAME_INDICES[ANIMATION_TARGET_GULP_STAGE_FIVE_COUNT] = {23};
static const struct Animation ANIMATION_TARGET_GULP_STAGE_FIVE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_GULP_STAGE_FIVE_FRAME_INDICES,
.count = ANIMATION_TARGET_GULP_STAGE_FIVE_COUNT,
.length = 60,
.isLoop = false
};
#define ANIMATION_TARGET_BURP_STAGE_FIVE_COUNT 1
static const u32 ANIMATION_TARGET_BURP_STAGE_FIVE_FRAME_INDICES[ANIMATION_TARGET_BURP_STAGE_FIVE_COUNT] = {24};
static const struct Animation ANIMATION_TARGET_BURP_STAGE_FIVE_STRUCT =
{
.frameIndices = (u32*)ANIMATION_TARGET_BURP_STAGE_FIVE_FRAME_INDICES,
.count = ANIMATION_TARGET_BURP_STAGE_FIVE_COUNT,
.length = 60,
.isLoop = false
};
static const struct Animation ANIMATION_TARGET_STRUCTS[ANIMATION_TARGET_COUNT] =
{
ANIMATION_TARGET_IDLE_STAGE_ONE_STRUCT,
ANIMATION_TARGET_POINT_STAGE_ONE_STRUCT,
ANIMATION_TARGET_GULP_STAGE_ONE_STRUCT,
ANIMATION_TARGET_BURP_STAGE_ONE_STRUCT,
ANIMATION_TARGET_IDLE_STAGE_TWO_STRUCT,
ANIMATION_TARGET_POINT_STAGE_TWO_STRUCT,
ANIMATION_TARGET_GULP_STAGE_TWO_STRUCT,
ANIMATION_TARGET_BURP_STAGE_TWO_STRUCT,
ANIMATION_TARGET_IDLE_STAGE_THREE_STRUCT,
ANIMATION_TARGET_POINT_STAGE_THREE_STRUCT,
ANIMATION_TARGET_GULP_STAGE_THREE_STRUCT,
ANIMATION_TARGET_BURP_STAGE_THREE_STRUCT,
ANIMATION_TARGET_IDLE_STAGE_FOUR_STRUCT,
ANIMATION_TARGET_POINT_STAGE_FOUR_STRUCT,
ANIMATION_TARGET_GULP_STAGE_FOUR_STRUCT,
ANIMATION_TARGET_BURP_STAGE_FOUR_STRUCT,
ANIMATION_TARGET_IDLE_STAGE_FIVE_STRUCT,
ANIMATION_TARGET_POINT_STAGE_FIVE_STRUCT,
ANIMATION_TARGET_GULP_STAGE_FIVE_STRUCT,
ANIMATION_TARGET_BURP_STAGE_FIVE_STRUCT
};
typedef struct ComponentAnimationTarget
{
Component component;
AnimationTargetType type;
AnimationTargetActionType action;
EntityID playerID;
bool isPointDisabled;
} ComponentAnimationTarget;
void component_animation_target_init(ComponentAnimationTarget* self, ECS* ecs, AnimationTargetType type, EntityID playerID);
void component_animation_target_tick(ComponentAnimationTarget* self, ECS* ecs);
static const ComponentInfo COMPONENT_ANIMATION_TARGET_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_animation_target_tick,
NULL,
NULL
}
},
.type = COMPONENT_ANIMATION_TARGET,
.size = sizeof(ComponentAnimationTarget)
};

View File

@ -0,0 +1,26 @@
#include "component_collect.h"
void _component_collect_circle_set(ComponentCollect* self, ECS* ecs);
void
_component_collect_circle_set(ComponentCollect* self, ECS* ecs)
{
ComponentCircleCollider* circleCollider;
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
self->circle.position[0] = circleCollider->circle.position[0];
self->circle.position[1] = circleCollider->circle.position[1];
}
void
component_collect_init(ComponentCollect* self, ECS* ecs, f32 radius)
{
self->circle.radius = radius;
}
void
component_collect_tick(ComponentCollect* self, ECS* ecs)
{
_component_collect_circle_set(self, ecs);
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "component_world_object.h"
typedef struct ComponentCollect
{
Component component;
Circle circle;
} ComponentCollect;
void component_collect_tick(ComponentCollect* self, ECS* ecs);
void component_collect_init(ComponentCollect* self, ECS* ecs, f32 radius);
static const ComponentInfo COMPONENT_COLLECT_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_collect_tick,
NULL,
NULL
}
},
.type = COMPONENT_COLLECT,
.size = sizeof(ComponentCollect)
};

View File

@ -0,0 +1,169 @@
#include "component_collectible.h"
void _component_collectible_increment(ComponentCollectible* self, ECS* ecs, EntityID id);
void _component_collectible_collect(ComponentCollectible* self, ECS* ecs, EntityID id);
void
_component_collectible_increment(ComponentCollectible* self, ECS* ecs, EntityID id)
{
ComponentFood* food;
ComponentPower* power;
ComponentStamina* stamina;
ComponentColorChange* colorChange;
switch (self->type)
{
case COLLECTIBLE_FOOD:
food = ecs_component_get(ecs, COMPONENT_FOOD, id);
if (!food)
return;
food->value += COMPONENT_COLLECTIBLE_FOOD_VALUE * food->multiplier;
sound_play(&ecs->resources->sounds[SOUND_FOOD_COLLECT]);
break;
case COLLECTIBLE_POWER:
colorChange = ecs_component_get(ecs, COMPONENT_COLOR_CHANGE, id);
power = ecs_component_get(ecs, COMPONENT_POWER, id);
if (!power)
return;
power->value += COMPONENT_COLLECTIBLE_POWER_VALUE;
sound_play(&ecs->resources->sounds[SOUND_POWER]);
if (!colorChange)
return;
component_color_change_init(colorChange, ecs, COMPONENT_COLLECTIBLE_POWER_COLOR,TRANSPARENT, COMPONENT_COLLECTIBLE_POWER_COLOR_CHANGE_TIME, true, false);
break;
case COLLECTIBLE_STAMINA:
stamina = ecs_component_get(ecs, COMPONENT_STAMINA, id);
colorChange = ecs_component_get(ecs, COMPONENT_COLOR_CHANGE, id);
if (!stamina)
return;
stamina->value += COMPONENT_COLLECTIBLE_STAMINA_VALUE;
sound_play(&ecs->resources->sounds[SOUND_STAMINA]);
if (!colorChange)
return;
component_color_change_init(colorChange, ecs, COMPONENT_COLLECTIBLE_STAMINA_COLOR,TRANSPARENT, COMPONENT_COLLECTIBLE_STAMINA_COLOR_CHANGE_TIME, true, false);
break;
case COLLECTIBLE_ROTTEN_FOOD:
food = ecs_component_get(ecs, COMPONENT_FOOD, id);
if (!food)
return;
food->value -= COMPONENT_COLLECTIBLE_FOOD_VALUE;
sound_play(&ecs->resources->sounds[SOUND_BLEH]);
break;
case COLLECTIBLE_AMULET:
sound_play(&ecs->resources->sounds[SOUND_POWER]);
break;
default:
break;
}
}
void
_component_collectible_collect(ComponentCollectible* self, ECS* ecs, EntityID id)
{
_component_collectible_increment(self, ecs, id);
ecs_entity_delete(ecs, self->component.id);
}
void
component_collectible_add(ComponentCollectible* self, ECS* ecs)
{
ecs_components_add
(
ecs,
COMPONENT_COLLECTIBLE_DEPENDENCIES,
COMPONENT_COLLECTIBLE_DEPENDENCY_COUNT,
self->component.id
);
}
void
component_collectible_init
(
ComponentCollectible* self,
ECS* ecs,
Texture* texture,
const vec2 size,
const vec3 position,
CollectibleType type
)
{
component_world_object_init
(
ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id),
ecs,
texture,
size,
position,
COMPONENT_COLLECTIBLE_HEIGHT_OFFSET,
COMPONENT_COLLECTIBLE_RADIUS
);
component_levitate_init
(
ecs_component_get(ecs, COMPONENT_LEVITATE, self->component.id),
ecs,
COMPONENT_COLLECTIBLE_LEVITATE_DISTANCE,
COMPONENT_COLLECTIBLE_LEVITATE_FREQUENCY
);
self->type = type;
}
void
component_collectible_tick(ComponentCollectible* self, ECS* ecs)
{
ComponentCircleCollider* circleCollider;
ComponentHoming* homing;
bool isTarget;
bool isAbleToBeCollected;
EntityID target;
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
homing = ecs_component_get(ecs, COMPONENT_HOMING, self->component.id);
isTarget = false;
isAbleToBeCollected = true;
for (s32 i = 0; i < (s32)ecs->lists[COMPONENT_COLLECT].components.count; i++)
{
ComponentCollect* collect;
collect = ecs_component_from_index_get(ecs, COMPONENT_COLLECT, i);
if (circle_collide_check(&collect->circle, &circleCollider->circle))
{
target = collect->component.id;
isTarget = true;
}
}
if (!isTarget)
return;
if (self->type == COLLECTIBLE_FOOD)
{
ComponentFood* food;
food = ecs_component_get(ecs, COMPONENT_FOOD, target);
if (food->value >= food->max)
{
homing->isHoming = false;
isAbleToBeCollected = false;
//sound_play(&ecs->resources->sounds[SOUND_CANT_CARRY]);
}
}
if (isAbleToBeCollected)
{
if (!homing->isHoming)
component_homing_init(homing, ecs, target, COMPONENT_COLLECTIBLE_HOMING_SPEED);
if (component_circle_collider_collide_check(circleCollider, ecs, target))
_component_collectible_collect(self, ecs, target);
}
}

View File

@ -0,0 +1,85 @@
#pragma once
#include "component_homing.h"
#include "component_collect.h"
#include "component_world_object.h"
#include "component_levitate.h"
#include "component_food.h"
#include "component_power.h"
#include "component_stamina.h"
#include "../visual/component_color_change.h"
static const f32 COMPONENT_COLLECTIBLE_HEIGHT_OFFSET = 1000.0f;
static const f32 COMPONENT_COLLECTIBLE_RADIUS = 64.0f;
static const u32 COMPONENT_COLLECTIBLE_FOOD_VALUE = 1;
static const f32 COMPONENT_COLLECTIBLE_POWER_VALUE = 10.0f;
static const f32 COMPONENT_COLLECTIBLE_STAMINA_VALUE = 50.0f;
static const u32 COMPONENT_COLLECTIBLE_HOMING_SPEED = 3.0f;
static const f32 COMPONENT_COLLECTIBLE_LEVITATE_DISTANCE = 32.0f;
static const f32 COMPONENT_COLLECTIBLE_LEVITATE_FREQUENCY = 10.0f;
static const u32 COMPONENT_COLLECTIBLE_STAMINA_COLOR_CHANGE_TIME = 30;
static const u32 COMPONENT_COLLECTIBLE_POWER_COLOR_CHANGE_TIME = 30;
static const vec4 COMPONENT_COLLECTIBLE_POWER_COLOR = {0.60f, 1.0f, 0.80f, 0.0f};
static const vec4 COMPONENT_COLLECTIBLE_STAMINA_COLOR = {1.0f, 0.2f, 0.40f, 0.0f};
typedef struct Vector Vector;
#define COLLECTIBLE_TYPE_COUNT COLLECTIBLE_ROTTEN_FOOD + 1
typedef enum CollectibleType
{
COLLECTIBLE_FOOD,
COLLECTIBLE_STAMINA,
COLLECTIBLE_POWER,
COLLECTIBLE_LOREBOOK,
COLLECTIBLE_AMULET,
COLLECTIBLE_ROTTEN_FOOD
} CollectibleType;
typedef struct ComponentCollectible
{
Component component;
CollectibleType type;
} ComponentCollectible;
void
component_collectible_init
(
ComponentCollectible* self,
ECS* ecs,
Texture* texture,
const vec2 size,
const vec3 position,
CollectibleType type
);
void component_collectible_add(ComponentCollectible* self, ECS* ecs);
void component_collectible_tick(ComponentCollectible* self, ECS* ecs);
#define COMPONENT_COLLECTIBLE_DEPENDENCY_COUNT 3
static const ComponentType COMPONENT_COLLECTIBLE_DEPENDENCIES[COMPONENT_COLLECTIBLE_DEPENDENCY_COUNT] =
{
COMPONENT_WORLD_OBJECT,
COMPONENT_HOMING,
COMPONENT_LEVITATE
};
static const ComponentInfo COMPONENT_COLLECTIBLE_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_collectible_add,
NULL,
(ECSFunction)component_collectible_tick,
NULL,
NULL
}
},
.type = COMPONENT_COLLECTIBLE,
.size = sizeof(ComponentCollectible)
};

View File

@ -0,0 +1,52 @@
#include "component_collide_slow.h"
void _component_collide_slow_collisions_tick(ComponentCollideSlow* self, ECS* ecs);
void
_component_collide_slow_collisions_tick(ComponentCollideSlow* self, ECS* ecs)
{
ComponentCircleCollider* circleCollider;
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
self->isPreviousColliding = self->isColliding;
self->isColliding = false;
ecs->isLog = false;
for (s32 i = 0; i < (s32)circleCollider->collisions.count; i++)
{
ComponentPhysics* collidePhysics;
ComponentWorldObject* collideWorldObject;
EntityID* id;
f32 angle;
f32 distance;
id = vector_get(&circleCollider->collisions, i);
collidePhysics = ecs_component_get(ecs, COMPONENT_PHYSICS, *id);
collideWorldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, *id);
if (!collideWorldObject || !collidePhysics)
continue;
if (!collideWorldObject->isAirborne)
{
collidePhysics->velocity[0] *= COMPONENT_COLLIDE_SLOW_VELOCITY_MULTIPLIER;
collidePhysics->velocity[1] *= COMPONENT_COLLIDE_SLOW_VELOCITY_MULTIPLIER;
self->isColliding = true;
}
}
if (self->isPreviousColliding != self->isColliding)
sound_play(&ecs->resources->sounds[SOUND_STICKY]);
ecs->isLog = true;
}
void
component_collide_slow_tick(ComponentCollideSlow* self, ECS* ecs)
{
_component_collide_slow_collisions_tick(self, ecs);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "component_world_object.h"
typedef struct ComponentCollideSlow
{
Component component;
bool isColliding;
bool isPreviousColliding;
} ComponentCollideSlow;
static const f32 COMPONENT_COLLIDE_SLOW_VELOCITY_MULTIPLIER = 0.5f;
void component_collide_slow_tick(ComponentCollideSlow* self, ECS* ecs);
static const ComponentInfo COMPONENT_COLLIDE_SLOW_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_collide_slow_tick,
NULL,
NULL
}
},
.type = COMPONENT_COLLIDE_SLOW,
.size = sizeof(ComponentCollideSlow)
};

View File

@ -0,0 +1,26 @@
#include "component_food.h"
void
component_food_tick(ComponentFood* self, ECS* ecs)
{
self->value = CLAMP(self->value, 0, self->max);
if (self->value == self->max)
{
if (!self->isJustFull)
{
sound_play(&ecs->resources->sounds[SOUND_CANT_CARRY]);
self->isJustFull = true;
}
}
else
self->isJustFull = false;
}
void
component_food_init(ComponentFood* self, ECS* ecs, s32 value, s32 max, s32 multiplier)
{
self->value = value;
self->max = max;
self->multiplier = multiplier;
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "component_world_object.h"
typedef struct ComponentFood
{
Component component;
s32 value;
s32 max;
s32 multiplier;
bool isJustFull;
} ComponentFood;
void component_food_tick(ComponentFood* self, ECS* ecs);
void component_food_init(ComponentFood* self, ECS* ecs, s32 value, s32 max, s32 multiplier);
static const ComponentInfo COMPONENT_FOOD_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_food_tick,
NULL,
NULL
}
},
.type = COMPONENT_FOOD,
.size = sizeof(ComponentFood)
};

View File

@ -0,0 +1,62 @@
#include "component_game_object.h"
void
component_game_object_init
(
ComponentGameObject* self,
ECS* ecs,
Texture* texture,
RendererBuffer buffer,
Origin origin,
vec2 size,
vec3 position
)
{
ComponentPhysics* physics;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
component_texture_quad_init
(
ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id),
ecs,
texture,
COMPONENT_TEXTURE_QUAD_FLIP_DEFAULT,
origin,
buffer,
COMPONENT_TEXTURE_QUAD_ROTATION_DEFAULT,
size,
COMPONENT_TEXTURE_QUAD_SCALE_DEFAULT,
COMPONENT_TEXTURE_QUAD_UV_MIN_DEFAULT,
COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT,
COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT,
position,
COMPONENT_TEXTURE_QUAD_COLOR_DEFAULT
);
glm_vec3_copy(position, physics->position);
}
void
component_game_object_add(ComponentGameObject* self, ECS* ecs)
{
ecs_components_add
(
ecs,
COMPONENT_GAME_OBJECT_DEPENDENCIES,
COMPONENT_GAME_OBJECT_DEPENDENCY_COUNT,
self->component.id
);
}
void
component_game_object_tick(ComponentGameObject* self, ECS* ecs)
{
ComponentTextureQuad* textureQuad;
ComponentPhysics* physics;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
glm_vec3_copy(physics->position, textureQuad->position);
}

View File

@ -0,0 +1,48 @@
#pragma once
#include "../visual/component_texture_quad.h"
#include "../physics/component_physics.h"
typedef struct ComponentGameObject
{
Component component;
} ComponentGameObject;
void
component_game_object_init
(
ComponentGameObject* self,
ECS* ecs,
Texture* texture,
RendererBuffer buffer,
Origin origin,
vec2 size,
vec3 position
);
void component_game_object_add(ComponentGameObject* self, ECS* ecs);
void component_game_object_tick(ComponentGameObject* self, ECS* ecs);
#define COMPONENT_GAME_OBJECT_DEPENDENCY_COUNT 2
static const ComponentType COMPONENT_GAME_OBJECT_DEPENDENCIES[COMPONENT_GAME_OBJECT_DEPENDENCY_COUNT] =
{
COMPONENT_PHYSICS,
COMPONENT_TEXTURE_QUAD,
};
static const ComponentInfo COMPONENT_GAME_OBJECT_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_game_object_add,
NULL,
(ECSFunction)component_game_object_tick,
NULL,
NULL
}
},
.type = COMPONENT_GAME_OBJECT,
.size = sizeof(ComponentGameObject)
};

View File

@ -0,0 +1,31 @@
#include "component_homing.h"
void
component_homing_init(ComponentHoming* self, ECS* ecs, EntityID targetID, f32 speed)
{
self->targetID = targetID;
self->speed = speed;
self->isHoming = true;
}
void
component_homing_tick(ComponentHoming* self, ECS* ecs)
{
if (!self->isHoming)
return;
ComponentPhysics* physics;
ComponentPhysics* targetPhysics;
f32 angle;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
targetPhysics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->targetID);
if (!targetPhysics)
return;
angle = ATAN(physics->position[0], targetPhysics->position[0], physics->position[1], targetPhysics->position[1]);
physics->velocity[0] += self->speed * cos(angle);
physics->velocity[1] += self->speed * sin(angle);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "../physics/component_physics.h"
typedef struct ComponentHoming
{
Component component;
EntityID targetID;
f32 speed;
bool isHoming;
} ComponentHoming;
void component_homing_tick(ComponentHoming* self, ECS* ecs);
void component_homing_init(ComponentHoming* self, ECS* ecs, EntityID targetID, f32 speed);
static const ComponentInfo COMPONENT_HOMING_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_homing_tick,
NULL,
NULL
}
},
.type = COMPONENT_HOMING,
.size = sizeof(ComponentHoming)
};

View File

@ -0,0 +1,44 @@
#include "component_levitate.h"
void
component_levitate_add(ComponentLevitate* self, ECS* ecs)
{
self->counterID = entity_counter_add(ecs);
}
void
component_levitate_delete(ComponentLevitate* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->counterID);
}
void
component_levitate_tick(ComponentLevitate* self, ECS* ecs)
{
ComponentCounter* counter;
ComponentWorldObject* worldObject;
counter = ecs_component_get(ecs, COMPONENT_COUNTER, self->counterID);
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
worldObject->heightOffset = self->distance + ((self->distance / 2.0f) * cos((f32)counter->value / self->frequency));
}
void
component_levitate_init
(
ComponentLevitate* self,
ECS* ecs,
f32 distance,
f32 frequency
)
{
ComponentWorldObject* worldObject;
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
self->frequency = frequency;
self->distance = distance;
worldObject->isGravityAffected = false;
}

View File

@ -0,0 +1,42 @@
#pragma once
#include "component_world_object.h"
#include "../../entity/utility/entity_counter.h"
typedef struct ComponentLevitate
{
Component component;
f32 distance;
f32 frequency;
EntityID counterID;
} ComponentLevitate;
void component_levitate_add(ComponentLevitate* self, ECS* ecs);
void component_levitate_delete(ComponentLevitate* self, ECS* ecs);
void component_levitate_tick(ComponentLevitate* self, ECS* ecs);
void
component_levitate_init
(
ComponentLevitate* self,
ECS* ecs,
f32 distance,
f32 frequency
);
static const ComponentInfo COMPONENT_LEVITATE_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_levitate_add,
(ECSFunction)component_levitate_delete,
(ECSFunction)component_levitate_tick,
NULL,
NULL
}
},
.type = COMPONENT_LEVITATE,
.size = sizeof(ComponentLevitate)
};

View File

@ -0,0 +1,111 @@
#include "component_plane_object.h"
void _component_plane_object_depth_set(ComponentPlaneObject* self, ECS* ecs);
void _component_plane_object_circle_collider_set(ComponentPlaneObject* self, ECS* ecs);
void
_component_plane_object_circle_collider_set(ComponentPlaneObject* self, ECS* ecs)
{
ComponentCircleCollider* circleCollider;
ComponentTextureQuad* textureQuad;
ComponentPhysics* physics;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
circleCollider->circle.position[0] = physics->position[0];
circleCollider->circle.position[1] = physics->position[1] + (textureQuad->size[1] / 2.0f);
}
void
_component_plane_object_depth_set(ComponentPlaneObject* self, ECS* ecs)
{
ComponentPhysics* physics;
ComponentTextureQuad* textureQuad;
f32 depth;
f32 yOffset;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
yOffset = COMPONENT_PLANE_OBJECT_DEPTH_Y_OFFSET_MULTIPLIER * ((physics->position[1] + textureQuad->size[1]) / COMPONENT_PLANE_OBJECT_BOUNDS[3]);
depth = COMPONENT_PLANE_OBJECT_DEPTH_MAX - yOffset;
depth += COMPONENT_PLANE_OBJECT_DEPTH_MIN;
physics->position[2] = depth;
}
void
_component_plane_object_bounds_set(ComponentPlaneObject* self, ECS* ecs)
{
ComponentPhysics* physics;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
physics->position[0] = CLAMP(physics->position[0], COMPONENT_PLANE_OBJECT_BOUNDS[0], COMPONENT_PLANE_OBJECT_BOUNDS[2]);
physics->position[1] = CLAMP(physics->position[1], COMPONENT_PLANE_OBJECT_BOUNDS[1], COMPONENT_PLANE_OBJECT_BOUNDS[3]);
}
void
component_plane_object_init
(
ComponentPlaneObject* self,
ECS* ecs,
Texture* texture,
vec2 size,
vec3 position,
f32 radius
)
{
component_game_object_init
(
ecs_component_get(ecs, COMPONENT_GAME_OBJECT, self->component.id),
ecs,
texture,
COMPONENT_PLANE_OBJECT_BUFFER,
COMPONENT_PLANE_OBJECT_ORIGIN,
size,
position
);
component_circle_collider_init
(
ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id),
(f32*)position,
radius
);
component_physics_init
(
ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id),
ecs,
position,
COMPONENT_PLANE_OBJECT_VELOCITY_MAX,
COMPONENT_PLANE_OBJECT_FRICTION
);
_component_plane_object_circle_collider_set(self, ecs);
}
void
component_plane_object_add(ComponentPlaneObject* self, ECS* ecs)
{
ecs_components_add
(
ecs,
COMPONENT_PLANE_OBJECT_DEPENDENCIES,
COMPONENT_PLANE_OBJECT_DEPENDENCY_COUNT,
self->component.id
);
}
void
component_plane_object_tick(ComponentPlaneObject* self, ECS* ecs)
{
_component_plane_object_bounds_set(self, ecs);
_component_plane_object_depth_set(self, ecs);
_component_plane_object_circle_collider_set(self, ecs);
}

View File

@ -0,0 +1,58 @@
#pragma once
#include "component_game_object.h"
#include "../physics/component_circle_collider.h"
static const RendererBuffer COMPONENT_PLANE_OBJECT_BUFFER = RENDERER_BUFFER_WORLD;
static const f32 COMPONENT_PLANE_OBJECT_FRICTION = 0.985f;
static const f32 COMPONENT_PLANE_OBJECT_DEPTH_Y_OFFSET_MULTIPLIER = 0.1f;
static const f32 COMPONENT_PLANE_OBJECT_DEPTH_MIN = 0.3f;
static const f32 COMPONENT_PLANE_OBJECT_DEPTH_MAX = 0.4f;
static const vec3 COMPONENT_PLANE_OBJECT_VELOCITY_MAX = {0.0f, 0.0f, 0.0f};
static const vec4 COMPONENT_PLANE_OBJECT_BOUNDS = {250.0f, 250.0f, 6300.0f, 3100.0f};
#define COMPONENT_PLANE_OBJECT_ORIGIN ORIGIN_CENTER
typedef struct ComponentPlaneObject
{
Component component;
} ComponentPlaneObject;
void
component_plane_object_init
(
ComponentPlaneObject* self,
ECS* ecs,
Texture* texture,
vec2 size,
vec3 position,
f32 radius
);
void component_plane_object_add(ComponentPlaneObject* self, ECS* ecs);
void component_plane_object_delete(ComponentPlaneObject* self, ECS* ecs);
void component_plane_object_tick(ComponentPlaneObject* self, ECS* ecs);
#define COMPONENT_PLANE_OBJECT_DEPENDENCY_COUNT 2
static const ComponentType COMPONENT_PLANE_OBJECT_DEPENDENCIES[COMPONENT_PLANE_OBJECT_DEPENDENCY_COUNT] =
{
COMPONENT_GAME_OBJECT,
COMPONENT_CIRCLE_COLLIDER
};
static const ComponentInfo COMPONENT_PLANE_OBJECT_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_plane_object_add,
NULL,
(ECSFunction)component_plane_object_tick,
NULL,
NULL
}
},
.type = COMPONENT_PLANE_OBJECT,
.size = sizeof(ComponentPlaneObject)
};

View File

@ -0,0 +1,148 @@
#include "component_player_control.h"
void _component_player_control_movement_tick(ComponentPlayerControl* self, ECS* ecs);
void _component_player_control_movement(ComponentPlayerControl* self, ECS* ecs);
void _component_player_control_lunge(ComponentPlayerControl* self, ECS* ecs);
void _component_player_control_lunge_tick(ComponentPlayerControl* self, ECS* ecs);
static vec2 SIZE = {64.0f, 64.0f};
static vec3 POSITION = {0.0f, 0.0f, 0.0f};
void
component_player_control_add(ComponentPlayerControl* self, ECS* ecs)
{
ecs_components_add(ecs, COMPONENT_PLAYER_CONTROL_DEPENDENCIES, COMPONENT_PLAYER_CONTROL_DEPENDENCY_COUNT, self->component.id);
self->lungeTimerID = entity_timer_add(ecs, COMPONENT_PLAYER_CONTROL_LUNGE_TIMER_MAX);
}
void
component_player_control_delete(ComponentPlayerControl* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->lungeTimerID);
}
void
_component_player_control_movement(ComponentPlayerControl* self, ECS* ecs)
{
ComponentPhysics* physics;
ComponentWorldObject* worldObject;
vec2 mousePosition;
vec2 physicsPosition;
f32 velocityGain;
f32 distanceFromMouse;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
physicsPosition[0] = physics->position[0];
physicsPosition[1] = physics->position[1];
mouse_buffer_position_get(&ecs->input->mouse, RENDERER_BUFFER_WORLD, ecs->renderer, mousePosition);
worldObject->angle = mouse_angle_from_buffer_position_get(&ecs->input->mouse, RENDERER_BUFFER_WORLD, ecs->renderer, physicsPosition);
velocityGain = COMPONENT_PLAYER_CONTROL_VELOCITY_DEFAULT;
distanceFromMouse = DISTANCE_2D
(
physicsPosition[0],
mousePosition[0],
physicsPosition[1],
mousePosition[1]
);
if (distanceFromMouse < COMPONENT_PLAYER_CONTROL_VELOCITY_DISTANCE_MAX)
{
f32 nextPositionDistance;
velocityGain *= (distanceFromMouse / COMPONENT_PLAYER_CONTROL_VELOCITY_DISTANCE_MAX);
nextPositionDistance = component_physics_next_position_distance_get(physics, ecs);
if (nextPositionDistance < COMPONENT_PLAYER_CONTROL_VELOCITY_STOP_THRESHOLD)
{
velocityGain = 0.0f;
glm_vec2_zero(physics->velocity);
}
}
physics->velocity[0] += velocityGain * cos(worldObject->angle);
physics->velocity[1] += velocityGain * sin(worldObject->angle);
}
void
_component_player_control_movement_tick(ComponentPlayerControl* self, ECS* ecs)
{
ComponentWorldObject* worldObject;
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
if (!worldObject->isAirborne)
_component_player_control_movement(self, ecs);
}
void
_component_player_control_lunge(ComponentPlayerControl* self, ECS* ecs)
{
ComponentPhysics* physics;
ComponentWorldObject* worldObject;
vec2 physicsPosition;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
physicsPosition[0] = physics->position[0];
physicsPosition[1] = physics->position[1];
worldObject->angle = mouse_angle_from_buffer_position_get(&ecs->input->mouse, RENDERER_BUFFER_WORLD, ecs->renderer, physicsPosition);
physics->velocity[0] = COMPONENT_PLAYER_CONTROL_LUNGE_VELOCITY * cos(worldObject->angle);
physics->velocity[1] = COMPONENT_PLAYER_CONTROL_LUNGE_VELOCITY * sin(worldObject->angle);
worldObject->heightOffsetVelocity += COMPONENT_PLAYER_CONTROL_LUNGE_HEIGHT_OFFSET_VELOCITY;
worldObject->isAirborne = true;
worldObject->heightOffset += COMPONENT_PLAYER_CONTROL_LUNGE_HEIGHT_OFFSET_VELOCITY;
}
void
_component_player_control_lunge_tick(ComponentPlayerControl* self, ECS* ecs)
{
self->isLunge = false;
if (control_pressed(ecs->control, CONTROL_ACTION_SECONDARY))
{
ComponentTimer* lungeTimer;
ComponentStamina* stamina;
ComponentWorldObject* worldObject;
lungeTimer = ecs_component_get(ecs, COMPONENT_TIMER, self->lungeTimerID);
stamina = ecs_component_get(ecs, COMPONENT_STAMINA, self->component.id);
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, self->component.id);
if
(
lungeTimer->isFinished &&
stamina->value >= COMPONENT_PLAYER_CONTROL_LUNGE_STAMINA_COST &&
!worldObject->isAirborne
)
{
component_timer_init(lungeTimer, ecs, COMPONENT_PLAYER_CONTROL_LUNGE_TIMER_MAX);
stamina->value -= COMPONENT_PLAYER_CONTROL_LUNGE_STAMINA_COST;
self->isLunge = true;
}
}
if (self->isLunge)
_component_player_control_lunge(self, ecs);
}
void
component_player_control_tick(ComponentPlayerControl* self, ECS* ecs)
{
_component_player_control_movement_tick(self, ecs);
_component_player_control_lunge_tick(self, ecs);
}

View File

@ -0,0 +1,50 @@
#pragma once
#include "component_world_object.h"
#include "component_stamina.h"
#include "../../entity/visual/entity_sprite.h"
#include "../../entity/utility/entity_timer.h"
static const f32 COMPONENT_PLAYER_CONTROL_VELOCITY_DEFAULT = 1.0f;
static const f32 COMPONENT_PLAYER_CONTROL_VELOCITY_DISTANCE_MAX = 500.0f;
static const f32 COMPONENT_PLAYER_CONTROL_VELOCITY_IN_CIRCLE_MULTIPLIER = 0.9f;
static const f32 COMPONENT_PLAYER_CONTROL_VELOCITY_STOP_THRESHOLD = 3.0f;
static const f32 COMPONENT_PLAYER_CONTROL_LUNGE_VELOCITY = 50.0f;
static const f32 COMPONENT_PLAYER_CONTROL_LUNGE_HEIGHT_OFFSET_VELOCITY = 10.0f;
static const s32 COMPONENT_PLAYER_CONTROL_LUNGE_STAMINA_COST = 25;
static const s32 COMPONENT_PLAYER_CONTROL_LUNGE_TIMER_MAX = 10;
typedef struct ComponentPlayerControl
{
Component component;
bool isLunge;
EntityID lungeTimerID;
} ComponentPlayerControl;
void component_player_control_add(ComponentPlayerControl* self, ECS* ecs);
void component_player_control_tick(ComponentPlayerControl* self, ECS* ecs);
#define COMPONENT_PLAYER_CONTROL_DEPENDENCY_COUNT 2
static const ComponentType COMPONENT_PLAYER_CONTROL_DEPENDENCIES[COMPONENT_PLAYER_CONTROL_DEPENDENCY_COUNT] =
{
COMPONENT_WORLD_OBJECT,
COMPONENT_STAMINA,
};
static const ComponentInfo COMPONENT_PLAYER_CONTROL_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_player_control_add,
NULL,
(ECSFunction)component_player_control_tick,
NULL,
NULL
}
},
.type = COMPONENT_PLAYER_CONTROL,
.size = sizeof(ComponentPlayerControl)
};

View File

@ -0,0 +1,16 @@
#include "component_power.h"
void
component_power_init(ComponentPower* self, ECS* ecs, f32 max, f32 gain)
{
self->value = max;
self->max = max;
self->gain = gain;
}
void
component_power_tick(ComponentPower* self, ECS* ecs)
{
self->value += self->gain;
self->value = MAX(self->value, self->max);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "../../ecs_entity.h"
typedef struct ComponentPower
{
Component component;
f32 value;
f32 max;
f32 gain;
} ComponentPower;
void component_power_tick(ComponentPower* self, ECS* ecs);
void component_power_init(ComponentPower* self, ECS* ecs, f32 max, f32 gain);
static const ComponentInfo COMPONENT_POWER_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_power_tick,
NULL,
NULL
}
},
.type = COMPONENT_POWER,
.size = sizeof(ComponentPower)
};

View File

@ -0,0 +1,46 @@
#include "component_solid.h"
void _component_solid_collisions_tick(ComponentSolid* self, ECS* ecs);
void
_component_solid_collisions_tick(ComponentSolid* self, ECS* ecs)
{
ComponentCircleCollider* circleCollider;
ComponentPhysics* physics;
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
for (s32 i = 0; i < (s32)circleCollider->collisions.count; i++)
{
ComponentPhysics* collidePhysics;
ComponentCircleCollider* collideCircleCollider;
EntityID* id;
f32 angle;
id = vector_get(&circleCollider->collisions, i);
collidePhysics = ecs_component_get(ecs, COMPONENT_PHYSICS, *id);
collideCircleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, *id);
angle = ATAN
(
physics->position[0],
collidePhysics->position[0],
physics->position[1],
collidePhysics->position[1]
);
collidePhysics->position[0] = physics->position[0] + ((circleCollider->circle.radius * 2) * cos(angle));
collidePhysics->position[1] = physics->position[1] + ((circleCollider->circle.radius * 2) * sin(angle));
collidePhysics->position[0] += (collideCircleCollider->circle.radius * 2) * cos(angle);
collidePhysics->position[1] += (collideCircleCollider->circle.radius * 2) * sin(angle);
}
}
void
component_solid_tick(ComponentSolid* self, ECS* ecs)
{
_component_solid_collisions_tick(self, ecs);
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "component_world_object.h"
typedef struct ComponentSolid
{
Component component;
} ComponentSolid;
void component_solid_tick(ComponentSolid* self, ECS* ecs);
static const ComponentInfo COMPONENT_SOLID_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_solid_tick,
NULL,
NULL
}
},
.type = COMPONENT_SOLID,
.size = sizeof(ComponentSolid)
};

View File

@ -0,0 +1,13 @@
#include "component_stage.h"
void
component_stage_init(ComponentStage* self, ECS* ecs, u32 value)
{
self->value = value;
}
void
component_stage_tick(ComponentStage* self, ECS* ecs)
{
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "../../ecs_entity.h"
typedef struct ComponentStage
{
Component component;
u32 value;
} ComponentStage;
void component_stage_tick(ComponentStage* self, ECS* ecs);
void component_stage_init(ComponentStage* self, ECS* ecs, u32 value);
static const ComponentInfo COMPONENT_STAGE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_stage_tick,
NULL,
NULL
}
},
.type = COMPONENT_STAGE,
.size = sizeof(ComponentStage)
};

View File

@ -0,0 +1,16 @@
#include "component_stamina.h"
void
component_stamina_init(ComponentStamina* self, ECS* ecs, f32 max, f32 gain)
{
self->value = max;
self->max = max;
self->gain = gain;
}
void
component_stamina_tick(ComponentStamina* self, ECS* ecs)
{
self->value += self->gain;
self->value = MAX(self->value, self->max);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "../../ecs_entity.h"
typedef struct ComponentStamina
{
Component component;
f32 value;
f32 max;
f32 gain;
} ComponentStamina;
void component_stamina_tick(ComponentStamina* self, ECS* ecs);
void component_stamina_init(ComponentStamina* self, ECS* ecs, f32 max, f32 gain);
static const ComponentInfo COMPONENT_STAMINA_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_stamina_tick,
NULL,
NULL
}
},
.type = COMPONENT_STAMINA,
.size = sizeof(ComponentStamina)
};

View File

@ -0,0 +1,37 @@
#include "component_take_food.h"
void
component_take_food_tick(ComponentTakeFood* self, ECS* ecs)
{
ComponentCircleCollider* circleCollider;
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
self->isTakeFood = false;
ecs->isLog = false;
for (s32 i = 0; i < (s32)circleCollider->collisions.count; i++)
{
ComponentFood* collideFood;
ComponentFood* food;
EntityID* id;
id = vector_get(&circleCollider->collisions, i);
collideFood = ecs_component_get(ecs, COMPONENT_FOOD, *id);
food = ecs_component_get(ecs, COMPONENT_FOOD, self->component.id);
if (!collideFood)
continue;
if (collideFood->value > 0)
{
food->value += (collideFood->value * food->multiplier);
collideFood->value = 0;
self->isTakeFood = true;
}
}
ecs->isLog = true;
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "component_world_object.h"
#include "component_food.h"
typedef struct ComponentTakeFood
{
Component component;
bool isTakeFood;
} ComponentTakeFood;
void component_take_food_tick(ComponentTakeFood* self, ECS* ecs);
static const ComponentInfo COMPONENT_TAKE_FOOD_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_take_food_tick,
NULL,
NULL
}
},
.type = COMPONENT_TAKE_FOOD,
.size = sizeof(ComponentTakeFood)
};

View File

@ -0,0 +1,12 @@
#include "component_threshold.h"
void
component_threshold_tick(ComponentThreshold* self, ECS* ecs)
{
}
void
component_threshold_init(ComponentThreshold* self, ECS* ecs, u32 value)
{
self->value = value;
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "../../ecs_entity.h"
typedef struct ComponentThreshold
{
Component component;
s32 value;
s32 max;
} ComponentThreshold;
void component_threshold_tick(ComponentThreshold* self, ECS* ecs);
void component_threshold_init(ComponentThreshold* self, ECS* ecs, u32 value);
static const ComponentInfo COMPONENT_THRESHOLD_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_threshold_tick,
NULL,
NULL
}
},
.type = COMPONENT_THRESHOLD,
.size = sizeof(ComponentThreshold)
};

View File

@ -0,0 +1,213 @@
#include "component_world_object.h"
void _component_world_object_shadow_set(ComponentWorldObject* self, ECS* ecs);
void _component_world_object_height_offset_set(ComponentWorldObject* self, ECS* ecs);
void _component_world_object_depth_set(ComponentWorldObject* self, ECS* ecs);
void _component_world_object_circle_collider_set(ComponentWorldObject* self, ECS* ecs);
void _component_world_object_direction_set(ComponentWorldObject* self, ECS* ecs);
void
_component_world_object_shadow_set(ComponentWorldObject* self, ECS* ecs)
{
ComponentTextureQuad* shadowTextureQuad;
ComponentTextureQuad* textureQuad;
ComponentCircleCollider* circleCollider;
ComponentPhysics* physics;
f32 shadowScale;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
shadowTextureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->shadowID);
shadowTextureQuad->size[0] = circleCollider->circle.radius;
shadowTextureQuad->size[1] = COMPONENT_WORLD_OBJECT_SHADOW_HEIGHT;
shadowTextureQuad->position[0] = physics->position[0];
shadowTextureQuad->position[1] = physics->position[1] + (textureQuad->size[1] / 2.0f);
shadowTextureQuad->position[2] = physics->position[2] + COMPONENT_WORLD_OBJECT_SHADOW_Z_OFFSET;
shadowScale = 1 - (self->heightOffset * COMPONENT_WORLD_OBJECT_HEIGHT_OFFSET_SHADOW_SCALE_MULTIPLIER);
shadowTextureQuad->scale[0] = shadowScale;
shadowTextureQuad->scale[1] = shadowScale;
shadowTextureQuad->scale[0] = MIN(shadowTextureQuad->scale[0], 0);
shadowTextureQuad->scale[1] = MIN(shadowTextureQuad->scale[1], 0);
}
void
_component_world_object_height_offset_set(ComponentWorldObject* self, ECS* ecs)
{
ComponentTextureQuad* textureQuad;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
if (self->isGravityAffected)
self->heightOffsetVelocity -= COMPONENT_WORLD_OBJECT_GRAVITY;
self->heightOffset += self->heightOffsetVelocity;
if (self->heightOffset <= 0.0f)
{
self->isAirborne = false;
self->heightOffset = 0.0f;
self->heightOffsetVelocity = 0.0f;
}
else
self->isAirborne = true;
textureQuad->offset[1] = -self->heightOffset;
}
void
_component_world_object_circle_collider_set(ComponentWorldObject* self, ECS* ecs)
{
ComponentCircleCollider* circleCollider;
ComponentTextureQuad* textureQuad;
ComponentPhysics* physics;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id);
circleCollider->circle.position[0] = physics->position[0];
circleCollider->circle.position[1] = physics->position[1] + (textureQuad->size[1] / 2.0f);
}
void
_component_world_object_depth_set(ComponentWorldObject* self, ECS* ecs)
{
ComponentPhysics* physics;
ComponentTextureQuad* textureQuad;
f32 depth;
f32 yOffset;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
yOffset = COMPONENT_WORLD_OBJECT_DEPTH_Y_OFFSET_MULTIPLIER * ((physics->position[1] + textureQuad->size[1]) / COMPONENT_WORLD_OBJECT_BOUNDS[3]);
depth = COMPONENT_WORLD_OBJECT_DEPTH_MAX - yOffset;
depth += COMPONENT_WORLD_OBJECT_DEPTH_MIN;
physics->position[2] = depth;
}
void
_component_world_object_bounds_set(ComponentWorldObject* self, ECS* ecs)
{
ComponentPhysics* physics;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
physics->position[0] = CLAMP(physics->position[0], COMPONENT_WORLD_OBJECT_BOUNDS[0], COMPONENT_WORLD_OBJECT_BOUNDS[2]);
physics->position[1] = CLAMP(physics->position[1], COMPONENT_WORLD_OBJECT_BOUNDS[1], COMPONENT_WORLD_OBJECT_BOUNDS[3]);
}
void
_component_world_object_direction_set(ComponentWorldObject* self, ECS* ecs)
{
if
(
(self->angle >= 0.0f && self->angle < PI_FOURTH) ||
(self->angle >= PI + PI_HALF + PI_FOURTH && self->angle < TAU)
)
self->direction = DIRECTION_RIGHT;
if (self->angle >= PI_FOURTH && self->angle < PI_HALF + PI_FOURTH)
self->direction = DIRECTION_DOWN;
if (self->angle >= PI_HALF + PI_FOURTH && self->angle < PI + PI_FOURTH)
self->direction = DIRECTION_LEFT;
if (self->angle >= PI + PI_FOURTH && self->angle < PI + PI_HALF + PI_FOURTH)
self->direction = DIRECTION_UP;
}
void
component_world_object_init
(
ComponentWorldObject* self,
ECS* ecs,
Texture* texture,
vec2 size,
vec3 position,
f32 heightOffset,
f32 radius
)
{
component_game_object_init
(
ecs_component_get(ecs, COMPONENT_GAME_OBJECT, self->component.id),
ecs,
texture,
COMPONENT_WORLD_OBJECT_BUFFER,
COMPONENT_WORLD_OBJECT_ORIGIN,
size,
position
);
component_circle_collider_init
(
ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, self->component.id),
(f32*)position,
radius
);
component_physics_init
(
ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id),
ecs,
position,
COMPONENT_WORLD_OBJECT_VELOCITY_MAX,
COMPONENT_WORLD_OBJECT_FRICTION
);
self->shadowID = entity_sprite_add
(
ecs,
&ecs->resources->textures[TEXTURE_SHADOW],
COMPONENT_WORLD_OBJECT_BUFFER,
COMPONENT_WORLD_OBJECT_ORIGIN,
(f32*)size,
(f32*)position
);
self->heightOffset = heightOffset;
self->isGravityAffected = true;
_component_world_object_shadow_set(self, ecs);
_component_world_object_height_offset_set(self, ecs);
_component_world_object_circle_collider_set(self, ecs);
}
void
component_world_object_add(ComponentWorldObject* self, ECS* ecs)
{
ecs_components_add
(
ecs,
COMPONENT_WORLD_OBJECT_DEPENDENCIES,
COMPONENT_WORLD_OBJECT_DEPENDENCY_COUNT,
self->component.id
);
}
void
component_world_object_delete(ComponentWorldObject* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->shadowID);
}
void
component_world_object_tick(ComponentWorldObject* self, ECS* ecs)
{
_component_world_object_depth_set(self, ecs);
_component_world_object_shadow_set(self, ecs);
_component_world_object_height_offset_set(self, ecs);
_component_world_object_bounds_set(self, ecs);
_component_world_object_direction_set(self, ecs);
_component_world_object_circle_collider_set(self, ecs);
}

View File

@ -0,0 +1,72 @@
#pragma once
#include "component_game_object.h"
#include "../physics/component_circle_collider.h"
#include "../../entity/visual/entity_sprite.h"
static const RendererBuffer COMPONENT_WORLD_OBJECT_BUFFER = RENDERER_BUFFER_WORLD;
static const f32 COMPONENT_WORLD_OBJECT_SHADOW_Z_OFFSET = 0.001f;
static const f32 COMPONENT_WORLD_OBJECT_HEIGHT_OFFSET_SHADOW_SCALE_MULTIPLIER = 0.005f;
static const f32 COMPONENT_WORLD_OBJECT_FRICTION = 0.985f;
static const f32 COMPONENT_WORLD_OBJECT_SHADOW_HEIGHT = 32.0f;
static const f32 COMPONENT_WORLD_OBJECT_DEPTH_Y_OFFSET_MULTIPLIER = 0.1f;
static const f32 COMPONENT_WORLD_OBJECT_DEPTH_MIN = 0.1f;
static const f32 COMPONENT_WORLD_OBJECT_DEPTH_MAX = 0.2f;
static const f32 COMPONENT_WORLD_OBJECT_GRAVITY = 1.0f;
static const vec3 COMPONENT_WORLD_OBJECT_VELOCITY_MAX = {100.0f, 100.0f, 100.0f};
static const vec4 COMPONENT_WORLD_OBJECT_BOUNDS = {250.0f, 250.0f, 6300.0f, 3100.0f};
#define COMPONENT_WORLD_OBJECT_ORIGIN ORIGIN_CENTER
typedef struct ComponentWorldObject
{
Component component;
EntityID shadowID;
f32 heightOffset;
f32 heightOffsetVelocity;
f32 angle;
Direction direction;
bool isAirborne;
bool isGravityAffected;
} ComponentWorldObject;
void
component_world_object_init
(
ComponentWorldObject* self,
ECS* ecs,
Texture* texture,
vec2 size,
vec3 position,
f32 heightOffset,
f32 radius
);
void component_world_object_add(ComponentWorldObject* self, ECS* ecs);
void component_world_object_delete(ComponentWorldObject* self, ECS* ecs);
void component_world_object_tick(ComponentWorldObject* self, ECS* ecs);
#define COMPONENT_WORLD_OBJECT_DEPENDENCY_COUNT 2
static const ComponentType COMPONENT_WORLD_OBJECT_DEPENDENCIES[COMPONENT_WORLD_OBJECT_DEPENDENCY_COUNT] =
{
COMPONENT_GAME_OBJECT,
COMPONENT_CIRCLE_COLLIDER
};
static const ComponentInfo COMPONENT_WORLD_OBJECT_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_world_object_add,
(ECSFunction)component_world_object_delete,
(ECSFunction)component_world_object_tick,
NULL,
NULL
}
},
.type = COMPONENT_WORLD_OBJECT,
.size = sizeof(ComponentWorldObject)
};

View File

@ -0,0 +1,66 @@
#include "component_circle_collider.h"
void _component_circle_collider_collisions_tick(ComponentCircleCollider* self, ECS* ecs);
void
_component_circle_collider_collisions_tick(ComponentCircleCollider* self, ECS* ecs)
{
vector_clear(&self->collisions);
for (s32 i = 0; i < (s32)ecs->lists[COMPONENT_CIRCLE_COLLIDER].components.count; i++)
{
EntityID* id;
ComponentCircleCollider* circleCollider;
id = vector_get(&ecs->lists[COMPONENT_CIRCLE_COLLIDER].components, i);
if (*id == self->component.id)
continue;
circleCollider = ecs_component_get(ecs, COMPONENT_CIRCLE_COLLIDER, *id);
if (circle_collide_check(&self->circle, &circleCollider->circle))
vector_push(&self->collisions, id);
}
}
bool
component_circle_collider_collide_check(ComponentCircleCollider* self, ECS* ecs, EntityID id)
{
for (s32 i = 0; i < (s32)self->collisions.count; i++)
{
EntityID* checkID;
checkID = vector_get(&self->collisions, i);
if (*checkID == id)
return true;
}
return false;
}
void
component_circle_collider_add(ComponentCircleCollider* self, ECS* ecs)
{
vector_init(&self->collisions, sizeof(EntityID));
}
void
component_circle_collider_delete(ComponentCircleCollider* self, ECS* ecs)
{
vector_free(&self->collisions);
}
void
component_circle_collider_tick(ComponentCircleCollider* self, ECS* ecs)
{
_component_circle_collider_collisions_tick(self, ecs);
}
void
component_circle_collider_init(ComponentCircleCollider* self, vec2 position, f32 radius)
{
glm_vec2_copy(position, self->circle.position);
self->circle.radius = radius;
}

View File

@ -0,0 +1,42 @@
#pragma once
#include "../../ecs_entity.h"
#include "../../../../engine/circle.h"
typedef struct ComponentCircleCollider
{
Component component;
Circle circle;
Vector collisions; /* EntityID */
} ComponentCircleCollider;
void component_circle_collider_add(ComponentCircleCollider* self, ECS* ecs);
void component_circle_collider_delete(ComponentCircleCollider* self, ECS* ecs);
void component_circle_collider_tick(ComponentCircleCollider* self, ECS* ecs);
bool component_circle_collider_collide_check(ComponentCircleCollider* self, ECS* ecs, EntityID id);
void component_circle_collider_init
(
ComponentCircleCollider* self,
vec2 position,
f32 radius
);
static const ComponentInfo COMPONENT_CIRCLE_COLLIDER_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_circle_collider_add,
(ECSFunction)component_circle_collider_delete,
(ECSFunction)component_circle_collider_tick,
NULL,
NULL
}
},
.type = COMPONENT_CIRCLE_COLLIDER,
.size = sizeof(ComponentCircleCollider)
};

View File

@ -0,0 +1,21 @@
#include "component_copy_mouse_position.h"
void
component_copy_mouse_position_add(ComponentCopyMousePosition* self, ECS* ecs)
{
component_copy_mouse_position_tick(self, ecs);
}
void
component_copy_mouse_position_tick(ComponentCopyMousePosition* self, ECS* ecs)
{
ComponentPhysics* physics;
vec2 mousePosition;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->component.id);
mouse_buffer_position_get(&ecs->input->mouse, RENDERER_BUFFER_CURSOR, ecs->renderer, mousePosition);
physics->position[0] = mousePosition[0];
physics->position[1] = mousePosition[1];
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "component_physics.h"
#include "../../../input/input.h"
typedef struct ComponentCopyMousePosition
{
Component component;
} ComponentCopyMousePosition;
void component_copy_mouse_position_add(ComponentCopyMousePosition* self, ECS* ecs);
void component_copy_mouse_position_tick(ComponentCopyMousePosition* self, ECS* ecs);
static const ComponentInfo COMPONENT_COPY_MOUSE_POSITION_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_copy_mouse_position_add,
NULL,
(ECSFunction)component_copy_mouse_position_tick,
NULL,
NULL
}
},
.type = COMPONENT_COPY_MOUSE_POSITION,
.size = sizeof(ComponentCopyMousePosition)
};

View File

@ -0,0 +1,67 @@
#include "component_physics.h"
void
component_physics_tick(ComponentPhysics* self, ECS* ecs)
{
glm_vec3_add(self->velocity, self->position, self->position);
glm_vec3_scale(self->velocity, self->friction, self->velocity);
self->velocity[0] = MAX(self->velocity[0], self->velocityMax[0]);
self->velocity[1] = MAX(self->velocity[1], self->velocityMax[1]);
self->velocity[2] = MAX(self->velocity[2], self->velocityMax[2]);
if
(
self->velocity[0] != 0.0f ||
self->velocity[1] != 0.0f
)
self->isMoving = true;
else
self->isMoving = false;
}
void
component_physics_next_position_get(ComponentPhysics* self, ECS* ecs, vec2 position)
{
position[0] = self->position[0] + self->velocity[0];
position[1] = self->position[1] + self->velocity[1];
}
f32
component_physics_next_position_distance_get(ComponentPhysics* self, ECS* ecs)
{
vec2 position;
component_physics_next_position_get(self, ecs, position);
return DISTANCE_2D
(
position[0],
self->position[0],
position[1],
self->position[1]
);
}
void
component_physics_add(ComponentPhysics* self, ECS* ecs)
{
self->friction = COMPONENT_PHYSICS_FRICTION_DEFAULT;
glm_vec3_copy((f32*)COMPONENT_PHYSICS_VELOCITY_MAX_DEFAULT, self->velocityMax);
}
void
component_physics_init
(
ComponentPhysics* self,
ECS* ecs,
const vec3 position,
const vec3 velocityMax,
f32 friction
)
{
glm_vec3_copy((f32*)position, self->position);
glm_vec3_copy((f32*)velocityMax, self->velocityMax);
self->friction = friction;
}

View File

@ -0,0 +1,48 @@
#pragma once
#include "../../ecs_entity.h"
#include "../../../input/control.h"
static const f32 COMPONENT_PHYSICS_FRICTION_DEFAULT = 1.0f;
static const vec3 COMPONENT_PHYSICS_VELOCITY_MAX_DEFAULT = {1000.0f, 1000.0f, 1000.0f};
typedef struct ComponentPhysics
{
Component component;
vec3 position;
vec3 velocity;
vec3 velocityMax;
f32 friction;
bool isMoving;
} ComponentPhysics;
void component_physics_tick(ComponentPhysics* self, ECS* ecs);
void component_physics_next_position_get(ComponentPhysics* self, ECS* ecs, vec2 position);
f32 component_physics_next_position_distance_get(ComponentPhysics* self, ECS* ecs);
void component_physics_init
(
ComponentPhysics* self,
ECS* ecs,
const vec3 position,
const vec3 velocityMax,
f32 friction
);
static const ComponentInfo COMPONENT_PHYSICS_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_physics_tick,
NULL,
NULL
}
},
.type = COMPONENT_PHYSICS,
.size = sizeof(ComponentPhysics)
};

View File

@ -0,0 +1,48 @@
#include "component_button.h"
void
component_button_add(ComponentButton* self, ECS* ecs)
{
for (s32 i = 0; i < COMPONENT_BUTTON_DEPENDENCY_COUNT; i++)
ecs_component_add(ecs, COMPONENT_BUTTON_DEPENDENCIES[i], self->component.id);
}
void
component_button_tick(ComponentButton* self, ECS* ecs)
{
ComponentTextureQuad* textureQuad;
vec2 mousePosition;
Rectangle rectangle;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
mouse_buffer_position_get(&ecs->input->mouse, textureQuad->buffer, ecs->renderer, mousePosition);
component_texture_quad_rectangle_get(textureQuad, &rectangle);
if (rectangle_has_point(&rectangle, mousePosition))
{
self->state = BUTTON_STATE_HOVER;
glm_vec4_copy((f32*)COMPONENT_BUTTON_STATE_HOVER_COLOR, textureQuad->color);
if (control_held(ecs->control, CONTROL_ACTION_PRIMARY))
{
if (self->state != BUTTON_STATE_PRESSED)
{
self->isJustPressed = true;
sound_play(&ecs->resources->sounds[SOUND_SELECT]);
}
else
self->isJustPressed = false;
glm_vec4_copy((f32*)COMPONENT_BUTTON_STATE_PRESSED_COLOR, textureQuad->color);
self->state = BUTTON_STATE_PRESSED;
}
}
else
{
glm_vec4_copy((f32*)COMPONENT_BUTTON_STATE_NONE_COLOR, textureQuad->color);
self->state = BUTTON_STATE_NONE;
}
}

View File

@ -0,0 +1,51 @@
#pragma once
#include "../visual/component_texture_quad.h"
#include "../physics/component_physics.h"
#include "../../entity/utility/entity_timer.h"
#define BUTTON_STATE_COUNT BUTTON_STATE_PRESSED + 1
typedef enum ButtonState
{
BUTTON_STATE_NONE,
BUTTON_STATE_HOVER,
BUTTON_STATE_PRESSED
} ButtonState;
typedef struct ComponentButton
{
Component component;
ButtonState state;
bool isJustPressed;
} ComponentButton;
void component_button_add(ComponentButton* self, ECS* ecs);
void component_button_tick(ComponentButton* self, ECS* ecs);
#define COMPONENT_BUTTON_DEPENDENCY_COUNT 1
static const ComponentType COMPONENT_BUTTON_DEPENDENCIES[COMPONENT_BUTTON_DEPENDENCY_COUNT] =
{
COMPONENT_TEXTURE_QUAD
};
static const ComponentInfo COMPONENT_BUTTON_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_button_add,
NULL,
(ECSFunction)component_button_tick,
NULL,
NULL
}
},
.type = COMPONENT_BUTTON,
.size = sizeof(ComponentButton)
};
static const vec4 COMPONENT_BUTTON_STATE_NONE_COLOR = {1.0f, 1.0f, 1.0f, 1.0f};
static const vec4 COMPONENT_BUTTON_STATE_HOVER_COLOR = {0.75f, 0.75f, 0.75f, 1.0f};
static const vec4 COMPONENT_BUTTON_STATE_PRESSED_COLOR = {0.5f, 0.5f, 0.5f, 1.0f};

View File

@ -0,0 +1,13 @@
#include "component_counter.h"
void
component_counter_init(ComponentCounter* self, ECS* ecs)
{
self->value = 0;
}
void
component_counter_tick(ComponentCounter* self, ECS* ecs)
{
self->value++;
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "../../ecs_entity.h"
typedef struct ComponentCounter
{
Component component;
s32 value;
} ComponentCounter;
void component_counter_init(ComponentCounter* self, ECS* ecs);
void component_counter_tick(ComponentCounter* self, ECS* ecs);
static const ComponentInfo COMPONENT_COUNTER_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_counter_tick,
NULL,
NULL,
}
},
.type = COMPONENT_COUNTER,
.size = sizeof(ComponentCounter)
};

View File

@ -0,0 +1,43 @@
#include "component_delete_on_timer.h"
void
component_delete_on_timer_add(ComponentDeleteOnTimer* self, ECS* ecs)
{
ComponentTimer* timer;
self->timerID = entity_timer_add(ecs, -1);
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timerID);
timer->component.isDisabled = true;
}
void
component_delete_on_timer_delete(ComponentDeleteOnTimer* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->timerID);
}
void
component_delete_on_timer_init(ComponentDeleteOnTimer* self, ECS* ecs, s32 value)
{
ComponentTimer* timer;
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timerID);
component_timer_init(timer, ecs, value);
timer->component.isDisabled = false;
}
void
component_delete_on_timer_tick(ComponentDeleteOnTimer* self, ECS* ecs)
{
ComponentTimer* timer;
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timerID);
if (timer->isFinished)
ecs_entity_delete(ecs, self->component.id);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "../../entity/utility/entity_timer.h"
typedef struct ComponentDeleteOnTimer
{
Component component;
EntityID timerID;
} ComponentDeleteOnTimer;
void component_delete_on_timer_init(ComponentDeleteOnTimer* self, ECS* ecs, s32 value);
void component_delete_on_timer_add(ComponentDeleteOnTimer* self, ECS* ecs);
void component_delete_on_timer_delete(ComponentDeleteOnTimer* self, ECS* ecs);
void component_delete_on_timer_tick(ComponentDeleteOnTimer* self, ECS* ecs);
static const ComponentInfo COMPONENT_DELETE_ON_TIMER_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_delete_on_timer_add,
(ECSFunction)component_delete_on_timer_delete,
(ECSFunction)component_delete_on_timer_tick,
NULL,
NULL,
}
},
.type = COMPONENT_DELETE_ON_TIMER,
.size = sizeof(ComponentDeleteOnTimer)
};

View File

@ -0,0 +1,25 @@
#include "component_timer.h"
void
component_timer_init(ComponentTimer* self, ECS* ecs, s32 value)
{
self->value = value;
self->startValue = value;
self->isFinished = false;
}
void
component_timer_tick(ComponentTimer* self, ECS* ecs)
{
if (self->isFinished)
return;
if (self->value <= 0)
{
self->isFinished = true;
self->value = 0;
return;
}
self->value--;
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "../../ecs_entity.h"
typedef struct ComponentTimer
{
Component component;
s32 value;
s32 startValue;
bool isFinished;
} ComponentTimer;
void component_timer_init(ComponentTimer* self, ECS* ecs, s32 value);
void component_timer_tick(ComponentTimer* self, ECS* ecs);
static const ComponentInfo COMPONENT_TIMER_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_timer_tick,
NULL,
NULL,
}
},
.type = COMPONENT_TIMER,
.size = sizeof(ComponentTimer)
};

View File

@ -0,0 +1,33 @@
#include "component_atlas.h"
void
component_atlas_uv_get(ComponentAtlas* self, Texture* texture, vec2 uvMin, vec2 uvMax)
{
vec2 position;
position[0] = (self->index % self->size[1]) * self->frameSize[0];
position[1] = (s32)((f32)self->index / self->size[1]) * self->frameSize[1];
uvMin[0] = (f32)position[0] / texture->size[0];
uvMin[1] = (f32)position[1] / texture->size[1];
uvMax[0] = (f32)(position[0] + self->frameSize[0]) / texture->size[0];
uvMax[1] = (f32)(position[1] + self->frameSize[1]) / texture->size[1];
}
void
component_atlas_init(ComponentAtlas* self, ECS* ecs, const ivec2 frameSize, const ivec2 size, u32 index)
{
glm_ivec2_copy((s32*)frameSize, self->frameSize);
glm_ivec2_copy((s32*)size, self->size);
self->index = index;
}
void
component_atlas_tick(ComponentAtlas* self, ECS* ecs)
{
ComponentTextureQuad* textureQuad;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
component_atlas_uv_get(self, textureQuad->texture, textureQuad->uvMin, textureQuad->uvMax);
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "component_texture_quad.h"
typedef struct ComponentAtlas
{
Component component;
ivec2 frameSize;
ivec2 size;
u32 index;
} ComponentAtlas;
void component_atlas_init(ComponentAtlas* self, ECS* ecs, const ivec2 frameSize, const ivec2 size, u32 index);
void component_atlas_tick(ComponentAtlas* self, ECS* ecs);
void component_atlas_uv_get(ComponentAtlas* self, Texture* texture, vec2 uvMin, vec2 uvMax);
static const ComponentInfo COMPONENT_ATLAS_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_atlas_tick,
NULL,
NULL,
}
},
.type = COMPONENT_ATLAS,
.size = sizeof(ComponentAtlas)
};

View File

@ -0,0 +1,66 @@
#include "component_camera_focus.h"
void
component_camera_focus_tick(ComponentCameraFocus* self, ECS* ecs)
{
ComponentPhysics* physics;
vec3 position;
//f32 velocityPercent;
//vec2 positionPercent;
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, self->entityID);
if (!physics)
return;
glm_vec3_copy(physics->position, position);
/*
positionPercent[0] = (physics->position[0] + (physics->velocity[0] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER)) / self->camera->orthographic.size[0];
positionPercent[1] = (physics->position[1] + (physics->velocity[1] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER)) / self->camera->orthographic.size[1];
*/
/*
position[0] += physics->velocity[0] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER;
position[1] += physics->velocity[1] * COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER;
*/
position[0] -= self->camera->orthographic.size[0] / 2;
position[1] -= self->camera->orthographic.size[1] / 2;
/*
position[0] += (physics->position[0]) - ((self->camera->orthographic.size[0] / 4) * (1 - self->camera->zoom));
position[1] += (physics->position[1]) - ((self->camera->orthographic.size[1] / 4) * (1 - self->camera->zoom));
*/
position[2] = 0.0f;
//velocityPercent = 0.0f;
/*
if (fabs(physics->velocity[0]) >= fabs(physics->velocity[1]))
velocityPercent = fabs(physics->velocity[0]) / physics->velocityMax[0];
else if (fabs(physics->velocity[1]) > fabs(physics->velocity[0]))
velocityPercent = fabs(physics->velocity[1]) / physics->velocityMax[1];
self->camera->zoom = COMPONENT_CAMERA_FOCUS_ZOOM_MIN;
self->camera->zoom += (velocityPercent * (COMPONENT_CAMERA_FOCUS_ZOOM_MAX - COMPONENT_CAMERA_FOCUS_ZOOM_MIN));
*/
//glm_vec3_print(position, stderr);
camera_position_set(self->camera, position);
}
void
component_camera_focus_init
(
ComponentCameraFocus* self,
ECS* ecs,
Camera* camera,
u32 entityID
)
{
self->camera = camera;
self->entityID = entityID;
}

View File

@ -0,0 +1,43 @@
#pragma once
#include "../physics/component_physics.h"
static const f32 COMPONENT_CAMERA_FOCUS_VELOCITY_MULTIPLIER = 10.0f;
static const f32 COMPONENT_CAMERA_FOCUS_VELOCITY_ZOOM_MULTIPLIER = 0.1f;
static const f32 COMPONENT_CAMERA_FOCUS_ZOOM_MAX = 0.40f;
static const f32 COMPONENT_CAMERA_FOCUS_ZOOM_MIN = 0.25f;
typedef struct ComponentCameraFocus
{
Component component;
Camera* camera;
EntityID entityID;
} ComponentCameraFocus;
void component_camera_focus_tick(ComponentCameraFocus* self, ECS* ecs);
void
component_camera_focus_init
(
ComponentCameraFocus* self,
ECS* ecs,
Camera* camera,
EntityID entityID
);
static const ComponentInfo COMPONENT_CAMERA_FOCUS_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_camera_focus_tick,
NULL,
NULL
}
},
.type = COMPONENT_CAMERA_FOCUS,
.size = sizeof(ComponentCameraFocus)
};

View File

@ -0,0 +1,109 @@
#include "component_color_change.h"
void
component_color_change_add(ComponentColorChange* self, ECS* ecs)
{
self->timerID = entity_timer_add(ecs, -1);
self->component.isDisabled = true;
}
void
component_color_change_delete(ComponentColorChange* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->timerID);
}
void
component_color_change_tick(ComponentColorChange* self, ECS* ecs)
{
ComponentTextureQuad* textureQuad;
ComponentText* text;
ComponentTimer* timer;
vec4 colorStep;
vec4* color;
vec4* colorCover;
if (self->isFinished)
return;
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timerID);
ecs->isLog = false;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
text = ecs_component_get(ecs, COMPONENT_TEXT, self->component.id);
ecs->isLog = true;
if (textureQuad)
{
color = &textureQuad->color;
colorCover = &textureQuad->colorCover;
}
else if (text)
{
color = &text->color;
colorCover = &text->colorCover;
}
else
return;
if (self->isColorCover)
glm_vec4_scale(self->colorStep, timer->value, *colorCover);
else
glm_vec4_scale(self->colorStep, timer->value, *color);
if (timer->isFinished)
{
self->isFinished = true;
if (self->isReturn)
{
if (self->isColorCover)
glm_vec4_copy(self->returnColor, *colorCover);
else
glm_vec4_copy(self->returnColor, *color);
}
return;
}
}
void
component_color_change_init(ComponentColorChange* self, ECS* ecs, const vec4 endColor, const vec4 beginColor, u32 length, bool isColorCover, bool isReturn)
{
ComponentTimer* timer;
ComponentTextureQuad* textureQuad;
ComponentText* text;
vec4 colorDifference;
ecs->isLog = false;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
text = ecs_component_get(ecs, COMPONENT_TEXT, self->component.id);
ecs->isLog = true;
glm_vec4_copy((f32*)beginColor, self->beginColor);
glm_vec4_copy((f32*)endColor, self->endColor);
if (textureQuad)
glm_vec4_copy((f32*)textureQuad->color, self->returnColor);
else if (text)
glm_vec4_copy((f32*)text->color, self->returnColor);
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timerID);
component_timer_init(timer, ecs, length);
timer->component.isDisabled = false;
glm_vec4_sub(self->endColor, self->beginColor, colorDifference);
glm_vec4_scale(colorDifference, (1.0f / length), self->colorStep);
self->isColorCover = isColorCover;
self->isReturn = isReturn;
self->isFinished = false;
self->component.isDisabled = false;
}

View File

@ -0,0 +1,51 @@
#pragma once
#include "component_texture_quad.h"
#include "component_text.h"
#include "../../entity/utility/entity_timer.h"
typedef struct ComponentColorChange
{
Component component;
vec4 beginColor;
vec4 endColor;
vec4 returnColor;
vec4 colorStep;
bool isColorCover;
bool isReturn;
bool isFinished;
EntityID timerID;
} ComponentColorChange;
void component_color_change_add(ComponentColorChange* self, ECS* ecs);
void component_color_change_delete(ComponentColorChange* self, ECS* ecs);
void component_color_change_tick(ComponentColorChange* self, ECS* ecs);
void
component_color_change_init
(
ComponentColorChange* self,
ECS* ecs,
const vec4 endColor,
const vec4 beginColor,
u32 length,
bool isColorCover,
bool isReturn
);
static const ComponentInfo COMPONENT_COLOR_CHANGE_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_color_change_add,
(ECSFunction)component_color_change_delete,
(ECSFunction)component_color_change_tick,
NULL,
NULL
}
},
.type = COMPONENT_COLOR_CHANGE,
.size = sizeof(ComponentColorChange)
};

View File

@ -0,0 +1,34 @@
#include "component_color_match.h"
void _component_color_match_set(ComponentColorMatch* self, ECS* ecs);
void
_component_color_match_set(ComponentColorMatch* self, ECS* ecs)
{
ComponentTextureQuad* matchTextureQuad;
ComponentTextureQuad* textureQuad;
matchTextureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->matchID);
if (matchTextureQuad == NULL)
return;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
glm_vec4_copy(matchTextureQuad->color, textureQuad->color);
glm_vec4_copy(matchTextureQuad->colorCover, textureQuad->colorCover);
}
void
component_color_match_tick(ComponentColorMatch* self, ECS* ecs)
{
_component_color_match_set(self, ecs);
}
void
component_color_match_init(ComponentColorMatch* self, ECS* ecs, EntityID matchID)
{
self->matchID = matchID;
_component_color_match_set(self, ecs);
}

View File

@ -0,0 +1,38 @@
#pragma once
#include "component_texture_quad.h"
typedef struct ComponentColorMatch
{
Component component;
EntityID matchID;
} ComponentColorMatch;
void component_color_match_add(ComponentColorMatch* self, ECS* ecs);
void component_color_match_delete(ComponentColorMatch* self, ECS* ecs);
void component_color_match_tick(ComponentColorMatch* self, ECS* ecs);
void
component_color_match_init
(
ComponentColorMatch* self,
ECS* ecs,
EntityID matchID
);
static const ComponentInfo COMPONENT_COLOR_MATCH_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_color_match_tick,
NULL,
NULL
}
},
.type = COMPONENT_COLOR_MATCH,
.size = sizeof(ComponentColorMatch)
};

View File

@ -0,0 +1,108 @@
#include "component_dialogue.h"
static void _component_dialogue_string_set(ComponentDialogue* self, ECS* ecs);
static void
_component_dialogue_string_set(ComponentDialogue* self, ECS* ecs)
{
ComponentText* text;
char string[COMPONENT_TEXT_STRING_MAX];
memset(string, '\0', COMPONENT_TEXT_STRING_MAX);
memcpy(string, self->string, self->index + 1);
text = ecs_component_get(ecs, COMPONENT_TEXT, self->component.id);
component_text_string_set(text, ecs, string, self->index + 1);
sound_play(&ecs->resources->sounds[SOUND_BLIP]);
}
void
component_dialogue_add(ComponentDialogue* self, ECS* ecs)
{
for (s32 i = 0 ; i < COMPONENT_DIALOGUE_DEPENDENCY_COUNT; i++)
ecs_component_add(ecs, COMPONENT_DIALOGUE_DEPENDENCIES[i], self->component.id);
self->timerID = entity_timer_add(ecs, COMPONENT_DIALOGUE_SPEED_DEFAULT);
self->skipTimerID = entity_timer_add(ecs, COMPONENT_DIALOGUE_SKIP_TIMER_VALUE);
}
void
component_dialogue_delete(ComponentDialogue* self, ECS* ecs)
{
for (s32 i = 0 ; i < COMPONENT_DIALOGUE_DEPENDENCY_COUNT; i++)
ecs_component_delete(ecs, COMPONENT_DIALOGUE_DEPENDENCIES[i], self->component.id);
ecs_entity_delete(ecs, self->timerID);
ecs_entity_delete(ecs, self->skipTimerID);
}
void
component_dialogue_tick(ComponentDialogue* self, ECS* ecs)
{
ComponentTimer* timer;
if (self->isFinished)
return;
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timerID);
if (timer->isFinished)
{
self->index++;
_component_dialogue_string_set(self, ecs);
if (self->index >= self->length)
self->isFinished = true;
else
component_timer_init(timer, ecs, self->speed);
}
if (control_released(ecs->control, CONTROL_ACTION_PRIMARY))
{
ComponentTimer* skipTimer;
skipTimer = ecs_component_get(ecs, COMPONENT_TIMER, self->skipTimerID);
if (!skipTimer->isFinished)
return;
self->index = self->length - 1;
timer->value = 0;
timer->isFinished = true;
component_timer_init(timer, ecs, self->speed);
component_timer_init(skipTimer, ecs, COMPONENT_DIALOGUE_SKIP_TIMER_VALUE);
}
}
void
component_dialogue_init
(
ComponentDialogue* self,
ECS* ecs,
const char* string,
u32 speed
)
{
ComponentTimer* timer;
ComponentTimer* skipTimer;
self->speed = speed;
memcpy(self->string, string, COMPONENT_TEXT_STRING_MAX);
timer = ecs_component_get(ecs, COMPONENT_TIMER, self->timerID);
skipTimer = ecs_component_get(ecs, COMPONENT_TIMER, self->skipTimerID);
component_timer_init(timer, ecs, self->speed);
component_timer_init(skipTimer, ecs, COMPONENT_DIALOGUE_SKIP_TIMER_VALUE);
self->length = strlen(self->string);
self->index = 0;
self->isFinished = false;
_component_dialogue_string_set(self, ecs);
}

View File

@ -0,0 +1,57 @@
#pragma once
#include "component_text.h"
#include "../../entity/utility/entity_timer.h"
static const u32 COMPONENT_DIALOGUE_SPEED_DEFAULT = 3;
static const u32 COMPONENT_DIALOGUE_SKIP_TIMER_VALUE = 1;
typedef struct ComponentDialogue
{
Component component;
char string[COMPONENT_TEXT_STRING_MAX];
u32 speed;
u32 index;
u32 length;
bool isFinished;
EntityID timerID;
EntityID skipTimerID;
} ComponentDialogue;
void component_dialogue_add(ComponentDialogue* self, ECS* ecs);
void component_dialogue_delete(ComponentDialogue* self, ECS* ecs);
void component_dialogue_tick(ComponentDialogue* self, ECS* ecs);
void component_dialogue_string_set(ComponentDialogue* self, ECS* ecs);
void
component_dialogue_init
(
ComponentDialogue* self,
ECS* ecs,
const char* string,
u32 speed
);
#define COMPONENT_DIALOGUE_DEPENDENCY_COUNT 1
static const ComponentType COMPONENT_DIALOGUE_DEPENDENCIES[COMPONENT_DIALOGUE_DEPENDENCY_COUNT] =
{
COMPONENT_TEXT
};
static const ComponentInfo COMPONENT_DIALOGUE_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_dialogue_add,
(ECSFunction)component_dialogue_delete,
(ECSFunction)component_dialogue_tick,
NULL,
NULL
}
},
.type = COMPONENT_DIALOGUE,
.size = sizeof(ComponentDialogue)
};

View File

@ -0,0 +1,67 @@
#include "component_drop_shadow.h"
static void _component_drop_shadow_texture_quad_set(ComponentDropShadow* self, ECS* ecs);
static void
_component_drop_shadow_texture_quad_set(ComponentDropShadow* self, ECS* ecs)
{
ComponentTextureQuad* textureQuadDropShadow;
ComponentTextureQuad* textureQuad;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
if (!self->isSpriteInit)
{
self->spriteID = entity_sprite_add
(
ecs,
textureQuad->texture,
textureQuad->buffer,
textureQuad->origin,
textureQuad->size,
textureQuad->position
);
self->isSpriteInit = true;
}
textureQuadDropShadow = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->spriteID);
memcpy(textureQuadDropShadow, textureQuad, sizeof(ComponentTextureQuad));
textureQuadDropShadow->component.id = self->spriteID;
glm_vec4_copy(self->color, textureQuadDropShadow->color);
textureQuadDropShadow->position[0] += self->offset[0];
textureQuadDropShadow->position[1] += self->offset[1];
textureQuadDropShadow->position[2] += COMPONENT_DROP_SHADOW_Z_OFFSET;
}
void
component_drop_shadow_add(ComponentDropShadow* self, ECS* ecs)
{
self->spriteID = ecs_entity_add(ecs);
}
void
component_drop_shadow_delete(ComponentDropShadow* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->spriteID);
}
void
component_drop_shadow_tick(ComponentDropShadow* self, ECS* ecs)
{
_component_drop_shadow_texture_quad_set(self, ecs);
}
void
component_drop_shadow_init(ComponentDropShadow* self, ECS* ecs, vec4 color, vec2 offset)
{
glm_vec4_copy(color, self->color);
glm_vec2_copy(offset, self->offset);
_component_drop_shadow_texture_quad_set(self, ecs);
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "../../entity/visual/entity_sprite.h"
static const f32 COMPONENT_DROP_SHADOW_Z_OFFSET = 0.001f;
typedef struct ComponentDropShadow
{
Component component;
vec4 color;
vec2 offset;
bool isSpriteInit;
EntityID spriteID;
} ComponentDropShadow;
void component_drop_shadow_init(ComponentDropShadow* self, ECS* ecs, vec4 color, vec2 offset);
void component_drop_shadow_tick(ComponentDropShadow* self, ECS* ecs);
void component_drop_shadow_add(ComponentDropShadow* self, ECS* ecs);
void component_drop_shadow_delete(ComponentDropShadow* self, ECS* ecs);
static const ComponentInfo COMPONENT_DROP_SHADOW_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_drop_shadow_add,
(ECSFunction)component_drop_shadow_delete,
(ECSFunction)component_drop_shadow_tick,
NULL
}
},
.type = COMPONENT_DROP_SHADOW,
.size = sizeof(ComponentDropShadow)
};

View File

@ -0,0 +1,42 @@
#include "component_pulsate.h"
void
component_pulsate_add(ComponentPulsate* self, ECS* ecs)
{
self->counterID = entity_counter_add(ecs);
}
void
component_pulsate_delete(ComponentPulsate* self, ECS* ecs)
{
ecs_entity_delete(ecs, self->counterID);
}
void
component_pulsate_tick(ComponentPulsate* self, ECS* ecs)
{
ComponentCounter* counter;
ComponentTextureQuad* textureQuad;
counter = ecs_component_get(ecs, COMPONENT_COUNTER, self->counterID);
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
textureQuad->scale[0] = 1 + ((self->maxScale[0] - self->minScale[0]) / 2.0f) * cos((f32)counter->value / self->frequency);
textureQuad->scale[1] = 1 + ((self->maxScale[1] - self->minScale[1]) / 2.0f) * cos((f32)counter->value / self->frequency);
}
void
component_pulsate_init
(
ComponentPulsate* self,
ECS* ecs,
vec2 minScale,
vec2 maxScale,
f32 frequency
)
{
self->frequency = frequency;
glm_vec2_copy(minScale, self->minScale);
glm_vec2_copy(maxScale, self->maxScale);
}

View File

@ -0,0 +1,47 @@
#pragma once
#include "../../ecs_entity.h"
#include "component_texture_quad.h"
#include "../../entity/utility/entity_counter.h"
typedef struct ComponentPulsate
{
Component component;
vec2 minScale;
vec2 maxScale;
f32 frequency;
EntityID counterID;
} ComponentPulsate;
void component_pulsate_add(ComponentPulsate* self, ECS* ecs);
void component_pulsate_delete(ComponentPulsate* self, ECS* ecs);
void component_pulsate_tick(ComponentPulsate* self, ECS* ecs);
void
component_pulsate_init
(
ComponentPulsate* self,
ECS* ecs,
vec2 minScale,
vec2 maxScale,
f32 frequency
);
static const ComponentInfo COMPONENT_PULSATE_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_pulsate_add,
(ECSFunction)component_pulsate_delete,
(ECSFunction)component_pulsate_tick,
NULL,
NULL
}
},
.type = COMPONENT_PULSATE,
.size = sizeof(ComponentPulsate)
};

View File

@ -0,0 +1,17 @@
#include "component_rotate.h"
void
component_rotate_tick(ComponentRotate* self, ECS* ecs)
{
ComponentTextureQuad* textureQuad;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
textureQuad->rotation += self->speed;
}
void
component_rotate_init(ComponentRotate* self, ECS* ecs, f32 speed)
{
self->speed = speed;
}

View File

@ -0,0 +1,38 @@
#pragma once
#include "component_texture_quad.h"
typedef struct ComponentRotate
{
Component component;
f32 speed;
} ComponentRotate;
void component_rotate_add(ComponentRotate* self, ECS* ecs);
void component_rotate_delete(ComponentRotate* self, ECS* ecs);
void component_rotate_tick(ComponentRotate* self, ECS* ecs);
void
component_rotate_init
(
ComponentRotate* self,
ECS* ecs,
f32 speed
);
static const ComponentInfo COMPONENT_ROTATE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_rotate_tick,
NULL,
NULL
}
},
.type = COMPONENT_ROTATE,
.size = sizeof(ComponentRotate)
};

View File

@ -0,0 +1,45 @@
#include "component_scale_value.h"
void _component_scale_value_set(ComponentScaleValue* self, ECS* ecs);
void
_component_scale_value_set(ComponentScaleValue* self, ECS* ecs)
{
ComponentTextureQuad* textureQuad;
void* component;
f32 value;
f32 max;
f32 percent;
vec2 sizeDifference;
vec2 scaledSize;
textureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, self->component.id);
component = ecs_component_get(ecs, self->type, self->id);
memcpy(&value, (u8*)component + sizeof(Component), sizeof(f32));
memcpy(&max, (u8*)component + sizeof(Component) + sizeof(f32), sizeof(f32));
percent = value / max;
glm_vec2_sub(self->maxSize, self->minSize, sizeDifference);
glm_vec2_scale(sizeDifference, percent, scaledSize);
glm_vec2_copy(self->minSize, textureQuad->size);
glm_vec2_add(textureQuad->size, scaledSize, textureQuad->size);
}
void
component_scale_value_init(ComponentScaleValue* self, ECS* ecs, vec2 minSize, vec2 maxSize, ComponentType type, EntityID id)
{
self->id = id;
self->type = type;
glm_vec2_copy(minSize, self->minSize);
glm_vec2_copy(maxSize, self->maxSize);
_component_scale_value_set(self, ecs);
}
void
component_scale_value_tick(ComponentScaleValue* self, ECS* ecs)
{
_component_scale_value_set(self, ecs);
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "component_texture_quad.h"
typedef struct ComponentScaleValue
{
Component component;
vec2 minSize;
vec2 maxSize;
ComponentType type;
EntityID id;
} ComponentScaleValue;
void component_scale_value_init(ComponentScaleValue* self, ECS* ecs, vec2 minSize, vec2 maxSize, ComponentType type, EntityID id);
void component_scale_value_tick(ComponentScaleValue* self, ECS* ecs);
static const ComponentInfo COMPONENT_SCALE_VALUE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_scale_value_tick,
NULL,
NULL
}
},
.type = COMPONENT_SCALE_VALUE,
.size = sizeof(ComponentScaleValue)
};

View File

@ -0,0 +1,236 @@
#include "component_text.h"
void _component_text_glyph_size_get(ComponentText* self, Texture* texture, vec2 size);
void _component_text_glyph_position_get(ComponentText* self, Texture* texture, vec3 position);
void _component_text_glyph_entities_init(ComponentText* self, ECS* ecs);
void _component_text_glyph_entities_free(ComponentText* self, ECS* ecs);
void _component_text_glyphs_position_set(ComponentText* self, ECS* ecs);
void _component_text_glyphs_color_set(ComponentText* self, ECS* ecs);
void
_component_text_glyph_size_get(ComponentText* self, Texture* texture, vec2 size)
{
size[0] = texture->size[0] * self->scale[0];
size[1] = texture->size[1] * self->scale[1];
}
void
_component_text_glyph_entities_init(ComponentText* self, ECS* ecs)
{
vec2 dropShadowOffset;
glm_vec2_zero(dropShadowOffset);
dropShadowOffset[1] = (s32)(self->font->size * COMPONENT_TEXT_DROP_SHADOW_FONT_SIZE_MULTIPLIER);
for (s32 i = 0; i < (s32)self->length; i++)
{
EntityID glyphID;
vec2 glyphSize;
vec3 glyphPosition;
char glyph;
glyph = self->string[i];
if (glyph == '\n')
glyph = ' ';
_component_text_glyph_size_get(self, &self->font->glyphTextures[(s32)glyph], glyphSize);
glyphID = entity_glyph_add
(
ecs,
&self->font->glyphTextures[(s32)glyph],
self->buffer,
glyphSize,
self->position,
self->color,
self->dropShadowColor,
dropShadowOffset
);
vector_push(&self->glyphEntities, &glyphID);
}
_component_text_glyphs_position_set(self, ecs);
for (s32 i = 0; i < (s32)self->length; i++)
{
EntityID* glyphEntityID;
ComponentDropShadow* glyphEntityDropShadow;
glyphEntityID = (EntityID*)vector_get(&self->glyphEntities, i);
glyphEntityDropShadow = ecs_component_get(ecs, COMPONENT_DROP_SHADOW, *glyphEntityID);
component_drop_shadow_tick(glyphEntityDropShadow, ecs);
}
}
void
_component_text_glyph_entities_free(ComponentText* self, ECS* ecs)
{
for (s32 i = 0; i < (s32)self->length; i++)
{
EntityID* glyphEntity;
glyphEntity = (EntityID*)vector_get(&self->glyphEntities, i);
ecs_entity_delete(ecs, *glyphEntity);
}
vector_clear(&self->glyphEntities);
}
void
_component_text_glyphs_position_set(ComponentText* self, ECS* ecs)
{
GlyphMetrics glyphMetrics;
f32 currentLineWidth;
f32 increment;
f32 kerning;
f32 lineBegin;
f32 lineSkip;
f32 advance;
vec3 position;
lineSkip = font_line_skip_get(self->font);
glm_vec3_copy(self->position, position);
currentLineWidth = 0.0f;
lineBegin = position[0];
for (s32 i = 0; i < (s32)self->length; i++)
{
EntityID* glyphEntityID;
ComponentTextureQuad* glyphEntityTextureQuad;
char glyph;
glyph = self->string[i];
glyphEntityID = (EntityID*)vector_get(&self->glyphEntities, i);
glyphEntityTextureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, *glyphEntityID);
font_glyph_metrics_init(self->font, &glyphMetrics, glyph);
advance = glyphMetrics.advance;
if
(
glyph == '\n' ||
(glyph == ' ' && (currentLineWidth > self->wrap) && self->wrap != -1)
)
{
position[0] = lineBegin;
position[1] += lineSkip * self->scale[1];
advance = 0.0f;
currentLineWidth = 0.0f;
}
if (i < (s32)self->length)
kerning = (f32)font_glyph_kerning_get(self->font, glyph, self->string[i + 1]);
else
kerning = 0.0f;
glm_vec3_copy(position, glyphEntityTextureQuad->position);
increment = advance + kerning;
position[0] += increment;
position[2] -= COMPONENT_TEXT_Z_OFFSET_INCREMENT;
currentLineWidth += increment;
}
}
void
_component_text_glyphs_color_set(ComponentText* self, ECS* ecs)
{
for (s32 i = 0; i < (s32)self->length; i++)
{
EntityID* glyphEntityID;
ComponentTextureQuad* glyphEntityTextureQuad;
ComponentDropShadow* glyphEntityDropShadow;
ComponentTextureQuad* glyphEntityDropShadowTextureQuad;
glyphEntityID = (EntityID*)vector_get(&self->glyphEntities, i);
glyphEntityTextureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, *glyphEntityID);
glyphEntityDropShadow = ecs_component_get(ecs, COMPONENT_DROP_SHADOW, *glyphEntityID);
glyphEntityDropShadowTextureQuad = ecs_component_get(ecs, COMPONENT_TEXTURE_QUAD, glyphEntityDropShadow->spriteID);
glm_vec4_copy(self->color, glyphEntityTextureQuad->color);
glm_vec4_copy(self->colorCover, glyphEntityTextureQuad->colorCover);
glyphEntityDropShadowTextureQuad->color[3] = self->color[3];
glm_vec4_copy(self->colorCover, glyphEntityDropShadowTextureQuad->colorCover);
}
}
void
component_text_string_set(ComponentText* self, ECS* ecs, char* string, u32 length)
{
_component_text_glyph_entities_free(self, ecs);
if (length > COMPONENT_TEXT_STRING_MAX)
return;
self->length = length;
memset(self->string, '\0', sizeof(char) * COMPONENT_TEXT_STRING_MAX);
memcpy(self->string, string, sizeof(char) * self->length);
_component_text_glyph_entities_init(self, ecs);
}
void
component_text_add(ComponentText* self, ECS* ecs)
{
glm_vec4_copy(COMPONENT_TEXT_COLOR_DEFAULT, self->color);
glm_vec4_copy(COMPONENT_TEXT_COLOR_COVER_DEFAULT, self->color);
glm_vec4_copy(COMPONENT_TEXT_DROP_SHADOW_COLOR_DEFAULT, self->dropShadowColor);
glm_vec2_copy(COMPONENT_TEXT_SCALE_DEFAULT, self->scale);
self->wrap = COMPONENT_TEXT_WRAP_DEFAULT;
vector_init(&self->glyphEntities, sizeof(EntityID));
}
void
component_text_delete(ComponentText* self, ECS* ecs)
{
_component_text_glyph_entities_free(self, ecs);
vector_free(&self->glyphEntities);
}
void
component_text_tick(ComponentText* self, ECS* ecs)
{
_component_text_glyphs_position_set(self, ecs);
_component_text_glyphs_color_set(self, ecs);
}
void
component_text_init
(
ComponentText* self,
ECS* ecs,
Font* font,
RendererBuffer buffer,
char* string,
vec3 position,
u32 length,
s32 wrap
)
{
self->font = font;
self->wrap = wrap;
self->buffer = buffer;
glm_vec3_copy(position, self->position);
component_text_string_set(self, ecs, string, length);
}

View File

@ -0,0 +1,79 @@
#pragma once
#include "../../ecs_entity.h"
#include "../../../../engine/rectangle.h"
#include "../../../../engine/font.h"
#include "../../../render/texture_quad.h"
#include "../../../resource/resource_shader.h"
#include "../physics/component_physics.h"
#include "../../entity/visual/entity_glyph.h"
#define COMPONENT_TEXT_LIMIT 1024
#define COMPONENT_TEXT_STRING_MAX 1024
#define COMPONENT_TEXT_COLOR_DEFAULT (f32*)OPAQUE
#define COMPONENT_TEXT_COLOR_COVER_DEFAULT (f32*)OPAQUE
#define COMPONENT_TEXT_DROP_SHADOW_COLOR_DEFAULT (f32*)BLACK
#define COMPONENT_TEXT_Z_OFFSET_INCREMENT 0.0001f
#define COMPONENT_TEXT_DROP_SHADOW_FONT_SIZE_MULTIPLIER 0.125f
static const vec2 COMPONENT_TEXT_SCALE_DEFAULT = {1.0f, 1.0f};
static const f32 COMPONENT_TEXT_WRAP_DEFAULT = -1;
static const vec3 COMPONENT_TEXT_OFFSET_DEFAULT = {0.0f, 0.0f, 0.0f};
typedef struct ComponentText
{
Component component;
Shader* shader;
RendererBuffer buffer;
Font* font;
Vector glyphEntities; /* EntityID */
char string[COMPONENT_TEXT_STRING_MAX];
s32 wrap;
u32 length;
vec2 scale;
vec3 offset;
vec3 position;
vec4 color;
vec4 colorCover;
vec4 dropShadowColor;
} ComponentText;
void component_text_add(ComponentText* self, ECS* ecs);
void component_text_delete(ComponentText* self, ECS* ecs);
void component_text_string_set(ComponentText* self, ECS* ecs, char* string, u32 length);
void component_text_tick(ComponentText* self, ECS* ecs);
void
component_text_init
(
ComponentText* self,
ECS* ecs,
Font* font,
RendererBuffer buffer,
char* string,
vec3 position,
u32 length,
s32 wrap
);
static const ComponentInfo COMPONENT_TEXT_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_text_add,
(ECSFunction)component_text_delete,
(ECSFunction)component_text_tick,
NULL,
NULL
}
},
.type = COMPONENT_TEXT,
.size = sizeof(ComponentText)
};

View File

@ -0,0 +1,176 @@
#include "component_texture_quad.h"
void
component_texture_quad_size_get(ComponentTextureQuad* self, vec2 size)
{
glm_vec2_copy(self->size, size);
glm_vec2_mul(size, self->scale, size);
}
void
component_texture_quad_position_get(ComponentTextureQuad* self, vec3 position)
{
vec2 size;
glm_vec3_copy(self->position, position);
glm_vec3_add(position, self->offset, position);
component_texture_quad_size_get(self, size);
switch (self->origin)
{
case ORIGIN_CENTER:
position[0] -= size[0] / 2;
position[1] -= size[1] / 2;
break;
case ORIGIN_TOP_LEFT:
default:
break;
}
}
void
component_texture_quad_origin_point_get(ComponentTextureQuad* self, vec3 originPoint)
{
vec2 size;
glm_vec3_zero(originPoint);
switch (self->origin)
{
case ORIGIN_CENTER:
component_texture_quad_size_get(self, size);
originPoint[0] = size[0] / 2;
originPoint[1] = size[1] / 2;
case ORIGIN_TOP_LEFT:
default:
break;
}
}
void
component_texture_quad_model_get(ComponentTextureQuad* self, mat4 model)
{
vec3 position;
vec3 originPoint;
component_texture_quad_position_get(self, position);
component_texture_quad_origin_point_get(self, originPoint);
glm_mat4_identity(model);
glm_translate(model, position);
glm_rotate_at(model, originPoint, self->rotation, (f32*)COMPONENT_TEXTURE_QUAD_ROTATION_AXIS);
}
void
component_texture_quad_rectangle_get(ComponentTextureQuad* self, Rectangle* rectangle)
{
vec2 size;
vec2 difference;
component_texture_quad_size_get(self, size);
rectangle->x = (self->position[0] - (size[0] / 2)) + self->offset[0];
rectangle->y = (self->position[1] - (size[1] / 2)) + self->offset[1];
rectangle->w = size[0];
rectangle->h = size[1];
}
s32
component_texture_quad_sort(ComponentTextureQuad* a, ComponentTextureQuad* b)
{
return a->position[2] > b->position[2] ? -1 : 1;
}
void
component_texture_quad_init
(
ComponentTextureQuad* self,
ECS* ecs,
Texture* texture,
Flip flip,
Origin origin,
RendererBuffer buffer,
f32 rotation,
vec2 size,
vec2 scale,
vec2 uvMin,
vec2 uvMax,
vec3 offset,
vec3 position,
vec4 color
)
{
self->texture = texture;
self->flip = flip;
self->origin = origin;
self->buffer = buffer;
self->rotation = rotation;
glm_vec2_copy(size, self->size);
glm_vec2_copy(scale, self->scale);
glm_vec2_copy(uvMin, self->uvMin);
glm_vec2_copy(uvMax, self->uvMax);
glm_vec3_copy(COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT, self->offset);
glm_vec4_copy(COMPONENT_TEXTURE_QUAD_COLOR_COVER, self->colorCover);
glm_vec3_copy(position, self->position);
glm_vec4_copy(color, self->color);
}
void
component_texture_quad_add(ComponentTextureQuad* self, ECS* ecs)
{
component_texture_quad_init
(
self,
ecs,
&ecs->resources->textures[COMPONENT_TEXTURE_QUAD_TEXTURE_DEFAULT],
COMPONENT_TEXTURE_QUAD_FLIP_DEFAULT,
COMPONENT_TEXTURE_QUAD_ORIGIN_DEFAULT,
COMPONENT_TEXTURE_QUAD_BUFFER_DEFAULT,
COMPONENT_TEXTURE_QUAD_ROTATION_DEFAULT,
COMPONENT_TEXTURE_QUAD_SIZE_DEFAULT,
COMPONENT_TEXTURE_QUAD_SCALE_DEFAULT,
COMPONENT_TEXTURE_QUAD_UV_MIN_DEFAULT,
COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT,
COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT,
COMPONENT_TEXTURE_QUAD_POSITION_DEFAULT,
COMPONENT_TEXTURE_QUAD_COLOR_DEFAULT
);
}
void
component_texture_quad_draw(ComponentTextureQuad* self, ECS* ecs)
{
mat4 model;
mat4 view;
mat4 projection;
vec2 size;
component_texture_quad_model_get(self, model);
component_texture_quad_size_get(self, size);
camera_view_get(&ecs->renderer->camera[self->buffer], view);
camera_projection_get(&ecs->renderer->camera[self->buffer], projection);
renderer_buffer_use(ecs->renderer, self->buffer);
texture_quad_draw
(
self->texture,
ecs->renderer,
&ecs->resources->shaders[SHADER_TEXTURE_QUAD],
self->uvMin,
self->uvMax,
model,
view,
projection,
size,
self->color,
self->colorCover,
self->flip
);
renderer_buffer_unbind();
}

View File

@ -0,0 +1,85 @@
#pragma once
#include "../../ecs_entity.h"
#include "../../../../engine/rectangle.h"
#include "../../../render/texture_quad.h"
#include "../../../resource/resource_shader.h"
typedef struct ComponentTextureQuad
{
Component component;
Flip flip;
Origin origin;
RendererBuffer buffer;
Texture* texture;
f32 rotation;
vec2 scale;
vec2 size;
vec2 uvMax;
vec2 uvMin;
vec3 offset;
vec3 position;
vec4 color;
vec4 colorCover;
} ComponentTextureQuad;
void component_texture_quad_init
(
ComponentTextureQuad* self,
ECS* ecs,
Texture* texture,
Flip flip,
Origin origin,
RendererBuffer buffer,
f32 rotation,
vec2 size,
vec2 scale,
vec2 uvMin,
vec2 uvMax,
vec3 position,
vec3 offset,
vec4 color
);
void component_texture_quad_size_get(ComponentTextureQuad* self, vec2 size);
void component_texture_quad_position_get(ComponentTextureQuad* self, vec3 position);
void component_texture_quad_origin_point_get(ComponentTextureQuad* self, vec3 originPoint);
void component_texture_quad_model_get(ComponentTextureQuad* self, mat4 model);
void component_texture_quad_rectangle_get(ComponentTextureQuad* self, Rectangle* rectangle);
s32 component_texture_quad_sort(ComponentTextureQuad* a, ComponentTextureQuad* b);
void component_texture_quad_draw(ComponentTextureQuad* self, ECS* ecs);
static const ComponentInfo COMPONENT_TEXTURE_QUAD_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
NULL,
NULL,
(ECSFunction)component_texture_quad_draw
}
},
.type = COMPONENT_TEXTURE_QUAD,
.size = sizeof(ComponentTextureQuad)
};
#define COMPONENT_TEXTURE_QUAD_UV_MIN_DEFAULT TEXTURE_QUAD_UV_MIN_DEFAULT
#define COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT TEXTURE_QUAD_UV_MAX_DEFAULT
#define COMPONENT_TEXTURE_QUAD_COLOR_DEFAULT TEXTURE_QUAD_COLOR_DEFAULT
#define COMPONENT_TEXTURE_QUAD_FLIP_DEFAULT TEXTURE_QUAD_FLIP_DEFAULT
#define COMPONENT_TEXTURE_QUAD_ORIGIN_DEFAULT TEXTURE_QUAD_ORIGIN_DEFAULT
static const RendererBuffer COMPONENT_TEXTURE_QUAD_BUFFER_DEFAULT = RENDERER_BUFFER_WORLD;
static const ShaderType COMPONENT_TEXTURE_QUAD_SHADER_DEFAULT = SHADER_TEXTURE_QUAD;
static const TextureType COMPONENT_TEXTURE_QUAD_TEXTURE_DEFAULT = TEXTURE_DEFAULT;
static const f32 COMPONENT_TEXTURE_QUAD_ROTATION_DEFAULT = 0.0f;
static const vec2 COMPONENT_TEXTURE_QUAD_SCALE_DEFAULT = {1.0f, 1.0f};
static const vec2 COMPONENT_TEXTURE_QUAD_SIZE_DEFAULT = {32.0f, 32.0f};
static const vec3 COMPONENT_TEXTURE_QUAD_POSITION_DEFAULT = {0.0f, 0.0f, 0.0f};
static const vec3 COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT = {0.0f, 0.0f, 0.0f};
static const vec3 COMPONENT_TEXTURE_QUAD_ROTATION_AXIS = {0.0f, 0.0f, 1.0f};
static const vec4 COMPONENT_TEXTURE_QUAD_COLOR_COVER = {0.0f, 0.0f, 0.0f, 1.0f};

View File

@ -0,0 +1,128 @@
#include "component_value_text.h"
s32 _component_value_text_value_get(ComponentValueText* self, ECS* ecs);
s32 _component_value_text_max_get(ComponentValueText* self, ECS* ecs);
void _component_value_text_set(ComponentValueText* self, ECS* ecs);
s32
_component_value_text_value_get(ComponentValueText* self, ECS* ecs)
{
u8* component;
s32 value;
component = (u8*)ecs_component_get(ecs, self->type, self->id);
// Get first value of component, after the component struct. If it segfaults, not my problem.
memcpy(&value, component + sizeof(Component), sizeof(u32));
return value;
}
s32
_component_value_text_max_get(ComponentValueText* self, ECS* ecs)
{
u8* component;
s32 max;
component = (u8*)ecs_component_get(ecs, self->type, self->id);
// Get second value of component, after the component struct and the value. If it segfaults, not my problem.
memcpy(&max, component + sizeof(Component) + sizeof(u32), sizeof(u32));
return max;
}
void
_component_value_text_set(ComponentValueText* self, ECS* ecs)
{
ComponentText* text;
u32 minutes;
u32 seconds;
u32 milliseconds;
u32 max;
char string[COMPONENT_VALUE_TEXT_STRING_MAX];
text = ecs_component_get(ecs, COMPONENT_TEXT, self->component.id);
memset(string, '\0', COMPONENT_VALUE_TEXT_STRING_MAX);
switch (self->textType)
{
case COMPONENT_VALUE_TEXT_TYPE_TIMER:
time_formatted_get(self->value, &minutes, &seconds, &milliseconds);
snprintf(string, COMPONENT_VALUE_TEXT_STRING_MAX, self->format, minutes, seconds, milliseconds);
break;
case COMPONENT_VALUE_TEXT_TYPE_INTEGER_MAX:
max = _component_value_text_max_get(self, ecs);
snprintf(string, COMPONENT_VALUE_TEXT_STRING_MAX, self->format, self->value, max);
break;
case COMPONENT_VALUE_TEXT_TYPE_INTEGER:
default:
snprintf(string, COMPONENT_VALUE_TEXT_STRING_MAX, self->format, self->value);
break;
}
component_text_string_set(text, ecs, string, strlen(string));
}
void
component_value_text_add(ComponentValueText* self, ECS* ecs)
{
ecs_components_add
(
ecs,
COMPONENT_VALUE_TEXT_DEPENDENCIES,
COMPONENT_VALUE_TEXT_DEPENDENCY_COUNT,
self->component.id
);
}
void
component_value_text_tick(ComponentValueText* self, ECS* ecs)
{
self->value = _component_value_text_value_get(self, ecs);
if (self->value != self->previousValue)
{
_component_value_text_set(self, ecs);
self->previousValue = self->value;
}
}
void
component_value_text_init
(
ComponentValueText* self,
ECS* ecs,
Font* font,
RendererBuffer buffer,
const vec3 position,
ComponentType type,
ComponentValueTextType textType,
const char* format,
EntityID id
)
{
component_text_init
(
ecs_component_get(ecs, COMPONENT_TEXT, self->component.id),
ecs,
font,
buffer,
"1",
position,
0,
-1
);
self->format = format;
self->type = type;
self->textType = textType;
self->id = id;
self->value = _component_value_text_value_get(self, ecs);
self->previousValue = self->value;
_component_value_text_set(self, ecs);
}

View File

@ -0,0 +1,64 @@
#pragma once
#include "component_text.h"
#include "../../../../engine/time.h"
#define COMPONENT_VALUE_TEXT_STRING_MAX 64
typedef enum ComponentValueTextType
{
COMPONENT_VALUE_TEXT_TYPE_INTEGER,
COMPONENT_VALUE_TEXT_TYPE_INTEGER_MAX,
COMPONENT_VALUE_TEXT_TYPE_TIMER,
} ComponentValueTextType;
typedef struct ComponentValueText
{
Component component;
ComponentType type;
ComponentValueTextType textType;
EntityID id;
const char* format;
s32 previousValue;
s32 value;
} ComponentValueText;
void component_value_text_add(ComponentValueText* self, ECS* ecs);
void component_value_text_tick(ComponentValueText* self, ECS* ecs);
void
component_value_text_init
(
ComponentValueText* self,
ECS* ecs,
Font* font,
RendererBuffer buffer,
const vec3 position,
ComponentType type,
ComponentValueTextType textType,
const char* format,
EntityID id
);
#define COMPONENT_VALUE_TEXT_DEPENDENCY_COUNT 1
static const ComponentType COMPONENT_VALUE_TEXT_DEPENDENCIES[COMPONENT_VALUE_TEXT_DEPENDENCY_COUNT] =
{
COMPONENT_TEXT
};
static const ComponentInfo COMPONENT_VALUE_TEXT_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_value_text_add,
NULL,
(ECSFunction)component_value_text_tick,
NULL,
NULL
}
},
.type = COMPONENT_VALUE_TEXT,
.size = sizeof(ComponentText)
};

71
src/game/ecs/ecs.c Normal file
View File

@ -0,0 +1,71 @@
#include "ecs.h"
static void _ecs_function(ECS* self, ECSFunctionType type);
static void
_ecs_function(ECS* self, ECSFunctionType type)
{
for (s32 i = 0; i < COMPONENT_COUNT; i++)
{
ComponentList* list;
list = &self->lists[i];
ecs_component_list_function(list, type);
}
}
void
ecs_tick(ECS* self)
{
if (!self->isFunctionDisabled[ECS_FUNCTION_TICK])
_ecs_function(self, ECS_FUNCTION_TICK);
}
void
ecs_update(ECS* self)
{
if (!self->isFunctionDisabled[ECS_FUNCTION_UPDATE])
_ecs_function(self, ECS_FUNCTION_UPDATE);
}
void
ecs_draw(ECS* self)
{
vector_sort(&self->lists[COMPONENT_TEXTURE_QUAD].components, (SortCompareFunction)component_texture_quad_sort);
if (!self->isFunctionDisabled[ECS_FUNCTION_DRAW])
_ecs_function(self, ECS_FUNCTION_DRAW);
}
void
ecs_init(ECS* self, Renderer* renderer, Control* control, Input* input, Resources* resources, Postprocessing* postprocessing)
{
self->renderer = renderer;
self->control = control;
self->input = input;
self->resources = resources;
self->postprocessing = postprocessing;
self->isLog = true;
for (s32 i = 0 ; i < COMPONENT_COUNT; i++)
ecs_component_list_init(&self->lists[i], self, COMPONENT_INFO[i]);
}
void
ecs_clear(ECS* self)
{
for (s32 i = 0 ; i < COMPONENT_COUNT; i++)
ecs_component_list_clear(&self->lists[i]);
self->nextID = 0;
}
void
ecs_free(ECS* self)
{
for (s32 i = 0 ; i < COMPONENT_COUNT; i++)
ecs_component_list_free(&self->lists[i]);
memset(self, '\0', sizeof(ECS));
}

100
src/game/ecs/ecs.h Normal file
View File

@ -0,0 +1,100 @@
#pragma once
#include "component/animation/component_animation.h"
#include "component/animation/component_animation_player.h"
#include "component/animation/component_animation_target.h"
#include "component/game/component_collect.h"
#include "component/game/component_collectible.h"
#include "component/game/component_collide_slow.h"
#include "component/game/component_food.h"
#include "component/game/component_threshold.h"
#include "component/game/component_game_object.h"
#include "component/game/component_homing.h"
#include "component/game/component_levitate.h"
#include "component/game/component_player_control.h"
#include "component/game/component_power.h"
#include "component/game/component_solid.h"
#include "component/game/component_stamina.h"
#include "component/game/component_take_food.h"
#include "component/game/component_stage.h"
#include "component/game/component_plane_object.h"
#include "component/game/component_world_object.h"
#include "component/physics/component_circle_collider.h"
#include "component/physics/component_copy_mouse_position.h"
#include "component/physics/component_physics.h"
#include "component/ui/component_button.h"
#include "component/utility/component_counter.h"
#include "component/utility/component_timer.h"
#include "component/utility/component_delete_on_timer.h"
#include "component/visual/component_atlas.h"
#include "component/visual/component_camera_focus.h"
#include "component/visual/component_dialogue.h"
#include "component/visual/component_drop_shadow.h"
#include "component/visual/component_color_change.h"
#include "component/visual/component_color_match.h"
#include "component/visual/component_scale_value.h"
#include "component/visual/component_pulsate.h"
#include "component/visual/component_rotate.h"
#include "component/visual/component_text.h"
#include "component/visual/component_texture_quad.h"
#include "component/visual/component_value_text.h"
#include "../input/control.h"
#include "../../engine/renderer.h"
#include "../render/postprocessing.h"
#include "../resource/resources.h"
static const struct ComponentInfo COMPONENT_INFO[COMPONENT_COUNT] =
{
/* Utility */
COMPONENT_TIMER_INFO,
COMPONENT_COUNTER_INFO,
COMPONENT_DELETE_ON_TIMER_INFO,
/* Physics */
COMPONENT_PHYSICS_INFO,
COMPONENT_COPY_MOUSE_POSITION_INFO,
COMPONENT_CIRCLE_COLLIDER_INFO,
/* Game */
COMPONENT_GAME_OBJECT_INFO,
COMPONENT_PLANE_OBJECT_INFO,
COMPONENT_WORLD_OBJECT_INFO,
COMPONENT_SOLID_INFO,
COMPONENT_LEVITATE_INFO,
COMPONENT_COLLIDE_SLOW_INFO,
COMPONENT_COLLECTIBLE_INFO,
COMPONENT_COLLECT_INFO,
COMPONENT_HOMING_INFO,
COMPONENT_FOOD_INFO,
COMPONENT_THRESHOLD_INFO,
COMPONENT_TAKE_FOOD_INFO,
COMPONENT_STAGE_INFO,
COMPONENT_STAMINA_INFO,
COMPONENT_POWER_INFO,
COMPONENT_PLAYER_CONTROL_INFO,
/* Animation */
COMPONENT_ANIMATION_INFO,
COMPONENT_ANIMATION_PLAYER_INFO,
COMPONENT_ANIMATION_TARGET_INFO,
/* UI */
COMPONENT_BUTTON_INFO,
/* Visual */
COMPONENT_DROP_SHADOW_INFO,
COMPONENT_TEXTURE_QUAD_INFO,
COMPONENT_TEXT_INFO,
COMPONENT_DIALOGUE_INFO,
COMPONENT_VALUE_TEXT_INFO,
COMPONENT_ATLAS_INFO,
COMPONENT_CAMERA_FOCUS_INFO,
COMPONENT_COLOR_CHANGE_INFO,
COMPONENT_COLOR_MATCH_INFO,
COMPONENT_SCALE_VALUE_INFO,
COMPONENT_ROTATE_INFO,
COMPONENT_PULSATE_INFO
};
void ecs_tick(ECS* self);
void ecs_update(ECS* self);
void ecs_draw(ECS* self);
void ecs_init(ECS* self, Renderer* renderer, Control* control, Input* input, Resources* resources, Postprocessing* postprocessing);
void ecs_clear(ECS* self);
void ecs_free(ECS* self);

View File

@ -0,0 +1,104 @@
#include "ecs_component.h"
static bool isFirstTimeComponentAdded = false;
void*
ecs_component_get(ECS* self, ComponentType type, EntityID id)
{
void* component;
component = ecs_component_list_get(&self->lists[type], id);
if
(
(!component && !isFirstTimeComponentAdded) &&
self->isLog
)
printf("%s Type: %i, ID: %u\n", STRING_ECS_COMPONENT_ID_ERROR, type, id);
return component;
}
void*
ecs_component_from_index_get(ECS* self, ComponentType type, u32 index)
{
void* component;
component = vector_get(&self->lists[type].components, index);
if
(
(!component && !isFirstTimeComponentAdded) &&
self->isLog
)
printf("%s Type: %i, ID: %i\n", STRING_ECS_COMPONENT_INDEX_ERROR, type, index);
return component;
}
void*
ecs_component_add(ECS* self, ComponentType type, EntityID id)
{
void* component;
ECSFunction add;
isFirstTimeComponentAdded = true;
component = ecs_component_get(self, type, id);
if (component)
return component;
isFirstTimeComponentAdded = false;
component = vector_push(&self->lists[type].components, NULL);
memcpy(component, (void*)&id, sizeof(EntityID));
add = self->lists[type].system.functions[ECS_FUNCTION_ADD];
if (add)
add(component, self);
return component;
}
void
ecs_component_delete(ECS* self, ComponentType type, EntityID id)
{
for (s32 i = 0; i < (s32)self->lists[type].components.count; i++)
{
EntityID checkID;
void* component;
component = vector_get(&self->lists[type].components, i);
memcpy(&checkID, component, sizeof(EntityID));
if (checkID == id)
{
ECSFunction delete;
delete = self->lists[type].system.functions[ECS_FUNCTION_DELETE];
if (delete)
delete(component, self);
vector_remove(&self->lists[type].components, i);
}
}
}
void
ecs_components_add(ECS* self, const ComponentType* types, u32 count, EntityID id)
{
for (s32 i = 0; i < (s32)count; i++)
ecs_component_add(self, types[i], id);
}
void
ecs_components_delete(ECS* self, const ComponentType* types, u32 count, EntityID id)
{
for (s32 i = 0; i < (s32)count; i++)
ecs_component_delete(self, types[i], id);
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "ecs_component_list.h"
#define STRING_ECS_COMPONENT_ID_ERROR "[ERROR] ECS component get failed! Invalid entity ID! |"
#define STRING_ECS_COMPONENT_INDEX_ERROR "[ERROR] ECS component get failed! Invalid index! |"
void ecs_component_delete(ECS* self, ComponentType type, EntityID id);
void* ecs_component_add(ECS* self, ComponentType type, EntityID id);
void* ecs_component_get(ECS* self, ComponentType type, EntityID id);
void* ecs_component_from_index_get(ECS* self, ComponentType type, u32 index);
void ecs_components_add(ECS* self, const ComponentType* types, u32 count, EntityID id);
void ecs_components_delete(ECS* self, const ComponentType* types, u32 count, EntityID id);

View File

@ -0,0 +1,73 @@
#include "ecs_component_list.h"
void
ecs_component_list_init(ComponentList* self, ECS* ecs, ComponentInfo info)
{
self->ecs = ecs;
self->type = info.type;
self->system = info.system;
vector_init(&self->components, info.size);
}
void
ecs_component_list_function(ComponentList* self, ECSFunctionType type)
{
ECSFunction function;
function = self->system.functions[type];
if (!function)
return;
for (s32 i = 0; i < (s32)self->components.count; i++)
{
void* component;
Component ecsComponent;
component = vector_get(&self->components, i);
memcpy(&ecsComponent, component, sizeof(Component));
if
(
ecsComponent.isDisabled ||
ecsComponent.isFunctionDisabled[type]
)
continue;
function(component, self->ecs);
}
}
void*
ecs_component_list_get(ComponentList* self, EntityID id)
{
for (s32 i = 0; i < (s32)self->components.count; i++)
{
u32 checkID;
void* component;
component = vector_get(&self->components, i);
memcpy(&checkID, component, sizeof(u32));
if (checkID == id)
return component;
}
return NULL;
}
void
ecs_component_list_clear(ComponentList* self)
{
vector_clear(&self->components);
}
void
ecs_component_list_free(ComponentList* self)
{
vector_free(&self->components);
memset(self, '\0', sizeof(ComponentList));
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "ECS_COMMON.h"
void* ecs_component_list_get(ComponentList* self, EntityID id);
void ecs_component_list_init(ComponentList* self, ECS* ecs, ComponentInfo info);
void ecs_component_list_function(ComponentList* self, ECSFunctionType type);
void ecs_component_list_clear(ComponentList* self);
void ecs_component_list_free(ComponentList* self);

20
src/game/ecs/ecs_entity.c Normal file
View File

@ -0,0 +1,20 @@
#include "ecs_entity.h"
EntityID
ecs_entity_add(ECS* self)
{
EntityID id;
id = self->nextID;
self->nextID++;
return id;
}
void
ecs_entity_delete(ECS* self, EntityID id)
{
for (s32 i = 0; i < COMPONENT_COUNT; i++)
ecs_component_delete(self, (ComponentType)i, id);
}

View File

@ -0,0 +1,6 @@
#pragma once
#include "ecs_component.h"
u32 ecs_entity_add(ECS* ecs);
void ecs_entity_delete(ECS* ecs, EntityID id);

View File

@ -0,0 +1,46 @@
#include "entity_collectible.h"
EntityID
entity_collectible_add(ECS* ecs, const vec3 position, CollectibleType type)
{
EntityID id;
ComponentPhysics* physics;
vec3 smokePosition;
id = ecs_entity_add(ecs);
ecs_components_add(ecs, ENTITY_COLLECTIBLE_DEPENDENCIES, ENTITY_COLLECTIBLE_DEPENDENCY_COUNT, id);
component_collectible_init
(
ecs_component_get(ecs, COMPONENT_COLLECTIBLE, id),
ecs,
&ecs->resources->textures[TEXTURE_COLLECTIBLE],
ENTITY_COLLECTIBLE_SIZE,
position,
type
);
component_atlas_init
(
ecs_component_get(ecs, COMPONENT_ATLAS, id),
ecs,
ENTITY_COLLECTIBLE_ATLAS_FRAME_SIZE,
ENTITY_COLLECTIBLE_ATLAS_SIZE,
(u32)type
);
physics = ecs_component_get(ecs, COMPONENT_PHYSICS, id);
glm_vec3_copy(physics->position, smokePosition);
smokePosition[2] += ENTITY_COLLECTIBLE_SMOKE_Z_OFFSET;
entity_smoke_add
(
ecs,
smokePosition
);
return id;
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "../../component/game/component_collectible.h"
#include "../../component/visual/component_rotate.h"
#include "../../component/visual/component_atlas.h"
#include "entity_smoke.h"
static const vec2 ENTITY_COLLECTIBLE_SIZE = {128.0f, 128.0f};
static const ivec2 ENTITY_COLLECTIBLE_ATLAS_FRAME_SIZE = {32, 32};
static const ivec2 ENTITY_COLLECTIBLE_ATLAS_SIZE = {1, 6};
static const f32 ENTITY_COLLECTIBLE_SMOKE_Z_OFFSET = 0.01f;
#define ENTITY_COLLECTIBLE_DEPENDENCY_COUNT 3
static const ComponentType ENTITY_COLLECTIBLE_DEPENDENCIES[ENTITY_COLLECTIBLE_DEPENDENCY_COUNT] =
{
COMPONENT_ATLAS,
COMPONENT_COLLECTIBLE,
COMPONENT_ROTATE
};
EntityID entity_collectible_add(ECS* ecs, const vec3 position, CollectibleType type);

View File

@ -0,0 +1,7 @@
#include "entity_collectible_amulet.h"
EntityID
entity_collectible_amulet_add(ECS* ecs, const vec3 position)
{
return entity_collectible_add(ecs, position, COLLECTIBLE_AMULET);
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "entity_collectible.h"
EntityID entity_collectible_amulet_add(ECS* ecs, const vec3 position);

View File

@ -0,0 +1,7 @@
#include "entity_collectible_food.h"
EntityID
entity_collectible_food_add(ECS* ecs, const vec3 position)
{
return entity_collectible_add(ecs, position, COLLECTIBLE_FOOD);
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "entity_collectible.h"
EntityID entity_collectible_food_add(ECS* ecs, const vec3 position);

View File

@ -0,0 +1,11 @@
#include "entity_collectible_power.h"
EntityID
entity_collectible_power_add(ECS* ecs, const vec3 position)
{
EntityID id;
id = entity_collectible_add(ecs, position, COLLECTIBLE_POWER);
return id;
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "entity_collectible.h"
EntityID entity_collectible_power_add(ECS* ecs, const vec3 position);

View File

@ -0,0 +1,7 @@
#include "entity_collectible_rotten_food.h"
EntityID
entity_collectible_rotten_food_add(ECS* ecs, const vec3 position)
{
return entity_collectible_add(ecs, position, COLLECTIBLE_ROTTEN_FOOD);
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "entity_collectible.h"
EntityID entity_collectible_rotten_food_add(ECS* ecs, const vec3 position);

View File

@ -0,0 +1,11 @@
#include "entity_collectible_stamina.h"
EntityID
entity_collectible_stamina_add(ECS* ecs, const vec3 position)
{
EntityID id;
id = entity_collectible_add(ecs, position, COLLECTIBLE_STAMINA);
return id;
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "entity_collectible.h"
EntityID entity_collectible_stamina_add(ECS* ecs, const vec3 position);

View File

@ -0,0 +1,83 @@
#include "entity_player.h"
EntityID
entity_player_add(ECS* ecs, const vec3 position)
{
EntityID id;
ComponentWorldObject* worldObject;
ComponentColorChange* colorChange;
id = ecs_entity_add(ecs);
ecs_components_add(ecs, ENTITY_PLAYER_DEPENDENCIES, ENTITY_PLAYER_DEPENDENCY_COUNT, id);
worldObject = ecs_component_get(ecs, COMPONENT_WORLD_OBJECT, id),
component_world_object_init
(
worldObject,
ecs,
&ecs->resources->textures[TEXTURE_PLAYER],
PLAYER_SIZE,
position,
PLAYER_HEIGHT_OFFSET,
PLAYER_RADIUS
);
worldObject->angle = PLAYER_ANGLE;
component_atlas_init
(
ecs_component_get(ecs, COMPONENT_ATLAS, id),
ecs,
PLAYER_ATLAS_FRAME_SIZE,
PLAYER_ATLAS_SIZE,
PLAYER_ATLAS_INDEX
);
component_camera_focus_init
(
ecs_component_get(ecs, COMPONENT_CAMERA_FOCUS, id),
ecs,
&ecs->renderer->camera[RENDERER_BUFFER_WORLD],
id
);
component_stamina_init
(
ecs_component_get(ecs, COMPONENT_STAMINA, id),
ecs,
PLAYER_STAMINA_MAX,
PLAYER_STAMINA_GAIN
);
component_power_init
(
ecs_component_get(ecs, COMPONENT_POWER, id),
ecs,
PLAYER_POWER_MAX,
PLAYER_POWER_GAIN
);
component_collect_init
(
ecs_component_get(ecs, COMPONENT_COLLECT, id),
ecs,
PLAYER_COLLECT_RADIUS
);
component_food_init
(
ecs_component_get(ecs, COMPONENT_FOOD, id),
ecs,
0,
PLAYER_FOOD_MAX,
PLAYER_FOOD_MULTIPLIER
);
colorChange = ecs_component_get(ecs, COMPONENT_COLOR_CHANGE, id);
colorChange->component.isDisabled = true;
return id;
}

Some files were not shown because too many files have changed in this diff Show More