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;
}