Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 26 additions & 80 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -199,69 +199,6 @@ else ()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D__FNAME__=__FILE__")
endif ()

# PROGRAMS:
add_executable(breakhack
src/main.c
src/texture.c
src/screenresolution.c
src/sprite.c
src/sprite_util.c
src/util.c
src/event.c
src/player.c
src/save.c
src/map.c
src/map_lua.c
src/camera.c
src/timer.c
src/roommatrix.c
src/position.c
src/monster.c
src/stats.c
src/actiontext.c
src/random.c
src/time.c
src/linkedlist.c
src/hashtable.c
src/gui.c
src/item.c
src/item_builder.c
src/pointer.c
src/gui_button.c
src/particle_engine.c
src/particle_emitter.c
src/menu.c
src/collisions.c
src/keyboard.c
src/input.c
src/mixer.c
src/io_util.c
src/physfsrwops.c
src/skillbar.c
src/texturecache.c
src/skill.c
src/projectile.c
src/vector2d.c
src/map_room_modifiers.c
lib/sqlite3/sqlite3.c
src/db.c
src/settings.c
src/actiontextbuilder.c
src/animation.c
src/trap.c
src/artifact.c
src/screen.c
src/hiscore.c
src/object.c
src/gui_util.c
src/tooltip.c
src/tooltip_manager.c
src/gamecontroller.c
src/effect_util.c
${STEAM_SOURCES}
)
set_property(TARGET breakhack PROPERTY C_STANDARD 99)

set(INCLUDE_DIRS
${PROJECT_BINARY_DIR}
${SDL_INCLUDE_DIR}
Expand All @@ -274,11 +211,15 @@ set(INCLUDE_DIRS
lib/bh_random/src
lib/checksum/src
)

target_include_directories(breakhack PRIVATE ${INCLUDE_DIRS})
# PROGRAMS:
add_executable(${PROJECT_NAME})
add_subdirectory(src)
add_subdirectory(lib/sqlite3)
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 99)
target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDE_DIRS})

