From fcc7adfb2232ea8ce28f6df47d8dbd326f9aa7fa Mon Sep 17 00:00:00 2001 From: declan Date: Mon, 6 Oct 2025 17:30:49 +0100 Subject: [PATCH] added badman shooting and reloading --- code/first.c | 19 +++++++++++++----- code/game/aabb.h | 1 + code/game/bandit.h | 10 +++++++++- code/game/impl/aabb.c | 8 ++++++++ code/game/impl/bandit.c | 43 +++++++++++++++++++++++++++++++++++++++-- code/game/impl/player.c | 4 ++-- code/game/impl/world.c | 7 +++++-- code/game/player.h | 3 ++- 8 files changed, 82 insertions(+), 13 deletions(-) diff --git a/code/first.c b/code/first.c index 6272ef7..e079e81 100644 --- a/code/first.c +++ b/code/first.c @@ -125,13 +125,22 @@ int main(int argc, char **argv) badman->waitTime = 0; badman->maxWaitTime = 2; badman->poiCount = 2; + badman->shootoutTimer = 1.5; + badman->agroRadius = 600.0; + badman->bullets = 6; + badman->shootDelay = 1; + badman->accuracyRange = 0.25; + badman->reloadTime = 2.5; + badman->reloadTimer = 0; badman->pointsOfInterest[0] = 937; badman->pointsOfInterest[1] = 12; world->npcPOI[0] = 100; world->player.world = world; - world->player.pos.x = 0; - world->player.pos.y = 0; + world->player.collision.pos.x = 0; + world->player.collision.pos.y = 0; + world->player.collision.size.x = 1; + world->player.collision.size.y = 2; world->player.bulletsLoaded = PLAYER_BULLET_COUNT; world->player.reloadTimer = 0; world->player.currentArea = WORLD_AREA_OUTSIDE; @@ -216,7 +225,7 @@ int main(int argc, char **argv) world->propTypes[12].assetHandle=D_ImageHandle(&game->draw, S("house_int")); world->propTypes[12].scale=6.875f; } - game->editor.enabled = true; + game->editor.enabled = false; game->editor.mode = G_EDITOR_MODE_TILE; game->editor.currentLevel = WORLD_AREA_OUTSIDE; @@ -343,8 +352,8 @@ int main(int argc, char **argv) if(!game->editor.enabled) { UpdateWorld(1.0f / 60.0f, game->world); - game->camera.p.x = game->world->player.pos.x; - game->camera.p.y = game->world->player.pos.y; + game->camera.p.x = game->world->player.collision.pos.x; + game->camera.p.y = game->world->player.collision.pos.y; } D_AnimationUpdate(&animation, 1.0f / 250.0f); diff --git a/code/game/aabb.h b/code/game/aabb.h index 5c22fb3..4a07859 100644 --- a/code/game/aabb.h +++ b/code/game/aabb.h @@ -14,5 +14,6 @@ function bool AABB_Collide(AABB a, AABB b); function bool AABB_Point(AABB a, V2f v); function bool AABB_Slab(V2f origin, V2f point, AABB a); function V2f AABB_Centre(AABB a); +function bool AABB_Circle(F32 rad, V2f radOrigin, AABB a); #endif // LD_GAME_AABB_H_ diff --git a/code/game/bandit.h b/code/game/bandit.h index a55f973..b9eb7f8 100644 --- a/code/game/bandit.h +++ b/code/game/bandit.h @@ -2,11 +2,13 @@ #define LD_GAME_BANDIT_H_ typedef enum BANDIT_ACTION BANDIT_ACTION; -enum BANDIT_ACTION { +enum BANDIT_ACTION +{ BANDIT_WAITING, BANDIT_WALKING, BANDIT_RUNNING, BANDIT_SHOOTING, + BANDIT_SHOOTOUT, }; typedef struct Bandit Bandit; @@ -50,12 +52,18 @@ struct Bandit { F32 shootDelay; // After each shot this is set to shootDelay; F32 shootCooldownTimer; + // Countdown to shootout + F32 shootoutTimer; // How long it takes them to reload. F32 reloadTime; + // When gun is empty this is set to reloadTime. + F32 reloadTimer; // Accuracy, their shots can vary between this angle either side (rads) F32 accuracyRange; // A the circle around the bandit where they will trigger the quicktime reaction scene F32 agroRadius; }; +function V2f shootTowards(Bandit* bandit, V2f target, Random* r); + #endif // LD_GAME_BANDIT_H_ diff --git a/code/game/impl/aabb.c b/code/game/impl/aabb.c index f927452..b7d475d 100644 --- a/code/game/impl/aabb.c +++ b/code/game/impl/aabb.c @@ -38,3 +38,11 @@ bool AABB_Slab(V2f origin, V2f point, AABB a) V2f AABB_Centre(AABB a) { return V2F(a.pos.x + a.size.x/2, a.pos.y + a.size.y/2); } + +bool AABB_Circle(F32 rad, V2f radOrigin, AABB a) +{ + V2f aCentre = AABB_Centre(a); + F32 xSq = (Abs(aCentre.x) - Abs(radOrigin.x)) * (Abs(aCentre.x) - Abs(radOrigin.x)); + F32 ySq = (Abs(aCentre.y) - Abs(radOrigin.y)) * (Abs(aCentre.y) - Abs(radOrigin.y)); + return SDL_sqrt(xSq + ySq) < rad; +} \ No newline at end of file diff --git a/code/game/impl/bandit.c b/code/game/impl/bandit.c index bd5d1d5..f9a311d 100644 --- a/code/game/impl/bandit.c +++ b/code/game/impl/bandit.c @@ -1,13 +1,27 @@ #include "game/world.h" #include "game/bandit.h" +V2f shootTowards(Bandit *bandit, V2f target, Random* r) +{ + V2f shooterV2 = bandit->collision.pos; + F32 randX = Random_F32(r, -bandit->accuracyRange, bandit->accuracyRange); + F32 randY = Random_F32(r, -bandit->accuracyRange, bandit->accuracyRange); + return V2F(shooterV2.x + (target.x - shooterV2.x) * (1 + randX), shooterV2.x + (target.y - shooterV2.y) * (1 + randY)); +} + void UpdateBandit(F32 delta, Bandit *bandit, World *world) { if ( - world->player.controls.shot && AABB_Slab(world->player.pos, world->player.shotPos, bandit->collision) && bandit->currentArea == world->player.currentArea) + world->player.controls.shot && AABB_Slab(world->player.collision.pos, world->player.shotPos, bandit->collision) && bandit->currentArea == world->player.currentArea) { printf("You shot the bandit %*.s\n", Sv(bandit->name)); bandit->health--; } + if (AABB_Circle(bandit->agroRadius, AABB_Centre(bandit->collision), world->player.collision) && !(bandit->mode == BANDIT_SHOOTING || bandit->mode == BANDIT_SHOOTOUT)) + { + printf("begin shootout"); + // shootout time o.o + bandit->mode = BANDIT_SHOOTOUT; + } switch (bandit->mode) { case BANDIT_WAITING: bandit->waitTime+=delta; @@ -41,7 +55,32 @@ void UpdateBandit(F32 delta, Bandit *bandit, World *world) { bandit->collision.pos.x = cNav.pos.x * (1 - bandit->walkTimer/NPC_SPEED) + tNav.pos.x * bandit->walkTimer/NPC_SPEED; bandit->collision.pos.y = cNav.pos.y * (1 - bandit->walkTimer/NPC_SPEED) + tNav.pos.y * bandit->walkTimer/NPC_SPEED; break; - // TODO Shooting + case BANDIT_SHOOTOUT: + bandit->shootoutTimer-=delta; + if(bandit->shootoutTimer < 0){ + bandit->mode=BANDIT_SHOOTING; + } + break; + case BANDIT_SHOOTING: + bandit->shootCooldownTimer -= delta; + bandit->reloadTimer -= delta; + if (bandit->shootCooldownTimer < 0 && bandit->reloadTimer < 0) + { + printf("shoot at player"); + bandit->bullets--; + bandit->shootCooldownTimer = bandit->shootDelay; + V2f banditShot = shootTowards(bandit, world->player.collision.pos, &world->random); + if(AABB_Slab(bandit->collision.pos, banditShot, world->player.collision)){ + // gets shot lmao + printf("hit"); + } + if(bandit->bullets == 0){ + printf("enemy reload"); + bandit->bullets = 6; + bandit->reloadTimer = bandit->reloadTime; + } + } + break; // TODO Running away } } diff --git a/code/game/impl/player.c b/code/game/impl/player.c index 8375d1e..70f89b8 100644 --- a/code/game/impl/player.c +++ b/code/game/impl/player.c @@ -73,6 +73,6 @@ void PlayerUpdate(F32 delta, Player *player) { } } dir = V2f_Scale(NormaliseV2F(dir), PLAYER_SPEED*delta); - player->pos.x += dir.x; - player->pos.y += dir.y; + player->collision.pos.x += dir.x; + player->collision.pos.y += dir.y; } diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 63757c3..c7a4805 100644 --- a/code/game/impl/world.c +++ b/code/game/impl/world.c @@ -9,6 +9,9 @@ void UpdateWorld(F32 delta, World *world) { + if(world->bandit.mode == BANDIT_SHOOTOUT){ + delta = delta/4; + } UpdateBandit(delta, &world->bandit, world); UpdateNPCs(delta, world); PlayerUpdate(delta, &world->player); @@ -21,7 +24,7 @@ void UpdateNPCs(F32 delta, World *world) NPC *npc = &world->npcs[i]; UpdateNPC(delta, npc, world); if ( - world->player.controls.shot && AABB_Slab(world->player.pos, world->player.shotPos, npc->collision) && npc->currentArea == world->player.currentArea) + world->player.controls.shot && AABB_Slab(world->player.collision.pos, world->player.shotPos, npc->collision) && npc->currentArea == world->player.currentArea) { printf("You shot %*.s\n", Sv(world->npcs[i].name)); } @@ -69,7 +72,7 @@ void RenderWorld(World *world, D_Context *draw) { V2f drawPos = AABB_Centre(world->bandit.collision); D_Rect(draw, drawPos.x, drawPos.y, .texture = 9); } - D_Rect(draw, world->player.pos.x, world->player.pos.y, .texture = 1); + D_Rect(draw, world->player.collision.pos.x, world->player.collision.pos.y, .texture = 1); } void SaveWorld(M_Arena *arena, World *world) { diff --git a/code/game/player.h b/code/game/player.h index a727453..627bc1f 100644 --- a/code/game/player.h +++ b/code/game/player.h @@ -5,6 +5,7 @@ #include "../core/macros.h" #include +#include "aabb.h" #define PLAYER_SPEED 10.0f #define PLAYER_RELOAD_TIME 1.5f @@ -23,7 +24,7 @@ typedef struct Player Player; struct Player { World *world; - V2f pos; + AABB collision; World_Area currentArea; U32 bulletsLoaded; ControlState controls;