aboutsummaryrefslogtreecommitdiff
path: root/src
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
parent77a06748f9f394486cad833e2ca351e8dbcc7361 (diff)
Bullet system added
Diffstat (limited to 'src')
-rw-r--r--src/bullets.c165
-rw-r--r--src/bullets.h34
-rw-r--r--src/entities/antifaShip.c20
-rw-r--r--src/entities/soldato.c23
-rw-r--r--src/entities/soldato.h2
-rw-r--r--src/entity.c40
-rw-r--r--src/entity.h26
-rw-r--r--src/game.c4
-rw-r--r--src/game.h2
-rw-r--r--src/gameCommon.h3
-rw-r--r--src/gameScreen.c7
11 files changed, 302 insertions, 24 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);
+}
diff --git a/src/bullets.h b/src/bullets.h
new file mode 100644
index 0000000..a01a967
--- /dev/null
+++ b/src/bullets.h
@@ -0,0 +1,34 @@
+#include "gameCommon.h"
+#include "entity.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.
+ 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);
+
+KfError addBullet(Bullets * bullets, Bullet bullet);
+KfError popBackBullets(Bullets * bullets);
+
+void updateBullets(Game * game, Bullets * bullets);
+void updateBullet(Game * game, Bullet * bullet);
+
+#endif
diff --git a/src/entities/antifaShip.c b/src/entities/antifaShip.c
index c2e292a..2d58510 100644
--- a/src/entities/antifaShip.c
+++ b/src/entities/antifaShip.c
@@ -1,8 +1,7 @@
#include "antifaShip.h"
#include "game.h"
#include "settings.h"
-
-// TODO: Get rid of some magic numbers.
+#include "bullets.h"
void initAntifaShip(Entity * entity, Game * game) {
entity->model = &game->assets.models[ANTIFA_SHIP_ASSET];
@@ -43,6 +42,23 @@ void controlAntifaShipJoystick(Game * game, Entity * entity) {
float rollStick = GetGamepadAxisMovement(gamePadNum, settings.rollStick);
float speedStick = GetGamepadAxisMovement(gamePadNum, settings.speedStick);
+ // 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);
+ }
+
Vector3 stick = (Vector3){
pitchStick,
-yawStick,
diff --git a/src/entities/soldato.c b/src/entities/soldato.c
index 30dfa6b..beec40a 100644
--- a/src/entities/soldato.c
+++ b/src/entities/soldato.c
@@ -7,19 +7,19 @@ void initSoldato(Entity * entity, Game * game) {
// Acceleration.
entity->useAcceleration = true;
entity->acceleration = (EntityAcceleration){
- .speedUp = 5.0,
- .speedDown = 0.00001
+ .speedUp = 20.0,
+ .speedDown = 15.0
};
// PID configs.
PIDConfig speedPIDConfig = {
- .kP = -0.5,
+ .kP = 1,
.kI = 0.0,
.kD = 0.0,
.angleMode = false,
.doClamp = true,
.min = 0.0,
- .max = 30.0
+ .max = 100.0
};
// Allocate data.
@@ -31,7 +31,15 @@ void initSoldato(Entity * entity, Game * game) {
}
Soldato * data = (Soldato*)entity->data;
- data->speedPID = createPID(speedPIDConfig);
+
+ // Create fly to point.
+ data->flyToPoint = (EntityFlyToPointInfo){
+ //.controller.speedPID = createPID(speedPIDConfig),
+ .controller.bangbang.speed = 20.0,
+ .controller.bangbang.stopAt = 0.0,
+ .controlType = ENTITY_FLY_TO_POINT_BANG_BANG,
+ .rotationSpeed = 0.0
+ };
}
void closeSoldato(Entity * entity) {
@@ -43,11 +51,10 @@ void updateSoldato(Game * game, Entity * entity) {
Entity * player = getEntityFromWorld(game->world, 0);
Soldato * data = (Soldato*)entity->data;
- entityFlightToPoint(
+ entityFlyToPoint(
entity,
player->position,
- &data->speedPID,
- 5.0
+ &data->flyToPoint
);
}
diff --git a/src/entities/soldato.h b/src/entities/soldato.h
index 5123aee..f93206d 100644
--- a/src/entities/soldato.h
+++ b/src/entities/soldato.h
@@ -6,7 +6,7 @@
#define SOLDATO_H
typedef struct Soldato {
- PID speedPID;
+ EntityFlyToPointInfo flyToPoint;
} Soldato;
void initSoldato(Entity * entity, Game * game);
diff --git a/src/entity.c b/src/entity.c
index e918617..285744d 100644
--- a/src/entity.c
+++ b/src/entity.c
@@ -52,6 +52,7 @@ Entity createEntity(EntityType type, Game * game) {
// Set defaults.
Entity entity = (Entity){
.type = type,
+ .model = NULL,
.position = Vector3Zero(),
.rotation = QuaternionIdentity(),
.velocity = entityVelocityIdentity(),
@@ -59,6 +60,7 @@ Entity createEntity(EntityType type, Game * game) {
.useAcceleration = false,
.updateCb = info.updateCb,
.drawCb = info.drawCb,
+ .health = 1.0,
.data = NULL
};
@@ -152,7 +154,7 @@ void entityJoystickControl(Entity * entity, Vector3 stick, float speed) {
entityUpdatePosition(entity);
}
-void entityFlightToPoint(Entity * entity, Vector3 point, PID * speedPID, float rotationSpeed) {
+void entityFlyToPoint(Entity * entity, Vector3 point, EntityFlyToPointInfo * info) {
float t = GetFrameTime();
// Get distance and direction.
@@ -164,19 +166,37 @@ void entityFlightToPoint(Entity * entity, Vector3 point, PID * speedPID, float r
Quaternion rotation = QuaternionInvert(QuaternionFromMatrix(matrix));
// Rotate this fucker.
- if (rotationSpeed == 0.0)
+ if (info->rotationSpeed == 0.0)
entity->rotation = rotation;
else
- entity->rotation = QuaternionSlerp(entity->rotation, rotation, t * rotationSpeed);
+ entity->rotation = QuaternionSlerp(entity->rotation, rotation, t * info->rotationSpeed);
// Velocity control.
- float s = runPID(0.0, Vector3Length(dis), speedPID);
+ float speed = 0.0;
+
+ float distance = Vector3Length(dis);
+
+ switch (info->controlType) {
+ case ENTITY_FLY_TO_POINT_PID:
+ speed = runPID(0.0, -distance, &info->controller.speedPID);
+ break;
+ case ENTITY_FLY_TO_POINT_BANG_BANG:
+ speed = info->controller.bangbang.speed;
+
+ if (distance <= info->controller.bangbang.stopAt)
+ speed = 0.0;
+
+ break;
+ default: // Something is fucked up.
+ break;
+ }
+
Matrix m = QuaternionToMatrix(QuaternionInvert(entity->rotation));
// Accelerate.
if (entity->useAcceleration)
- s = accelerateValue(
- s,
+ speed = accelerateValue(
+ speed,
entity->lastVelocity.speed,
entity->acceleration.speedUp * t,
entity->acceleration.speedDown * t
@@ -184,13 +204,13 @@ void entityFlightToPoint(Entity * entity, Vector3 point, PID * speedPID, float r
// Velocity.
entity->velocity.velocity = (Vector3){
- m.m2 * s,
- m.m6 * s,
- m.m10 * s
+ m.m2 * speed,
+ m.m6 * speed,
+ m.m10 * speed
};
entityUpdatePosition(entity);
- entity->velocity.speed = s;
+ entity->velocity.speed = speed;
entity->lastVelocity = entity->velocity;
}
diff --git a/src/entity.h b/src/entity.h
index c6fa6c6..dc6be72 100644
--- a/src/entity.h
+++ b/src/entity.h
@@ -64,6 +64,9 @@ typedef struct Entity {
EntityUpdateCb updateCb;
EntityDrawCb drawCb;
+ // Health is a percent from 1.0 to 0.0.
+ float health;
+
// Used for whatever.
void * data;
} Entity;
@@ -92,7 +95,26 @@ void entityUpdateRotation(Entity * entity);
void entityJoystickControl(Entity * entity, Vector3 stick, float speed);
-// 0.0 rotationSpeed for directly setting the rotation.
-void entityFlightToPoint(Entity * entity, Vector3 point, PID * speedPID, float rotationSpeed);
+enum {
+ ENTITY_FLY_TO_POINT_PID,
+ ENTITY_FLY_TO_POINT_BANG_BANG
+};
+
+// Shit for fly to point.
+typedef struct EntityFlyToPointInfo {
+ union {
+ PID speedPID;
+
+ struct {
+ float speed;
+ float stopAt;
+ } bangbang;
+ } controller;
+
+ uint8_t controlType;
+ float rotationSpeed; // 0.0 to not use.
+} EntityFlyToPointInfo;
+
+void entityFlyToPoint(Entity * entity, Vector3 point, EntityFlyToPointInfo * info);
#endif
diff --git a/src/game.c b/src/game.c
index 8096779..5bf35c4 100644
--- a/src/game.c
+++ b/src/game.c
@@ -19,6 +19,9 @@ void initGame(Game * game) {
// Camera.
initPlayerCamera(&game->playerCamera);
+
+ // Bullets.
+ initBullets(&game->bullets);
// World.
initWorld(&game->world);
@@ -39,6 +42,7 @@ 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 78eb873..555b5b4 100644
--- a/src/game.h
+++ b/src/game.h
@@ -6,6 +6,7 @@
#include "assets.h"
#include "world.h"
#include "settings.h"
+#include "bullets.h"
#ifndef GAME_H
#define GAME_H
@@ -23,6 +24,7 @@ typedef struct Game {
Assets assets;
World world;
Settings settings;
+ Bullets bullets;
} Game;
void initGame(Game * game);
diff --git a/src/gameCommon.h b/src/gameCommon.h
index 08ce5fe..4c22664 100644
--- a/src/gameCommon.h
+++ b/src/gameCommon.h
@@ -19,6 +19,9 @@
typedef struct Game Game;
typedef struct Entity Entity;
+// How far from center you can go.
+#define GAME_BOUNDS 1000.0
+
#define WINDOW_WIDTH 960
#define WINDOW_HEIGHT 540
diff --git a/src/gameScreen.c b/src/gameScreen.c
index 3282a8f..286a026 100644
--- a/src/gameScreen.c
+++ b/src/gameScreen.c
@@ -1,6 +1,7 @@
#include "gameScreen.h"
#include "game.h"
#include "world.h"
+#include "bullets.h"
void updateGameScreen(Game * game) {
@@ -14,11 +15,15 @@ void updateGameScreen(Game * game) {
BeginMode3D(game->playerCamera);
- DrawGrid(500, 25.0);
+ DrawGrid(50, 25.0);
+
+ //DrawSphereWires(Vector3Zero(), GAME_BOUNDS, 32, 32, WHITE);
// Draw world.
drawWorld(&game->world, game);
+ updateBullets(game, &game->bullets);
+
EndMode3D();
}