#include "bullets.h" #include "game.h" Bullet createBulletFromEntity(Entity entity, float damage) { return (Bullet){ .ray = (Ray){ entity.position, Vector3RotateByQuaternion((Vector3){0.0, 0.0, 1.0}, entity.rotation) }, .fromId = entity.id, .fromFingerprint = entity.fingerprint, .damage = damage }; } 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 }; return hitInfo; } BulletHitInfo shootBullet(World * world, Bullet bullet) { int i, j; RayCollision collision; Entity * currentEntity; Ray ray; // Set direction. ray.direction = bullet.ray.direction; // Stores all the hits so we can find closest one. int hits[world->entitiesCount]; size_t hitsSize = 0; // 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) 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) { hits[hitsSize] = i; ++hitsSize; break; } } } // 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; } } // Handle closest bullet. return handleBulletHit(&world->entities[hits[closestNum]], bullet); }