aboutsummaryrefslogtreecommitdiff
path: root/src/bullets.c
diff options
context:
space:
mode:
authornathansmithsmith <thenathansmithsmith@gmail.com>2023-07-20 03:08:57 -0600
committernathansmithsmith <thenathansmithsmith@gmail.com>2023-07-20 03:08:57 -0600
commit43e31b6e124da754ef928d22fbb9a1d7640aab4b (patch)
tree698f723866bd99982a6c606c63cfa0387863e2db /src/bullets.c
parentf3f5fedbf591c10fa675a32103bab9480b42abe8 (diff)
New bullet system
Diffstat (limited to 'src/bullets.c')
-rw-r--r--src/bullets.c181
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);
}