From cf200e8bf524d77e2c5e2407a1c280b67b696a36 Mon Sep 17 00:00:00 2001 From: DavoSK Date: Thu, 2 Feb 2023 22:01:03 +0100 Subject: [PATCH] weapon hit system --- code/foundation/src/models/components.h | 5 ++ code/games/survival/src/game.c | 5 +- code/games/survival/src/system_weapon.c | 93 ++++++++++++++++++++++++- 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/code/foundation/src/models/components.h b/code/foundation/src/models/components.h index 1035909..7c8fb21 100644 --- a/code/foundation/src/models/components.h +++ b/code/foundation/src/models/components.h @@ -123,6 +123,10 @@ typedef struct { uint8_t _unused; } HealthDecreased; +typedef struct { + uint8_t amount; +} Damage; + typedef struct { uint16_t id; } Classify; @@ -283,6 +287,7 @@ typedef struct { X(HealthRegen)\ X(HealDelay)\ X(HealthDecreased)\ + X(Damage)\ X(Mob)\ X(MobHuntPlayer)\ X(MobMelee)\ diff --git a/code/games/survival/src/game.c b/code/games/survival/src/game.c index 2c94ef7..472c476 100644 --- a/code/games/survival/src/game.c +++ b/code/games/survival/src/game.c @@ -8,6 +8,8 @@ #include "gui/notifications.h" +static ecs_query_t *ecs_mobpos_query = NULL; + // custom systems #include "system_mob.c" #include "system_weapon.c" @@ -18,9 +20,10 @@ void mob_systems(ecs_world_t *ecs) { ECS_SYSTEM_TICKED(ecs, MobMeleeAtk, EcsPostUpdate, components.Position, components.Mob, components.MobHuntPlayer, components.MobMelee); //NOTE(DavoSK): weapons + ecs_mobpos_query = ecs_query_new(world_ecs(), "components.Mob, components.Position"); ECS_SYSTEM_TICKED(ecs, WeaponKnifeMechanic, EcsPostUpdate, components.WeaponKnife, components.Position, components.Input); + ECS_SYSTEM_TICKED(ecs, WeaponProjectileHit, EcsPostUpdate, components.WeaponProjectile, components.Position, components.Rotation); ECS_SYSTEM_TICKED(ecs, WeaponProjectileExpire, EcsPostUpdate, components.WeaponProjectile, components.Position); - //ECS_OBSERVER(ecs, MobDetectPlayers1, EcsOnAdd, components.Mob); } diff --git a/code/games/survival/src/system_weapon.c b/code/games/survival/src/system_weapon.c index dbc7b5d..d95634e 100644 --- a/code/games/survival/src/system_weapon.c +++ b/code/games/survival/src/system_weapon.c @@ -1,3 +1,7 @@ +ZPL_DIAGNOSTIC_PUSH_WARNLEVEL(0) +#include "tinyc2.h" +ZPL_DIAGNOSTIC_POP + #define WEAPON_KNIFE_SPAWN_DELAY 20 #define WEAPON_PROJECTILE_POS_OFFSET 200.0f #define WEAPON_PROJECTILE_SPEED 500.0f @@ -71,7 +75,92 @@ void WeaponProjectileExpire(ecs_iter_t *it) { } } +zpl_vec2 rotate_point(float cx, float cy, float angle, zpl_vec2 p){ + return (zpl_vec2) { + .x = zpl_cos(angle) * (p.x - cx) - zpl_sin(angle) * (p.y - cy) + cx, + .y = zpl_sin(angle) * (p.x - cx) + zpl_cos(angle) * (p.y - cy) + cy + }; +} + void WeaponProjectileHit(ecs_iter_t *it) { - //TODO(DavoSK): hit entity, attach take damage component - //remove projectile + const WeaponProjectile *weapon = ecs_field(it, WeaponProjectile, 1); + const Position *pos = ecs_field(it, Position, 2); + const Rotation *rot = ecs_field(it, Rotation, 3); + + for (int i = 0; i < it->count; i++) { + ecs_iter_t it2 = ecs_query_iter(world_ecs(), ecs_mobpos_query); + while (ecs_query_next(&it2)) { + Mob *mob = ecs_field(&it2, Mob, 1); + Position *mob_pos = ecs_field(&it2, Position, 2); + + for (int j = 0; j < it2.count; j++) { + float p_x = pos[i].x; + float p_y = pos[i].y; + float p2_x = mob_pos[j].x /*+ v2[j].x*/; + float p2_y = mob_pos[j].y /*+ v2[j].y*/; + + //NOTE(DavoSK): since our weapon has also rotation + //we need to rotate its bbox by rot + float rot_radians = zpl_to_radians(rot[i].angle); + zpl_vec2 bbox_min = rotate_point(p_x, p_y, rot_radians, (zpl_vec2){ + .x = p_x - WORLD_BLOCK_SIZE / 2, + .y = p_y - WORLD_BLOCK_SIZE / 4 + }); + + zpl_vec2 bbox_max = rotate_point(p_x, p_y, rot_radians, (zpl_vec2){ + .x = p_x + WORLD_BLOCK_SIZE / 2, + .y = p_y + WORLD_BLOCK_SIZE / 4 + }); + + c2AABB box_a = { + .min = { .x = bbox_min.x, .y = bbox_min.y }, + .max = { .x = bbox_max.x, .y = bbox_max.y } + }; + + c2AABB box_b = { + .min = { p2_x - WORLD_BLOCK_SIZE / 2, p2_y - WORLD_BLOCK_SIZE / 4 }, + .max = { p2_x + WORLD_BLOCK_SIZE / 2, p2_y + WORLD_BLOCK_SIZE / 4 }, + }; + + float r1x = (box_a.max.x-box_a.min.x); + float r1y = (box_a.max.y-box_a.min.y); + float r1 = (r1x*r1x + r1y*r1y)*.5f; + + float r2x = (box_b.max.x-box_b.min.x); + float r2y = (box_b.max.y-box_b.min.y); + float r2 = (r2x*r2x + r2y*r2y)*.5f; + + { + float dx = (p2_x-p_x); + float dy = (p2_y-p_y); + float d = (dx*dx + dy*dy); + + if (d > r1 && d > r2) + continue; + } + + // c2Circle circle_a = { + // .p = { p_x, p_y }, + // .r = r1/2.f, + // }; + + // c2Circle circle_b = { + // .p = { p2_x, p2_y }, + // .r = r2/2.f, + // }; + + + // const void *shapes_a[] = { &circle_a, &box_a }; + // const void *shapes_b[] = { &circle_b, &box_b }; + + c2Manifold m = { 0 }; + c2Collide(&box_a, 0, C2_TYPE_AABB, &box_b, 0, C2_TYPE_AABB, &m); + + if(m.count) { + ecs_set(it->world, it2.entities[j], Damage, { .amount = weapon[i].damage }); + entity_despawn(it->entities[i]); + } + } + } + } } \ No newline at end of file