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.
This commit is contained in:
Enno Rehling 2014-06-12 22:14:07 -07:00
parent 30c1b0e1ff
commit d503937999
37 changed files with 186 additions and 304 deletions

View File

@ -8461,10 +8461,9 @@
<arg name="unit" type="unit"/> <arg name="unit" type="unit"/>
<arg name="command" type="order"/> <arg name="command" type="order"/>
<arg name="value" type="int"/> <arg name="value" type="int"/>
<arg name="name" type="string"/>
</type> </type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Um $localize($name) zu bauen, braucht man ein Talent von mindestens $int($value)."</text> <text locale="de">"$unit($unit) in $region($region): '$order($command)' - Um das zu bauen, braucht man ein Talent von mindestens $int($value)."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - To build $localize($name) requires a skill of at least $int($value)."</text> <text locale="en">"$unit($unit) in $region($region): '$order($command)' - This requires a skill of at least $int($value) to build."</text>
</message> </message>
<message name="slave_active" section="battle"> <message name="slave_active" section="battle">

View File

@ -3,5 +3,7 @@
require "lunit" require "lunit"
require "tests.settings" require "tests.settings"
require "tests.config" require "tests.config"
-- require "tests.ships"
lunit.main() lunit.main()

View File

@ -7,6 +7,7 @@ function setup()
eressea.settings.set("nmr.removenewbie", "0") eressea.settings.set("nmr.removenewbie", "0")
eressea.settings.set("nmr.timeout", "0") eressea.settings.set("nmr.timeout", "0")
eressea.settings.set("NewbieImmunity", "0") eressea.settings.set("NewbieImmunity", "0")
eressea.config.parse('{ "races": { "human" : {}}}')
end end
function test_landing1() function test_landing1()
@ -78,24 +79,24 @@ function test_landing_harbour_unpaid()
end end
function test_landing_terrain() function test_landing_terrain()
local ocean = region.create(1, 0, "ocean") local ocean = region.create(1, 0, "ocean")
local r = region.create(0, 0, "glacier") local r = region.create(0, 0, "glacier")
local f = faction.create("noreply@eressea.de", "human", "de") local f = faction.create("noreply@eressea.de", "human", "de")
local f2 = faction.create("noreply@eressea.de", "human", "de") local f2 = faction.create("noreply@eressea.de", "human", "de")
local s = ship.create(ocean, "longboat") local s = ship.create(ocean, "longboat")
local u1 = unit.create(f, ocean, 1) local u1 = unit.create(f, ocean, 1)
local u2 = unit.create(f2, r, 1) local u2 = unit.create(f2, r, 1)
assert_not_nil(u2) assert_not_nil(u2)
u1:add_item("money", 1000) u1:add_item("money", 1000)
u2:add_item("money", 1000) u2:add_item("money", 1000)
u1.ship = s u1.ship = s
u1:set_skill("sailing", 10) u1:set_skill("sailing", 10)
u1:clear_orders() u1:clear_orders()
u1:add_order("NACH w") u1:add_order("NACH w")
process_orders() process_orders()
assert_equal(ocean.id, u1.region.id) -- cannot land in glacier without harbour assert_equal(ocean.id, u1.region.id) -- cannot land in glacier without harbour
end end
function test_landing_insects() function test_landing_insects()

View File

@ -276,7 +276,6 @@
<F N="../src/util/functions.c"/> <F N="../src/util/functions.c"/>
<F N="../src/triggers/gate.c"/> <F N="../src/triggers/gate.c"/>
<F N="../src/give.c"/> <F N="../src/give.c"/>
<F N="../src/attributes/giveitem.c"/>
<F N="../src/triggers/giveitem.c"/> <F N="../src/triggers/giveitem.c"/>
<F N="../src/attributes/gm.c"/> <F N="../src/attributes/gm.c"/>
<F N="../src/modules/gmcmd.c"/> <F N="../src/modules/gmcmd.c"/>
@ -430,7 +429,6 @@
<F N="../src/util/functions.h"/> <F N="../src/util/functions.h"/>
<F N="../src/triggers/gate.h"/> <F N="../src/triggers/gate.h"/>
<F N="../src/give.h"/> <F N="../src/give.h"/>
<F N="../src/attributes/giveitem.h"/>
<F N="../src/triggers/giveitem.h"/> <F N="../src/triggers/giveitem.h"/>
<F N="../src/attributes/gm.h"/> <F N="../src/attributes/gm.h"/>
<F N="../src/modules/gmcmd.h"/> <F N="../src/modules/gmcmd.h"/>

