diff options
author | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-18 05:54:30 -0600 |
---|---|---|
committer | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-18 05:54:30 -0600 |
commit | f3f5fedbf591c10fa675a32103bab9480b42abe8 (patch) | |
tree | 54b46a23279cc45091393762c0d01b9c3637b729 /src/bullets.c | |
parent | 77a06748f9f394486cad833e2ca351e8dbcc7361 (diff) |
Bullet system added
Diffstat (limited to 'src/bullets.c')
-rw-r--r-- | src/bullets.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/src/bullets.c b/src/bullets.c new file mode 100644 index 0000000..10116c2 --- /dev/null +++ b/src/bullets.c @@ -0,0 +1,165 @@ +#include "bullets.h" +#include "game.h" + +Bullet createBullet(Entity entity, Vector3 direction, Vector3 offset, float damage) { + Bullet bullet = (Bullet){ + .hit = false, + .ray = (Ray){ + .position = Vector3Add(entity.position, offset), + .direction = direction, + }, + .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]; + + if (last->hit) + popBackBullets(bullets); + else if (Vector3Length(last->ray.position) >= GAME_BOUNDS) + popBackBullets(bullets); +} + +void updateBullet(Game * game, Bullet * bullet) { + int i, j; + RayCollision collision; + Ray ray; + Entity * currentEntity; + + // Already hit. + if (bullet->hit) + return; + + // Set direction. + ray.direction = bullet->ray.direction; + + // Check collision. + for (i = 0; i < game->world.entitiesCount; ++i) { + currentEntity = &game->world.entities[i]; + + // This was the entity that shot it. + 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); + + // Loop through meshes. + for (j = 0; j < currentEntity->model->meshCount; ++j) { + collision = GetRayCollisionMesh( + ray, + currentEntity->model->meshes[j], + currentEntity->model->transform + ); + + // Did hit. + if (!collision.hit) + continue; + + currentEntity->health -= bullet->damage; + bullet->hit = true; + goto afterCollisionCheck; + } + } + +afterCollisionCheck: + + // Update position. + bullet->ray.position = Vector3Add( + bullet->ray.position, + bullet->ray.direction + ); + + // Debug ray (: + //DrawRay(bullet->ray, BLUE); +} |