diff options
author | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-20 03:08:57 -0600 |
---|---|---|
committer | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-20 03:08:57 -0600 |
commit | 43e31b6e124da754ef928d22fbb9a1d7640aab4b (patch) | |
tree | 698f723866bd99982a6c606c63cfa0387863e2db /src/bullets.c | |
parent | f3f5fedbf591c10fa675a32103bab9480b42abe8 (diff) |
New bullet system
Diffstat (limited to 'src/bullets.c')
-rw-r--r-- | src/bullets.c | 181 |
1 files changed, 58 insertions, 123 deletions
diff --git a/src/bullets.c b/src/bullets.c index 10116c2..ea913c7 100644 --- a/src/bullets.c +++ b/src/bullets.c @@ -1,138 +1,59 @@ #include "bullets.h" #include "game.h" -Bullet createBullet(Entity entity, Vector3 direction, Vector3 offset, float damage) { - Bullet bullet = (Bullet){ - .hit = false, +Bullet createBulletFromEntity(Entity entity, float damage) { + return (Bullet){ .ray = (Ray){ - .position = Vector3Add(entity.position, offset), - .direction = direction, + entity.position, + Vector3RotateByQuaternion((Vector3){0.0, 0.0, 1.0}, entity.rotation) }, .fromId = entity.id, .fromFingerprint = entity.fingerprint, .damage = damage }; - - return bullet; -} - -void initBullets(Bullets * bullets) { - bullets->bullets = NULL; - bullets->bulletsCount = 0; -} - -void freeBullets(Bullets * bullets) { - if (bullets->bullets != NULL) - KF_FREE(bullets->bullets); -} - -KfError addBullet(Bullets * bullets, Bullet bullet) { - // Not allocated yet. - if (bullets->bullets == NULL) { - bullets->bullets = (Bullet*)KF_CALLOC(1, sizeof(Bullet)); - - if (bullets->bullets == NULL) { - ALLOCATION_ERROR; - return KFERROR; - } - - bullets->bulletsCount = 1; - bullets->bullets[0] = bullet; - return KFSUCCESS; - } - - ++bullets->bulletsCount; - - // Reallocate. - bullets->bullets = (Bullet*)KF_REALLOCARRAY( - bullets->bullets, - bullets->bulletsCount, - sizeof(Bullet) - ); - - if (bullets->bullets == NULL) { - ALLOCATION_ERROR; - return KFERROR; - } - - bullets->bullets[bullets->bulletsCount - 1] = bullet; - return KFSUCCESS; -} - -KfError popBackBullets(Bullets * bullets) { - if (bullets->bullets == NULL) - return KFSUCCESS; - - // At one. - if (bullets->bulletsCount == 1) { - KF_FREE(bullets->bullets); - bullets->bullets = NULL; - bullets->bulletsCount = 0; - return KFSUCCESS; - } - - --bullets->bulletsCount; - - // Reallocate. - bullets->bullets = (Bullet*)KF_REALLOCARRAY( - bullets->bullets, - bullets->bulletsCount, - sizeof(Bullet) - ); - - if (bullets->bullets == NULL) { - ALLOCATION_ERROR; - return KFERROR; - } - - return KFSUCCESS; } -void updateBullets(Game * game, Bullets * bullets) { - int i; - Bullet * last = NULL; - - if (bullets->bullets == NULL) - return; - - // Update each bullet. - for (i = 0; i < bullets->bulletsCount; ++i) - updateBullet(game, &bullets->bullets[i]); - - // Remove end if hit or out of bounds. - last = &bullets->bullets[bullets->bulletsCount - 1]; +BulletHitInfo handleBulletHit(Entity * entity, Bullet bullet) { + // Handle health. + entity->health -= bullet.damage; + entity->health = Clamp(entity->health, ENTITY_MIN_HEALTH, ENTITY_MAX_HEALTH); + + // Check hit info. + BulletHitInfo hitInfo = (BulletHitInfo){ + .hit = true, + .killed = entity->health == 0.0, + .hitId = entity->id, + .hitFingerprint = entity->fingerprint + }; - if (last->hit) - popBackBullets(bullets); - else if (Vector3Length(last->ray.position) >= GAME_BOUNDS) - popBackBullets(bullets); + return hitInfo; } -void updateBullet(Game * game, Bullet * bullet) { +BulletHitInfo shootBullet(World * world, Bullet bullet) { int i, j; RayCollision collision; - Ray ray; Entity * currentEntity; - - // Already hit. - if (bullet->hit) - return; + Ray ray; // Set direction. - ray.direction = bullet->ray.direction; + ray.direction = bullet.ray.direction; + + // Stores all the hits so we can find closest one. + int hits[world->entitiesCount]; + size_t hitsSize = 0; - // Check collision. - for (i = 0; i < game->world.entitiesCount; ++i) { - currentEntity = &game->world.entities[i]; + // Loop through entities. + for (i = 0; i < world->entitiesCount; ++i) { + currentEntity = &world->entities[i]; // This was the entity that shot it. - if (currentEntity->fingerprint == bullet->fromFingerprint) + if (currentEntity->fingerprint == bullet.fromFingerprint) continue; else if (currentEntity->model == NULL) // Null model indeed. continue; // Set position relative to entity. - ray.position = Vector3Subtract(bullet->ray.position, currentEntity->position); + ray.position = Vector3Subtract(bullet.ray.position, currentEntity->position); // Loop through meshes. for (j = 0; j < currentEntity->model->meshCount; ++j) { @@ -143,23 +64,37 @@ void updateBullet(Game * game, Bullet * bullet) { ); // Did hit. - if (!collision.hit) - continue; - - currentEntity->health -= bullet->damage; - bullet->hit = true; - goto afterCollisionCheck; + if (collision.hit) { + hits[hitsSize] = i; + ++hitsSize; + break; + } } } -afterCollisionCheck: - - // Update position. - bullet->ray.position = Vector3Add( - bullet->ray.position, - bullet->ray.direction - ); + // No hits. + if (hitsSize == 0) + return (BulletHitInfo){ + .hit = false, + .killed = false, + .hitId = ENTITY_NONE, + }; + + float dis = Vector3Distance(world->entities[hits[0]].position, bullet.ray.position); + float closest = dis; + int closestNum = 0; + + // Find closest. + for (i = 0; i < hitsSize; ++i) { + dis = Vector3Distance(world->entities[hits[i]].position, bullet.ray.position); + + // This fucker is closer. + if (dis < closest) { + closest = dis; + closestNum = i; + } + } - // Debug ray (: - //DrawRay(bullet->ray, BLUE); + // Handle closest bullet. + return handleBulletHit(&world->entities[hits[closestNum]], bullet); } |