aboutsummaryrefslogtreecommitdiff
path: root/src/bullets.c
diff options
context:
space:
mode:
authornathansmithsmith <thenathansmithsmith@gmail.com>2023-07-18 05:54:30 -0600
committernathansmithsmith <thenathansmithsmith@gmail.com>2023-07-18 05:54:30 -0600
commitf3f5fedbf591c10fa675a32103bab9480b42abe8 (patch)
tree54b46a23279cc45091393762c0d01b9c3637b729 /src/bullets.c
parent77a06748f9f394486cad833e2ca351e8dbcc7361 (diff)
Bullet system added
Diffstat (limited to 'src/bullets.c')
-rw-r--r--src/bullets.c165
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);
+}