if (NOT MSVC)
set_target_properties(breakhack PROPERTIES COMPILE_FLAGS
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS
-std=gnu11 -pedantic -Wall -Wextra -Wshadow
-Wpointer-arith -Wcast-qual -Wstrict-prototypes
-Wmissing-prototypes -Wconversion -Wno-sign-conversion
Expand All @@ -297,7 +238,7 @@ endif ()
# Sqlite has some warnings that I we don't need to see
set_source_files_properties(lib/sqlite3/sqlite3.c COMPILE_FLAGS -w)

target_link_libraries(breakhack
target_link_libraries(${PROJECT_NAME}
${CMAKE_DL_LIBS} # Sqlite needs DL libs
${SDL_LIBRARY}
${SDL_IMAGE_LIBRARY}
Expand All @@ -310,19 +251,19 @@ target_link_libraries(breakhack
)

if (STEAM)
target_link_libraries(breakhack
target_link_libraries(${PROJECT_NAME}
${STEAMWORKS_LIBRARY}
steamworks_c_wrapper
)
endif ()

if (MSVC)
set_target_properties(breakhack PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE /NODEFAULTLIB:MSVCRTD")
set_target_properties(breakhack PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
set_target_properties(breakhack PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
set_target_properties(breakhack PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "_CONSOLE")
set_target_properties(breakhack PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS /NODEFAULTLIB:MSVCRTD")
set_target_properties(breakhack PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:CONSOLE /NODEFAULTLIB:MSVCRTD")
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS_DEBUG "_CONSOLE")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELWITHDEBINFO "/SUBSYSTEM:CONSOLE")
set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS_RELWITHDEBINFO "_CONSOLE")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS /NODEFAULTLIB:MSVCRTD")
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_MINSIZEREL "/SUBSYSTEM:WINDOWS")
endif (MSVC)

# TESTS:
Expand All @@ -344,6 +285,11 @@ IF (CMOCKA_FOUND AND NOT OSX AND NOT CLANG)
target_link_libraries(test_hashtable ${CMOCKA_LIBRARY})
add_test(test_hashtable test_hashtable)

add_executable(test_pos_heap test/test_pos_heap.c src/pos_heap.c src/util.c)
target_include_directories(test_pos_heap PRIVATE ${INCLUDE_DIRS})
target_link_libraries(test_pos_heap ${CMOCKA_LIBRARY})
add_test(test_pos_heap test_pos_heap)

add_executable(test_input test/test_input.c src/input.c src/keyboard.c)
target_include_directories(test_input PRIVATE ${INCLUDE_DIRS})
target_link_libraries(test_input
Expand Down Expand Up @@ -413,7 +359,7 @@ endif ()
include(InstallRequiredSystemLibraries)

if (NOT STEAM)
INSTALL(TARGETS breakhack
INSTALL(TARGETS ${PROJECT_NAME}
COMPONENT Release
RUNTIME DESTINATION bin/
)
Expand All @@ -422,7 +368,7 @@ if (NOT STEAM)
DESTINATION share/breakhack/
)
else ()
INSTALL(TARGETS breakhack
INSTALL(TARGETS ${PROJECT_NAME}
COMPONENT Release
RUNTIME DESTINATION .
)
Expand All @@ -432,7 +378,7 @@ else ()
)
endif ()

set(CPACK_INSTALL_CMAKE_PROJECTS "${PROJECT_BINARY_DIR};breakhack;Release;.")
set(CPACK_INSTALL_CMAKE_PROJECTS "${PROJECT_BINARY_DIR};${PROJECT_NAME};Release;.")
set(CPACK_PACKAGE_NAME "BreakHack")
set(CPACK_PACKAGE_VENDOR "OliveShark")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
Expand All @@ -444,9 +390,9 @@ set(CPACK_PACKAGE_VERSION_PATCH ${breakhack_PATCH_VERSION})
set(CPACK_PACKAGE_INSTALL_DIRECTORY "BreakHack")
set(CPACK_PACKAGE_CHECKSUM "MD5")
if (WIN32)
set(CPACK_PACKAGE_FILE_NAME "breakhack-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-win32")
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-win32")
else ()
set(CPACK_PACKAGE_FILE_NAME "breakhack-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
endif ()
if (STEAM)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
Expand All @@ -455,7 +401,7 @@ endif ()

if(UNIX)
set(CPACK_GENERATOR TGZ ZIP)
set(CPACK_STRIP_FILES breakhack)
set(CPACK_STRIP_FILES ${PROJECT_NAME})
set(CPACK_SOURCE_STRIP_FILES "")
elseif(WIN32)
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
Expand Down
3 changes: 3 additions & 0 deletions lib/sqlite3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS *.c)

target_sources(${PROJECT_NAME} PRIVATE ${SOURCE_FILES})
7 changes: 7 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
file(GLOB SOURCE_FILES CONFIGURE_DEPENDS *.c)

if (STEAM)
file(GLOB SOURCE_FILES CONFIGURE_DEPENDS steam/*.c)
endif ()

target_sources(${PROJECT_NAME} PRIVATE ${SOURCE_FILES})
2 changes: 1 addition & 1 deletion src/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ typedef int64_t Sint64;
typedef uint64_t Uint64;

typedef enum Direction_t {
UP, DOWN, LEFT, RIGHT
UP, DOWN, LEFT, RIGHT, INVALID
} Direction;

typedef enum GameMode {
Expand Down
138 changes: 96 additions & 42 deletions src/monster.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "trap.h"
#include "object.h"
#include "mixer.h"
#include "pos_heap.h"

static void
monster_set_sprite_clip_for_current_state(Monster *m)
Expand Down Expand Up @@ -371,67 +372,117 @@ monster_drunk_walk(Monster *m, RoomMatrix *rm)
}
}

/**
* \brief Get the first move in the provided path
*/
static Direction
find_first_in_path(const Position *from, const Position *dest, const Position *start)
{
Position current = *dest;
Position next = *dest;
while (!position_equals(&next, start)) {
current = next;
next = from[current.x + current.y * MAP_ROOM_WIDTH];
}

Vector2d dir = { current.x - next.x, current.y - next.y };
if (dir.x > 0)
return RIGHT;
else if (dir.x < 0)
return LEFT;
else if (dir.y > 0)
return DOWN;
else
return UP;
}

/* Manhattan distance */
#define MDIST(p1, p2) abs(p1.x - p2.x) + abs(p1.y - p2.y)

/**
* \brief A* path finding algorithm
*
* This is a basic A* algorithm implementation usinga heap for the open_set.
* The pathing will avoid dangerous, lethal and blocked tiles but not tiles
* with monsters on so there can still be some stacking there.
*/
static Direction
get_optimal_move_towards(Monster *m, RoomMatrix *rm, const Position *dest)
get_optimal_move_towards(Monster *m, RoomMatrix *rm, const Position dest)
{
Direction ret_val = INVALID;
int x_dist, y_dist;
Position mPos;
const Position start = position_to_matrix_coords(&m->sprite->pos);
const Vector2d directions[] = {
VECTOR2D_UP,
VECTOR2D_DOWN,
VECTOR2D_LEFT,
VECTOR2D_RIGHT,
};

mPos = position_to_matrix_coords(&m->sprite->pos);
PHeap open_set;

unsigned int currentScore = 100;
unsigned int chosenDirection = UP;

for (unsigned int i = 0; i < 4; ++i) {
Position next = mPos;
unsigned int nextScore = 0;

switch (i) {
case UP:
next.y -= 1;
break;
case DOWN:
next.y += 1;
break;
case LEFT:
next.x -= 1;
break;
case RIGHT:
next.x += 1;
break;
}
uint16_t gScore[MAP_ROOM_WIDTH * MAP_ROOM_HEIGHT];
uint16_t fScore[MAP_ROOM_WIDTH * MAP_ROOM_HEIGHT];

if (position_equals(&next, dest)) {
chosenDirection = (Direction) i;
break;
}
memset(gScore, 0xFF, sizeof(gScore));
memset(fScore, 0xFF, sizeof(fScore));

Position from[MAP_ROOM_WIDTH * MAP_ROOM_HEIGHT];
bool visited[MAP_ROOM_WIDTH * MAP_ROOM_HEIGHT] = { false };
const size_t WIDTH = MAP_ROOM_WIDTH;

if (!position_in_roommatrix(&next))
continue;
/* Pre-allocate all the space we'll need and add start node */
pheap_init(&open_set, MAP_ROOM_WIDTH * MAP_ROOM_HEIGHT);
pheap_insert(&open_set, start, MDIST(start, dest));
visited[start.x + start.y * WIDTH] = true;

x_dist = abs(next.x - dest->x);
y_dist = abs(next.y - dest->y);
gScore[start.x + start.y * WIDTH] = 0;
fScore[start.x + start.y * WIDTH] = MDIST(start, dest);

if (rm->spaces[next.x][next.y].occupied
|| rm->spaces[next.x][next.y].lethal
|| rm->spaces[next.x][next.y].trap) {
nextScore += 50;
while (open_set.size > 0) {
Position current = pheap_pop(&open_set);
if (position_equals(&current, &dest)) {
ret_val = find_first_in_path(from, &dest, &start);
goto out;
}

nextScore += x_dist > y_dist ? x_dist : y_dist;
if (nextScore < currentScore) {
currentScore = nextScore;
chosenDirection = (Direction) i;
for (size_t i = 0; i < 4; i++) {
Position next = {
current.x + directions[i].x,
current.y + directions[i].y,
};

if (!position_equals(&next, &dest)) {
if (!position_in_roommatrix(&next)
|| rm->spaces[next.x][next.y].occupied
|| rm->spaces[next.x][next.y].lethal
|| rm->spaces[next.x][next.y].trap) {
continue;
}
}

uint32_t temp_score = 1 + gScore[current.x + current.y * WIDTH];
if (temp_score < gScore[next.x + next.y * WIDTH]) {
from[next.x + next.y * WIDTH] = current;
gScore[next.x + next.y * WIDTH] = temp_score;
fScore[next.x + next.y * WIDTH] = temp_score + MDIST(next, dest);
if (!visited[next.x + next.y * WIDTH]) {
visited[next.x + next.y * WIDTH] = true;
pheap_insert(&open_set, next, fScore[next.x + next.y * WIDTH]);
}
}
}
}

return chosenDirection;
out:
pheap_destroy(&open_set);
return ret_val;
}

static void
monster_agressive_walk(Monster *m, RoomMatrix *rm)
{
unsigned int chosenDirection = get_optimal_move_towards(m, rm, &rm->playerRoomPos);
unsigned int chosenDirection = get_optimal_move_towards(m, rm, rm->playerRoomPos);

switch (chosenDirection) {
case UP:
Expand All @@ -446,6 +497,9 @@ monster_agressive_walk(Monster *m, RoomMatrix *rm)
case RIGHT:
move(m, rm, VECTOR2D_RIGHT);
break;
case INVALID:
default:
break;
}
}

Expand Down
Loading
Loading