fp: Move game stuff into game files
This commit is contained in:
+94
-1
@@ -1,6 +1,6 @@
|
||||
#if defined(__clang__)
|
||||
#pragma once
|
||||
#include "playground_unity.h"
|
||||
#include "feely_pona_unity.h"
|
||||
#endif
|
||||
|
||||
static bool operator==(FP_GameEntityHandle const &lhs, FP_GameEntityHandle const &rhs)
|
||||
@@ -449,3 +449,96 @@ static bool FP_Game_EntityActionHasFailed(FP_GameEntityAction const *action)
|
||||
bool result = action ? action->flags & FP_GameEntityActionFlag_Failed : true;
|
||||
return result;
|
||||
}
|
||||
|
||||
static Dqn_Slice<Dqn_V2I> FP_Game_AStarPathFind(FP_Game *game, Dqn_Arena *arena, TELY_Platform *platform, Dqn_V2I src_tile, Dqn_V2I dest_tile)
|
||||
{
|
||||
Dqn_DSMap<FP_GameAStarNode> astar_info = Dqn_DSMap_Init<FP_GameAStarNode>(128);
|
||||
DQN_DEFER { Dqn_DSMap_Deinit(&astar_info); };
|
||||
|
||||
Dqn_FArray<Dqn_V2I, 128> frontier = {};
|
||||
Dqn_FArray_Add(&frontier, src_tile);
|
||||
|
||||
Dqn_usize tile_count_x = DQN_CAST(Dqn_usize)(platform->core.window_size.w / game->tile_size);
|
||||
Dqn_usize tile_count_y = DQN_CAST(Dqn_usize)(platform->core.window_size.h / game->tile_size);
|
||||
|
||||
// NOTE: Initialise the starting cost
|
||||
uint64_t src_tile_u64 = (DQN_CAST(uint64_t)src_tile.y << 32) | (DQN_CAST(uint64_t)src_tile.x << 0);
|
||||
Dqn_DSMap_MakeKeyU64(&astar_info, src_tile_u64);
|
||||
|
||||
while (frontier.size) {
|
||||
Dqn_V2I curr_tile = Dqn_FArray_PopFront(&frontier, 1);
|
||||
if (curr_tile == dest_tile)
|
||||
break;
|
||||
|
||||
Dqn_FArray<Dqn_V2I, 4> neighbours = {};
|
||||
{
|
||||
Dqn_V2I left = Dqn_V2I_InitNx2(curr_tile.x - 1, curr_tile.y);
|
||||
Dqn_V2I right = Dqn_V2I_InitNx2(curr_tile.x + 1, curr_tile.y);
|
||||
Dqn_V2I top = Dqn_V2I_InitNx2(curr_tile.x, curr_tile.y - 1);
|
||||
Dqn_V2I bottom = Dqn_V2I_InitNx2(curr_tile.x, curr_tile.y + 1);
|
||||
|
||||
if (left.x >= 0)
|
||||
Dqn_FArray_Add(&neighbours, left);
|
||||
if (right.x <= tile_count_x)
|
||||
Dqn_FArray_Add(&neighbours, right);
|
||||
if (top.y >= 0)
|
||||
Dqn_FArray_Add(&neighbours, top);
|
||||
if (bottom.y <= tile_count_y)
|
||||
Dqn_FArray_Add(&neighbours, bottom);
|
||||
}
|
||||
|
||||
uint64_t const curr_tile_u64 = (DQN_CAST(uint64_t)curr_tile.y << 32) | (DQN_CAST(uint64_t)curr_tile.x << 0);
|
||||
Dqn_usize const curr_cost = Dqn_DSMap_FindKeyU64(&astar_info, curr_tile_u64).value->cost;
|
||||
for (Dqn_V2I next_tile : neighbours) {
|
||||
|
||||
Dqn_usize new_cost = curr_cost + 1;
|
||||
uint64_t next_tile_u64 = (DQN_CAST(uint64_t)next_tile.y << 32) | (DQN_CAST(uint64_t)next_tile.x << 0);
|
||||
Dqn_DSMapResult<FP_GameAStarNode> next_cost_result = Dqn_DSMap_MakeKeyU64(&astar_info, next_tile_u64);
|
||||
|
||||
if (next_cost_result.found && new_cost >= next_cost_result.value->cost)
|
||||
continue;
|
||||
|
||||
Dqn_usize manhattan_dist = DQN_ABS(dest_tile.x - next_tile.x) + DQN_ABS(dest_tile.y - next_tile.y);
|
||||
next_cost_result.value->cost = new_cost;
|
||||
next_cost_result.value->came_from = curr_tile;
|
||||
next_cost_result.value->heuristic = new_cost + manhattan_dist;
|
||||
|
||||
// TODO(doyle): Find the insert location into the frontier
|
||||
bool inserted = false;
|
||||
DQN_FOR_UINDEX(index, frontier.size) {
|
||||
Dqn_V2I frontier_tile = frontier.data[index];
|
||||
uint64_t frontier_tile_u64 = DQN_CAST(uint64_t)frontier_tile.y << 32 | DQN_CAST(uint64_t)frontier_tile.x << 0;
|
||||
Dqn_usize frontier_heuristic = Dqn_DSMap_FindKeyU64(&astar_info, frontier_tile_u64).value->heuristic;
|
||||
if (next_cost_result.value->heuristic >= frontier_heuristic)
|
||||
continue;
|
||||
|
||||
Dqn_FArray_Insert(&frontier, index, next_tile);
|
||||
inserted = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (inserted)
|
||||
continue;
|
||||
|
||||
Dqn_FArray_Add(&frontier, next_tile);
|
||||
}
|
||||
}
|
||||
|
||||
Dqn_usize slice_size = 0;
|
||||
for (Dqn_V2I it = dest_tile; it != src_tile; slice_size++) {
|
||||
uint64_t key_u64 = (DQN_CAST(uint64_t)it.y << 32) | (DQN_CAST(uint64_t)it.x << 0);
|
||||
it = Dqn_DSMap_FindKeyU64(&astar_info, key_u64).value->came_from;
|
||||
}
|
||||
|
||||
Dqn_Slice<Dqn_V2I> result = Dqn_Slice_Alloc<Dqn_V2I>(arena, slice_size, Dqn_ZeroMem_No);
|
||||
slice_size = 0;
|
||||
for (Dqn_V2I it = dest_tile; it != src_tile; ) {
|
||||
result.data[slice_size++] = it;
|
||||
uint64_t key_u64 = (DQN_CAST(uint64_t)it.y << 32) | (DQN_CAST(uint64_t)it.x << 0);
|
||||
it = Dqn_DSMap_FindKeyU64(&astar_info, key_u64).value->came_from;
|
||||
}
|
||||
|
||||
DQN_ASSERT(result.size == slice_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user