diff --git a/.gitignore b/.gitignore index f25181b..c094b4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ code/compile_commands.json code/.cache +.vscode diff --git a/code/core/impl/math.c b/code/core/impl/math.c index 9490038..c1a2cd7 100644 --- a/code/core/impl/math.c +++ b/code/core/impl/math.c @@ -1,8 +1,22 @@ +#include V2f V2F(F32 x, F32 y) { V2f result = { x, y }; return result; } +function V2f V2f_Scale(V2f x, F32 scale) { + return V2F(x.x * scale, x.y * scale); +} + +V2f NormaliseV2F(V2f x) { + F32 magnitude = sqrtf((x.x * x.x) + (x.y * x.y)); + if(magnitude > 0.0){ + F32 inverse = 1.0f/magnitude; + return V2F(x.x*inverse, x.y*inverse); + } + return x; +} + V3f V3F(F32 x, F32 y, F32 z) { V3f result = { x, y, z }; return result; @@ -18,11 +32,6 @@ R2f R2F(V2f min, V2f max) { return result; } -V2f V2f_Scale(V2f x, F32 s) { - V2f result = { x.x * s, x.y * s }; - return result; -} - V3f V3f_Neg(V3f x) { V3f result = { -x.x, -x.y, -x.z }; return result; diff --git a/code/core/math.h b/code/core/math.h index 8f1a4e1..4dd6d84 100644 --- a/code/core/math.h +++ b/code/core/math.h @@ -4,6 +4,8 @@ #define PI_F32 (3.14159265358979323846264338f) #define TAU_F32 (2.0f * PI_F32) +#define Abs(x) (((x) < 0 ? -(x) : (x))) + typedef struct Random Random; struct Random { U64 state; @@ -128,6 +130,9 @@ function V3f M4x4F_VMul3(Mat4x4F m, V3f v); function Mat4x4FInv M4x4F_Perspective(F32 fov, F32 aspect, F32 nearp, F32 farp); function Mat4x4FInv M4x4F_CameraView(V3f x, V3f y, V3f z, V3f p); +function V2f NormaliseV2F(V2f x); +function V2f V2f_Scale(V2f x, F32 scale); + // Random function Random Random_Seed(U64 seed); diff --git a/code/core/types.h b/code/core/types.h index 73f2a4d..51b3133 100644 --- a/code/core/types.h +++ b/code/core/types.h @@ -34,4 +34,7 @@ struct Str8 { #define U32_MAX ((U32) -1) #define U64_MAX ((U64) -1) +#define F32_MAX ((F32) 3.40282346638528859811704183484516925e+038F) +#define F64_MAX ((F64) 1.79769313486231570814527423731704357e+308L) + #endif // LD_CORE_TYPES_H_ diff --git a/code/first.c b/code/first.c index c52cee8..ddfc93e 100644 --- a/code/first.c +++ b/code/first.c @@ -1,6 +1,7 @@ #include #include #include +#include #define STB_IMAGE_IMPLEMENTATION 1 #include @@ -23,11 +24,13 @@ #include "game/impl/world.c" #include "game/impl/npc.c" +#include "game/impl/bandit.c" #include "game/testnavmesh.h" -int main(int argc, char **argv) { - (void) argc; - (void) argv; +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; if (!SDL_Init(SDL_INIT_VIDEO)) { @@ -65,35 +68,52 @@ int main(int argc, char **argv) { camera->fov = 60.0f; camera->nearp = 0.01f; - camera->farp = 1000.0f; + camera->farp = 1000.0f; game->draw.camera = camera; + World *world = M_ArenaPush(arena, World); + game->world = world; + world->random = Random_Seed(29237489723847); + world->npcCount = 1; + for(U32 i = 0; i < world->npcCount; i++) { + NPC *npc1 = &world->npcs[i]; + npc1->collision.pos.x = 15; + npc1->collision.pos.y = 15; + npc1->collision.size.x = 1; + npc1->collision.size.y = 1; + npc1->name = S("Matt"); + npc1->mode = NPC_ACTION_WAITING; + npc1->waitTime = 0; + npc1->maxWaitTime = 5; + npc1->currentNavNode = 0; + npc1->collision.pos.x = 15; + npc1->collision.pos.y = 15; + npc1->collision.size.x = 10; + npc1->collision.size.y = 10; + } + + Bandit *badman = &world->bandit; + badman->collision.pos.x = 15; + badman->collision.pos.y = 15; + badman->collision.size.x = 10; + badman->collision.size.y = 10; + badman->name = S("Leroy Brown"); + badman->mode = BANDIT_WAITING; + badman->waitTime = 0; + badman->maxWaitTime = 2; + badman->poiCount = 2; + badman->pointsOfInterest[0] = 937; + badman->pointsOfInterest[1] = 12; + + world->navMesh = &TestNavMesh; + world->npcPOI[0] = 100; + world->player.pos.x = 0; + world->player.pos.y = 0; + world->player.bulletsLoaded = PLAYER_BULLET_COUNT; + world->player.reloadTimer = 0; } bool running = true; - World world = { - .npcCount = 2, - .npcs = { - { - .collision = {{10, 10}, {10, 10}}, - .name = S("Matt"), - .mode = NPC_ACTION_WAITING, - .waitTime = 0, - .maxWaitTime = 5, - .currentNavNode = 87 - },{ - .collision = {{15, 15}, {10, 10}}, - .name = S("James"), - .mode = NPC_ACTION_WAITING, - .waitTime = 0, - .maxWaitTime = 10, - .currentNavNode = 0 - } - }, - .navMesh = &TestNavMesh, - .npcPOI = {100}, - .player = {.pos = {0,0}} - }; printf("%zu size in bytes\n", sizeof(TestNavMesh)); @@ -106,36 +126,21 @@ int main(int argc, char **argv) { { running = false; } - else if (e.type == SDL_EVENT_KEY_DOWN) { - if (e.key.key == SDLK_W) { - game->camera.p.y -= 0.2f; - } - if (e.key.key == SDLK_S) { - game->camera.p.y += 0.2f; - } - - if (e.key.key == SDLK_A) { - game->camera.p.x -= 0.2f; - } - - if (e.key.key == SDLK_D) { - game->camera.p.x += 0.2f; - } - } - - ProcessEvents(&e, &world); + ProcessEvents(&e, game->world); } - UpdateWorld(1.0f / 60.0f, &world); + 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; int w, h; SDL_GetWindowSizeInPixels(window, &w, &h); - game->draw.window_width = w; + game->draw.window_width = w; game->draw.window_height = h; - G_CalculateCamera(&game->camera, (F32) w / (F32) h); + G_CalculateCamera(&game->camera, (F32)w / (F32)h); Vk_Frame *frame = Vk_FrameBegin(window); VkCommandBuffer cmd = frame->cmd; @@ -147,24 +152,29 @@ int main(int argc, char **argv) { clear_colour.color.float32[3] = 1.0f; VkRenderingAttachmentInfo colour_attachment = {0}; - colour_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; - colour_attachment.imageView = vk.swapchain.views[frame->image]; + colour_attachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + colour_attachment.imageView = vk.swapchain.views[frame->image]; colour_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - colour_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - colour_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - colour_attachment.clearValue = clear_colour; + colour_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + colour_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + colour_attachment.clearValue = clear_colour; VkRenderingInfo rendering_info = {0}; - rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; - rendering_info.renderArea = (VkRect2D) { 0, 0, w, h }; - rendering_info.layerCount = 1; + rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + rendering_info.renderArea = (VkRect2D){0, 0, w, h}; + rendering_info.layerCount = 1; rendering_info.colorAttachmentCount = 1; - rendering_info.pColorAttachments = &colour_attachment; + rendering_info.pColorAttachments = &colour_attachment; vk.CmdBeginRendering(cmd, &rendering_info); D_Begin(&game->draw, frame, D_MAX_RECTS); + RenderWorld(game->world, &game->draw); + D_Rect(&game->draw, 0.0f, 0.0f, .texture = 1); + D_Rect(&game->draw, -8.0f, 0.0f, .texture = 2, .scale = 2.0f); + D_Rect(&game->draw, 6.0f, 0.0f, .texture = 3); + D_End(&game->draw, frame); vk.CmdEndRendering(cmd); diff --git a/code/game/aabb.h b/code/game/aabb.h index e61ba60..9344521 100644 --- a/code/game/aabb.h +++ b/code/game/aabb.h @@ -3,15 +3,15 @@ #include "../core/types.h" #include "../core/macros.h" - typedef struct AABB AABB; -struct AABB { +struct AABB +{ V2f pos; V2f size; }; - 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); -#endif // LD_GAME_AABB_H_ +#endif // LD_GAME_AABB_H_ diff --git a/code/game/bandit.h b/code/game/bandit.h index 2c25215..3814017 100644 --- a/code/game/bandit.h +++ b/code/game/bandit.h @@ -6,7 +6,7 @@ enum BANDIT_ACTION { BANDIT_WAITING, BANDIT_WALKING, BANDIT_RUNNING, - BANDIT_SHOOTOUT, + BANDIT_SHOOTING, }; typedef struct Bandit Bandit; @@ -22,6 +22,7 @@ struct Bandit { // How long they will wait in this location. F32 maxWaitTime; + U32 poiCount; // Places the bandit walks to / from // E.g. hide outs, home, saloon U32 pointsOfInterest[12]; diff --git a/code/game/core.h b/code/game/core.h index ef6797d..af23ec5 100644 --- a/code/game/core.h +++ b/code/game/core.h @@ -1,5 +1,6 @@ #if !defined(LD_GAME_CORE_H_) #define LD_GAME_CORE_H_ +#include "world.h" typedef struct G_Camera G_Camera; struct G_Camera { @@ -18,6 +19,8 @@ struct G_State { D_Context draw; G_Camera camera; + + World *world; }; function void G_ImagesLoad(G_State *game); @@ -35,6 +38,5 @@ function R3f G_CameraBounds(G_Camera *camera); #include "player.h" #include "nav.h" #include "npc.h" -#include "world.h" #endif // LD_GAME_CORE_H_ diff --git a/code/game/impl/aabb.c b/code/game/impl/aabb.c index c1d1fba..dfeb99b 100644 --- a/code/game/impl/aabb.c +++ b/code/game/impl/aabb.c @@ -1,15 +1,36 @@ #include "game/aabb.h" -#include "core/types.h" +#include -bool AABB_Collide(AABB a, AABB b) { +bool AABB_Collide(AABB a, AABB b) +{ bool collision_x = a.pos.x + a.size.x >= b.pos.x && b.pos.x + b.size.x >= a.pos.x; bool collision_y = a.pos.y + a.size.x >= b.pos.y && b.pos.y + b.size.y >= a.pos.y; return collision_x && collision_y; } -bool AABB_Point(AABB a, V2f v) { +bool AABB_Point(AABB a, V2f v) +{ bool collision_x = a.pos.x + a.size.x >= v.x && a.pos.x <= v.x; bool collision_y = a.pos.x + a.size.y >= v.y && a.pos.y <= v.y; return collision_x && collision_y; } +bool AABB_Slab(V2f origin, V2f point, AABB a) +{ + V2f start = a.pos; + V2f finish = {a.pos.x + a.size.x, a.pos.y + a.size.y}; + V2f invdirection = {1 / (origin.x - point.x), 1 / (origin.y - point.y)}; + // x + F32 tLow = (start.x - origin.x) * invdirection.x; + F32 tHigh = (finish.x - origin.x) * invdirection.x; + F32 tMin = Min(tLow, tHigh); + F32 tMax = Max(tLow, tHigh); + // y + tLow = (start.y - origin.y) * invdirection.y; + tHigh = (finish.y - origin.y) * invdirection.y; + + tMin = Max(tMin, Min(tLow, tHigh)); + tMax = Min(tMax, Max(tLow, tHigh)); + + return tMax >= tMin; +} diff --git a/code/game/impl/bandit.c b/code/game/impl/bandit.c new file mode 100644 index 0000000..5aeb2a4 --- /dev/null +++ b/code/game/impl/bandit.c @@ -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 + } +} diff --git a/code/game/impl/nav.c b/code/game/impl/nav.c index a6e7fe9..b8b024e 100644 --- a/code/game/impl/nav.c +++ b/code/game/impl/nav.c @@ -6,45 +6,54 @@ #define MAX_UNFINISHED 128 typedef struct navSearchNodeState navSearchNodeState; -struct navSearchNodeState{ +struct navSearchNodeState +{ bool visited; - U64 distance; + F64 distance; U32 shortest; bool addedToUnvisited; }; typedef struct navSearchState navSearchState; -struct navSearchState{ +struct navSearchState +{ navSearchNodeState nodeStates[NAV_MAX_NODES]; }; -navSearchState initState(U32 start, U32 meshSize) { - navSearchState state = {}; - for(U32 i = 0; i < meshSize; i++) { - state.nodeStates[i].visited = false; +navSearchState initState(U32 start, U32 meshSize) +{ + navSearchState state; + for (U32 i = 0; i < meshSize; i++) + { + state.nodeStates[i].visited = false; state.nodeStates[i].addedToUnvisited = false; - state.nodeStates[i].distance = U64_MAX; - state.nodeStates[i].shortest = 0; + state.nodeStates[i].distance = F64_MAX; + state.nodeStates[i].shortest = 0; } state.nodeStates[start].distance = 0; return state; } -U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchState state, U32 *offset) { - U32 lowest = U32_MAX; +U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchState state, U32 *offset) +{ + U32 lowest = U32_MAX; U32 lowestI = U32_MAX; bool startFound = false; - for(U32 i = *offset; i < unfinishedCount; i++) { + for (U32 i = *offset; i < unfinishedCount; i++) + { navSearchNodeState checkNode = state.nodeStates[unfinishedIndexes[i]]; - if(checkNode.visited) { - if(!startFound) { + if (checkNode.visited) + { + if (!startFound) + { *offset = i; } continue; } startFound = true; - if (lowest > checkNode.distance) { - lowest = cast(U32) checkNode.distance; + if (lowest > checkNode.distance) + { + lowest = cast(U32) checkNode.distance; lowestI = unfinishedIndexes[i]; } } @@ -53,6 +62,12 @@ U32 getLowestState(U32 unfinishedIndexes[128], U32 unfinishedCount, navSearchSta // Generate a path to follow between the start and end node. NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) { + // This is a stupid fix, since it's easier to work backwards + // to generate a path, I'm swapping the start / end, to generate + // it backwards + U32 tmp = end; + end = start; + start = tmp; navSearchState state = initState(start, mesh->nodeCount); U32 unfinishedCount = 1; U32 unfinishedIndexes[NAV_MAX_NODES] = {start}; @@ -68,14 +83,15 @@ NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) { NavConnection *connection = &mesh->nodes[lowestNodeIndex].connections[connectionI]; navSearchNodeState *testNode = &state.nodeStates[connection->NodeIndex]; if(testNode->visited) {continue;} - U32 distance = cast(U32) (state.nodeStates[lowestNodeIndex].distance + connection->Cost); - distance += cast(U32) (mesh->nodes[end].pos.x - mesh->nodes[connection->NodeIndex].pos.x); - distance += cast(U32) (mesh->nodes[end].pos.y - mesh->nodes[connection->NodeIndex].pos.y); + F64 distance = cast(F64) (state.nodeStates[lowestNodeIndex].distance + connection->Cost); + distance += cast(F64) Abs((mesh->nodes[end].pos.x - mesh->nodes[connection->NodeIndex].pos.x)); + distance += cast(F64) Abs((mesh->nodes[end].pos.y - mesh->nodes[connection->NodeIndex].pos.y)); if(testNode->distance > distance) { testNode->distance = distance; testNode->shortest = lowestNodeIndex; } - if(!testNode->addedToUnvisited) { + if (!testNode->addedToUnvisited) + { unfinishedIndexes[unfinishedCount] = connection->NodeIndex; unfinishedCount++; testNode->addedToUnvisited = true; @@ -83,13 +99,15 @@ NavPath Nav_Path(NavMesh *mesh, U32 start, U32 end) { } state.nodeStates[lowestNodeIndex].visited = true; lowestNodeIndex = getLowestState(unfinishedIndexes, unfinishedCount, state, &unfinishedOffset); - if(lowestNodeIndex == end) { + if (lowestNodeIndex == end) + { found = true; } } NavPath res_path = {0}; U32 index = end; - while(index!=start) { + while (index != start) + { res_path.indexes[res_path.nodeCount] = index; res_path.nodeCount++; index = state.nodeStates[index].shortest; diff --git a/code/game/impl/npc.c b/code/game/impl/npc.c index 4c9d1a2..3ea5599 100644 --- a/code/game/impl/npc.c +++ b/code/game/impl/npc.c @@ -1,22 +1,22 @@ #include "game/npc.h" #include "game/world.h" #include "core/types.h" +#include "core/math.h" -#include - -void updateNPC(F32 delta, NPC *npc, World *world) { +void UpdateNPC(F32 delta, NPC *npc, World *world) { switch (npc->mode) { case NPC_ACTION_WAITING: npc->waitTime+=delta; if(npc->waitTime > npc->maxWaitTime) { npc->mode = NPC_ACTION_WALKING; - U32 next = npc->targetNavNode == 100 ? 20 : 100; - npc->targetNavNode = next; // TODO RANDOM - printf("Starting to nav path\n"); + // TODO change targets to poi's rather than just random nodes + // TODO choose either global POI's or use NPC custom poi if + // customPOI is true + do { + npc->targetNavNode = Random_U32(&world->random, 0, world->navMesh->nodeCount); + } while(npc->targetNavNode == npc->currentNavNode); npc->path = Nav_Path(world->navMesh, npc->currentNavNode, npc->targetNavNode); - printf("done\n"); npc->walkTimer = 0; - printf("%.*s started walking to %d\n", Sv(npc->name), npc->targetNavNode); } break; case NPC_ACTION_WALKING: @@ -24,18 +24,18 @@ void updateNPC(F32 delta, NPC *npc, World *world) { if(npc->walkTimer >= NPC_SPEED){ npc->walkTimer = 0; if(npc->path.nodeCount == npc->pathIndex+1){ - printf("Finished! so I'm waiting\n"); npc->mode = NPC_ACTION_WAITING; - npc->maxWaitTime = 20; // TODO RANDOM + npc->maxWaitTime = Random_F32(&world->random, 20, 140); npc->waitTime = 0; + npc->currentNavNode = npc->targetNavNode; npc->pathIndex = 0; return; } - npc->pathIndex+=1; npc->currentNavNode = npc->path.indexes[npc->pathIndex]; + npc->pathIndex+=1; } NavNode cNav = world->navMesh->nodes[npc->currentNavNode]; - NavNode tNav = world->navMesh->nodes[npc->pathIndex]; + NavNode tNav = world->navMesh->nodes[npc->path.indexes[npc->pathIndex]]; npc->collision.pos.x = cNav.pos.x * (1 - npc->walkTimer/NPC_SPEED) + tNav.pos.x * npc->walkTimer/NPC_SPEED; npc->collision.pos.y = cNav.pos.y * (1 - npc->walkTimer/NPC_SPEED) + tNav.pos.y * npc->walkTimer/NPC_SPEED; break; diff --git a/code/game/impl/player.c b/code/game/impl/player.c index ae8ded7..f9c442c 100644 --- a/code/game/impl/player.c +++ b/code/game/impl/player.c @@ -1,26 +1,78 @@ #include "../player.h" +#include #include #include -void PlayerUpdate(SDL_Event *event, Player *player) +void PlayerInput(SDL_Event *event, Player *player) { - SDL_KeyboardEvent key = event->key; - switch(key.key) { - case SDLK_W: { - player->pos.y += 10; + player->controls.shot = false; + SDL_KeyboardEvent key = event->key; + SDL_MouseButtonEvent mouseBtn = event->button; + if(event->type == SDL_EVENT_KEY_DOWN || event->type == SDL_EVENT_KEY_UP) { + bool val = event->type == SDL_EVENT_KEY_DOWN; + switch (key.key) + { + case SDLK_W: + { + player->controls.upDown = val; break; } - case SDLK_A: { - player->pos.x -= 10; + case SDLK_A: + { + player->controls.leftDown = val; break; } - case SDLK_D: { - player->pos.x += 10; + case SDLK_D: + { + player->controls.rightDown = val; break; } - case SDLK_S: { - player->pos.y -= 10; + case SDLK_S: + { + player->controls.downDown = val; break; } } + } + if ( + event->type == SDL_EVENT_MOUSE_BUTTON_DOWN + && mouseBtn.button == SDL_BUTTON_LEFT + ) { + 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"); + }; + } +} + +void PlayerUpdate(F32 delta, Player *player) { + V2f dir = V2F(0, 0); + if(player->controls.upDown) { + dir.y -= 1; + } + if(player->controls.downDown) { + dir.y += 1; + } + if(player->controls.leftDown) { + dir.x -= 1; + } + if(player->controls.rightDown) { + 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); + player->pos.x += dir.x; + player->pos.y += dir.y; } diff --git a/code/game/impl/world.c b/code/game/impl/world.c index 3f218d7..3734e08 100644 --- a/code/game/impl/world.c +++ b/code/game/impl/world.c @@ -3,18 +3,38 @@ #include "../player.h" #include -void UpdateWorld(F32 delta, World *world) { +void UpdateWorld(F32 delta, World *world) +{ + UpdateBandit(delta, &world->bandit, world); UpdateNPCs(delta, world); + PlayerUpdate(delta, &world->player); } -void UpdateNPCs(F32 delta, World *world) { - for(U32 i = 0; i < world->npcCount; i++) { - updateNPC(delta, &world->npcs[i], world); +void UpdateNPCs(F32 delta, World *world) +{ + for (U32 i = 0; i < world->npcCount; i++) + { + 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)); + } } } -void ProcessEvents(SDL_Event *event, World *world) { - PlayerUpdate(event, &world->player); +void ProcessEvents(SDL_Event *event, World *world) +{ + PlayerInput(event, &world->player); +} + +void RenderWorld(World *world, D_Context *draw) { + for(U32 i = 0; i < world->npcCount; i++) { + 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); } void G_WorldDraw(G_State *game, World *world) { diff --git a/code/game/npc.h b/code/game/npc.h index ad66f50..3805ba4 100644 --- a/code/game/npc.h +++ b/code/game/npc.h @@ -5,7 +5,7 @@ #include "npc_look.h" #include "../core/types.h" -#define NPC_SPEED 0.2f +#define NPC_SPEED 1.0f typedef enum NPC_ACTION NPC_ACTION; enum NPC_ACTION { @@ -23,6 +23,10 @@ struct NPC { Str8 name; NPC_LOOK look; + bool customPOI; + U32 customPOICount; + U32 npcPOI[16]; + //// Actions NPC_ACTION mode; // How long they've been waiting diff --git a/code/game/player.h b/code/game/player.h index 8067026..5a994dc 100644 --- a/code/game/player.h +++ b/code/game/player.h @@ -6,12 +6,31 @@ #include +#define PLAYER_SPEED 10.0f +#define PLAYER_RELOAD_TIME 1.5f +#define PLAYER_BULLET_COUNT 6 + +typedef struct ControlState ControlState; +struct ControlState { + bool rightDown; + bool leftDown; + bool upDown; + bool downDown; + bool shot; +}; + typedef struct Player Player; struct Player { V2f pos; + U32 bulletsLoaded; + ControlState controls; + V2f shotPos; + + F32 reloadTimer; }; -function void PlayerUpdate(SDL_Event *event, Player *player); +function void PlayerInput(SDL_Event *event, Player *player); +function void PlayerUpdate(F32 delta, Player *player); #endif // LD_GAME_PLAYER_H_ diff --git a/code/game/world.h b/code/game/world.h index 8bc969c..2cd96eb 100644 --- a/code/game/world.h +++ b/code/game/world.h @@ -4,6 +4,7 @@ #include "player.h" #include "npc.h" #include "bandit.h" +#include "../core/math.h" // Areas are which typedef U32 World_Area; @@ -16,6 +17,7 @@ typedef struct World World; struct World { //// Static stuff NavMesh *navMesh; + Random random; //// Player Player player; @@ -33,10 +35,10 @@ struct World { }; function void UpdateWorld(F32 delta, World *world); +function void RenderWorld(World *world, D_Context *drawContext ); function void ProcessEvents(SDL_Event *event, World *world); function void UpdateNPCs(F32 delta, World *world); -function void updateNPC(F32 delta, NPC *npc, World *world); - -function void G_WorldDraw(G_State *game, 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_