From d503937999c1e50f437ecf98327d658a46366cb2 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 12 Jun 2014 22:14:07 -0700 Subject: [PATCH] working on making json config understand ships and buildings. new tests in progress. remove giveitem.c attribute, the name clashed with a trigger, and it was only part of an arena that is gone from the game, I think. --- core/res/messages.xml | 5 +- scripts/runtests.lua | 2 + scripts/tests/rules.lua | 37 +++++----- se/eressea.vpj | 2 - se/tests.vpj | 2 + src/attributes/CMakeLists.txt | 3 +- src/attributes/giveitem.c | 133 ---------------------------------- src/attributes/giveitem.h | 36 --------- src/bind_faction.c | 2 +- src/bind_ship.c | 2 +- src/bind_unit.c | 2 +- src/bindings.c | 2 +- src/creport.c | 4 +- src/economy.c | 4 +- src/gmtool.c | 2 +- src/items/phoenixcompass.c | 2 +- src/kernel/battle_test.c | 6 +- src/kernel/build.c | 6 +- src/kernel/building.c | 9 ++- src/kernel/building.h | 2 +- src/kernel/item.c | 2 +- src/kernel/jsonconf.c | 58 +++++++++++++-- src/kernel/move_test.c | 6 +- src/kernel/race.c | 71 +++++++++--------- src/kernel/race.h | 7 +- src/kernel/save.c | 2 +- src/kernel/ship.c | 23 ++++-- src/kernel/ship.h | 4 +- src/kernel/ship_test.c | 8 +- src/kernel/xmlreader.c | 19 ++--- src/laws.c | 2 +- src/laws_test.c | 6 +- src/market.c | 2 +- src/modules/arena.c | 3 - src/report.c | 4 +- src/test_eressea.c | 3 +- src/tests.c | 7 +- 37 files changed, 186 insertions(+), 304 deletions(-) delete mode 100644 src/attributes/giveitem.c delete mode 100644 src/attributes/giveitem.h diff --git a/core/res/messages.xml b/core/res/messages.xml index 82db333ea..e87c4900f 100644 --- a/core/res/messages.xml +++ b/core/res/messages.xml @@ -8461,10 +8461,9 @@ - - "$unit($unit) in $region($region): '$order($command)' - Um $localize($name) zu bauen, braucht man ein Talent von mindestens $int($value)." - "$unit($unit) in $region($region): '$order($command)' - To build $localize($name) requires a skill of at least $int($value)." + "$unit($unit) in $region($region): '$order($command)' - Um das zu bauen, braucht man ein Talent von mindestens $int($value)." + "$unit($unit) in $region($region): '$order($command)' - This requires a skill of at least $int($value) to build." diff --git a/scripts/runtests.lua b/scripts/runtests.lua index 109443411..8ea9614c0 100644 --- a/scripts/runtests.lua +++ b/scripts/runtests.lua @@ -3,5 +3,7 @@ require "lunit" require "tests.settings" require "tests.config" +-- require "tests.ships" + lunit.main() diff --git a/scripts/tests/rules.lua b/scripts/tests/rules.lua index 97a3966fb..6ed6601cb 100644 --- a/scripts/tests/rules.lua +++ b/scripts/tests/rules.lua @@ -7,6 +7,7 @@ function setup() eressea.settings.set("nmr.removenewbie", "0") eressea.settings.set("nmr.timeout", "0") eressea.settings.set("NewbieImmunity", "0") + eressea.config.parse('{ "races": { "human" : {}}}') end function test_landing1() @@ -78,24 +79,24 @@ function test_landing_harbour_unpaid() end function test_landing_terrain() - local ocean = region.create(1, 0, "ocean") - local r = region.create(0, 0, "glacier") - local f = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") - local s = ship.create(ocean, "longboat") - local u1 = unit.create(f, ocean, 1) - local u2 = unit.create(f2, r, 1) - assert_not_nil(u2) - u1:add_item("money", 1000) - u2:add_item("money", 1000) - - u1.ship = s - u1:set_skill("sailing", 10) - u1:clear_orders() - u1:add_order("NACH w") - process_orders() - - assert_equal(ocean.id, u1.region.id) -- cannot land in glacier without harbour + local ocean = region.create(1, 0, "ocean") + local r = region.create(0, 0, "glacier") + local f = faction.create("noreply@eressea.de", "human", "de") + local f2 = faction.create("noreply@eressea.de", "human", "de") + local s = ship.create(ocean, "longboat") + local u1 = unit.create(f, ocean, 1) + local u2 = unit.create(f2, r, 1) + assert_not_nil(u2) + u1:add_item("money", 1000) + u2:add_item("money", 1000) + + u1.ship = s + u1:set_skill("sailing", 10) + u1:clear_orders() + u1:add_order("NACH w") + process_orders() + + assert_equal(ocean.id, u1.region.id) -- cannot land in glacier without harbour end function test_landing_insects() diff --git a/se/eressea.vpj b/se/eressea.vpj index cdfe0d2c0..58c297c2c 100644 --- a/se/eressea.vpj +++ b/se/eressea.vpj @@ -276,7 +276,6 @@ - @@ -430,7 +429,6 @@ - diff --git a/se/tests.vpj b/se/tests.vpj index 8ff7a974d..fffc6340c 100644 --- a/se/tests.vpj +++ b/se/tests.vpj @@ -279,8 +279,10 @@ Name="Other Files" Filters=""> + + diff --git a/src/attributes/CMakeLists.txt b/src/attributes/CMakeLists.txt index 7268b6436..34299b4b2 100644 --- a/src/attributes/CMakeLists.txt +++ b/src/attributes/CMakeLists.txt @@ -4,7 +4,6 @@ alliance.c attributes.c fleechance.c follow.c -giveitem.c gm.c hate.c iceberg.c @@ -25,4 +24,4 @@ FOREACH(_FILE ${_FILES}) LIST(APPEND _SOURCES ${PROJECT_NAME}/${_FILE}) ENDFOREACH(_FILE) SET(ATTRIBUTES_SRC ${_SOURCES} PARENT_SCOPE) - \ No newline at end of file + diff --git a/src/attributes/giveitem.c b/src/attributes/giveitem.c deleted file mode 100644 index d809eb111..000000000 --- a/src/attributes/giveitem.c +++ /dev/null @@ -1,133 +0,0 @@ -/* -Copyright (c) 1998-2010, Enno Rehling - Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#include -#include "giveitem.h" -#include - -/* kernel includes */ -#include -#include -#include -#include - -/* util includes */ -#include -#include -#include -#include - -#include - -/* libc includes */ -#include -#include - -typedef struct give_data { - struct building *building; - struct item *items; -} give_data; - -static void -a_writegive(const attrib * a, const void *owner, struct storage *store) -{ - give_data *gdata = (give_data *) a->data.v; - item *itm; - write_building_reference(gdata->building, store); - for (itm = gdata->items; itm; itm = itm->next) { - WRITE_TOK(store, resourcename(itm->type->rtype, 0)); - WRITE_INT(store, itm->number); - } - WRITE_TOK(store, "end"); -} - -static int a_readgive(attrib * a, void *owner, struct storage *store) -{ - give_data *gdata = (give_data *) a->data.v; - variant var; - char zText[32]; - - READ_INT(store, &var.i); - if (var.i > 0) { - gdata->building = findbuilding(var.i); - if (gdata->building == NULL) { - ur_add(var, &gdata->building, resolve_building); - } - } else { - gdata->building = NULL; - } - for (;;) { - int i; - READ_TOK(store, zText, sizeof(zText)); - if (!strcmp("end", zText)) - break; - READ_INT(store, &i); - if (i == 0) - i_add(&gdata->items, i_new(it_find(zText), i)); - } - return AT_READ_OK; -} - -static void a_initgive(struct attrib *a) -{ - a->data.v = calloc(sizeof(give_data), 1); -} - -static void a_finalizegive(struct attrib *a) -{ - free(a->data.v); -} - -static int a_giveitem(attrib * a) -{ - give_data *gdata = (give_data *) a->data.v; - unit *u; - - if (gdata->building == NULL || gdata->items == NULL) - return 0; - u = building_owner(gdata->building); - if (u == NULL) - return 1; - while (gdata->items) { - item *itm = gdata->items; - i_change(&u->items, itm->type, itm->number); - i_free(i_remove(&gdata->items, itm)); - } - return 0; -} - -attrib_type at_giveitem = { - "giveitem", - a_initgive, a_finalizegive, - a_giveitem, - a_writegive, a_readgive -}; - -attrib *make_giveitem(struct building * b, struct item * ip) -{ - attrib *a = a_new(&at_giveitem); - give_data *gd = (give_data *) a->data.v; - gd->building = b; - gd->items = ip; - return a; -} - -void init_giveitem(void) -{ - at_register(&at_giveitem); -} diff --git a/src/attributes/giveitem.h b/src/attributes/giveitem.h deleted file mode 100644 index 952ca4fb7..000000000 --- a/src/attributes/giveitem.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright (c) 1998-2010, Enno Rehling - Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#ifndef H_ATTRIBUTE_GIVEITEM -#define H_ATTRIBUTE_GIVEITEM -#ifdef __cplusplus -extern "C" { -#endif - - struct building; - struct item; - - extern struct attrib_type at_giveitem; - - extern struct attrib *make_giveitem(struct building *b, struct item *items); - extern void init_giveitem(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/bind_faction.c b/src/bind_faction.c index 5d39b15c2..e733f8525 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -393,7 +393,7 @@ static int tolua_faction_set_race(lua_State * L) { faction *self = (faction *) tolua_tousertype(L, 1, 0); const char *name = tolua_tostring(L, 2, 0); - race *rc = rc_find(name); + const race *rc = rc_find(name); if (rc != NULL) { self->race = rc; } diff --git a/src/bind_ship.c b/src/bind_ship.c index d268c88c6..50e803c31 100644 --- a/src/bind_ship.c +++ b/src/bind_ship.c @@ -180,7 +180,7 @@ static int tolua_ship_get_coast(lua_State * L) static int tolua_ship_get_type(lua_State * L) { ship *self = (ship *) tolua_tousertype(L, 1, 0); - tolua_pushstring(L, self->type->name[0]); + tolua_pushstring(L, self->type->_name); return 1; } diff --git a/src/bind_unit.c b/src/bind_unit.c index e54356d13..cccb045ab 100755 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -849,7 +849,7 @@ static int tolua_unit_set_race(lua_State * L) { unit *self = (unit *) tolua_tousertype(L, 1, 0); const char *rcname = tolua_tostring(L, 2, 0); - race *rc = rc_find(rcname); + const race *rc = rc_find(rcname); if (rc != NULL) { if (self->irace == u_race(self)) { self->irace = NULL; diff --git a/src/bindings.c b/src/bindings.c index 6159c665e..748049e02 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -758,7 +758,7 @@ static int config_get_ships(lua_State * L) lua_createtable(L, ql_length(shiptypes), 0); for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { ship_type *stype = (ship_type *) ql_get(ql, qi); - tolua_pushstring(L, TOLUA_CAST stype->name[0]); + tolua_pushstring(L, TOLUA_CAST stype->_name); lua_rawseti(L, -2, ++i); } return 1; diff --git a/src/creport.c b/src/creport.c index 56a740e66..875c5e6e3 100644 --- a/src/creport.c +++ b/src/creport.c @@ -634,8 +634,8 @@ cr_output_ship(FILE * F, const ship * sh, const unit * u, int fcaptain, fprintf(F, "\"%s\";Name\n", sh->name); if (sh->display && sh->display[0]) fprintf(F, "\"%s\";Beschr\n", sh->display); - fprintf(F, "\"%s\";Typ\n", add_translation(sh->type->name[0], - locale_string(f->locale, sh->type->name[0]))); + fprintf(F, "\"%s\";Typ\n", add_translation(sh->type->_name, + locale_string(f->locale, sh->type->_name))); fprintf(F, "%d;Groesse\n", sh->size); if (sh->damage) { int percent = diff --git a/src/economy.c b/src/economy.c index c85bdf6ac..6d015106b 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1753,7 +1753,7 @@ int make_cmd(unit * u, struct order *ord) /* if the item cannot be made, we probably didn't mean to make it */ itype = NULL; } else if (stype != NULL) { - const char *sname = LOC(lang, stype->name[0]); + const char *sname = LOC(lang, stype->_name); const char *iname = LOC(lang, resourcename(itype->rtype, 0)); if (strlen(iname) < strlen(sname)) stype = NULL; @@ -1771,7 +1771,7 @@ int make_cmd(unit * u, struct order *ord) if (btype != NULL && stype != NULL) { const char *bname = LOC(lang, btype->_name); - const char *sname = LOC(lang, stype->name[0]); + const char *sname = LOC(lang, stype->_name); if (strlen(sname) < strlen(bname)) btype = NULL; else diff --git a/src/gmtool.c b/src/gmtool.c index 7db2a13a3..53cb33efd 100644 --- a/src/gmtool.c +++ b/src/gmtool.c @@ -394,7 +394,7 @@ static void paint_info_region(window * wnd, const state * st) wattroff(win, A_BOLD | COLOR_PAIR(COLOR_YELLOW)); for (sh = r->ships; sh && line < maxline; sh = sh->next) { mvwprintw(win, line, 1, "%.4s ", itoa36(sh->no)); - mvwaddnstr(win, line++, 6, (char *)sh->type->name[0], size - 5); + mvwaddnstr(win, line++, 6, (char *)sh->type->_name, size - 5); } } if (r->units && (st->info_flags & IFL_FACTIONS)) { diff --git a/src/items/phoenixcompass.c b/src/items/phoenixcompass.c index 2e754795c..dcec08cdd 100644 --- a/src/items/phoenixcompass.c +++ b/src/items/phoenixcompass.c @@ -49,7 +49,7 @@ use_phoenixcompass(struct unit *u, const struct item_type *itype, direction_t direction; unit *u2; direction_t closest_neighbour_direction = 0; - static race *rc_phoenix = NULL; + static const race *rc_phoenix = NULL; if (rc_phoenix == NULL) { rc_phoenix = rc_find("phoenix"); diff --git a/src/kernel/battle_test.c b/src/kernel/battle_test.c index 8bdc50822..f20fc51bc 100644 --- a/src/kernel/battle_test.c +++ b/src/kernel/battle_test.c @@ -71,7 +71,7 @@ static void test_defenders_get_building_bonus(CuTest * tc) test_cleanup(); test_create_world(); r = findregion(0, 0); - btype = bt_find("castle"); + btype = bt_get_or_create("castle"); btype->protection = &add_two; bld = test_create_building(r, btype); bld->size = 10; @@ -114,7 +114,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc) test_cleanup(); test_create_world(); r = findregion(0, 0); - btype = bt_find("castle"); + btype = bt_get_or_create("castle"); btype->protection = &add_two; bld = test_create_building(r, btype); bld->size = 10; @@ -143,7 +143,7 @@ static void test_building_bonus_respects_size(CuTest * tc) test_cleanup(); test_create_world(); r = findregion(0, 0); - btype = bt_find("castle"); + btype = bt_get_or_create("castle"); btype->protection = &add_two; bld = test_create_building(r, btype); bld->size = 10; diff --git a/src/kernel/build.c b/src/kernel/build.c index 38d17e061..118e7f21a 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -886,8 +886,7 @@ create_ship(region * r, unit * u, const struct ship_type *newtype, int want, /* check if skill and material for 1 size is available */ if (eff_skill(u, cons->skill, r) < cons->minskill) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, - "error_build_skill_low", "value name", cons->minskill, - newtype->name[1])); + "error_build_skill_low", "value", cons->minskill)); return; } @@ -946,8 +945,7 @@ void continue_ship(region * r, unit * u, int want) } if (eff_skill(u, cons->skill, r) < cons->minskill) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, - "error_build_skill_low", "value name", cons->minskill, - sh->type->name[1])); + "error_build_skill_low", "value", cons->minskill)); return; } msize = maxbuild(u, cons); diff --git a/src/kernel/building.c b/src/kernel/building.c index 140c25eeb..437f6f6a1 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -131,7 +131,7 @@ typedef struct building_typelist { quicklist *buildingtypes = NULL; /* Returns a building type for the (internal) name */ -building_type *bt_find(const char *name) +static building_type *bt_find_i(const char *name) { quicklist *ql; int qi; @@ -146,6 +146,11 @@ building_type *bt_find(const char *name) return NULL; } +const building_type *bt_find(const char *name) +{ + return bt_find_i(name); +} + void bt_register(building_type * type) { if (type->init) { @@ -157,7 +162,7 @@ void bt_register(building_type * type) building_type *bt_get_or_create(const char *name) { if (name != NULL) { - building_type *btype = bt_find(name); + building_type *btype = bt_find_i(name); if (btype == NULL) { btype = calloc(sizeof(building_type), 1); btype->_name = _strdup(name); diff --git a/src/kernel/building.h b/src/kernel/building.h index 122bb45a2..7b2eb934a 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -73,8 +73,8 @@ extern "C" { extern struct quicklist *buildingtypes; - building_type *bt_find(const char *name); building_type *bt_get_or_create(const char *name); + const building_type *bt_find(const char *name); void register_buildings(void); void bt_register(struct building_type *type); int bt_effsize(const struct building_type *btype, diff --git a/src/kernel/item.c b/src/kernel/item.c index c4210999e..f66c6db94 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -847,7 +847,7 @@ use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, } else { const race *irace = u_irace(u); if (irace == u_race(u)) { - static race *rcfailure; + static const race *rcfailure; if (!rcfailure) { rcfailure = rc_find("smurf"); if (!rcfailure) diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index c030968d1..e41c45b9d 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -49,6 +49,28 @@ without prior permission by the authors of Eressea. #include #include +void json_building(cJSON *json, building_type *rc) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error("building %s is not a json object: %d\n", json->string, json->type); + return; + } + for (child=json->child;child;child=child->next) { + log_error("building %s contains unknown attribute %s\n", json->string, child->string); + } +} + +void json_ship(cJSON *json, ship_type *rc) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error("ship %s is not a json object: %d\n", json->string, json->type); + return; + } + for (child=json->child;child;child=child->next) { + log_error("ship %s contains unknown attribute %s\n", json->string, child->string); + } +} + void json_race(cJSON *json, race *rc) { cJSON *child; if (json->type!=cJSON_Object) { @@ -119,6 +141,28 @@ void json_race(cJSON *json, race *rc) { } } +void json_buildings(cJSON *json) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error("ships is not a json object: %d\n", json->type); + return; + } + for (child=json->child;child;child=child->next) { + json_building(child, bt_get_or_create(child->string)); + } +} + +void json_ships(cJSON *json) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error("ships is not a json object: %d\n", json->type); + return; + } + for (child=json->child;child;child=child->next) { + json_ship(child, st_get_or_create(child->string)); + } +} + void json_races(cJSON *json) { cJSON *child; if (json->type!=cJSON_Object) { @@ -126,11 +170,7 @@ void json_races(cJSON *json) { return; } for (child=json->child;child;child=child->next) { - race * rc = rc_find(child->string); - if (!rc) { - rc = rc_add(rc_new((const char *)child->string)); - json_race(child, rc); - } + json_race(child, rc_get_or_create(child->string)); } } @@ -144,5 +184,13 @@ void json_config(cJSON *json) { if (child && child->type==cJSON_Object) { json_races(child); } + child = cJSON_GetObjectItem(json, "ships"); + if (child && child->type==cJSON_Object) { + json_ships(child); + } + child = cJSON_GetObjectItem(json, "buildings"); + if (child && child->type==cJSON_Object) { + json_buildings(child); + } } diff --git a/src/kernel/move_test.c b/src/kernel/move_test.c index 640b9ada8..1a8d4d272 100644 --- a/src/kernel/move_test.c +++ b/src/kernel/move_test.c @@ -59,13 +59,13 @@ static void test_building_type_exists(CuTest * tc) { region *r; building *b; - building_type *btype; - building_type *btype2 = (building_type *)calloc(1, sizeof(building_type)); + building_type *btype, *btype2; test_cleanup(); test_create_world(); - btype = bt_find("castle"); + btype2 = bt_get_or_create("lighthouse"); + btype = bt_get_or_create("castle"); r = findregion(-1, 0); b = new_building(btype, r, default_locale); diff --git a/src/kernel/race.c b/src/kernel/race.c index 5fafd159f..65fbabf10 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -106,45 +106,13 @@ void free_races(void) { } } -race *rc_new(const char *zName) -{ - char zBuffer[80]; - race *rc = (race *)calloc(sizeof(race), 1); - - rc->hitpoints = 1; - if (strchr(zName, ' ') != NULL) { - log_error("race '%s' has an invalid name. remove spaces\n", zName); - assert(strchr(zName, ' ') == NULL); - } - strcpy(zBuffer, zName); - rc->_name[0] = _strdup(zBuffer); - sprintf(zBuffer, "%s_p", zName); - rc->_name[1] = _strdup(zBuffer); - sprintf(zBuffer, "%s_d", zName); - rc->_name[2] = _strdup(zBuffer); - sprintf(zBuffer, "%s_x", zName); - rc->_name[3] = _strdup(zBuffer); - rc->precombatspell = NULL; - - rc->attack[0].type = AT_COMBATSPELL; - rc->attack[1].type = AT_NONE; - return rc; -} - -race *rc_add(race * rc) -{ - rc->index = num_races++; - rc->next = races; - return races = rc; -} - static const char *racealias[][2] = { {"uruk", "orc"}, /* there was a time when the orc race was called uruk (and there were other orcs). That was really confusing */ {"skeletton lord", "skeleton lord"}, /* we once had a typo here. it is fixed */ {NULL, NULL} }; -race *rc_find(const char *name) +static race *rc_find_i(const char *name) { const char *rname = name; race *rc = races; @@ -161,6 +129,41 @@ race *rc_find(const char *name) return rc; } +const race * rc_find(const char *name) { + return rc_find_i(name); +} + +race *rc_get_or_create(const char *zName) +{ + race *rc = rc_find_i(zName); + if (!rc) { + char zBuffer[80]; + + rc = (race *)calloc(sizeof(race), 1); + rc->hitpoints = 1; + if (strchr(zName, ' ') != NULL) { + log_error("race '%s' has an invalid name. remove spaces\n", zName); + assert(strchr(zName, ' ') == NULL); + } + strcpy(zBuffer, zName); + rc->_name[0] = _strdup(zBuffer); + sprintf(zBuffer, "%s_p", zName); + rc->_name[1] = _strdup(zBuffer); + sprintf(zBuffer, "%s_d", zName); + rc->_name[2] = _strdup(zBuffer); + sprintf(zBuffer, "%s_x", zName); + rc->_name[3] = _strdup(zBuffer); + rc->precombatspell = NULL; + + rc->attack[0].type = AT_COMBATSPELL; + rc->attack[1].type = AT_NONE; + rc->index = num_races++; + rc->next = races; + return races = rc; + } + return rc; +} + /** dragon movement **/ bool allowed_dragon(const region * src, const region * target) { @@ -296,7 +299,7 @@ variant read_race_reference(struct storage *store) result.v = NULL; return result; } else { - result.v = rc_find(zName); + result.v = rc_find_i(zName); } assert(result.v != NULL); return result; diff --git a/src/kernel/race.h b/src/kernel/race.h index 65af93600..3782fe217 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -109,10 +109,9 @@ extern "C" { extern struct race_list *get_familiarraces(void); extern struct race *races; - extern struct race *rc_find(const char *); - extern const char *rc_name(const struct race *, int); - extern struct race *rc_add(struct race *); - extern struct race *rc_new(const char *zName); + extern race *rc_get_or_create(const char *name); + extern const race *rc_find(const char *); + extern const char *rc_name(const race *, int); extern int rc_specialdamage(const race *, const race *, const struct weapon_type *); void free_races(void); diff --git a/src/kernel/save.c b/src/kernel/save.c index ad1ce1fb3..5599d2fc8 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1881,7 +1881,7 @@ int writegame(const char *filename) write_ship_reference(sh, &store); WRITE_STR(&store, (const char *)sh->name); WRITE_STR(&store, sh->display ? (const char *)sh->display : ""); - WRITE_TOK(&store, sh->type->name[0]); + WRITE_TOK(&store, sh->type->_name); WRITE_INT(&store, sh->size); WRITE_INT(&store, sh->damage); WRITE_INT(&store, sh->flags & SFL_SAVEMASK); diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 1af72caf4..972d00025 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -72,7 +72,7 @@ const ship_type *findshiptype(const char *name, const struct locale *lang) for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { ship_type *stype = (ship_type *) ql_get(ql, qi); variant var2; - const char *n = locale_string(lang, stype->name[0]); + const char *n = locale_string(lang, stype->_name); var2.v = (void *)stype; addtoken(&sn->names, n, var2); } @@ -83,23 +83,32 @@ const ship_type *findshiptype(const char *name, const struct locale *lang) return (const ship_type *)var.v; } -const ship_type *st_find(const char *name) +static ship_type *st_find_i(const char *name) { quicklist *ql; int qi; for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { ship_type *stype = (ship_type *) ql_get(ql, qi); - if (strcmp(stype->name[0], name) == 0) { + if (strcmp(stype->_name, name) == 0) { return stype; } } return NULL; } -void st_register(const ship_type * type) -{ - ql_push(&shiptypes, (void *)type); +const ship_type *st_find(const char *name) { + return st_find_i(name); +} + +ship_type *st_get_or_create(const char * name) { + ship_type * st = st_find_i(name); + if (!st) { + st = (ship_type *)calloc(sizeof(ship_type), 1); + st->_name = _strdup(name); + ql_push(&shiptypes, (void *)st); + } + return st; } #define MAXSHIPHASH 7919 @@ -177,7 +186,7 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) sh->type = stype; sh->region = r; - sname = LOC(lang, stype->name[0]); + sname = LOC(lang, stype->_name); if (!sname) { sname = LOC(lang, parameters[P_SHIP]); if (!sname) { diff --git a/src/kernel/ship.h b/src/kernel/ship.h index 3f758c1bd..fd3d562b5 100644 --- a/src/kernel/ship.h +++ b/src/kernel/ship.h @@ -32,7 +32,7 @@ extern "C" { #define SFL_NOCOAST 0x04 typedef struct ship_type { - const char *name[2]; + const char *_name; int range; /* range in regions */ int flags; /* flags */ @@ -64,7 +64,7 @@ extern "C" { /* Alte Schiffstypen: */ extern const ship_type *st_find(const char *name); - extern void st_register(const ship_type * type); + extern ship_type *st_get_or_create(const char *name); #define NOSHIP NULL diff --git a/src/kernel/ship_test.c b/src/kernel/ship_test.c index f0f8309d7..3b8108fca 100644 --- a/src/kernel/ship_test.c +++ b/src/kernel/ship_test.c @@ -18,11 +18,9 @@ static void test_register_ship(CuTest * tc) test_cleanup(); - stype = (ship_type *)calloc(sizeof(ship_type), 1); - stype->name[0] = _strdup("herp"); - st_register(stype); - - CuAssertPtrNotNull(tc, st_find("herp")); + stype = st_get_or_create("herp"); + CuAssertPtrNotNull(tc, stype); + CuAssertPtrEquals(tc, stype, (void *)st_find("herp")); } static void test_ship_set_owner(CuTest * tc) diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 73d73978d..3ccc2cb3b 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -516,15 +516,13 @@ static int parse_ships(xmlDocPtr doc) for (i = 0; i != nodes->nodeNr; ++i) { xmlNodePtr child, node = nodes->nodeTab[i]; xmlChar *propValue; - ship_type *st = (ship_type *)calloc(sizeof(ship_type), 1); + ship_type *st; xmlXPathObjectPtr result; int k, c; propValue = xmlGetProp(node, BAD_CAST "name"); assert(propValue != NULL); - st->name[0] = _strdup((const char *)propValue); - st->name[1] = - strcat(strcpy(malloc(strlen(st->name[0]) + 3), st->name[0]), "_a"); + st = st_get_or_create((const char *)propValue); xmlFree(propValue); st->cabins = xml_ivalue(node, "cabins", 0) * PERSON_WEIGHT; @@ -583,14 +581,11 @@ static int parse_ships(xmlDocPtr doc) if (st->coasts[c] != NULL) ++c; else { - log_warning("ship %s mentions a non-existing terrain %s.\n", st->name[0], propValue); + log_warning("ship %s mentions a non-existing terrain %s.\n", st->_name, propValue); } xmlFree(propValue); } xmlXPathFreeObject(result); - - /* finally, register the new building type */ - st_register(st); } } xmlXPathFreeObject(ships); @@ -777,7 +772,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) if (propValue != NULL) { const race *rc = rc_find((const char *)propValue); if (rc == NULL) - rc = rc_add(rc_new((const char *)propValue)); + rc = rc_get_or_create((const char *)propValue)); racelist_insert(&wtype->modifiers[k].races, rc); xmlFree(propValue); } @@ -1102,7 +1097,7 @@ static int parse_resources(xmlDocPtr doc) if (propValue != NULL) { rc = rc_find((const char *)propValue); if (rc == NULL) - rc = rc_add(rc_new((const char *)propValue)); + rc = rc_get_or_create((const char *)propValue); xmlFree(propValue); } rdata->modifiers[k].race = rc; @@ -1697,7 +1692,7 @@ static int parse_races(xmlDocPtr doc) assert(propValue != NULL); rc = rc_find((const char *)propValue); if (rc == NULL) - rc = rc_add(rc_new((const char *)propValue)); + rc = rc_get_or_create((const char *)propValue); xmlFree(propValue); propValue = xmlGetProp(node, BAD_CAST "damage"); @@ -1887,7 +1882,7 @@ static int parse_races(xmlDocPtr doc) assert(propValue != NULL); frc = rc_find((const char *)propValue); if (!frc) { - frc = rc_add(rc_new((const char *)propValue)); + frc = rc_get_or_create((const char *)propValue); } if (xml_bvalue(node, "default", false)) { rc->familiars[k] = rc->familiars[0]; diff --git a/src/laws.c b/src/laws.c index 4ec82da73..b1ed2361a 100755 --- a/src/laws.c +++ b/src/laws.c @@ -1988,7 +1988,7 @@ int name_cmd(struct unit *u, struct order *ord) } else { const struct locale *lang = locales; for (; lang; lang = nextlocale(lang)) { - const char *sdname = LOC(lang, sh->type->name[0]); + const char *sdname = LOC(lang, sh->type->_name); size_t sdlen = strlen(sdname); if (strlen(sh->name) >= sdlen && strncmp(sh->name, sdname, sdlen) == 0) { diff --git a/src/laws_test.c b/src/laws_test.c index e624d12ce..0fc15d500 100644 --- a/src/laws_test.c +++ b/src/laws_test.c @@ -26,7 +26,7 @@ static void test_new_building_can_be_renamed(CuTest * tc) test_cleanup(); test_create_world(); - btype = bt_find("castle"); + btype = bt_get_or_create("castle"); r = findregion(-1, 0); b = new_building(btype, r, default_locale); @@ -44,7 +44,7 @@ static void test_rename_building(CuTest * tc) test_cleanup(); test_create_world(); - btype = bt_find("castle"); + btype = bt_get_or_create("castle"); r = findregion(-1, 0); b = new_building(btype, r, default_locale); @@ -67,7 +67,7 @@ static void test_rename_building_twice(CuTest * tc) test_cleanup(); test_create_world(); - btype = bt_find("castle"); + btype = bt_get_or_create("castle"); r = findregion(-1, 0); b = new_building(btype, r, default_locale); diff --git a/src/market.c b/src/market.c index aea233570..d80d8bdad 100644 --- a/src/market.c +++ b/src/market.c @@ -32,7 +32,7 @@ static unsigned int get_markets(region * r, unit ** results, size_t size) { unsigned int n = 0; building *b; - static building_type *btype; + static const building_type *btype; if (!btype) btype = bt_find("market"); if (!btype) diff --git a/src/modules/arena.c b/src/modules/arena.c index 3b741cdb3..3ebdeff81 100644 --- a/src/modules/arena.c +++ b/src/modules/arena.c @@ -25,9 +25,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* modules include */ #include "score.h" -/* attributes include */ -#include - /* items include */ #include diff --git a/src/report.c b/src/report.c index 10a35b3cb..b71bb1109 100644 --- a/src/report.c +++ b/src/report.c @@ -1879,11 +1879,11 @@ nr_ship(FILE * F, const seen_region * sr, const ship * sh, const faction * f, n = (n + 99) / 100; /* 1 Silber = 1 GE */ bytes = _snprintf(bufp, size, "%s, %s, (%d/%d)", shipname(sh), - LOC(f->locale, sh->type->name[0]), n, shipcapacity(sh) / 100); + LOC(f->locale, sh->type->_name), n, shipcapacity(sh) / 100); } else { bytes = _snprintf(bufp, size, "%s, %s", shipname(sh), LOC(f->locale, - sh->type->name[0])); + sh->type->_name)); } if (wrptr(&bufp, &size, bytes) != 0) WARN_STATIC_BUFFER(); diff --git a/src/test_eressea.c b/src/test_eressea.c index 5c4b815fe..c9d33ecde 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -72,5 +72,6 @@ int RunAllTests(void) } int main(int argc, char ** argv) { - return RunAllTests(); + log_stderr = 0; + return RunAllTests(); } diff --git a/src/tests.c b/src/tests.c index d4dcc7263..7b9362535 100644 --- a/src/tests.c +++ b/src/tests.c @@ -24,7 +24,7 @@ struct race *test_create_race(const char *name) { - race *rc = rc_add(rc_new(name)); + race *rc = rc_get_or_create(name); rc->flags |= RCF_PLAYERRACE; rc->maintenance = 10; return rc; @@ -97,11 +97,8 @@ ship * test_create_ship(region * r, const ship_type * stype) ship_type * test_create_shiptype(const char ** names) { - ship_type * stype = (ship_type*)calloc(sizeof(ship_type), 1); - stype->name[0] = _strdup(names[0]); - stype->name[1] = _strdup(names[1]); + ship_type * stype = st_get_or_create(names[0]); locale_setstring(default_locale, names[0], names[0]); - st_register(stype); return stype; }