Add weapons
This commit is contained in:
@@ -16,6 +16,7 @@ ECS_COMPONENT_DECLARE(Position);
|
||||
ECS_COMPONENT_DECLARE(Size);
|
||||
ECS_COMPONENT_DECLARE(Velocity);
|
||||
ECS_COMPONENT_DECLARE(Rotation);
|
||||
ECS_COMPONENT_DECLARE(Orientation);
|
||||
ECS_COMPONENT_DECLARE(Steering);
|
||||
ECS_COMPONENT_DECLARE(TargetPosition);
|
||||
ECS_COMPONENT_DECLARE(Path);
|
||||
@@ -25,6 +26,8 @@ ECS_COMPONENT_DECLARE(TextureRegion);
|
||||
ECS_COMPONENT_DECLARE(Animation);
|
||||
ECS_COMPONENT_DECLARE(Easing);
|
||||
|
||||
ECS_COMPONENT_DECLARE(Arms);
|
||||
ECS_COMPONENT_DECLARE(Arm);
|
||||
ECS_COMPONENT_DECLARE(UnitAI);
|
||||
ECS_COMPONENT_DECLARE(UnitAction);
|
||||
|
||||
@@ -53,6 +56,7 @@ void initComponentIDs(ecs_world_t *ecs) {
|
||||
ECS_COMPONENT_DEFINE(ecs, Size);
|
||||
ECS_COMPONENT_DEFINE(ecs, Velocity);
|
||||
ECS_COMPONENT_DEFINE(ecs, Rotation);
|
||||
ECS_COMPONENT_DEFINE(ecs, Orientation);
|
||||
ECS_COMPONENT_DEFINE(ecs, Steering);
|
||||
ECS_COMPONENT_DEFINE(ecs, TargetPosition);
|
||||
ECS_COMPONENT_DEFINE(ecs, Path);
|
||||
@@ -62,6 +66,8 @@ void initComponentIDs(ecs_world_t *ecs) {
|
||||
ECS_COMPONENT_DEFINE(ecs, Animation);
|
||||
ECS_COMPONENT_DEFINE(ecs, Easing);
|
||||
|
||||
ECS_COMPONENT_DEFINE(ecs, Arms);
|
||||
ECS_COMPONENT_DEFINE(ecs, Arm);
|
||||
ECS_COMPONENT_DEFINE(ecs, UnitAI);
|
||||
ECS_COMPONENT_DEFINE(ecs, UnitAction);
|
||||
|
||||
|
||||
@@ -60,12 +60,13 @@ typedef BzSpatialGridID SpatialGridID;
|
||||
extern ECS_COMPONENT_DECLARE(SpatialGridID);
|
||||
|
||||
typedef Vector2 Position, Size, Velocity, TargetPosition, Steering;
|
||||
typedef f32 Rotation;
|
||||
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);
|
||||
|
||||
@@ -152,20 +153,31 @@ typedef struct EntityArms {
|
||||
* Gameplay components
|
||||
*********************************************************/
|
||||
|
||||
typedef Vector2 ItemOffset;
|
||||
|
||||
typedef struct WeaponMelee {
|
||||
|
||||
ecs_entity_t weapon;
|
||||
f32 reach;
|
||||
f32 damage;
|
||||
f32 speed;
|
||||
} WeaponMelee;
|
||||
typedef struct WeaponRanged {
|
||||
|
||||
ecs_entity_t weapon;
|
||||
int32_t ammo;
|
||||
} WeaponRanged;
|
||||
typedef struct WeaponShield {
|
||||
|
||||
ecs_entity_t weapon;
|
||||
} WeaponShield;
|
||||
typedef struct AttachedWeapons {
|
||||
typedef struct Arms {
|
||||
ecs_entity_t primary;
|
||||
ecs_entity_t secondary;
|
||||
} AttachedWeapons;
|
||||
} Arms;
|
||||
extern ECS_COMPONENT_DECLARE(Arms);
|
||||
typedef struct Arm {
|
||||
f32 offset;
|
||||
f32 extended;
|
||||
} Arm;
|
||||
extern ECS_COMPONENT_DECLARE(Arm);
|
||||
|
||||
extern ECS_COMPONENT_DECLARE(UnitAction);
|
||||
extern ECS_COMPONENT_DECLARE(UnitAI);
|
||||
|
||||
@@ -18,6 +18,7 @@ ecs_entity_t entityCreateWorker(const Position position, Game *game) {
|
||||
size.x, size.y);
|
||||
ecs_set(ECS, e, SpatialGridID, { spatialID });
|
||||
ecs_set(ECS, e, Rotation, { 0.0f });
|
||||
ecs_set(ECS, e, Orientation, {0.0f});
|
||||
ecs_set(ECS, e, Velocity, {});
|
||||
ecs_set(ECS, e, Steering, {});
|
||||
TextureRegion workerRegion = {
|
||||
@@ -46,5 +47,19 @@ ecs_entity_t entityCreateWorker(const Position position, Game *game) {
|
||||
.depositSpeed = 0.2f,
|
||||
.carryCapacity = 5,
|
||||
});
|
||||
|
||||
ecs_entity_t right = entityCreateEmpty();
|
||||
Arms arms = {.primary = right};
|
||||
ecs_set_ptr(ECS, e, Arms, &arms);
|
||||
ecs_set(ECS, right, Arm, {.offset = 45.0f, 4.5f});
|
||||
|
||||
ecs_set(ECS, right, Size, {8, 8});
|
||||
ecs_set(ECS, right, Rotation, { 0.0f });
|
||||
TextureRegion daggerRegion = {
|
||||
tileset->tiles,
|
||||
bzTilesetGetTileRegion(tileset, getItemTile(ITEM_AXE))
|
||||
};
|
||||
ecs_set_ptr(ECS, right, TextureRegion, &daggerRegion);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -393,4 +393,55 @@ static AnimationFrame entityGetAnimationFrame(EntityType entity, AnimType type,
|
||||
return (AnimationFrame) {-1, -1.0f};
|
||||
}
|
||||
|
||||
typedef enum ItemType {
|
||||
ITEM_STAFF,
|
||||
ITEM_PICKAXE,
|
||||
ITEM_AXE,
|
||||
ITEM_DAGGER,
|
||||
ITEM_WOOD_SHIELD,
|
||||
ITEM_SHIELD,
|
||||
ITEM_IRON_SHIELD,
|
||||
ITEM_BOW,
|
||||
ITEM_JAVLIN,
|
||||
ITEM_ARROW,
|
||||
ITEM_SWORD,
|
||||
ITEM_GREATSWORD,
|
||||
ITEM_CUTLASS,
|
||||
ITEM_BATTLEAXE,
|
||||
ITEM_GREATEAXE,
|
||||
ITEM_SYTHE,
|
||||
ITEM_MACE,
|
||||
ITEM_BATTLEHAMMER,
|
||||
ITEM_SPEAR,
|
||||
ITEM_TRIDENT,
|
||||
ITEM_COUNT,
|
||||
ITEM_NONE,
|
||||
} ItemType;
|
||||
|
||||
static ItemType getItemTile(ItemType type) {
|
||||
switch (type) {
|
||||
case ITEM_STAFF: return 7680;
|
||||
case ITEM_PICKAXE: return 7681;
|
||||
case ITEM_AXE: return 7682;
|
||||
case ITEM_DAGGER: return 7683;
|
||||
case ITEM_WOOD_SHIELD: return 7936;
|
||||
case ITEM_SHIELD: return 7937;
|
||||
case ITEM_IRON_SHIELD: return 7938;
|
||||
case ITEM_BOW: return 7939;
|
||||
case ITEM_JAVLIN: return 7942;
|
||||
case ITEM_ARROW: return 7943;
|
||||
case ITEM_SWORD: return 8192;
|
||||
case ITEM_GREATSWORD: return 8193;
|
||||
case ITEM_CUTLASS: return 8194;
|
||||
case ITEM_BATTLEAXE: return 8195;
|
||||
case ITEM_GREATEAXE: return 8196;
|
||||
case ITEM_SYTHE: return 8197;
|
||||
case ITEM_MACE: return 8198;
|
||||
case ITEM_BATTLEHAMMER: return 8199;
|
||||
case ITEM_SPEAR: return 8200;
|
||||
case ITEM_TRIDENT: return 8201;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GAME_TILESET_H
|
||||
|
||||
34
game/main.c
34
game/main.c
@@ -313,6 +313,7 @@ static void renderGame(Game *game, float dt) {
|
||||
// Entities
|
||||
bzArrayClear(game->drawData);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, game->drawQuery);
|
||||
ecs_entity_t worker = 0;
|
||||
while (ecs_iter_next(&it)) {
|
||||
Position *p = ecs_field(&it, Position, 1);
|
||||
Size *s = ecs_field(&it, Size, 2);
|
||||
@@ -320,6 +321,9 @@ static void renderGame(Game *game, float dt) {
|
||||
TextureRegion *t = ecs_field(&it, TextureRegion, 4);
|
||||
for (i32 i = 0; i < it.count; i++) {
|
||||
Rectangle dst = {p[i].x, p[i].y, s[i].x, s[i].y};
|
||||
if (dst.width == 10 && dst.height == 10) {
|
||||
worker = it.entities[i];
|
||||
}
|
||||
Vector2 origin = {dst.width * 0.5f, dst.height};
|
||||
dst.x += origin.x - dst.width * 0.5f;
|
||||
dst.y += origin.y - dst.height * 0.5f;
|
||||
@@ -327,8 +331,8 @@ static void renderGame(Game *game, float dt) {
|
||||
// Fixes texture bleeding issue
|
||||
src.x += 0.01f;
|
||||
src.y += 0.01f;
|
||||
src.width -= 0.01f;
|
||||
src.height -= 0.01f;
|
||||
src.width -= 0.02f;
|
||||
src.height -= 0.02f;
|
||||
if (t[i].flipX) src.width *= -1.0f;
|
||||
if (t[i].flipY) src.height *= -1.0f;
|
||||
bzArrayPush(game->drawData, (DrawData) {
|
||||
@@ -346,6 +350,32 @@ static void renderGame(Game *game, float dt) {
|
||||
DrawData draw = game->drawData[i];
|
||||
DrawTexturePro(draw.tex, draw.src, draw.dst, draw.origin, draw.rotation, WHITE);
|
||||
}
|
||||
Vector2 target = GetMousePosition();
|
||||
target = GetScreenToWorld2D(target, game->camera);
|
||||
static f32 elapsed = 0;
|
||||
static bool attack = false;
|
||||
static Vector2 lockedTarget;
|
||||
if (!attack && IsMouseButtonPressed(0)) {
|
||||
attack = true;
|
||||
lockedTarget = target;
|
||||
elapsed = 0;
|
||||
}
|
||||
elapsed += dt * 2;
|
||||
elapsed = Clamp(elapsed, 0, 1.0f);
|
||||
attack = false;
|
||||
if (worker && false) {
|
||||
Position *pos = ecs_get_mut(ECS, worker, Position);
|
||||
DrawCircle(pos->x, pos->y, 2.0f, BLUE);
|
||||
Vector2 attackVector = Vector2Subtract(lockedTarget, *pos);
|
||||
attackVector = Vector2Normalize(attackVector);
|
||||
attackVector = Vector2Scale(attackVector, 2.0f);
|
||||
DrawLine(pos->x, pos->y, pos->x + attackVector.x, pos->y + attackVector.y, RED);
|
||||
Rotation *rot = ecs_get_mut(ECS, worker, Rotation);
|
||||
f32 targetRot = Vector2Angle(*pos, lockedTarget);
|
||||
targetRot += 25 * DEG2RAD;
|
||||
*rot = targetRot * bzEase(BZ_EASE_IN_BACK, elapsed);
|
||||
bzLogInfo("%.2f", Vector2Angle(*pos, lockedTarget) * RAD2DEG);
|
||||
}
|
||||
|
||||
ecs_progress(ECS, dt);
|
||||
ecs_enable(ECS, renderDebugPathSystem, game->debugDraw.path);
|
||||
|
||||
@@ -141,6 +141,31 @@ void entityFollowPath(ecs_iter_t *it) {
|
||||
}
|
||||
}
|
||||
|
||||
static void entityUpdateArm(ecs_entity_t armEntity, Position pos, Velocity vel,
|
||||
Rotation rot, Orientation orient) {
|
||||
if (!armEntity) return;
|
||||
const Arm arm = *ecs_get(ECS, armEntity, Arm);
|
||||
|
||||
Vector2 v = {arm.extended, 0.0f};
|
||||
v = Vector2Rotate(v, orient + arm.offset);
|
||||
v = Vector2Add(v, pos);
|
||||
ecs_set_ptr(ECS, armEntity, Position, &v);
|
||||
}
|
||||
void entityUpdateArms(ecs_iter_t *it) {
|
||||
Position *position = ecs_field(it, Position, 1);
|
||||
Velocity *velocity = ecs_field(it, Velocity, 2);
|
||||
Rotation *rotation = ecs_field(it, Rotation, 3);
|
||||
Orientation *orientation = ecs_field(it, Orientation, 4);
|
||||
Arms *arms = ecs_field(it, Arms, 5);
|
||||
|
||||
for (i32 i = 0; i < it->count; i++) {
|
||||
entityUpdateArm(arms[i].primary, position[i], velocity[i],
|
||||
rotation[i], orientation[i]);
|
||||
entityUpdateArm(arms[i].secondary, position[i], velocity[i],
|
||||
rotation[i], orientation[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void renderColliders(ecs_iter_t *it) {
|
||||
Position *pos = ecs_field(it, Position, 1);
|
||||
Size *size = ecs_field(it, Size, 2);
|
||||
@@ -152,19 +177,27 @@ void renderColliders(ecs_iter_t *it) {
|
||||
}
|
||||
}
|
||||
|
||||
void renderRotationDirection(ecs_iter_t *it) {
|
||||
void renderOrientationDirection(ecs_iter_t *it) {
|
||||
Position *pos = ecs_field(it, Position, 1);
|
||||
Rotation *rot = ecs_field(it, Rotation, 2);
|
||||
Orientation *orientation = ecs_field(it, Orientation, 2);
|
||||
|
||||
for (i32 i = 0; i < it->count; i++) {
|
||||
Vector2 v = {10.0f, 0.0f};
|
||||
v = Vector2Rotate(v, rot[i]);
|
||||
Vector2 v = {6.0f, 0.0f};
|
||||
v = Vector2Rotate(v, orientation[i]);
|
||||
v = Vector2Add(v, pos[i]);
|
||||
DrawCircle(v.x, v.y, 1.0f, RED);
|
||||
DrawLine(pos->x, pos->y, v.x, v.y, RED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void renderArmPosition(ecs_iter_t *it) {
|
||||
Position *pos = ecs_field(it, Position, 1);
|
||||
Arm *arm = ecs_field(it, Arm, 2);
|
||||
|
||||
for (i32 i = 0; i < it->count; i++) {
|
||||
DrawCircle(pos[i].x, pos[i].y, 1.5f, ORANGE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void renderDebugPath(ecs_iter_t *it) {
|
||||
Path *path = ecs_field(it, Path, 1);
|
||||
|
||||
@@ -124,7 +124,12 @@ void inputUnitAction(Game *game, InputState *input) {
|
||||
while (ecs_iter_next(&it)) {
|
||||
for (i32 i = 0; i < it.count; i++) {
|
||||
const ecs_entity_t entity = it.entities[i];
|
||||
entitySetPath(entity, target, game);
|
||||
clearActions(entity, game);
|
||||
addAction(entity, game, &(const Action) {
|
||||
.type = ACTION_MOVE_TO,
|
||||
.as.moveTo.target = target,
|
||||
.as.moveTo.proximityThreshold = 6.0f,
|
||||
});
|
||||
}
|
||||
}
|
||||
ecs_defer_end(ECS);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "../game_state.h"
|
||||
|
||||
ecs_entity_t renderCollidersSystem;
|
||||
ecs_entity_t renderOrientDirSystem;
|
||||
ecs_entity_t renderArmPositionSystem;
|
||||
ecs_entity_t renderDebugPathSystem;
|
||||
|
||||
ECS_DTOR(SpatialGridID, gridID, {
|
||||
@@ -43,6 +45,7 @@ void setupSystems() {
|
||||
|
||||
ECS_SYSTEM(ECS, entityMoveToTarget, EcsOnUpdate, Position, Velocity, TargetPosition, Steering);
|
||||
ECS_SYSTEM(ECS, entityFollowPath, EcsOnUpdate, Path);
|
||||
ECS_SYSTEM(ECS, entityUpdateArms, EcsOnUpdate, Position, Velocity, Rotation, Orientation, Arms);
|
||||
|
||||
ECS_SYSTEM(ECS, handleUnitActionsSystem, EcsOnUpdate, UnitAction);
|
||||
ECS_SYSTEM(ECS, updateUnitAISystem, EcsOnUpdate, UnitAI, UnitAction);
|
||||
@@ -56,9 +59,14 @@ void setupSystems() {
|
||||
ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path);
|
||||
|
||||
ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, Size);
|
||||
ECS_SYSTEM(ECS, renderRotationDirection, EcsOnUpdate, Position, Rotation);
|
||||
ECS_SYSTEM(ECS, renderOrientationDirection, EcsOnUpdate, Position, Orientation);
|
||||
ECS_SYSTEM(ECS, renderArmPosition, EcsOnUpdate, Position, Arm);
|
||||
|
||||
renderDebugPathSystem = renderDebugPath;
|
||||
renderOrientDirSystem = renderOrientationDirection;
|
||||
renderArmPositionSystem = renderArmPosition;
|
||||
renderCollidersSystem = renderColliders;
|
||||
|
||||
ecs_enable(ECS, renderOrientDirSystem, false);
|
||||
ecs_enable(ECS, renderArmPositionSystem, false);
|
||||
}
|
||||
|
||||
@@ -101,6 +101,15 @@ void entityMoveToTarget(ecs_iter_t *it);
|
||||
*/
|
||||
void entityFollowPath(ecs_iter_t *it);
|
||||
|
||||
/*
|
||||
* 1. Position
|
||||
* 2. Velocity
|
||||
* 3. Rotation
|
||||
* 4. Orientation
|
||||
* 5. Arms
|
||||
*/
|
||||
void entityUpdateArms(ecs_iter_t *it);
|
||||
|
||||
|
||||
/*
|
||||
* 1: Position
|
||||
@@ -110,9 +119,15 @@ void renderColliders(ecs_iter_t *it);
|
||||
|
||||
/*
|
||||
* 1: Position
|
||||
* 2: Rotation
|
||||
* 2: Orientation
|
||||
*/
|
||||
void renderRotationDirection(ecs_iter_t *it);
|
||||
void renderOrientationDirection(ecs_iter_t *it);
|
||||
|
||||
/*
|
||||
* 1. Position
|
||||
* 2. Arm
|
||||
*/
|
||||
void renderArmPosition(ecs_iter_t *it);
|
||||
|
||||
/*
|
||||
* 1: Path
|
||||
@@ -161,6 +176,8 @@ void drawPlayerInputUI();
|
||||
**********************************/
|
||||
|
||||
extern ecs_entity_t renderCollidersSystem;
|
||||
extern ecs_entity_t renderOrientDirSystem;
|
||||
extern ecs_entity_t renderArmPositionSystem;
|
||||
extern ecs_entity_t renderDebugPathSystem;
|
||||
|
||||
void setupSystems();
|
||||
|
||||
@@ -12,8 +12,14 @@ void actionMoveTo(ecs_entity_t entity, Action *action, Game *game) {
|
||||
entitySetPath(entity, target, game);
|
||||
return;
|
||||
}
|
||||
Vector2 pos = *ecs_get(ECS, entity, Position);
|
||||
|
||||
const f32 dt = GetFrameTime();
|
||||
const Vector2 pos = *ecs_get(ECS, entity, Position);
|
||||
if (ecs_has(ECS, entity, Orientation)) {
|
||||
Orientation *orientation = ecs_get_mut(ECS, entity, Orientation);
|
||||
f32 dif = Vector2Angle(pos, target) - *orientation;
|
||||
dif = Clamp(dif, -10, 10) * dt * 10;
|
||||
*orientation += dif;
|
||||
}
|
||||
f32 dst = Vector2Distance(pos, target);
|
||||
if (dst < action->as.moveTo.proximityThreshold) {
|
||||
action->finished = true;
|
||||
|
||||
Reference in New Issue
Block a user