From 6db8d212ad66a7a934a47f319f88d1c811791798 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Fri, 22 Aug 2014 01:19:51 +0200 Subject: [PATCH] Server: Refactor yx_uint8 moving; handle actors hitting the map edge. --- TODO | 4 -- src/server/field_of_view.c | 99 +------------------------------------- src/server/map.c | 13 +++++ src/server/map.h | 8 ++- src/server/thing_actions.c | 29 ++++++----- src/server/yx_uint8.c | 83 +++++++++++++++++++++++--------- src/server/yx_uint8.h | 15 +++--- 7 files changed, 108 insertions(+), 143 deletions(-) diff --git a/TODO b/TODO index c9645c9..a5eb094 100644 --- a/TODO +++ b/TODO @@ -4,10 +4,6 @@ IN GENERAL: - expand use of hardcoded_strings module(s) -SERVER: - -- handle case of actors hitting the map edge - BOTH SERVER/CLIENT: - make server and client communicate by specific world state info requests diff --git a/src/server/field_of_view.c b/src/server/field_of_view.c index 45f3108..b430397 100644 --- a/src/server/field_of_view.c +++ b/src/server/field_of_view.c @@ -6,8 +6,9 @@ #include /* memset() */ #include "../common/rexit.h" /* exit_trouble() */ #include "../common/try_malloc.h" /* try_malloc() */ +#include "map.h" /* mv_yx_in_dir_legal() */ #include "things.h" /* Thing, ThingInMemory, add_thing_to_memory_map() */ -#include "yx_uint8.h" /* yx_uint8 */ +#include "yx_uint8.h" /* yx_uint8, mv_yx_in_hex_dir(), mv_yx_in_dir_wrap(), */ #include "world.h" /* world */ @@ -30,22 +31,6 @@ struct shadow_angle -/* Move "yx" into hex direction "d". */ -static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx); - -/* Move "yx" into hex direction "d". If this moves "yx" beyond the minimal (0) - * or maximal (UINT8_MAX) column or row, it wraps to the opposite side. Such - * wrapping is returned as a wraps enum value and stored, so that further calls - * to move "yx" back into the opposite direction may unwrap it again. Pass an - * "unwrap" of !0 to re-set the internal wrap memory to 0. - */ -static uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap); - -/* Wrapper to mv_yx_in_dir_wrap(), returns 1 if the wrapped function moved "yx" - * within the wrap borders and the map size, else 0. - */ -static uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx); - /* Recalculate angle < 0 or > CIRCLE to a value between these two limits. */ static uint32_t correct_angle(int32_t angle); @@ -91,86 +76,6 @@ static void update_map_memory(struct Thing * t, uint32_t map_size); -static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx) -{ - if (d == 'e') - { - yx->x = yx->x + (yx->y % 2); - yx->y--; - } - else if (d == 'd') - { - yx->x++; - } - else if (d == 'c') - { - yx->x = yx->x + (yx->y % 2); - yx->y++; - } - else if (d == 'x') - { - yx->x = yx->x - !(yx->y % 2); - yx->y++; - } - else if (d == 's') - { - yx->x--; - } - else if (d == 'w') - { - yx->x = yx->x - !(yx->y % 2); - yx->y--; - } -} - - - -static uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap) -{ - static int8_t wrap_west_east = 0; - static int8_t wrap_north_south = 0; - if (unwrap) - { - wrap_west_east = wrap_north_south = 0; - return 0; - } - struct yx_uint8 original; - original.y = yx->y; - original.x = yx->x; - mv_yx_in_hex_dir(d, yx); - if (strchr("edc", d) && yx->x < original.x) - { - wrap_west_east++; - } - else if (strchr("xsw", d) && yx->x > original.x) - { - wrap_west_east--; - } - if (strchr("we", d) && yx->y > original.y) - { - wrap_north_south--; - } - else if (strchr("xc", d) && yx->y < original.y) - { - wrap_north_south++; - } - return (wrap_west_east != 0) + (wrap_north_south != 0); -} - - - -static uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx) -{ - uint8_t wraptest = mv_yx_in_dir_wrap(dir, yx, 0); - if (!wraptest && yx->x < world.map.length && yx->y < world.map.length) - { - return 1; - } - return 0; -} - - - static uint32_t correct_angle(int32_t angle) { while (angle < 0) diff --git a/src/server/map.c b/src/server/map.c index 8ed37d9..50c7bf1 100644 --- a/src/server/map.c +++ b/src/server/map.c @@ -7,6 +7,7 @@ #include "../common/try_malloc.h" /* try_malloc() */ #include "../common/yx_uint8.h" /* struct yx_uint8 */ #include "rrand.h" /* rrand() */ +#include "yx_uint8.h" /* mv_yx_in_dir_wrap() */ #include "world.h" /* global world */ @@ -160,3 +161,15 @@ extern uint8_t is_passable(struct yx_uint8 pos) } return passable; } + + + +extern uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx) +{ + uint8_t wraptest = mv_yx_in_dir_wrap(dir, yx, 0); + if (!wraptest && yx->x < world.map.length && yx->y < world.map.length) + { + return 1; + } + return 0; +} diff --git a/src/server/map.h b/src/server/map.h index b1ad4c7..e3a28f9 100644 --- a/src/server/map.h +++ b/src/server/map.h @@ -6,8 +6,8 @@ #ifndef MAP_H_SERVER #define MAP_H_SERVER -#include /* uint8_t, uint16_t */ -#include "../common/yx_uint8.h" /* yx_uint8 struct */ +#include /* uint8_t */ +#include "../common/yx_uint8.h" /* yx_uint8 */ @@ -26,6 +26,10 @@ extern void remake_map(); */ extern uint8_t is_passable(struct yx_uint8 pos); +/* Wrapper to mv_yx_in_dir_wrap(), returns 1 if the wrapped function moved "yx" + * within the wrap borders and the map size, else 0. + */ +extern uint8_t mv_yx_in_dir_legal(char dir, struct yx_uint8 * yx); #endif diff --git a/src/server/thing_actions.c b/src/server/thing_actions.c index 9befd76..d120876 100644 --- a/src/server/thing_actions.c +++ b/src/server/thing_actions.c @@ -15,8 +15,8 @@ * set_thing_position(), get_thing_type(), * free_things_in_memory() */ -#include "map.h" /* is_passable() */ -#include "yx_uint8.h" /* mv_yx_in_dir(), yx_uint8_cmp() */ +#include "map.h" /* mv_yx_in_dir_legal(), is_passable() */ +#include "yx_uint8.h" /* mv_yx_in_dir_wrap(), yx_uint8_cmp() */ #include "world.h" /* global world */ @@ -259,21 +259,26 @@ extern void actor_wait(struct Thing * t) extern void actor_move(struct Thing * t) { char d = t->arg; - struct yx_uint8 target = mv_yx_in_dir(d, t->pos); struct Thing * other_t; - for (other_t = world.things; other_t != 0; other_t = other_t->next) + struct yx_uint8 target = t->pos; + uint8_t legal_move = mv_yx_in_dir_legal(d, &target); + mv_yx_in_dir_wrap(0, NULL, 1); + if (legal_move) { - if (0 == other_t->lifepoints || other_t == t) + for (other_t = world.things; other_t != 0; other_t = other_t->next) { - continue; - } - if (yx_uint8_cmp(&target, &other_t->pos)) - { - actor_hits_actor(t, other_t); - return; + if (0 == other_t->lifepoints || other_t == t) + { + continue; + } + if (yx_uint8_cmp(&target, &other_t->pos)) + { + actor_hits_actor(t, other_t); + return; + } } } - uint8_t passable = is_passable(target); + uint8_t passable = legal_move && is_passable(target); if (passable) { set_thing_position(t, target); diff --git a/src/server/yx_uint8.c b/src/server/yx_uint8.c index 626f9b4..c6a816d 100644 --- a/src/server/yx_uint8.c +++ b/src/server/yx_uint8.c @@ -1,8 +1,48 @@ /* src/server/yx_uint8.c */ #include "yx_uint8.h" -#include /* uint8_t, UINT8_MAX */ -#include "../common/yx_uint8.h" /* yx_uint8 struct */ +#include /* uint8_t, int8_t */ +#include /* strchr() */ +#include "../common/yx_uint8.h" /* yx_uint8 */ + + + +/* Move "yx" into hex direction "d". */ +static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx); + + + +static void mv_yx_in_hex_dir(char d, struct yx_uint8 * yx) +{ + if (d == 'e') + { + yx->x = yx->x + (yx->y % 2); + yx->y--; + } + else if (d == 'd') + { + yx->x++; + } + else if (d == 'c') + { + yx->x = yx->x + (yx->y % 2); + yx->y++; + } + else if (d == 'x') + { + yx->x = yx->x - !(yx->y % 2); + yx->y++; + } + else if (d == 's') + { + yx->x--; + } + else if (d == 'w') + { + yx->x = yx->x - !(yx->y % 2); + yx->y--; + } +} @@ -17,35 +57,34 @@ extern uint8_t yx_uint8_cmp(struct yx_uint8 * a, struct yx_uint8 * b) -extern struct yx_uint8 mv_yx_in_dir(char d, struct yx_uint8 yx) +extern uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap) { - if (d == 'e' && yx.y > 0 && (yx.x < UINT8_MAX || !(yx.y % 2))) - { - yx.x = yx.x + (yx.y % 2); - yx.y--; - } - else if (d == 'd' && yx.x < UINT8_MAX) + static int8_t wrap_west_east = 0; + static int8_t wrap_north_south = 0; + if (unwrap) { - yx.x++; + wrap_west_east = wrap_north_south = 0; + return 0; } - else if (d == 'c' && yx.y < UINT8_MAX && (yx.x < UINT8_MAX || !(yx.y % 2))) + struct yx_uint8 original; + original.y = yx->y; + original.x = yx->x; + mv_yx_in_hex_dir(d, yx); + if (strchr("edc", d) && yx->x < original.x) { - yx.x = yx.x + (yx.y % 2); - yx.y++; + wrap_west_east++; } - else if (d == 'x' && yx.y < UINT8_MAX && (yx.x > 0 || yx.y % 2)) + else if (strchr("xsw", d) && yx->x > original.x) { - yx.x = yx.x - !(yx.y % 2); - yx.y++; + wrap_west_east--; } - else if (d == 's' && yx.x > 0) + if (strchr("we", d) && yx->y > original.y) { - yx.x--; + wrap_north_south--; } - else if (d == 'w' && yx.y > 0 && (yx.x > 0 || yx.y % 2)) + else if (strchr("xc", d) && yx->y < original.y) { - yx.x = yx.x - !(yx.y % 2); - yx.y--; + wrap_north_south++; } - return yx; + return (wrap_west_east != 0) + (wrap_north_south != 0); } diff --git a/src/server/yx_uint8.h b/src/server/yx_uint8.h index ccfaa25..62cc9ce 100644 --- a/src/server/yx_uint8.h +++ b/src/server/yx_uint8.h @@ -7,19 +7,22 @@ #define YX_UINT8_H_SERVER #include /* uint8_t */ -#include "../common/yx_uint8.h" /* yx_uint8 struct */ +#include "../common/yx_uint8.h" /* yx_uint8 */ /* Return 1 if two yx_uint8 coordinates at "a" and "b" are equal, else 0. */ extern uint8_t yx_uint8_cmp(struct yx_uint8 * a, struct yx_uint8 * b); -/* Return yx_uint8 coordinate one step from "yx" in direction "dir" ('e': - * northeast, 'd': east, 'c': south-east, 'x': south-west, 's': west, ' 'w': - * north-west). If "dir" is invalid or would wrap the move around the edge of a - * 2^8x2^8 cells field, "yx" remains unchanged. +/* Move "yx" into hex direction "d". If this moves "yx" beyond the minimal (0) + * or maximal (UINT8_MAX) column or row, it wraps to the opposite side. Such + * wrapping is returned as a wraps enum value and stored, so that further calls + * to move "yx" back into the opposite direction may unwrap it again. Pass an + * "unwrap" of !0 to re-set the internal wrap memory to 0. + * Hex direction values for "d": 'e' (north-east), 'd' (east), 'c' (south-east), + * 'x' (south-west), 's' (west), 'w' (north-west) */ -extern struct yx_uint8 mv_yx_in_dir(char dir, struct yx_uint8 yx); +extern uint8_t mv_yx_in_dir_wrap(char d, struct yx_uint8 * yx, uint8_t unwrap); -- 2.30.2