#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); }