Files
ld58/code/game/impl/bandit.c

108 lines
4.0 KiB
C
Raw Normal View History

2025-10-05 21:05:29 +01:00
#include "game/world.h"
#include "game/bandit.h"
V2f ShootTowards(Bandit *bandit, V2f target, Random* r)
2025-10-06 17:30:49 +01:00
{
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));
}
2025-10-05 21:05:29 +01:00
void UpdateBandit(F32 delta, Bandit *bandit, World *world) {
for(U32 i = 0; i < world->portalCount; i++) {
2025-10-06 21:07:55 +01:00
if(AABB_Collide(world->portals[0].box, bandit->collision)) {
bandit->currentArea = world->portals[0].area;
}
}
2025-10-06 00:48:41 +01:00
if (
2025-10-06 17:30:49 +01:00
world->player.controls.shot && AABB_Slab(world->player.collision.pos, world->player.shotPos, bandit->collision) && bandit->currentArea == world->player.currentArea)
2025-10-06 00:48:41 +01:00
{
bandit->health--;
}
2025-10-06 17:30:49 +01:00
if (AABB_Circle(bandit->agroRadius, AABB_Centre(bandit->collision), world->player.collision) && !(bandit->mode == BANDIT_SHOOTING || bandit->mode == BANDIT_SHOOTOUT))
{
// shootout time o.o
bandit->mode = BANDIT_SHOOTOUT;
}
2025-10-05 21:05:29 +01:00
switch (bandit->mode) {
case BANDIT_WAITING:
bandit->waitTime+=delta;
if(bandit->waitTime > bandit->maxWaitTime) {
bandit->mode = BANDIT_WALKING;
do {
U32 randomChoice = Random_U32(&world->random, 0, bandit->poiCount);
bandit->targetNavNode = bandit->pointsOfInterest[randomChoice];
} while(bandit->targetNavNode == bandit->currentNavNode);
bandit->path = Nav_Path(world->navMesh, bandit->currentNavNode, bandit->targetNavNode);
bandit->walkTimer = 0;
}
break;
case BANDIT_WALKING:
bandit->walkTimer+=delta;
if(bandit->walkTimer >= NPC_SPEED){
bandit->walkTimer = 0;
if(bandit->path.nodeCount == bandit->pathIndex+1){
bandit->mode = BANDIT_WAITING;
bandit->maxWaitTime = Random_F32(&world->random, 20, 140);
bandit->waitTime = 0;
bandit->currentNavNode = bandit->targetNavNode;
bandit->pathIndex = 0;
return;
}
bandit->currentNavNode = bandit->path.indexes[bandit->pathIndex];
bandit->pathIndex+=1;
}
NavNode cNav = world->navMesh->nodes[bandit->currentNavNode];
NavNode tNav = world->navMesh->nodes[bandit->path.indexes[bandit->pathIndex]];
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;
2025-10-06 17:30:49 +01:00
case BANDIT_SHOOTOUT:
2025-10-06 21:54:48 +01:00
bandit->shootoutTimer-=delta;
2025-10-06 17:30:49 +01:00
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)
{
bandit->bullets--;
bandit->shootCooldownTimer = bandit->shootDelay;
V2f banditShot = ShootTowards(bandit, world->player.collision.pos, &world->random);
2025-10-06 17:30:49 +01:00
if(AABB_Slab(bandit->collision.pos, banditShot, world->player.collision)){
// gets shot lmao
2025-10-06 17:45:58 +01:00
world->player.health--;
2025-10-06 17:30:49 +01:00
}
if(bandit->bullets == 0){
bandit->bullets = 6;
bandit->reloadTimer = bandit->reloadTime;
}
}
break;
2025-10-05 21:05:29 +01:00
// TODO Running away
}
}
void BanditDraw(D_Context *draw, Bandit *bandit)
{
G_Outfit *outfit = &bandit->outfit;
R2f pframe = D_AnimationFrame(&outfit->state);
for (U32 it = 0; it < G_OUTFIT_COMPONENT_COUNT; ++it)
{
U32 flipped = (outfit->dir & G_OUTFIT_DIR_FLIPPED) != 0;
U32 dir = (outfit->dir & ~G_OUTFIT_DIR_FLIPPED);
U32 tid = outfit->e[dir].e[it];
if (tid != 0)
{
U32 flags = D_RECT_UV_ASPECT | (flipped ? D_RECT_FLIP_X : 0);
D_Rect(draw, bandit->collision.pos.x, bandit->collision.pos.y, .texture = tid, .uv = pframe, .flags = flags);
}
}
}