Files
PixelDefense/game/components.h

447 lines
12 KiB
C

#ifndef PIXELDEFENSE_COMPONENTS_H
#define PIXELDEFENSE_COMPONENTS_H
#include <breeze.h>
#include <flecs.h>
#include "constants.h"
#include "game_tileset.h"
// Needed, so we can clean up all game created entities
extern ECS_TAG_DECLARE(GameEntity);
typedef enum ResourceType {
RES_WOOD,
RES_GOLD,
RES_FOOD,
RES_COUNT,
} ResourceType;
static const char *getResourceTypePrettyName(ResourceType type) {
switch (type) {
case RES_WOOD: return "Wood";
case RES_GOLD: return "Gold";
case RES_FOOD: return "Food";
default: return "Invalid";
}
}
typedef struct Resource {
ResourceType type;
i32 amount;
} Resource;
extern ECS_COMPONENT_DECLARE(Resource);
typedef struct Owner {
Player player;
} Owner;
extern ECS_COMPONENT_DECLARE(Owner);
/**********************************************************
* Particle components
*********************************************************/
typedef struct FloatyTextParticle {
Vector2 pos;
Vector2 speed;
Color color;
Color targetColor;
char text[12];
f32 txtSize;
f32 duration;
f32 elapsed;
} FloatyTextParticle;
extern ECS_COMPONENT_DECLARE(FloatyTextParticle);
typedef struct EmitterAttachment {
ecs_entity_t baseEntity;
Vector2 offset;
} EmitterAttachment;
extern ECS_COMPONENT_DECLARE(EmitterAttachment);
typedef struct ParticleEmitter {
f32 emitterElapsed;
f32 emitterLifetime;
Vector2 pos;
struct ParticleEmitterData {
// emission
f32 emmitRate;
f32 emmitVariance;
f32 emmitVarianceMin, emmitVarianceMax;
// offset
Vector2 minOffset, maxOffset;
// startVel
Vector2 minStartVel, maxStartVel;
// endVel
Vector2 minEndVel, maxEndVel;
// startSize
f32 minStartSize, maxStartSize;
// endSize
f32 minEndSize, maxEndSize;
// startRotSpeed
f32 minStartRotSpeed, maxStartRotSpeed;
// endRotSpeed
f32 minEndRotSpeed, maxEndRotSpeed;
Color startColor, endColor;
// lifetime
f32 minLifetime, maxLifetime;
BlendMode blend;
BzTileID tileID;
} data;
ecs_entity_t targetParticles; // ParticleLayer0 / ParticleLayer1
} ParticleEmitter;
extern ECS_COMPONENT_DECLARE(ParticleEmitter);
static ParticleEmitter GET_FIREBALL_EMITTER() {
return (ParticleEmitter) {
.emitterLifetime = 2.0f,
.data.minOffset = { -2.0f, -2.0f },
.data.maxOffset = { 2.0f, 2.0f },
.data.emmitRate = 3.2f,
.data.emmitVariance = 1.0f,
.data.emmitVarianceMin = 0.0f,
.data.emmitVarianceMax = 1.0f,
.data.startColor = { 210, 40, 40, 210 },
.data.endColor = { 110, 20, 20, 110 },
.data.minLifetime = 0.3f,
.data.maxLifetime = 0.5f,
.data.minStartSize = 4.0f,
.data.maxStartSize = 6.0f,
.data.tileID = getParticleTypeTile(PARTICLE_CIRCLE),
.data.blend = BLEND_ADDITIVE
};
}
static ParticleEmitter GET_BLOOD_EMITTER() {
return (ParticleEmitter) {
.emitterLifetime = 0.3f,
.data.emmitRate = 1.8f,
.data.minOffset = { -3.6f, -3.6f },
.data.maxOffset = { 3.6f, 3.6f },
.data.minStartVel = { 4.5f, 7.3f },
.data.maxStartVel = { 2.5f, 3.3f },
.data.minEndVel = { -0.8f, 1.2f },
.data.maxEndVel = { -0.4f, 1.6f },
.data.minStartSize = 2.45f,
.data.maxStartSize = 3.3f,
.data.minEndSize = 0.8f,
.data.maxEndSize = 1.1f,
.data.minStartRotSpeed = 0.0f,
.data.maxStartRotSpeed = 360.0f,
.data.minEndRotSpeed = 400.5f,
.data.maxEndRotSpeed = 600.2f,
.data.startColor = { 210, 0, 0, 255 },
.data.endColor = { 110, 10, 10, 32 },
.data.minLifetime = 0.23,
.data.maxLifetime = 0.37,
.data.blend = BLEND_ALPHA,
.data.tileID = getParticleTypeTile(PARTICLE_SMALL_SQUARE),
};
}
typedef struct Particle {
Vector2 pos;
f32 rotation;
const Vector2 startVel, endVel;
const f32 startSize, endSize;
const f32 startRotSpeed, endRotSpeed;
const Color startColor, endColor;
const BlendMode blend: 8;
const BzTileID tileID: 24;
const f32 lifetime;
f32 elapsed;
} Particle;
static_assert(sizeof(Particle) == 64, "");
// 2 Separate components (Before entity, After entity), so we don't need to sort
typedef Particle ParticleLayer0, ParticleLayer1;
extern ECS_COMPONENT_DECLARE(ParticleLayer0);
extern ECS_COMPONENT_DECLARE(ParticleLayer1);
/**********************************************************
* Movement components
*********************************************************/
typedef BzSpatialGridID SpatialGridID;
extern ECS_COMPONENT_DECLARE(SpatialGridID);
typedef Vector2 Position, Size, Velocity, TargetPosition, Steering;
typedef f32 Rotation, Orientation;
extern ECS_COMPONENT_DECLARE(Position);
extern ECS_COMPONENT_DECLARE(Size);
extern ECS_COMPONENT_DECLARE(Velocity);
extern ECS_COMPONENT_DECLARE(Rotation);
extern ECS_COMPONENT_DECLARE(Orientation);
extern ECS_COMPONENT_DECLARE(Steering);
extern ECS_COMPONENT_DECLARE(TargetPosition);
#define PATH_DATA_SIZE 8
typedef struct PathData {
Position waypoints[PATH_DATA_SIZE];
size_t numWaypoints;
struct PathData *next;
} PathData;
typedef struct Path {
PathData *paths;
i32 curWaypoint;
} Path;
extern ECS_COMPONENT_DECLARE(Path);
/**********************************************************
* Render components
*********************************************************/
typedef struct TextureRegion {
Texture2D texture;
Rectangle rec;
bool flipX : 1;
bool flipY : 1;
} TextureRegion;
extern ECS_COMPONENT_DECLARE(TextureRegion);
/**********************************************************
* Animation components
*********************************************************/
typedef struct Animation {
EntityType entityType;
AnimType animType;
AnimationFrame frame;
AnimationSequence sequence;
BzTileset *tileset;
i32 curFrame;
f32 elapsed;
bool playInFull;
} Animation;
extern ECS_COMPONENT_DECLARE(Animation);
typedef struct Easing {
ecs_entity_t compID;
size_t memberOffset;
BzEaseType easingFunc;
// start + target * (easeStart + (easeTarget * x) + easeOffset) + offset
f32 target;
f32 start;
f32 offset;
f32 easeTarget;
f32 easeStart;
f32 easeOffset;
f32 x;
f32 elapsed;
f32 duration;
//struct Easing *next;
} Easing;
extern ECS_COMPONENT_DECLARE(Easing);
/**********************************************************
* Event components
*********************************************************/
typedef Rectangle HitBox;
typedef struct DamageEvent {
HitBox hitbox;
f32 amount;
} DamageEvent;
typedef struct HarvestEvent {
ResourceType type;
i32 amount;
} HarvestEvent;
typedef struct DepositEvent {
ResourceType type;
i32 amount;
} DepositEvent;
/**********************************************************
* Gameplay components
*********************************************************/
extern ECS_COMPONENT_DECLARE(HitBox);
extern ECS_COMPONENT_DECLARE(BzBTState);
extern ECS_COMPONENT_DECLARE(AIBlackboard);
extern ECS_TAG_DECLARE(Selectable);
extern ECS_TAG_DECLARE(Selected);
typedef struct AddPopCapacity {
i32 amount;
} AddPopCapacity;
extern ECS_COMPONENT_DECLARE(AddPopCapacity);
typedef struct ConsumePopCapacity {
i32 amount;
} ConsumePopCapacity;
extern ECS_COMPONENT_DECLARE(ConsumePopCapacity);
typedef struct Health {
f32 startHP;
f32 hp;
f32 lastChanged;
} Health;
extern ECS_COMPONENT_DECLARE(Health);
typedef struct Swarm {
i32 currWaypoint;
} Swarm;
extern ECS_COMPONENT_DECLARE(Swarm);
// Worker can:
// - Harvest
// - Build
// - Work
// - Attack (since it is also a unit)
typedef struct Worker {
// stats
f32 collectSpeed;
f32 depositSpeed;
i32 carry;
i32 carryCapacity;
ResourceType carryRes;
} Worker;
extern ECS_COMPONENT_DECLARE(Worker);
// Unit can:
// - Attack
typedef struct Unit {
f32 attackCooldown;
f32 attackElapsed;
f32 minDamage;
f32 maxDamage;
f32 maxSpeed;
f32 acceleration;
f32 deceleration;
EntityType unitType;
} Unit;
extern ECS_COMPONENT_DECLARE(Unit);
typedef struct Tower {
f32 range;
f32 projMinDamage;
f32 projMaxDamage;
f32 projMinLifespan;
f32 projMaxLifespan;
f32 projSpeed;
f32 projRadius;
i32 projDamageCount;
f32 fireCooldown;
f32 fireElapsed;
} Tower;
extern ECS_COMPONENT_DECLARE(Tower);
typedef struct Projectile {
Vector2 target;
f32 radius;
f32 damage;
ecs_entity_t lastDamaged;
i32 damageCount;
} Projectile;
extern ECS_COMPONENT_DECLARE(Projectile);
#define BUILDING_MAX_RECRUIT_SLOTS 4
typedef struct BuildingRecruitSlot {
EntityType entityType;
i32 numRecruiting;
f32 recruitTime;
f32 elapsed;
} BuildingRecruitSlot;
typedef struct BuildingRecruitInfo {
BuildingRecruitSlot slots[BUILDING_MAX_RECRUIT_SLOTS];
i32 numSlots;
} BuildingRecruitInfo;
extern ECS_COMPONENT_DECLARE(BuildingRecruitInfo);
typedef struct Building {
BuildingType type;
Vec2i pos;
Vec2i size;
} Building;
typedef struct Storage {
bool stores[RES_COUNT];
} Storage;
extern ECS_COMPONENT_DECLARE(Storage);
extern ECS_COMPONENT_DECLARE(Building);
typedef struct Harvestable {
i32 harvestLimit;
i32 harvestCount;
} Harvestable;
extern ECS_COMPONENT_DECLARE(Harvestable);
extern ECS_TAG_DECLARE(Buildable);
extern ECS_TAG_DECLARE(Attackable);
/**********************************************************
* Misc components
*********************************************************/
typedef u8 DrawLayer;
extern ECS_COMPONENT_DECLARE(DrawLayer);
typedef struct AttachedEntity {
ecs_entity_t entity;
} AttachedEntity;
extern ECS_COMPONENT_DECLARE(AttachedEntity);
typedef struct DelayDelete {
f32 time;
f32 elapsed;
} DelayDelete;
extern ECS_COMPONENT_DECLARE(DelayDelete);
void initComponentIDs(ecs_world_t *ecs);
void igTagCheckbox(const char *label, ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t tag);
typedef void(*ImGuiCompFn)(ecs_world_t *ecs, ecs_entity_t entity, ecs_entity_t comp);
void igResource(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igOwner(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igSpatialGridID(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igVec2Comp(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igFloat(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igPath(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igTextureRegion(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igAnimation(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igEasing(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igArms(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igArm(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igVisualizeBTState(const BzBTNode *node, const BzBTNodeState *state);
void igBzBTState(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igAIBlackboard(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igWorker(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
void igUnit(ecs_world_t *ecs,
ecs_entity_t entity, ecs_entity_t comp);
#endif //PIXELDEFENSE_COMPONENTS_H