X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/static/git-favicon.png?a=blobdiff_plain;f=src%2Fserver%2Fthings.c;h=eabded27bf98a554330ff84aab1abd34f384fccc;hb=778534bf6946fe0fef17e353c55678d248d8d09d;hp=d5aff96d93b70e29f52a69420950462782aaea5b;hpb=d92f16d5959fc846d3eaf669517eecb3969cda08;p=plomrogue diff --git a/src/server/things.c b/src/server/things.c index d5aff96..eabded2 100644 --- a/src/server/things.c +++ b/src/server/things.c @@ -2,12 +2,12 @@ #include "things.h" #include /* NULL */ -#include /* uint8_t, uint16_t, UINT16_MAX */ +#include /* uint8_t, uint16_t, UINT8_MAX, UINT16_MAX */ #include /* free() */ #include /* memset(), strlen() */ -#include "../common/rexit.h" /* exit_err() */ +#include "../common/rexit.h" /* exit_err(), exit_trouble() */ #include "../common/try_malloc.h" /* try_malloc() */ -#include "../common/yx_uint8.h" /* yx_uint8 struct */ +#include "../common/yx_uint8.h" /* yx_uint8 */ #include "map.h" /* is_passable() */ #include "rrand.h" /* rrand() */ #include "world.h" /* global world */ @@ -15,15 +15,29 @@ -/* Return pointer to thing of "id" in chain starting at "ptr". */ -static struct Thing * get_thing(struct Thing * ptr, uint8_t id); -/* Add thing of "type" to map on passable position. Don't put actor on actor. */ -static void add_thing(uint8_t type); +/* Return lowest unused id for new thing. */ +static uint8_t get_lowest_unused_id(); -static struct Thing * get_thing(struct Thing * ptr, uint8_t id) +static uint8_t get_lowest_unused_id() +{ + uint8_t i = 0; + while (1) + { + if (!get_thing(world.things, i, 1)) + { + return i; + } + exit_err(i == UINT8_MAX, "No unused ID available to add new thing."); + i++; + } +} + + + +extern struct Thing * get_thing(struct Thing * ptr, uint8_t id, uint8_t deep) { while (1) { @@ -31,10 +45,13 @@ static struct Thing * get_thing(struct Thing * ptr, uint8_t id) { return ptr; } - struct Thing * owned_thing = get_thing(ptr->owns, id); - if (NULL != owned_thing) + if (deep) { - return ptr; + struct Thing * owned_thing = get_thing(ptr->owns, id, 1); + if (NULL != owned_thing) + { + return ptr; + } } ptr = ptr->next; } @@ -42,18 +59,32 @@ static struct Thing * get_thing(struct Thing * ptr, uint8_t id) -static void add_thing(uint8_t type) +extern void free_thing_types(struct ThingType * tt_start) +{ + if (NULL == tt_start) + { + return; + } + free_thing_types(tt_start->next); + free(tt_start->name); + free(tt_start); +} + + + +extern struct Thing * add_thing(int16_t id, uint8_t type, uint8_t find_pos) { char * f_name = "add_thing()"; struct ThingType * tt = get_thing_type(type); struct Thing * t = try_malloc(sizeof(struct Thing), f_name); memset(t, 0, sizeof(struct Thing)); - t->id = world.thing_count++; + t->id = (0 <= id && id <= UINT8_MAX) ? id : get_lowest_unused_id(); t->type = tt->id; t->lifepoints = tt->lifepoints; char * err = "Space to put thing on too hard to find. Map too small?"; uint16_t i = 0; - while (1) + memset(&(t->pos), 0, sizeof(struct yx_uint8)); + while (find_pos) { struct yx_uint8 pos; for (pos.y = pos.x = 0; 0 == is_passable(pos); i++) @@ -81,19 +112,7 @@ static void add_thing(uint8_t type) struct Thing ** t_ptr_ptr = &world.things; for (; NULL != * t_ptr_ptr; t_ptr_ptr = &(*t_ptr_ptr)->next); * t_ptr_ptr = t; -} - - - -extern void free_thing_types(struct ThingType * tt_start) -{ - if (NULL == tt_start) - { - return; - } - free_thing_types(tt_start->next); - free(tt_start->name); - free(tt_start); + return t; } @@ -103,7 +122,7 @@ extern void add_things(uint8_t type, uint8_t n) uint8_t i; for (i = 0; i < n; i++) { - add_thing(type); + add_thing(-1, type, 1); } } @@ -160,19 +179,22 @@ extern void own_thing(struct Thing ** target, struct Thing ** source, extern struct Thing * get_player() { - return get_thing(world.things, 0); + return get_thing(world.things, 0, 1); } extern struct ThingType * get_thing_type(uint8_t id) { + char * f_name = "get_thing_type()"; struct ThingType * tt = world.thing_types; for (; NULL != tt && id != tt->id; tt = tt->next); char * err_intro = "Requested thing type of unused ID "; - char err[strlen(err_intro) + 3 + 1 + 1]; - sprintf(err, "%s%d.", err_intro, id); + uint16_t size = strlen(err_intro) + 3 + 1 + 1; + char * err = try_malloc(size, f_name); + exit_trouble(sprintf(err, "%s%d.", err_intro, id) < 0, f_name, "sprintf()"); exit_err(NULL == tt, err); + free(err); return tt; }