View File

@ -279,8 +279,10 @@
Name="Other Files" Name="Other Files"
Filters=""> Filters="">
<F N="../scripts/tests/config.lua"/> <F N="../scripts/tests/config.lua"/>
<F N="../scripts/tests/rules.lua"/>
<F N="../scripts/runtests.lua"/> <F N="../scripts/runtests.lua"/>
<F N="../scripts/tests/settings.lua"/> <F N="../scripts/tests/settings.lua"/>
<F N="../scripts/tests/ships.lua"/>
</Folder> </Folder>
</Files> </Files>
</Project> </Project>

View File

@ -4,7 +4,6 @@ alliance.c
attributes.c attributes.c
fleechance.c fleechance.c
follow.c follow.c
giveitem.c
gm.c gm.c
hate.c hate.c
iceberg.c iceberg.c
@ -25,4 +24,4 @@ FOREACH(_FILE ${_FILES})
LIST(APPEND _SOURCES ${PROJECT_NAME}/${_FILE}) LIST(APPEND _SOURCES ${PROJECT_NAME}/${_FILE})
ENDFOREACH(_FILE) ENDFOREACH(_FILE)
SET(ATTRIBUTES_SRC ${_SOURCES} PARENT_SCOPE) SET(ATTRIBUTES_SRC ${_SOURCES} PARENT_SCOPE)

View File

@ -1,133 +0,0 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
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 <platform.h>
#include "giveitem.h"
#include <kernel/config.h>
/* kernel includes */
#include <kernel/building.h>
#include <kernel/region.h>
#include <kernel/unit.h>
#include <kernel/item.h>
/* util includes */
#include <util/attrib.h>
#include <util/base36.h>
#include <util/resolve.h>
#include <util/goodies.h>
#include <storage.h>
/* libc includes */
#include <stdlib.h>
#include <string.h>
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);
}

View File

