fp: Move game stuff into game files

This commit is contained in:
2023-09-23 12:33:59 +10:00
parent f9f3cec9cc
commit cc202cefac
4 changed files with 142 additions and 146 deletions
+94 -1
View File
@@ -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;
}