first commit
This commit is contained in:
22
src/game/GAME_COMMON.h
Normal file
22
src/game/GAME_COMMON.h
Normal 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
66
src/game/ecs/ECS_COMMON.h
Normal 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;
|
||||
|
52
src/game/ecs/component/COMPONENT_COMMON.h
Normal file
52
src/game/ecs/component/COMPONENT_COMMON.h
Normal 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;
|
87
src/game/ecs/component/animation/component_animation.c
Normal file
87
src/game/ecs/component/animation/component_animation.c
Normal 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);
|
||||
}
|
44
src/game/ecs/component/animation/component_animation.h
Normal file
44
src/game/ecs/component/animation/component_animation.h
Normal 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)
|
||||
};
|
@ -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);
|
||||
}
|
199
src/game/ecs/component/animation/component_animation_player.h
Normal file
199
src/game/ecs/component/animation/component_animation_player.h
Normal 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)
|
||||
};
|
107
src/game/ecs/component/animation/component_animation_target.c
Normal file
107
src/game/ecs/component/animation/component_animation_target.c
Normal 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);
|
||||
}
|
296
src/game/ecs/component/animation/component_animation_target.h
Normal file
296
src/game/ecs/component/animation/component_animation_target.h
Normal 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)
|
||||
};
|
26
src/game/ecs/component/game/component_collect.c
Normal file
26
src/game/ecs/component/game/component_collect.c
Normal 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);
|
||||
}
|
29
src/game/ecs/component/game/component_collect.h
Normal file
29
src/game/ecs/component/game/component_collect.h
Normal 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)
|
||||
};
|
169
src/game/ecs/component/game/component_collectible.c
Normal file
169
src/game/ecs/component/game/component_collectible.c
Normal 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);
|
||||
}
|
||||
}
|
85
src/game/ecs/component/game/component_collectible.h
Normal file
85
src/game/ecs/component/game/component_collectible.h
Normal 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)
|
||||
};
|
52
src/game/ecs/component/game/component_collide_slow.c
Normal file
52
src/game/ecs/component/game/component_collide_slow.c
Normal 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);
|
||||
}
|
31
src/game/ecs/component/game/component_collide_slow.h
Normal file
31
src/game/ecs/component/game/component_collide_slow.h
Normal 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)
|
||||
};
|
26
src/game/ecs/component/game/component_food.c
Normal file
26
src/game/ecs/component/game/component_food.c
Normal 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;
|
||||
}
|
32
src/game/ecs/component/game/component_food.h
Normal file
32
src/game/ecs/component/game/component_food.h
Normal 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)
|
||||
};
|
62
src/game/ecs/component/game/component_game_object.c
Normal file
62
src/game/ecs/component/game/component_game_object.c
Normal 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);
|
||||
}
|
48
src/game/ecs/component/game/component_game_object.h
Normal file
48
src/game/ecs/component/game/component_game_object.h
Normal 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)
|
||||
};
|
31
src/game/ecs/component/game/component_homing.c
Normal file
31
src/game/ecs/component/game/component_homing.c
Normal 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);
|
||||
}
|
31
src/game/ecs/component/game/component_homing.h
Normal file
31
src/game/ecs/component/game/component_homing.h
Normal 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)
|
||||
};
|
44
src/game/ecs/component/game/component_levitate.c
Normal file
44
src/game/ecs/component/game/component_levitate.c
Normal 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;
|
||||
}
|
42
src/game/ecs/component/game/component_levitate.h
Normal file
42
src/game/ecs/component/game/component_levitate.h
Normal 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)
|
||||
};
|
111
src/game/ecs/component/game/component_plane_object.c
Normal file
111
src/game/ecs/component/game/component_plane_object.c
Normal 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);
|
||||
}
|
58
src/game/ecs/component/game/component_plane_object.h
Normal file
58
src/game/ecs/component/game/component_plane_object.h
Normal 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)
|
||||
};
|
148
src/game/ecs/component/game/component_player_control.c
Normal file
148
src/game/ecs/component/game/component_player_control.c
Normal 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);
|
||||
}
|
50
src/game/ecs/component/game/component_player_control.h
Normal file
50
src/game/ecs/component/game/component_player_control.h
Normal 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)
|
||||
};
|
16
src/game/ecs/component/game/component_power.c
Normal file
16
src/game/ecs/component/game/component_power.c
Normal 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);
|
||||
}
|
31
src/game/ecs/component/game/component_power.h
Normal file
31
src/game/ecs/component/game/component_power.h
Normal 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)
|
||||
};
|
46
src/game/ecs/component/game/component_solid.c
Normal file
46
src/game/ecs/component/game/component_solid.c
Normal 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);
|
||||
}
|
27
src/game/ecs/component/game/component_solid.h
Normal file
27
src/game/ecs/component/game/component_solid.h
Normal 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)
|
||||
};
|
13
src/game/ecs/component/game/component_stage.c
Normal file
13
src/game/ecs/component/game/component_stage.c
Normal 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)
|
||||
{
|
||||
|
||||
}
|
29
src/game/ecs/component/game/component_stage.h
Normal file
29
src/game/ecs/component/game/component_stage.h
Normal 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)
|
||||
};
|
16
src/game/ecs/component/game/component_stamina.c
Normal file
16
src/game/ecs/component/game/component_stamina.c
Normal 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);
|
||||
}
|
31
src/game/ecs/component/game/component_stamina.h
Normal file
31
src/game/ecs/component/game/component_stamina.h
Normal 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)
|
||||
};
|
37
src/game/ecs/component/game/component_take_food.c
Normal file
37
src/game/ecs/component/game/component_take_food.c
Normal 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;
|
||||
}
|
29
src/game/ecs/component/game/component_take_food.h
Normal file
29
src/game/ecs/component/game/component_take_food.h
Normal 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)
|
||||
};
|
12
src/game/ecs/component/game/component_threshold.c
Normal file
12
src/game/ecs/component/game/component_threshold.c
Normal 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;
|
||||
}
|
30
src/game/ecs/component/game/component_threshold.h
Normal file
30
src/game/ecs/component/game/component_threshold.h
Normal 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)
|
||||
};
|
213
src/game/ecs/component/game/component_world_object.c
Normal file
213
src/game/ecs/component/game/component_world_object.c
Normal 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);
|
||||
}
|
72
src/game/ecs/component/game/component_world_object.h
Normal file
72
src/game/ecs/component/game/component_world_object.h
Normal 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)
|
||||
};
|
66
src/game/ecs/component/physics/component_circle_collider.c
Normal file
66
src/game/ecs/component/physics/component_circle_collider.c
Normal 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;
|
||||
}
|
42
src/game/ecs/component/physics/component_circle_collider.h
Normal file
42
src/game/ecs/component/physics/component_circle_collider.h
Normal 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)
|
||||
};
|
@ -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];
|
||||
}
|
@ -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)
|
||||
};
|
67
src/game/ecs/component/physics/component_physics.c
Normal file
67
src/game/ecs/component/physics/component_physics.c
Normal 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;
|
||||
}
|
48
src/game/ecs/component/physics/component_physics.h
Normal file
48
src/game/ecs/component/physics/component_physics.h
Normal 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)
|
||||
};
|
48
src/game/ecs/component/ui/component_button.c
Normal file
48
src/game/ecs/component/ui/component_button.c
Normal 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;
|
||||
}
|
||||
}
|
51
src/game/ecs/component/ui/component_button.h
Normal file
51
src/game/ecs/component/ui/component_button.h
Normal 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};
|
13
src/game/ecs/component/utility/component_counter.c
Normal file
13
src/game/ecs/component/utility/component_counter.c
Normal 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++;
|
||||
}
|
29
src/game/ecs/component/utility/component_counter.h
Normal file
29
src/game/ecs/component/utility/component_counter.h
Normal 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)
|
||||
};
|
43
src/game/ecs/component/utility/component_delete_on_timer.c
Normal file
43
src/game/ecs/component/utility/component_delete_on_timer.c
Normal 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);
|
||||
}
|
31
src/game/ecs/component/utility/component_delete_on_timer.h
Normal file
31
src/game/ecs/component/utility/component_delete_on_timer.h
Normal 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)
|
||||
};
|
25
src/game/ecs/component/utility/component_timer.c
Normal file
25
src/game/ecs/component/utility/component_timer.c
Normal 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--;
|
||||
}
|
31
src/game/ecs/component/utility/component_timer.h
Normal file
31
src/game/ecs/component/utility/component_timer.h
Normal 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)
|
||||
};
|
33
src/game/ecs/component/visual/component_atlas.c
Normal file
33
src/game/ecs/component/visual/component_atlas.c
Normal 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);
|
||||
}
|
32
src/game/ecs/component/visual/component_atlas.h
Normal file
32
src/game/ecs/component/visual/component_atlas.h
Normal 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)
|
||||
};
|
66
src/game/ecs/component/visual/component_camera_focus.c
Normal file
66
src/game/ecs/component/visual/component_camera_focus.c
Normal 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;
|
||||
}
|
43
src/game/ecs/component/visual/component_camera_focus.h
Normal file
43
src/game/ecs/component/visual/component_camera_focus.h
Normal 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)
|
||||
};
|
109
src/game/ecs/component/visual/component_color_change.c
Normal file
109
src/game/ecs/component/visual/component_color_change.c
Normal 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;
|
||||
}
|
51
src/game/ecs/component/visual/component_color_change.h
Normal file
51
src/game/ecs/component/visual/component_color_change.h
Normal 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)
|
||||
};
|
34
src/game/ecs/component/visual/component_color_match.c
Normal file
34
src/game/ecs/component/visual/component_color_match.c
Normal 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);
|
||||
}
|
38
src/game/ecs/component/visual/component_color_match.h
Normal file
38
src/game/ecs/component/visual/component_color_match.h
Normal 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)
|
||||
};
|
108
src/game/ecs/component/visual/component_dialogue.c
Normal file
108
src/game/ecs/component/visual/component_dialogue.c
Normal 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);
|
||||
}
|
57
src/game/ecs/component/visual/component_dialogue.h
Normal file
57
src/game/ecs/component/visual/component_dialogue.h
Normal 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)
|
||||
};
|
67
src/game/ecs/component/visual/component_drop_shadow.c
Normal file
67
src/game/ecs/component/visual/component_drop_shadow.c
Normal 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);
|
||||
}
|
||||
|
||||
|
35
src/game/ecs/component/visual/component_drop_shadow.h
Normal file
35
src/game/ecs/component/visual/component_drop_shadow.h
Normal 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)
|
||||
};
|
42
src/game/ecs/component/visual/component_pulsate.c
Normal file
42
src/game/ecs/component/visual/component_pulsate.c
Normal 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);
|
||||
}
|
47
src/game/ecs/component/visual/component_pulsate.h
Normal file
47
src/game/ecs/component/visual/component_pulsate.h
Normal 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)
|
||||
};
|
17
src/game/ecs/component/visual/component_rotate.c
Normal file
17
src/game/ecs/component/visual/component_rotate.c
Normal 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;
|
||||
}
|
38
src/game/ecs/component/visual/component_rotate.h
Normal file
38
src/game/ecs/component/visual/component_rotate.h
Normal 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)
|
||||
};
|
45
src/game/ecs/component/visual/component_scale_value.c
Normal file
45
src/game/ecs/component/visual/component_scale_value.c
Normal 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);
|
||||
}
|
33
src/game/ecs/component/visual/component_scale_value.h
Normal file
33
src/game/ecs/component/visual/component_scale_value.h
Normal 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)
|
||||
};
|
||||
|
236
src/game/ecs/component/visual/component_text.c
Normal file
236
src/game/ecs/component/visual/component_text.c
Normal 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);
|
||||
}
|
79
src/game/ecs/component/visual/component_text.h
Normal file
79
src/game/ecs/component/visual/component_text.h
Normal 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)
|
||||
};
|
176
src/game/ecs/component/visual/component_texture_quad.c
Normal file
176
src/game/ecs/component/visual/component_texture_quad.c
Normal 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();
|
||||
}
|
85
src/game/ecs/component/visual/component_texture_quad.h
Normal file
85
src/game/ecs/component/visual/component_texture_quad.h
Normal 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};
|
128
src/game/ecs/component/visual/component_value_text.c
Normal file
128
src/game/ecs/component/visual/component_value_text.c
Normal 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);
|
||||
}
|
64
src/game/ecs/component/visual/component_value_text.h
Normal file
64
src/game/ecs/component/visual/component_value_text.h
Normal 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
71
src/game/ecs/ecs.c
Normal 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
100
src/game/ecs/ecs.h
Normal 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);
|
104
src/game/ecs/ecs_component.c
Normal file
104
src/game/ecs/ecs_component.c
Normal 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);
|
||||
}
|
13
src/game/ecs/ecs_component.h
Normal file
13
src/game/ecs/ecs_component.h
Normal 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);
|
73
src/game/ecs/ecs_component_list.c
Normal file
73
src/game/ecs/ecs_component_list.c
Normal 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));
|
||||
}
|
9
src/game/ecs/ecs_component_list.h
Normal file
9
src/game/ecs/ecs_component_list.h
Normal 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
20
src/game/ecs/ecs_entity.c
Normal 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);
|
||||
}
|
6
src/game/ecs/ecs_entity.h
Normal file
6
src/game/ecs/ecs_entity.h
Normal 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);
|
46
src/game/ecs/entity/game/entity_collectible.c
Normal file
46
src/game/ecs/entity/game/entity_collectible.c
Normal 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;
|
||||
}
|
22
src/game/ecs/entity/game/entity_collectible.h
Normal file
22
src/game/ecs/entity/game/entity_collectible.h
Normal 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);
|
7
src/game/ecs/entity/game/entity_collectible_amulet.c
Normal file
7
src/game/ecs/entity/game/entity_collectible_amulet.c
Normal 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);
|
||||
}
|
5
src/game/ecs/entity/game/entity_collectible_amulet.h
Normal file
5
src/game/ecs/entity/game/entity_collectible_amulet.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "entity_collectible.h"
|
||||
|
||||
EntityID entity_collectible_amulet_add(ECS* ecs, const vec3 position);
|
7
src/game/ecs/entity/game/entity_collectible_food.c
Normal file
7
src/game/ecs/entity/game/entity_collectible_food.c
Normal 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);
|
||||
}
|
5
src/game/ecs/entity/game/entity_collectible_food.h
Normal file
5
src/game/ecs/entity/game/entity_collectible_food.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "entity_collectible.h"
|
||||
|
||||
EntityID entity_collectible_food_add(ECS* ecs, const vec3 position);
|
11
src/game/ecs/entity/game/entity_collectible_power.c
Normal file
11
src/game/ecs/entity/game/entity_collectible_power.c
Normal 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;
|
||||
}
|
5
src/game/ecs/entity/game/entity_collectible_power.h
Normal file
5
src/game/ecs/entity/game/entity_collectible_power.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "entity_collectible.h"
|
||||
|
||||
EntityID entity_collectible_power_add(ECS* ecs, const vec3 position);
|
@ -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);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "entity_collectible.h"
|
||||
|
||||
EntityID entity_collectible_rotten_food_add(ECS* ecs, const vec3 position);
|
11
src/game/ecs/entity/game/entity_collectible_stamina.c
Normal file
11
src/game/ecs/entity/game/entity_collectible_stamina.c
Normal 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;
|
||||
}
|
5
src/game/ecs/entity/game/entity_collectible_stamina.h
Normal file
5
src/game/ecs/entity/game/entity_collectible_stamina.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "entity_collectible.h"
|
||||
|
||||
EntityID entity_collectible_stamina_add(ECS* ecs, const vec3 position);
|
83
src/game/ecs/entity/game/entity_player.c
Normal file
83
src/game/ecs/entity/game/entity_player.c
Normal 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
Reference in New Issue
Block a user