feat: Initial bandit roaming
This commit is contained in:
31
code/first.c
31
code/first.c
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "game/impl/world.c"
|
#include "game/impl/world.c"
|
||||||
#include "game/impl/npc.c"
|
#include "game/impl/npc.c"
|
||||||
|
#include "game/impl/bandit.c"
|
||||||
#include "game/testnavmesh.h"
|
#include "game/testnavmesh.h"
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -66,13 +67,13 @@ int main(int argc, char **argv)
|
|||||||
World *world = M_ArenaPush(arena, World);
|
World *world = M_ArenaPush(arena, World);
|
||||||
game->world = world;
|
game->world = world;
|
||||||
world->random = Random_Seed(29237489723847);
|
world->random = Random_Seed(29237489723847);
|
||||||
world->npcCount = 100;
|
world->npcCount = 1;
|
||||||
for(int i = 0; i < world->npcCount; i++) {
|
for(int i = 0; i < world->npcCount; i++) {
|
||||||
NPC *npc1 = &world->npcs[i];
|
NPC *npc1 = &world->npcs[i];
|
||||||
npc1->collision.pos.x = 15;
|
npc1->collision.pos.x = 15;
|
||||||
npc1->collision.pos.y = 15;
|
npc1->collision.pos.y = 15;
|
||||||
npc1->collision.size.x = 10;
|
npc1->collision.size.x = 1;
|
||||||
npc1->collision.size.y = 10;
|
npc1->collision.size.y = 1;
|
||||||
npc1->name = S("Matt");
|
npc1->name = S("Matt");
|
||||||
npc1->mode = NPC_ACTION_WAITING;
|
npc1->mode = NPC_ACTION_WAITING;
|
||||||
npc1->waitTime = 0;
|
npc1->waitTime = 0;
|
||||||
@@ -84,21 +85,25 @@ int main(int argc, char **argv)
|
|||||||
npc1->collision.size.y = 10;
|
npc1->collision.size.y = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
NPC *npc2 = &world->npcs[1];
|
Bandit *badman = &world->bandit;
|
||||||
npc2->collision.pos.x = 15;
|
badman->collision.pos.x = 15;
|
||||||
npc2->collision.pos.y = 15;
|
badman->collision.pos.y = 15;
|
||||||
npc2->collision.size.x = 10;
|
badman->collision.size.x = 10;
|
||||||
npc2->collision.size.y = 10;
|
badman->collision.size.y = 10;
|
||||||
npc2->name = S("James");
|
badman->name = S("Leroy Brown");
|
||||||
npc2->mode = NPC_ACTION_WAITING;
|
badman->mode = BANDIT_WAITING;
|
||||||
npc2->waitTime = 0;
|
badman->waitTime = 0;
|
||||||
npc2->maxWaitTime = 10;
|
badman->maxWaitTime = 2;
|
||||||
npc2->currentNavNode = 0;
|
badman->poiCount = 2;
|
||||||
|
badman->pointsOfInterest[0] = 937;
|
||||||
|
badman->pointsOfInterest[1] = 12;
|
||||||
|
|
||||||
world->navMesh = &TestNavMesh;
|
world->navMesh = &TestNavMesh;
|
||||||
world->npcPOI[0] = 100;
|
world->npcPOI[0] = 100;
|
||||||
world->player.pos.x = 0;
|
world->player.pos.x = 0;
|
||||||
world->player.pos.y = 0;
|
world->player.pos.y = 0;
|
||||||
|
world->player.bulletsLoaded = PLAYER_BULLET_COUNT;
|
||||||
|
world->player.reloadTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ enum BANDIT_ACTION {
|
|||||||
BANDIT_WAITING,
|
BANDIT_WAITING,
|
||||||
BANDIT_WALKING,
|
BANDIT_WALKING,
|
||||||
BANDIT_RUNNING,
|
BANDIT_RUNNING,
|
||||||
BANDIT_SHOOTOUT,
|
BANDIT_SHOOTING,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Bandit Bandit;
|
typedef struct Bandit Bandit;
|
||||||
@@ -22,6 +22,7 @@ struct Bandit {
|
|||||||
// How long they will wait in this location.
|
// How long they will wait in this location.
|
||||||
F32 maxWaitTime;
|
F32 maxWaitTime;
|
||||||
|
|
||||||
|
U32 poiCount;
|
||||||
// Places the bandit walks to / from
|
// Places the bandit walks to / from
|
||||||
// E.g. hide outs, home, saloon
|
// E.g. hide outs, home, saloon
|
||||||
U32 pointsOfInterest[12];
|
U32 pointsOfInterest[12];
|
||||||
|
|||||||
41
code/game/impl/bandit.c
Normal file
41
code/game/impl/bandit.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include "game/world.h"
|
||||||
|
#include "game/bandit.h"
|
||||||
|
|
||||||
|
void UpdateBandit(F32 delta, Bandit *bandit, World *world) {
|
||||||
|
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;
|
||||||
|
// TODO Shooting
|
||||||
|
// TODO Running away
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
#include "core/math.h"
|
#include "core/math.h"
|
||||||
|
|
||||||
void updateNPC(F32 delta, NPC *npc, World *world) {
|
void UpdateNPC(F32 delta, NPC *npc, World *world) {
|
||||||
switch (npc->mode) {
|
switch (npc->mode) {
|
||||||
case NPC_ACTION_WAITING:
|
case NPC_ACTION_WAITING:
|
||||||
npc->waitTime+=delta;
|
npc->waitTime+=delta;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#include "../player.h"
|
#include "../player.h"
|
||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
#include <SDL3/SDL_keycode.h>
|
#include <SDL3/SDL_keycode.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
void PlayerInput(SDL_Event *event, Player *player)
|
void PlayerInput(SDL_Event *event, Player *player)
|
||||||
{
|
{
|
||||||
|
player->controls.shot = false;
|
||||||
SDL_KeyboardEvent key = event->key;
|
SDL_KeyboardEvent key = event->key;
|
||||||
SDL_MouseButtonEvent mouseBtn = event->button;
|
SDL_MouseButtonEvent mouseBtn = event->button;
|
||||||
if(event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_KEY_UP) {
|
if(event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_KEY_UP) {
|
||||||
@@ -32,10 +34,20 @@ void PlayerInput(SDL_Event *event, Player *player)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mouseBtn.clicks == 1)
|
if (
|
||||||
{
|
event->type == SDL_EVENT_MOUSE_BUTTON_DOWN
|
||||||
// shooting
|
&& mouseBtn.button == SDL_BUTTON_LEFT
|
||||||
player->bulletsLoaded -= 1;
|
) {
|
||||||
|
if(player->bulletsLoaded > 0) {
|
||||||
|
// shooting
|
||||||
|
player->bulletsLoaded -= 1;
|
||||||
|
player->controls.shot = true;
|
||||||
|
player->shotPos = V2F(mouseBtn.x, mouseBtn.y);
|
||||||
|
printf("shot %f %f\n", mouseBtn.x, mouseBtn.y);
|
||||||
|
} else if(player->reloadTimer == 0) {
|
||||||
|
player->reloadTimer = PLAYER_RELOAD_TIME;
|
||||||
|
printf("reloading\n");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +65,13 @@ void PlayerUpdate(F32 delta, Player *player) {
|
|||||||
if(player->controls.rightDown) {
|
if(player->controls.rightDown) {
|
||||||
dir.x += 1;
|
dir.x += 1;
|
||||||
}
|
}
|
||||||
|
if(player->reloadTimer > 0) {
|
||||||
|
player->reloadTimer-=delta;
|
||||||
|
if(player->reloadTimer <= 0) {
|
||||||
|
player->bulletsLoaded = PLAYER_BULLET_COUNT;
|
||||||
|
player->reloadTimer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
dir = V2f_Scale(NormaliseV2F(dir), PLAYER_SPEED*delta);
|
dir = V2f_Scale(NormaliseV2F(dir), PLAYER_SPEED*delta);
|
||||||
player->pos.x += dir.x;
|
player->pos.x += dir.x;
|
||||||
player->pos.y += dir.y;
|
player->pos.y += dir.y;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
void UpdateWorld(F32 delta, World *world)
|
void UpdateWorld(F32 delta, World *world)
|
||||||
{
|
{
|
||||||
|
UpdateBandit(delta, &world->bandit, world);
|
||||||
UpdateNPCs(delta, world);
|
UpdateNPCs(delta, world);
|
||||||
PlayerUpdate(delta, &world->player);
|
PlayerUpdate(delta, &world->player);
|
||||||
}
|
}
|
||||||
@@ -13,7 +14,11 @@ void UpdateNPCs(F32 delta, World *world)
|
|||||||
{
|
{
|
||||||
for (U32 i = 0; i < world->npcCount; i++)
|
for (U32 i = 0; i < world->npcCount; i++)
|
||||||
{
|
{
|
||||||
updateNPC(delta, &world->npcs[i], world);
|
UpdateNPC(delta, &world->npcs[i], world);
|
||||||
|
if(world->player.controls.shot && AABB_Point(world->npcs[i].collision, world->player.shotPos)) {
|
||||||
|
// TODO we need to unproject the mouse location !!!
|
||||||
|
printf("You shot %.*s\n", Sv(world->npcs[i].name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +29,10 @@ void ProcessEvents(SDL_Event *event, World *world)
|
|||||||
|
|
||||||
void RenderWorld(World *world, D_Context *draw) {
|
void RenderWorld(World *world, D_Context *draw) {
|
||||||
for(int i = 0; i < world->npcCount; i++) {
|
for(int i = 0; i < world->npcCount; i++) {
|
||||||
D_Rect(draw, world->npcs[i].collision.pos.x, world->npcs[i].collision.pos.y, .texture = 1);
|
NPC npc = world->npcs[i];
|
||||||
|
D_Rect(draw, npc.collision.pos.x, npc.collision.pos.y, .texture = 1);
|
||||||
|
D_Rect(draw, npc.collision.pos.x, npc.collision.pos.y, .texture = 0, .dim = npc.collision.size);
|
||||||
}
|
}
|
||||||
|
D_Rect(draw, world->bandit.collision.pos.x, world->bandit.collision.pos.y, .texture = 9);
|
||||||
D_Rect(draw, world->player.pos.x, world->player.pos.y, .texture = 1);
|
D_Rect(draw, world->player.pos.x, world->player.pos.y, .texture = 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <SDL3/SDL_events.h>
|
#include <SDL3/SDL_events.h>
|
||||||
|
|
||||||
#define PLAYER_SPEED 10.0f
|
#define PLAYER_SPEED 10.0f
|
||||||
|
#define PLAYER_RELOAD_TIME 1.5f
|
||||||
|
#define PLAYER_BULLET_COUNT 6
|
||||||
|
|
||||||
typedef struct ControlState ControlState;
|
typedef struct ControlState ControlState;
|
||||||
struct ControlState {
|
struct ControlState {
|
||||||
@@ -14,6 +16,7 @@ struct ControlState {
|
|||||||
bool leftDown;
|
bool leftDown;
|
||||||
bool upDown;
|
bool upDown;
|
||||||
bool downDown;
|
bool downDown;
|
||||||
|
bool shot;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Player Player;
|
typedef struct Player Player;
|
||||||
@@ -22,6 +25,9 @@ struct Player
|
|||||||
V2f pos;
|
V2f pos;
|
||||||
U32 bulletsLoaded;
|
U32 bulletsLoaded;
|
||||||
ControlState controls;
|
ControlState controls;
|
||||||
|
V2f shotPos;
|
||||||
|
|
||||||
|
F32 reloadTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
function void PlayerInput(SDL_Event *event, Player *player);
|
function void PlayerInput(SDL_Event *event, Player *player);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ function void UpdateWorld(F32 delta, World *world);
|
|||||||
function void RenderWorld(World *world, D_Context *drawContext );
|
function void RenderWorld(World *world, D_Context *drawContext );
|
||||||
function void ProcessEvents(SDL_Event *event, World *world);
|
function void ProcessEvents(SDL_Event *event, World *world);
|
||||||
function void UpdateNPCs(F32 delta, World *world);
|
function void UpdateNPCs(F32 delta, World *world);
|
||||||
function void updateNPC(F32 delta, NPC *npc, World *world);
|
function void UpdateNPC(F32 delta, NPC *npc, World *world);
|
||||||
|
function void UpdateBandit(F32 delta, Bandit *bandit, World *world);
|
||||||
|
|
||||||
#endif // LD_GAME_WORLD_H_
|
#endif // LD_GAME_WORLD_H_
|
||||||
|
|||||||
Reference in New Issue
Block a user