added completly static build to meson, added line-of-sight test for aggro and map drawing
MCMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
project(orcsmasher LANGUAGES C)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wpedantic -Wno-type-limits")
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Og -g -fsanitize=address")
Minclude/algorithm.h
@@ -2,6 +2,7 @@
#define ALGORITHM_H
#include <stddef.h>
#include <game.h>
#include <config.h>
//creates a game, fills it with walls and empty fields
struct game make_maze(size_t y, size_t x);
@@ -10,7 +11,22 @@ typedef darray(struct point) pointarr;
//algorithm terminates with no path if target is not found within maxdist
//result contains target as well as the source point
//so even if next to the target, the result arr is at least 2 items big
pointarr astar(struct game *g, struct point start, struct point target, size_t maxdist);
pointarr astar(struct game *g, struct point start, struct point target, size_t maxdist);
#define insight(g,p1,p2) (insight_(g,p1,p2) || insight_(g,p2,p1))
static inline bool insight_(const struct game *g, struct point p1, struct point p2)
{
size_t view_left = SIGHT_RANGE; //FIXME: range seems too long ingame
while(!pointeq(p1,p2))
{
if(p1.x != p2.x)
p2.x += sign(p1.x - p2.x);
if(p1.y != p2.y)
p2.y += sign(p1.y - p2.y);
if(!(view_left--) || game_at(g, p2)->u->ground.type == WALL)
return false;
}
return true;
}
#endif //ALGORITHM_H
Minclude/config.h
@@ -1,7 +1,9 @@
#ifndef CONFIG_H
#define CONFIG_H
#define AGGRO_RANGE 4
#define AGGRO_RANGE 6
#define SIGHT_RANGE ((size_t)-1)
#define SIGHT_EMPTY true
#define GAME_MIN_Y 10
#define GAME_MIN_X 10
#define GAME_MAX_Y 30
@@ -14,4 +16,5 @@
#define MAX_LOOT 15
#endif //COFNIG_H
Minclude/helper.h
@@ -21,6 +21,13 @@ static inline unsigned int iabs(int i)
return i < 0 ? -i : i;
}
static inline int sign(int m)
{
return m < 0 ? -1:
m > 0 ? 1:
0;
}
static inline int ipow(int base, int exp)
{
int result = 1;
Mmeson.build
@@ -5,8 +5,10 @@ project('orcsmasher', 'c',
inc = include_directories('include')
cc = meson.get_compiler('c')
static_build = get_option('default_library') == 'static'
CFLAGS = []
CFLAGS = ['-Wno-type-limits']
LDFLAGS = []
if get_option('buildtype') == 'debug'
@@ -16,9 +18,11 @@ endif
if get_option('buildtype') == 'release'
CFLAGS += ['-O3', '-march=native', '-g']
if static_build
LDFLAGS += ['-static']
endif
endif
static_build = get_option('default_library') == 'static'
if static_build
LDFLAGS += ['-l:libgpm.a']
Msrc/loop.c
@@ -205,21 +205,23 @@ static void run_ai(struct game *g, struct point player)
goto next;
}
darray_append(checked, game_at(g, (struct point){y,x})->m.id);
res = astar(g, (struct point){y,x}, player, AGGRO_RANGE);
if(res.size >= 2) {
attack_move(g, (struct point){y,x}, darray_item(res, res.size-2));
} else {
struct point ps[4] =
{
{y, x-1},
{y, x+1},
{y-1, x},
{y+1, x}
};
move_object(g, (struct point){y,x}, ps[randrange(0,3)]);
if(insight(g, ((struct point){y,x}), player)) {
res = astar(g, (struct point){y,x}, player, 20);
if(res.size >= 2) {
attack_move(g, (struct point){y,x}, darray_item(res, res.size-2));
} else {
struct point ps[4] =
{
{y, x-1},
{y, x+1},
{y-1, x},
{y+1, x}
};
move_object(g, (struct point){y,x}, ps[randrange(0,3)]);
}
darray_free(res);
}
darray_free(res);
}
next:;
@@ -291,6 +293,7 @@ void loop()
delete_game(&g);
return;
case MOVE:;
struct point oldpos = player;
struct point targetpos = relative(player, c.u.d);
if(!in_bounds(&g, targetpos)) {
@@ -305,7 +308,7 @@ void loop()
loop();
return;
}
run_ai(&g, player);
run_ai(&g, oldpos);
break;
case SPAWN:
spawn_enemy(&g);
Msrc/tui.c
@@ -11,6 +11,8 @@
#include <string.h>
#include <helper.h>
#include <config.h>
#include <algorithm.h>
static PANEL *stdpanel = NULL;
static WINDOW *logbox = NULL;
@@ -240,10 +242,23 @@ void draw_map(const struct game *g, struct point p)
for(size_t j = startx; j < endx; j++)
{
struct field *f = game_at(g, (struct point){.y = i, .x = j});
if(f->has_monster)
waddch(mapwin, f->m.symbol);
else
waddch(mapwin, f->u->ground.symbol);
bool sight = insight(g, p, ((struct point){.y = i, .x = j}));
if(SIGHT_EMPTY || sight) { //TODO: add colors to unkown but sighted areas
if(!sight)
wattron(mapwin, A_DIM);
if(f->has_monster && sight) {
waddch(mapwin, f->m.symbol);
} else if(f->u->ground.type == ITEM && !sight) {
waddch(mapwin, ' ');
} else {
waddch(mapwin, f->u->ground.symbol);
}
if(!sight)
wattroff(mapwin, A_DIM);
} else {
waddch(mapwin, '.');
}
}
}