@ -1,36 +0,0 @@
/*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
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

View File

@ -393,7 +393,7 @@ static int tolua_faction_set_race(lua_State * L)
{ {
faction *self = (faction *) tolua_tousertype(L, 1, 0); faction *self = (faction *) tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0); const char *name = tolua_tostring(L, 2, 0);
race *rc = rc_find(name); const race *rc = rc_find(name);
if (rc != NULL) { if (rc != NULL) {
self->race = rc; self->race = rc;
} }

View File

@ -180,7 +180,7 @@ static int tolua_ship_get_coast(lua_State * L)
static int tolua_ship_get_type(lua_State * L) static int tolua_ship_get_type(lua_State * L)
{ {
ship *self = (ship *) tolua_tousertype(L, 1, 0); ship *self = (ship *) tolua_tousertype(L, 1, 0);
tolua_pushstring(L, self->type->name[0]); tolua_pushstring(L, self->type->_name);
return 1; return 1;
} }

View File

@ -849,7 +849,7 @@ static int tolua_unit_set_race(lua_State * L)
{ {
unit *self = (unit *) tolua_tousertype(L, 1, 0); unit *self = (unit *) tolua_tousertype(L, 1, 0);
const char *rcname = tolua_tostring(L, 2, 0); const char *rcname = tolua_tostring(L, 2, 0);
race *rc = rc_find(rcname); const race *rc = rc_find(rcname);
if (rc != NULL) { if (rc != NULL) {
if (self->irace == u_race(self)) { if (self->irace == u_race(self)) {
self->irace = NULL; self->irace = NULL;

View File

@ -758,7 +758,7 @@ static int config_get_ships(lua_State * L)
lua_createtable(L, ql_length(shiptypes), 0); lua_createtable(L, ql_length(shiptypes), 0);
for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) {
ship_type *stype = (ship_type *) ql_get(ql, qi); 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); lua_rawseti(L, -2, ++i);
} }
return 1; return 1;

View File

@ -634,8 +634,8 @@ cr_output_ship(FILE * F, const ship * sh, const unit * u, int fcaptain,
fprintf(F, "\"%s\";Name\n", sh->name); fprintf(F, "\"%s\";Name\n", sh->name);
if (sh->display && sh->display[0]) if (sh->display && sh->display[0])
fprintf(F, "\"%s\";Beschr\n", sh->display); fprintf(F, "\"%s\";Beschr\n", sh->display);
fprintf(F, "\"%s\";Typ\n", add_translation(sh->type->name[0], fprintf(F, "\"%s\";Typ\n", add_translation(sh->type->_name,
locale_string(f->locale, sh->type->name[0]))); locale_string(f->locale, sh->type->_name)));
fprintf(F, "%d;Groesse\n", sh->size); fprintf(F, "%d;Groesse\n", sh->size);
if (sh->damage) { if (sh->damage) {
int percent = int percent =

View File

@ -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 */ /* if the item cannot be made, we probably didn't mean to make it */
itype = NULL; itype = NULL;
} else if (stype != 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)); const char *iname = LOC(lang, resourcename(itype->rtype, 0));
if (strlen(iname) < strlen(sname)) if (strlen(iname) < strlen(sname))
stype = NULL; stype = NULL;
@ -1771,7 +1771,7 @@ int make_cmd(unit * u, struct order *ord)
if (btype != NULL && stype != NULL) { if (btype != NULL && stype != NULL) {
const char *bname = LOC(lang, btype->_name); 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)) if (strlen(sname) < strlen(bname))
btype = NULL; btype = NULL;
else else

View File

@ -394,7 +394,7 @@ static void paint_info_region(window * wnd, const state * st)
wattroff(win, A_BOLD | COLOR_PAIR(COLOR_YELLOW)); wattroff(win, A_BOLD | COLOR_PAIR(COLOR_YELLOW));
for (sh = r->ships; sh && line < maxline; sh = sh->next) { for (sh = r->ships; sh && line < maxline; sh = sh->next) {
mvwprintw(win, line, 1, "%.4s ", itoa36(sh->no)); 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)) { if (r->units && (st->info_flags & IFL_FACTIONS)) {

View File

@ -49,7 +49,7 @@ use_phoenixcompass(struct unit *u, const struct item_type *itype,
direction_t direction; direction_t direction;
unit *u2; unit *u2;
direction_t closest_neighbour_direction = 0; direction_t closest_neighbour_direction = 0;
static race *rc_phoenix = NULL; static const race *rc_phoenix = NULL;
if (rc_phoenix == NULL) { if (rc_phoenix == NULL) {
rc_phoenix = rc_find("phoenix"); rc_phoenix = rc_find("phoenix");

View File

@ -71,7 +71,7 @@ static void test_defenders_get_building_bonus(CuTest * tc)
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
r = findregion(0, 0); r = findregion(0, 0);
btype = bt_find("castle"); btype = bt_get_or_create("castle");
btype->protection = &add_two; btype->protection = &add_two;
bld = test_create_building(r, btype); bld = test_create_building(r, btype);
bld->size = 10; bld->size = 10;
@ -114,7 +114,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc)
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
r = findregion(0, 0); r = findregion(0, 0);
btype = bt_find("castle"); btype = bt_get_or_create("castle");
btype->protection = &add_two; btype->protection = &add_two;
bld = test_create_building(r, btype); bld = test_create_building(r, btype);
bld->size = 10; bld->size = 10;
@ -143,7 +143,7 @@ static void test_building_bonus_respects_size(CuTest * tc)
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
r = findregion(0, 0); r = findregion(0, 0);
btype = bt_find("castle"); btype = bt_get_or_create("castle");
btype->protection = &add_two; btype->protection = &add_two;
bld = test_create_building(r, btype); bld = test_create_building(r, btype);
bld->size = 10; bld->size = 10;

View File

@ -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 */ /* check if skill and material for 1 size is available */
if (eff_skill(u, cons->skill, r) < cons->minskill) { if (eff_skill(u, cons->skill, r) < cons->minskill) {
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder,
"error_build_skill_low", "value name", cons->minskill, "error_build_skill_low", "value", cons->minskill));
newtype->name[1]));
return; return;
} }
@ -946,8 +945,7 @@ void continue_ship(region * r, unit * u, int want)
} }
if (eff_skill(u, cons->skill, r) < cons->minskill) { if (eff_skill(u, cons->skill, r) < cons->minskill) {
ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder,
"error_build_skill_low", "value name", cons->minskill, "error_build_skill_low", "value", cons->minskill));
sh->type->name[1]));
return; return;
} }
msize = maxbuild(u, cons); msize = maxbuild(u, cons);

