aboutsummaryrefslogtreecommitdiff
path: root/src
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
parentf3f5fedbf591c10fa675a32103bab9480b42abe8 (diff)
New bullet system
Diffstat (limited to 'src')
-rw-r--r--src/bullets.c181
-rw-r--r--src/bullets.h29
-rw-r--r--src/entities/antifaShip.c22
-rw-r--r--src/entity.c28
-rw-r--r--src/entity.h16
-rw-r--r--src/game.c13
-rw-r--r--src/game.h1
-rw-r--r--src/gameScreen.c31
-rw-r--r--src/playerCamera.c27
-rw-r--r--src/playerCamera.h2
-rw-r--r--src/world.c54
11 files changed, 217 insertions, 187 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);
}
diff --git a/src/bullets.h b/src/bullets.h
index a01a967..eb6c15c 100644
--- a/src/bullets.h
+++ b/src/bullets.h
@@ -1,34 +1,29 @@
#include "gameCommon.h"
#include "entity.h"
+#include "world.h"
#ifndef BULLET_H
#define BULLET_H
// Just a simple, deadly, bullet.
typedef struct Bullet {
- bool hit;
Ray ray;
EntityId fromId;
- EntityFingerprint fromFingerprint; // Shooter gets shot before bullet hits object hehe.
+ EntityFingerprint fromFingerprint;
float damage;
} Bullet;
-// All the simple, deadly, bullets.
-typedef struct Bullets {
- Bullet * bullets;
- size_t bulletsCount;
-} Bullets;
-
-// Create the simple, deadly, bullet. offset is the bullet offset from the entity.
-Bullet createBullet(Entity entity, Vector3 direction, Vector3 offset, float damage);
-
-void initBullets(Bullets * bullets);
-void freeBullets(Bullets * bullets);
+typedef struct BulletHitInfo {
+ bool hit;
+ bool killed;
+ EntityId hitId;
+ EntityFingerprint hitFingerprint;
+} BulletHitInfo;
-KfError addBullet(Bullets * bullets, Bullet bullet);
-KfError popBackBullets(Bullets * bullets);
+// Uses entity postion and direction to create bullet ray.
+Bullet createBulletFromEntity(Entity entity, float damage);
-void updateBullets(Game * game, Bullets * bullets);
-void updateBullet(Game * game, Bullet * bullet);
+// Shoot this fucker.
+BulletHitInfo shootBullet(World * world, Bullet bullet);
#endif
diff --git a/src/entities/antifaShip.c b/src/entities/antifaShip.c
index 2d58510..1b90ea7 100644
--- a/src/entities/antifaShip.c
+++ b/src/entities/antifaShip.c
@@ -44,19 +44,15 @@ void controlAntifaShipJoystick(Game * game, Entity * entity) {
// Shoot button.
if (IsGamepadButtonPressed(gamePadNum, 8)) {
- Vector3 dir = Vector3Normalize(Vector3Subtract(
- getEntityFromWorld(game->world, 1)->position,
- entity->position
- ));
-
- Bullet bullet = createBullet(
- *entity,
- dir,
- Vector3Zero(),
- 0.1
- );
-
- addBullet(&game->bullets, bullet);
+ Bullet bullet = createBulletFromEntity(*entity, 1.0);
+ BulletHitInfo info = shootBullet(&game->world, bullet);
+
+ if (info.hit) {
+ Entity * hitEntity = getEntityFromWorld(game->world, info.hitId);
+ printVector3(hitEntity->position);
+ } else {
+ puts("no stink");
+ }
}
Vector3 stick = (Vector3){
diff --git a/src/entity.c b/src/entity.c
index 285744d..9c6e5e3 100644
--- a/src/entity.c
+++ b/src/entity.c
@@ -60,7 +60,8 @@ Entity createEntity(EntityType type, Game * game) {
.useAcceleration = false,
.updateCb = info.updateCb,
.drawCb = info.drawCb,
- .health = 1.0,
+ .health = ENTITY_MAX_HEALTH,
+ .collision.hit = false,
.data = NULL
};
@@ -74,6 +75,28 @@ void closeEntity(Entity * entity) {
entityTypeInfo[entity->type].closeCb(entity);
}
+bool entitiesCollide(Entity entity1, Entity entity2) {
+ int i;
+ Vector3 triangle[3];
+
+ /*
+ for (i = 0; i < mesh.triangleCount; ++i) {
+
+ for (j = 0; j < 3; ++j)
+ triangle[j] = (Vector3){
+ mesh.vertices[(i * 9) + (j * 3)],
+ mesh.vertices[(i * 9) + (j * 3) + 1],
+ mesh.vertices[(i * 9) + (j * 3) + 2],
+ };
+
+ DrawLine3D(triangle[0], triangle[1], BLUE);
+ DrawLine3D(triangle[1], triangle[2], BLUE);
+ DrawLine3D(triangle[2], triangle[0], BLUE);
+ }
+ */
+ return false;
+}
+
// Basic wireframe drawing.
void entityDraw(Entity * entity) {
entity->model->transform = QuaternionToMatrix(entity->rotation);
@@ -81,7 +104,7 @@ void entityDraw(Entity * entity) {
DrawModelWires(
*entity->model,
entity->position,
- 1,
+ 1.0,
GREEN
);
}
@@ -107,6 +130,7 @@ void entityUpdateRotation(Entity * entity) {
);
entity->rotation = QuaternionMultiply(entity->rotation, angularRotation);
+ entity->rotation = QuaternionNormalize(entity->rotation);
}
void entityJoystickControl(Entity * entity, Vector3 stick, float speed) {
diff --git a/src/entity.h b/src/entity.h
index dc6be72..844386c 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -45,11 +45,23 @@ typedef struct EntityVelocity {
EntityVelocity entityVelocityIdentity();
+// This fucker hit something.
+typedef struct EntityCollision {
+ bool hit;
+ EntityId fromId;
+ EntityFingerprint fromFingerprint;
+} EntityCollision;
+
+// Health stuff.
+#define ENTITY_MIN_HEALTH 0.0
+#define ENTITY_MAX_HEALTH 1.0
+
// This fucker is a entity.
typedef struct Entity {
EntityId id;
EntityFingerprint fingerprint;
EntityType type;
+
Model * model;
Vector3 position;
@@ -67,6 +79,8 @@ typedef struct Entity {
// Health is a percent from 1.0 to 0.0.
float health;
+ EntityCollision collision;
+
// Used for whatever.
void * data;
} Entity;
@@ -88,6 +102,8 @@ const extern EntityTypeInfo entityTypeInfo[ENTITY_TYPE_COUNT];
Entity createEntity(EntityType type, Game * game);
void closeEntity(Entity * entity);
+bool entitiesCollide(Entity entity1, Entity entity2);
+
// Helper functions for updating and drawing.
void entityDraw(Entity * entity);
void entityUpdatePosition(Entity * entity);
diff --git a/src/game.c b/src/game.c
index 5bf35c4..5141270 100644
--- a/src/game.c
+++ b/src/game.c
@@ -19,19 +19,19 @@ void initGame(Game * game) {
// Camera.
initPlayerCamera(&game->playerCamera);
-
- // Bullets.
- initBullets(&game->bullets);
// World.
initWorld(&game->world);
// Debug.
- WorldEntry entries[] = {
- (WorldEntry){ENTITY_ANTIFA, Vector3Zero(), QuaternionIdentity()},
- (WorldEntry){ENTITY_SOLDATO, (Vector3){0.0, 0.0, 10.0}, QuaternionIdentity()}
+ WorldEntry entries[101] = {
+ (WorldEntry){ENTITY_ANTIFA, Vector3Zero(), QuaternionIdentity()},
};
+ for (int i = 1; i < 101; ++i) {
+ entries[i] = (WorldEntry){ENTITY_CAPORALE, (Vector3){0.0, 0.0, i*10}, QuaternionIdentity()};
+ }
+
addEntriesToWorld(
&game->world,
game,
@@ -42,7 +42,6 @@ void initGame(Game * game) {
void closeGame(Game * game) {
unloadAssets(&game->assets);
- freeBullets(&game->bullets);
freeWorld(&game->world);
// Close window last.
diff --git a/src/game.h b/src/game.h
index 555b5b4..063a1cc 100644
--- a/src/game.h
+++ b/src/game.h
@@ -24,7 +24,6 @@ typedef struct Game {
Assets assets;
World world;
Settings settings;
- Bullets bullets;
} Game;
void initGame(Game * game);
diff --git a/src/gameScreen.c b/src/gameScreen.c
index 286a026..65b020c 100644
--- a/src/gameScreen.c
+++ b/src/gameScreen.c
@@ -3,27 +3,46 @@
#include "world.h"
#include "bullets.h"
+void drawCrossHair(float size, float thick, Color color) {
+ Vector3 center = (Vector3){GetScreenWidth() / 2.0, GetScreenHeight() / 2.0};
+
+ // Left to right.
+ DrawLineEx(
+ (Vector2){center.x - size, center.y},
+ (Vector2){center.x + size, center.y},
+ thick,
+ color
+ );
+
+ // Top to bottom.
+ DrawLineEx(
+ (Vector2){center.x, center.y - size},
+ (Vector2){center.x, center.y + size},
+ thick,
+ color
+ );
+}
+
void updateGameScreen(Game * game) {
+ ClearBackground(BLACK);
+
+ // Draw cross hair.
+ drawCrossHair(10.0, 2.0, BLUE);
// Update world.
updateWorld(&game->world, game);
- ClearBackground(BLACK);
-
// Camera.
updatePlayerCamera(&game->playerCamera, game);
+ // Draw.
BeginMode3D(game->playerCamera);
DrawGrid(50, 25.0);
- //DrawSphereWires(Vector3Zero(), GAME_BOUNDS, 32, 32, WHITE);
-
// Draw world.
drawWorld(&game->world, game);
- updateBullets(game, &game->bullets);
-
EndMode3D();
}
diff --git a/src/playerCamera.c b/src/playerCamera.c
index ded59b7..6b165f3 100644
--- a/src/playerCamera.c
+++ b/src/playerCamera.c
@@ -12,25 +12,18 @@ void initPlayerCamera(Camera3D * camera) {
void updatePlayerCamera(Camera3D * camera, Game * game) {
Entity * player = getEntityFromWorld(game->world, 0);
- camera->target = player->position;
+ Vector3 direction = Vector3RotateByQuaternion((Vector3){0.0, 0.0, 1.0}, player->rotation);
- Matrix m = QuaternionToMatrix(QuaternionInvert(player->rotation));
- Vector3 pos = (Vector3){0.0, CAMERA_DIS/2, -CAMERA_DIS};
+ // Position.
+ camera->position = Vector3Add(player->position, Vector3Scale(direction, CAMERA_DIS));
- camera->position = (Vector3){
- m.m0 * pos.x + m.m1 * pos.y + m.m2 * pos.z,
- m.m4 * pos.x + m.m5 * pos.y + m.m6 * pos.z,
- m.m8 * pos.x + m.m9 * pos.y + m.m10 * pos.z
- };
-
- camera->position = Vector3Add(camera->position, player->position);
+ // Target.
+ camera->target = Vector3Add(camera->position, direction);
- camera->up = (Vector3){
- m.m1 + m.m2,
- m.m5 + m.m6,
- m.m9 + m.m10
- };
+ // Up.
+ camera->up = Vector3RotateByQuaternion((Vector3){0.0, 1.0, 0.0}, player->rotation);
- camera->position = (Vector3){20.0, 20.0, 20.0};
- camera->up = (Vector3){0.0, 1.0, 0.0};
+ //camera->target = player->position;
+ //camera->position = (Vector3){10.0, 10.0, 10.0};
+ //camera->up = (Vector3){0.0, 1.0, 0.0};
}
diff --git a/src/playerCamera.h b/src/playerCamera.h
index 960c30d..87663d4 100644
--- a/src/playerCamera.h
+++ b/src/playerCamera.h
@@ -3,7 +3,7 @@
#ifndef PLAYER_CAMERA_H
#define PLAYER_CAMERA_H
-#define CAMERA_DIS 10.0
+#define CAMERA_DIS 5.0
void initPlayerCamera(Camera3D * camera);
void updatePlayerCamera(Camera3D * camera, Game * game);
diff --git a/src/world.c b/src/world.c
index 3bc02cd..553f2ed 100644
--- a/src/world.c
+++ b/src/world.c
@@ -225,17 +225,69 @@ KfError removeEntityFromWorld(World * world, EntityId id) {
return KFSUCCESS;
}
+void checkCollisionWithWorld(World * world, Entity * entity) {
+ int i, j;
+ Entity * entity2;
+ BoundingBox box1, box2;
+
+ Mesh mesh = entity->model->meshes[0];
+
+ Vector3 triangle[3];
+
+ for (i = 0; i < mesh.triangleCount; ++i) {
+
+ for (j = 0; j < 3; ++j)
+ triangle[j] = (Vector3){
+ mesh.vertices[(i * 9) + (j * 3)],
+ mesh.vertices[(i * 9) + (j * 3) + 1],
+ mesh.vertices[(i * 9) + (j * 3) + 2],
+ };
+
+ DrawLine3D(triangle[0], triangle[1], BLUE);
+ DrawLine3D(triangle[1], triangle[2], BLUE);
+ DrawLine3D(triangle[2], triangle[0], BLUE);
+ }
+
+ // Check for collision.
+ //for (i = 0; i < world->entitiesCount; ++i) {
+ // entity2 = &world->entities[i];
+
+ // if (entity->fingerprint == entity2->fingerprint)
+ // continue;
+
+ // // These fuckers collided.
+ // if (CheckCollisionBoxes(box1, box2)) {
+ // printf("hi %ld\n", clock());
+ // break;
+ // }
+ //}
+}
+
void updateWorld(World * world, Game * game) {
int i;
Entity * entity;
+ // People are fucking dying.
+ EntityId kills[world->entitiesCount];
+ size_t killCount = 0;
+
for (i = 0; i < world->entitiesCount; ++i) {
entity = &world->entities[i];
// Call update callback.
if (entity->updateCb != NULL)
entity->updateCb(game, entity);
+
+ // It fucking died.
+ if (entity->health <= 0.0) {
+ kills[killCount] = entity->id;
+ ++killCount;
+ }
}
+
+ // "bring out your dead!"
+ for (i = 0; i < killCount; ++i)
+ removeEntityFromWorld(world, kills[i]);
}
void drawWorld(World * world, Game * game) {
@@ -245,6 +297,8 @@ void drawWorld(World * world, Game * game) {
for (i = 0; i < world->entitiesCount; ++i) {
entity = &world->entities[i];
+ //checkCollisionWithWorld(world, entity);
+
// Call draw callback.
if (entity->drawCb != NULL)
entity->drawCb(game, entity);