Compare commits
2 Commits
a6266a336b
...
249109f117
| Author | SHA1 | Date | |
|---|---|---|---|
|
249109f117
|
|||
|
d0d79d0551
|
24
code/.vscode/launch.json
vendored
Normal file
24
code/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug 'main.c' Project",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/../build/ldebug",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "Build"
|
||||
}
|
||||
]
|
||||
}
|
||||
20
code/.vscode/tasks.json
vendored
Normal file
20
code/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build",
|
||||
"type": "shell",
|
||||
"command": "/home/matt/Repos/ld58/linux",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -45,4 +45,14 @@
|
||||
#define thread_var __thread
|
||||
#endif
|
||||
|
||||
#define S(x) Str8_Wrap(sizeof(x) - sizeof(*(x)), (U8 *) (x))
|
||||
Str8 Str8_Wrap(S64 count, U8 *data) {
|
||||
Str8 result;
|
||||
result.data = data;
|
||||
result.count = count;
|
||||
|
||||
return result;
|
||||
}
|
||||
#define Sv(x) (int) (x).count, (x).data
|
||||
|
||||
#endif // LD_CORE_MACROS_H_
|
||||
|
||||
100
code/game/impl/nav.c
Normal file
100
code/game/impl/nav.c
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "../nav.h"
|
||||
#include "../../core/types.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_UNFINISHED 128
|
||||
|
||||
typedef struct navSearchNodeState navSearchNodeState;
|
||||
struct navSearchNodeState{
|
||||
bool visited;
|
||||
U64 distance;
|
||||
U32 shortest;
|
||||
bool addedToUnvisited;
|
||||
};
|
||||
|
||||
typedef struct navSearchState navSearchState;
|
||||
struct navSearchState{
|
||||
navSearchNodeState nodeStates[NAV_MAX_NODES];
|
||||
};
|
||||
|
||||
navSearchState initState(U32 start, U32 meshSize) {
|
||||
navSearchState state = {};
|
||||
for(int i = 0; i < meshSize; i++) {
|
||||
state.nodeStates[i].visited = false;
|
||||
state.nodeStates[i].addedToUnvisited = false;
|
||||
// underflow to the max :)
|
||||
state.nodeStates[i].distance = -1;
|
||||
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 = -1;
|
||||
U32 lowestI = -1;
|
||||
bool startFound = false;
|
||||
for(int i = *offset; i < unfinishedCount; i++) {
|
||||
navSearchNodeState checkNode = state.nodeStates[unfinishedIndexes[i]];
|
||||
if(checkNode.visited) {
|
||||
if(!startFound) {
|
||||
*offset = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
startFound = true;
|
||||
if (lowest > checkNode.distance) {
|
||||
lowest = checkNode.distance;
|
||||
lowestI = unfinishedIndexes[i];
|
||||
}
|
||||
}
|
||||
return lowestI;
|
||||
}
|
||||
|
||||
// Generate a path to follow between the start and end node.
|
||||
NavPath Nav_Path(NavMesh mesh, U32 start, U32 end) {
|
||||
navSearchState state = initState(start, mesh.nodeCount);
|
||||
U32 unfinishedCount = 1;
|
||||
U32 unfinishedIndexes[NAV_MAX_NODES] = {start};
|
||||
// I don't want to spend time removing items from
|
||||
// the unfinished nodes, so when checking for a lowest
|
||||
// if I find the first N items have been checked, I'll mark
|
||||
// an offset to skip the first N items.
|
||||
U32 unfinishedOffset = 0;
|
||||
U32 lowestNodeIndex = start;
|
||||
bool found = false;
|
||||
while(!found) {
|
||||
for(int connectionI = 0 ; connectionI < mesh.nodes[lowestNodeIndex].connectionCount; connectionI++) {
|
||||
NavConnection connection = mesh.nodes[lowestNodeIndex].connections[connectionI];
|
||||
navSearchNodeState *testNode = &state.nodeStates[connection.NodeIndex];
|
||||
if(testNode->visited) {continue;}
|
||||
U32 distance = state.nodeStates[lowestNodeIndex].distance + connection.Cost;
|
||||
distance += mesh.nodes[end].pos.x - mesh.nodes[connection.NodeIndex].pos.x;
|
||||
distance += mesh.nodes[end].pos.y - mesh.nodes[connection.NodeIndex].pos.y;
|
||||
if(testNode->distance > distance) {
|
||||
testNode->distance = distance;
|
||||
testNode->shortest = lowestNodeIndex;
|
||||
}
|
||||
if(!testNode->addedToUnvisited) {
|
||||
unfinishedIndexes[unfinishedCount] = connection.NodeIndex;
|
||||
unfinishedCount++;
|
||||
testNode->addedToUnvisited = true;
|
||||
}
|
||||
}
|
||||
state.nodeStates[lowestNodeIndex].visited = true;
|
||||
lowestNodeIndex = getLowestState(unfinishedIndexes, unfinishedCount, state, &unfinishedOffset);
|
||||
if(lowestNodeIndex == end) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
NavPath res_path = {0};
|
||||
U32 index = end;
|
||||
while(index!=start) {
|
||||
res_path.indexes[res_path.nodeCount] = index;
|
||||
res_path.nodeCount++;
|
||||
index = state.nodeStates[index].shortest;
|
||||
}
|
||||
res_path.indexes[res_path.nodeCount] = start;
|
||||
res_path.nodeCount++;
|
||||
return res_path;
|
||||
}
|
||||
40
code/game/nav.h
Normal file
40
code/game/nav.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#if !defined(LD_GAME_NAV_H_)
|
||||
#define LD_GAME_NAV_H_
|
||||
|
||||
#include "../core/types.h"
|
||||
#include "../core/macros.h"
|
||||
|
||||
#define NAV_MAX_PATH 1024
|
||||
#define NAV_MAX_CONNECTIONS 8
|
||||
#define NAV_MAX_NODES 4096
|
||||
|
||||
typedef struct NavNode NavNode;
|
||||
|
||||
typedef struct NavConnection NavConnection;
|
||||
struct NavConnection{
|
||||
F32 Cost;
|
||||
U32 NodeIndex;
|
||||
};
|
||||
|
||||
struct NavNode {
|
||||
V2f pos;
|
||||
U8 connectionCount;
|
||||
NavConnection connections[NAV_MAX_CONNECTIONS];
|
||||
};
|
||||
|
||||
typedef struct NavPath NavPath;
|
||||
struct NavPath {
|
||||
U32 nodeCount;
|
||||
U32 indexes[NAV_MAX_PATH];
|
||||
};
|
||||
|
||||
typedef struct NavMesh NavMesh;
|
||||
struct NavMesh{
|
||||
U32 nodeCount;
|
||||
NavNode nodes[NAV_MAX_NODES];
|
||||
};
|
||||
|
||||
|
||||
function NavPath Nav_Path(NavMesh mesh, U32 start, U32 end);
|
||||
|
||||
#endif
|
||||
10
code/game/npc.h
Normal file
10
code/game/npc.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#if !defined(LD_GAME_NPC_H_)
|
||||
#define LD_GAME_NPC_H_
|
||||
#include "aabb.h"
|
||||
|
||||
typedef struct NPC NPC;
|
||||
struct NPC {
|
||||
AABB collision;
|
||||
};
|
||||
|
||||
#endif // LD_GAME_NPC_H_
|
||||
10
code/game/world.h
Normal file
10
code/game/world.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#if !defined(LD_GAME_WORLD_H_)
|
||||
#define LD_GAME_WORLD_H_
|
||||
|
||||
typedef struct World World;
|
||||
struct World {
|
||||
NPC[128] npcs;
|
||||
u32 npcCount;
|
||||
};
|
||||
|
||||
#endif // LD_GAME_WORLD_H_
|
||||
Reference in New Issue
Block a user