View File

@ -131,7 +131,7 @@ typedef struct building_typelist {
quicklist *buildingtypes = NULL; quicklist *buildingtypes = NULL;
/* Returns a building type for the (internal) name */ /* 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; quicklist *ql;
int qi; int qi;
@ -146,6 +146,11 @@ building_type *bt_find(const char *name)
return NULL; return NULL;
} }
const building_type *bt_find(const char *name)
{
return bt_find_i(name);
}
void bt_register(building_type * type) void bt_register(building_type * type)
{ {
if (type->init) { if (type->init) {
@ -157,7 +162,7 @@ void bt_register(building_type * type)
building_type *bt_get_or_create(const char *name) building_type *bt_get_or_create(const char *name)
{ {
if (name != NULL) { if (name != NULL) {
building_type *btype = bt_find(name); building_type *btype = bt_find_i(name);
if (btype == NULL) { if (btype == NULL) {
btype = calloc(sizeof(building_type), 1); btype = calloc(sizeof(building_type), 1);
btype->_name = _strdup(name); btype->_name = _strdup(name);

View File

@ -73,8 +73,8 @@ extern "C" {
extern struct quicklist *buildingtypes; extern struct quicklist *buildingtypes;
building_type *bt_find(const char *name);
building_type *bt_get_or_create(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 register_buildings(void);
void bt_register(struct building_type *type); void bt_register(struct building_type *type);
int bt_effsize(const struct building_type *btype, int bt_effsize(const struct building_type *btype,

View File

@ -847,7 +847,7 @@ use_bloodpotion(struct unit *u, const struct item_type *itype, int amount,
} else { } else {
const race *irace = u_irace(u); const race *irace = u_irace(u);
if (irace == u_race(u)) { if (irace == u_race(u)) {
static race *rcfailure; static const race *rcfailure;
if (!rcfailure) { if (!rcfailure) {
rcfailure = rc_find("smurf"); rcfailure = rc_find("smurf");
if (!rcfailure) if (!rcfailure)

View File

@ -49,6 +49,28 @@ without prior permission by the authors of Eressea.
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
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) { void json_race(cJSON *json, race *rc) {
cJSON *child; cJSON *child;
if (json->type!=cJSON_Object) { 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) { void json_races(cJSON *json) {
cJSON *child; cJSON *child;
if (json->type!=cJSON_Object) { if (json->type!=cJSON_Object) {
@ -126,11 +170,7 @@ void json_races(cJSON *json) {
return; return;
} }
for (child=json->child;child;child=child->next) { for (child=json->child;child;child=child->next) {
race * rc = rc_find(child->string); json_race(child, rc_get_or_create(child->string));
if (!rc) {
rc = rc_add(rc_new((const char *)child->string));
json_race(child, rc);
}
} }
} }
@ -144,5 +184,13 @@ void json_config(cJSON *json) {
if (child && child->type==cJSON_Object) { if (child && child->type==cJSON_Object) {
json_races(child); 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);
}
} }

View File

@ -59,13 +59,13 @@ static void test_building_type_exists(CuTest * tc)
{ {
region *r; region *r;
building *b; building *b;
building_type *btype; building_type *btype, *btype2;
building_type *btype2 = (building_type *)calloc(1, sizeof(building_type));
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
btype = bt_find("castle"); btype2 = bt_get_or_create("lighthouse");
btype = bt_get_or_create("castle");
r = findregion(-1, 0); r = findregion(-1, 0);
b = new_building(btype, r, default_locale); b = new_building(btype, r, default_locale);

View File

@ -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] = { 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 */ {"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 */ {"skeletton lord", "skeleton lord"}, /* we once had a typo here. it is fixed */
{NULL, NULL} {NULL, NULL}
}; };
race *rc_find(const char *name) static race *rc_find_i(const char *name)
{ {
const char *rname = name; const char *rname = name;
race *rc = races; race *rc = races;
@ -161,6 +129,41 @@ race *rc_find(const char *name)
return rc; 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 **/ /** dragon movement **/
bool allowed_dragon(const region * src, const region * target) bool allowed_dragon(const region * src, const region * target)
{ {
@ -296,7 +299,7 @@ variant read_race_reference(struct storage *store)
result.v = NULL; result.v = NULL;
return result; return result;
} else { } else {
result.v = rc_find(zName); result.v = rc_find_i(zName);
} }
assert(result.v != NULL); assert(result.v != NULL);
return result; return result;

View File

@ -109,10 +109,9 @@ extern "C" {
extern struct race_list *get_familiarraces(void); extern struct race_list *get_familiarraces(void);
extern struct race *races; extern struct race *races;
extern struct race *rc_find(const char *); extern race *rc_get_or_create(const char *name);
extern const char *rc_name(const struct race *, int); extern const race *rc_find(const char *);
extern struct race *rc_add(struct race *); extern const char *rc_name(const race *, int);
extern struct race *rc_new(const char *zName);
extern int rc_specialdamage(const race *, const race *, extern int rc_specialdamage(const race *, const race *,
const struct weapon_type *); const struct weapon_type *);
void free_races(void); void free_races(void);

View File

@ -1881,7 +1881,7 @@ int writegame(const char *filename)
write_ship_reference(sh, &store); write_ship_reference(sh, &store);
WRITE_STR(&store, (const char *)sh->name); WRITE_STR(&store, (const char *)sh->name);
WRITE_STR(&store, sh->display ? (const char *)sh->display : ""); 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->size);
WRITE_INT(&store, sh->damage); WRITE_INT(&store, sh->damage);
WRITE_INT(&store, sh->flags & SFL_SAVEMASK); WRITE_INT(&store, sh->flags & SFL_SAVEMASK);

View File

@ -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)) { for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) {
ship_type *stype = (ship_type *) ql_get(ql, qi); ship_type *stype = (ship_type *) ql_get(ql, qi);
variant var2; variant var2;
const char *n = locale_string(lang, stype->name[0]); const char *n = locale_string(lang, stype->_name);
var2.v = (void *)stype; var2.v = (void *)stype;
addtoken(&sn->names, n, var2); 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; 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; quicklist *ql;
int qi; int qi;
for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) {
ship_type *stype = (ship_type *) ql_get(ql, qi); 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 stype;
} }
} }
return NULL; return NULL;
} }
void st_register(const ship_type * type) const ship_type *st_find(const char *name) {
{ return st_find_i(name);
ql_push(&shiptypes, (void *)type); }
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 #define MAXSHIPHASH 7919
@ -177,7 +186,7 @@ ship *new_ship(const ship_type * stype, region * r, const struct locale *lang)
sh->type = stype; sh->type = stype;
sh->region = r; sh->region = r;
sname = LOC(lang, stype->name[0]); sname = LOC(lang, stype->_name);
if (!sname) { if (!sname) {
sname = LOC(lang, parameters[P_SHIP]); sname = LOC(lang, parameters[P_SHIP]);
if (!sname) { if (!sname) {

View File

@ -32,7 +32,7 @@ extern "C" {
#define SFL_NOCOAST 0x04 #define SFL_NOCOAST 0x04
typedef struct ship_type { typedef struct ship_type {
const char *name[2]; const char *_name;
int range; /* range in regions */ int range; /* range in regions */
int flags; /* flags */ int flags; /* flags */
@ -64,7 +64,7 @@ extern "C" {
/* Alte Schiffstypen: */ /* Alte Schiffstypen: */
extern const ship_type *st_find(const char *name); 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 #define NOSHIP NULL

View File

@ -18,11 +18,9 @@ static void test_register_ship(CuTest * tc)
test_cleanup(); test_cleanup();
stype = (ship_type *)calloc(sizeof(ship_type), 1); stype = st_get_or_create("herp");
stype->name[0] = _strdup("herp"); CuAssertPtrNotNull(tc, stype);
st_register(stype); CuAssertPtrEquals(tc, stype, (void *)st_find("herp"));
CuAssertPtrNotNull(tc, st_find("herp"));
} }
static void test_ship_set_owner(CuTest * tc) static void test_ship_set_owner(CuTest * tc)

View File

@ -516,15 +516,13 @@ static int parse_ships(xmlDocPtr doc)
for (i = 0; i != nodes->nodeNr; ++i) { for (i = 0; i != nodes->nodeNr; ++i) {
xmlNodePtr child, node = nodes->nodeTab[i]; xmlNodePtr child, node = nodes->nodeTab[i];
xmlChar *propValue; xmlChar *propValue;
ship_type *st = (ship_type *)calloc(sizeof(ship_type), 1); ship_type *st;
xmlXPathObjectPtr result; xmlXPathObjectPtr result;
int k, c; int k, c;
propValue = xmlGetProp(node, BAD_CAST "name"); propValue = xmlGetProp(node, BAD_CAST "name");
assert(propValue != NULL); assert(propValue != NULL);
st->name[0] = _strdup((const char *)propValue); st = st_get_or_create((const char *)propValue);
st->name[1] =
strcat(strcpy(malloc(strlen(st->name[0]) + 3), st->name[0]), "_a");
xmlFree(propValue); xmlFree(propValue);
st->cabins = xml_ivalue(node, "cabins", 0) * PERSON_WEIGHT; st->cabins = xml_ivalue(node, "cabins", 0) * PERSON_WEIGHT;
@ -583,14 +581,11 @@ static int parse_ships(xmlDocPtr doc)
if (st->coasts[c] != NULL) if (st->coasts[c] != NULL)
++c; ++c;
else { 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); xmlFree(propValue);
} }
xmlXPathFreeObject(result); xmlXPathFreeObject(result);
/* finally, register the new building type */
st_register(st);
} }
} }
xmlXPathFreeObject(ships); xmlXPathFreeObject(ships);
@ -777,7 +772,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype)
if (propValue != NULL) { if (propValue != NULL) {
const race *rc = rc_find((const char *)propValue); const race *rc = rc_find((const char *)propValue);
if (rc == NULL) 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); racelist_insert(&wtype->modifiers[k].races, rc);
xmlFree(propValue); xmlFree(propValue);
} }
@ -1102,7 +1097,7 @@ static int parse_resources(xmlDocPtr doc)
if (propValue != NULL) { if (propValue != NULL) {
rc = rc_find((const char *)propValue); rc = rc_find((const char *)propValue);
if (rc == NULL) if (rc == NULL)
rc = rc_add(rc_new((const char *)propValue)); rc = rc_get_or_create((const char *)propValue);
xmlFree(propValue); xmlFree(propValue);
} }
rdata->modifiers[k].race = rc; rdata->modifiers[k].race = rc;
@ -1697,7 +1692,7 @@ static int parse_races(xmlDocPtr doc)
assert(propValue != NULL); assert(propValue != NULL);
rc = rc_find((const char *)propValue); rc = rc_find((const char *)propValue);
if (rc == NULL) if (rc == NULL)
rc = rc_add(rc_new((const char *)propValue)); rc = rc_get_or_create((const char *)propValue);
xmlFree(propValue); xmlFree(propValue);
propValue = xmlGetProp(node, BAD_CAST "damage"); propValue = xmlGetProp(node, BAD_CAST "damage");
@ -1887,7 +1882,7 @@ static int parse_races(xmlDocPtr doc)
assert(propValue != NULL); assert(propValue != NULL);
frc = rc_find((const char *)propValue); frc = rc_find((const char *)propValue);
if (!frc) { if (!frc) {
frc = rc_add(rc_new((const char *)propValue)); frc = rc_get_or_create((const char *)propValue);
} }
if (xml_bvalue(node, "default", false)) { if (xml_bvalue(node, "default", false)) {
rc->familiars[k] = rc->familiars[0]; rc->familiars[k] = rc->familiars[0];

View File

@ -1988,7 +1988,7 @@ int name_cmd(struct unit *u, struct order *ord)
} else { } else {
const struct locale *lang = locales; const struct locale *lang = locales;
for (; lang; lang = nextlocale(lang)) { 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); size_t sdlen = strlen(sdname);
if (strlen(sh->name) >= sdlen if (strlen(sh->name) >= sdlen
&& strncmp(sh->name, sdname, sdlen) == 0) { && strncmp(sh->name, sdname, sdlen) == 0) {

View File

@ -26,7 +26,7 @@ static void test_new_building_can_be_renamed(CuTest * tc)
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
btype = bt_find("castle"); btype = bt_get_or_create("castle");
r = findregion(-1, 0); r = findregion(-1, 0);
b = new_building(btype, r, default_locale); b = new_building(btype, r, default_locale);
@ -44,7 +44,7 @@ static void test_rename_building(CuTest * tc)
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
btype = bt_find("castle"); btype = bt_get_or_create("castle");
r = findregion(-1, 0); r = findregion(-1, 0);
b = new_building(btype, r, default_locale); b = new_building(btype, r, default_locale);
@ -67,7 +67,7 @@ static void test_rename_building_twice(CuTest * tc)
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
btype = bt_find("castle"); btype = bt_get_or_create("castle");
r = findregion(-1, 0); r = findregion(-1, 0);
b = new_building(btype, r, default_locale); b = new_building(btype, r, default_locale);

View File

@ -32,7 +32,7 @@ static unsigned int get_markets(region * r, unit ** results, size_t size)
{ {
unsigned int n = 0; unsigned int n = 0;
building *b; building *b;
static building_type *btype; static const building_type *btype;
if (!btype) if (!btype)
btype = bt_find("market"); btype = bt_find("market");
if (!btype) if (!btype)

View File

@ -25,9 +25,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* modules include */ /* modules include */
#include "score.h" #include "score.h"
/* attributes include */
#include <attributes/giveitem.h>
/* items include */ /* items include */
#include <items/demonseye.h> #include <items/demonseye.h>

View File

@ -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 */ n = (n + 99) / 100; /* 1 Silber = 1 GE */
bytes = _snprintf(bufp, size, "%s, %s, (%d/%d)", shipname(sh), 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 { } else {
bytes = bytes =
_snprintf(bufp, size, "%s, %s", shipname(sh), LOC(f->locale, _snprintf(bufp, size, "%s, %s", shipname(sh), LOC(f->locale,
sh->type->name[0])); sh->type->_name));
} }
if (wrptr(&bufp, &size, bytes) != 0) if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER(); WARN_STATIC_BUFFER();

View File

@ -72,5 +72,6 @@ int RunAllTests(void)
} }
int main(int argc, char ** argv) { int main(int argc, char ** argv) {
return RunAllTests(); log_stderr = 0;
return RunAllTests();
} }

View File

@ -24,7 +24,7 @@
struct race *test_create_race(const char *name) 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->flags |= RCF_PLAYERRACE;
rc->maintenance = 10; rc->maintenance = 10;
return rc; 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 * test_create_shiptype(const char ** names)
{ {
ship_type * stype = (ship_type*)calloc(sizeof(ship_type), 1); ship_type * stype = st_get_or_create(names[0]);
stype->name[0] = _strdup(names[0]);
stype->name[1] = _strdup(names[1]);
locale_setstring(default_locale, names[0], names[0]); locale_setstring(default_locale, names[0], names[0]);
st_register(stype);
return stype; return stype;
} }