forked from github/server
Merge branch 'master' of github.com:eressea/server
This commit is contained in:
commit
612dfea36f
|
@ -3,7 +3,7 @@
|
|||
Version="10.0"
|
||||
VendorName="SlickEdit"
|
||||
TemplateName="GNU C/C++"
|
||||
WorkingDir="."
|
||||
WorkingDir=".."
|
||||
BuildSystem="vsbuild">
|
||||
<Config
|
||||
Name="Debug"
|
||||
|
@ -244,7 +244,9 @@
|
|||
<F N="../src/util/base36.test.c"/>
|
||||
<F N="../src/kernel/battle.test.c"/>
|
||||
<F N="../src/util/bsdstring.test.c"/>
|
||||
<F N="../src/kernel/build.test.c"/>
|
||||
<F N="../src/kernel/building.test.c"/>
|
||||
<F N="../src/kernel/config.test.c"/>
|
||||
<F N="../src/kernel/curse.test.c"/>
|
||||
<F N="../src/direction.test.c"/>
|
||||
<F N="../src/economy.test.c"/>
|
||||
|
@ -282,13 +284,15 @@
|
|||
<Folder
|
||||
Name="Other Files"
|
||||
Filters="">
|
||||
<F N="../tests/castles.lua"/>
|
||||
<F N="../tests/config.lua"/>
|
||||
<F N="../src/game.pkg"/>
|
||||
<F N="../tests/init.lua"/>
|
||||
<F N="../tests/locale.lua"/>
|
||||
<F N="../tests/movement.lua"/>
|
||||
<F N="../tests/regions.lua"/>
|
||||
<F N="../tests/settings.lua"/>
|
||||
<F N="../tests/ships.lua"/>
|
||||
<F N="../tests/study.lua"/>
|
||||
</Folder>
|
||||
</Files>
|
||||
</Project>
|
||||
|
|
|
@ -1792,7 +1792,8 @@ int make_cmd(unit * u, struct order *ord)
|
|||
if (pl && fval(pl, PFL_NOBUILD)) {
|
||||
cmistake(u, ord, 94, MSG_PRODUCE);
|
||||
} else {
|
||||
build_building(u, btype, m, ord);
|
||||
int id = getid();
|
||||
build_building(u, btype, id, m, ord);
|
||||
}
|
||||
} else if (itype != NULL) {
|
||||
create_item(u, itype, m);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
project(kernel C)
|
||||
|
||||
SET(_TEST_FILES
|
||||
build.test.c
|
||||
config.test.c
|
||||
ship.test.c
|
||||
spell.test.c
|
||||
|
|
|
@ -424,7 +424,7 @@ int build(unit * u, const construction * ctype, int completed, int want)
|
|||
if (want <= 0)
|
||||
return 0;
|
||||
if (type == NULL)
|
||||
return 0;
|
||||
return ENOMATERIALS;
|
||||
if (type->improvement == NULL && completed == type->maxsize)
|
||||
return ECOMPLETE;
|
||||
if (type->btype != NULL) {
|
||||
|
@ -616,7 +616,7 @@ message *msg_materials_required(unit * u, order * ord,
|
|||
|
||||
if (multi <= 0 || multi == INT_MAX)
|
||||
multi = 1;
|
||||
for (c = 0; ctype->materials[c].number; ++c) {
|
||||
for (c = 0; ctype && ctype->materials[c].number; ++c) {
|
||||
resource *res = malloc(sizeof(resource));
|
||||
res->number = multi * ctype->materials[c].number / ctype->reqsize;
|
||||
res->type = ctype->materials[c].rtype;
|
||||
|
@ -646,11 +646,11 @@ int maxbuild(const unit * u, const construction * cons)
|
|||
|
||||
/** old build routines */
|
||||
|
||||
void
|
||||
build_building(unit * u, const building_type * btype, int want, order * ord)
|
||||
int
|
||||
build_building(unit * u, const building_type * btype, int id, int want, order * ord)
|
||||
{
|
||||
region *r = u->region;
|
||||
int n = want, built = 0, id;
|
||||
int n = want, built = 0;
|
||||
building *b = NULL;
|
||||
/* einmalige Korrektur */
|
||||
const char *btname;
|
||||
|
@ -659,9 +659,10 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
static int rule_other = -1;
|
||||
|
||||
assert(u->number);
|
||||
assert(btype->construction);
|
||||
if (eff_skill(u, SK_BUILDING, r) == 0) {
|
||||
cmistake(u, ord, 101, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Falls eine Nummer angegeben worden ist, und ein Gebaeude mit der
|
||||
|
@ -670,7 +671,6 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
* baut man an der eigenen burg weiter. */
|
||||
|
||||
/* Wenn die angegebene Nummer falsch ist, KEINE Burg bauen! */
|
||||
id = getid();
|
||||
if (id > 0) { /* eine Nummer angegeben, keine neue Burg bauen */
|
||||
b = findbuilding(id);
|
||||
if (!b || b->region != u->region) { /* eine Burg mit dieser Nummer gibt es hier nicht */
|
||||
|
@ -680,7 +680,7 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
} else {
|
||||
/* keine neue Burg anfangen wenn eine Nummer angegeben war */
|
||||
cmistake(u, ord, 6, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (u->building && u->building->type == btype) {
|
||||
|
@ -693,27 +693,27 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
if (fval(btype, BTF_UNIQUE) && buildingtype_exists(r, btype, false)) {
|
||||
/* only one of these per region */
|
||||
cmistake(u, ord, 93, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (besieged(u)) {
|
||||
/* units under siege can not build */
|
||||
cmistake(u, ord, 60, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (btype->flags & BTF_NOBUILD) {
|
||||
/* special building, cannot be built */
|
||||
cmistake(u, ord, 221, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (r->terrain->max_road <= 0) {
|
||||
if ((r->terrain->flags & LAND_REGION) == 0) {
|
||||
/* special terrain, cannot build */
|
||||
cmistake(u, ord, 221, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (btype->flags & BTF_ONEPERTURN) {
|
||||
if (b && fval(b, BLD_EXPANDED)) {
|
||||
cmistake(u, ord, 318, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
n = 1;
|
||||
}
|
||||
|
@ -726,7 +726,7 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
unit *owner = building_owner(b);
|
||||
if (!owner || owner->faction != u->faction) {
|
||||
cmistake(u, ord, 1222, MSG_PRODUCE);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -754,18 +754,20 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
case ECOMPLETE:
|
||||
/* the building is already complete */
|
||||
cmistake(u, ord, 4, MSG_PRODUCE);
|
||||
return;
|
||||
break;
|
||||
case ENOMATERIALS:
|
||||
ADDMSG(&u->faction->msgs, msg_materials_required(u, ord,
|
||||
ADDMSG(&u->faction->msgs, msg_materials_required(u, ord,
|
||||
btype->construction, want));
|
||||
return;
|
||||
break;
|
||||
case ELOWSKILL:
|
||||
case ENEEDSKILL:
|
||||
/* no skill, or not enough skill points to build */
|
||||
cmistake(u, ord, 50, MSG_PRODUCE);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
if (built<=0) {
|
||||
return built;
|
||||
}
|
||||
|
||||
/* at this point, the building size is increased. */
|
||||
if (b == NULL) {
|
||||
/* build a new building */
|
||||
|
@ -784,7 +786,6 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
a->data.i = u->faction->alliance->id;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
btname = LOC(lang, btype->_name);
|
||||
|
@ -817,13 +818,14 @@ build_building(unit * u, const building_type * btype, int want, order * ord)
|
|||
free_order(new_order);
|
||||
}
|
||||
|
||||
b->size += built;
|
||||
b->size += built;
|
||||
fset(b, BLD_EXPANDED);
|
||||
|
||||
update_lighthouse(b);
|
||||
|
||||
ADDMSG(&u->faction->msgs, msg_message("buildbuilding",
|
||||
"building unit size", b, u, built));
|
||||
return built;
|
||||
}
|
||||
|
||||
static void build_ship(unit * u, ship * sh, int want)
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#include <platform.h>
|
||||
#include "types.h"
|
||||
#include "build.h"
|
||||
#include "order.h"
|
||||
#include "unit.h"
|
||||
#include "building.h"
|
||||
#include "faction.h"
|
||||
#include "region.h"
|
||||
#include "race.h"
|
||||
#include "item.h"
|
||||
#include <util/language.h>
|
||||
#include <CuTest.h>
|
||||
#include <tests.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static void test_build_building_no_materials(CuTest *tc) {
|
||||
unit *u;
|
||||
region *r;
|
||||
faction *f;
|
||||
race *rc;
|
||||
const building_type *btype;
|
||||
|
||||
test_cleanup();
|
||||
test_create_world();
|
||||
|
||||
rc = test_create_race("human");
|
||||
r = findregion(0, 0);
|
||||
f = test_create_faction(rc);
|
||||
assert(rc && f && r);
|
||||
u = test_create_unit(f, r);
|
||||
btype = bt_find("castle");
|
||||
assert(u && btype);
|
||||
set_level(u, SK_BUILDING, 1);
|
||||
CuAssertIntEquals(tc, ENOMATERIALS, build_building(u, btype, 0, 4, 0));
|
||||
CuAssertPtrEquals(tc, 0, r->buildings);
|
||||
CuAssertPtrEquals(tc, 0, u->building);
|
||||
}
|
||||
|
||||
static void test_build_building_success(CuTest *tc) {
|
||||
unit *u;
|
||||
region *r;
|
||||
faction *f;
|
||||
race *rc;
|
||||
const building_type *btype;
|
||||
const resource_type *rtype;
|
||||
|
||||
test_cleanup();
|
||||
test_create_world();
|
||||
|
||||
rc = test_create_race("human");
|
||||
rtype = get_resourcetype(R_STONE);
|
||||
btype = bt_find("castle");
|
||||
assert(btype && rc && rtype && rtype->itype);
|
||||
// TODO: assert(btype->construction);
|
||||
r = findregion(0, 0);
|
||||
assert(!r->buildings);
|
||||
f = test_create_faction(rc);
|
||||
assert(r && f);
|
||||
u = test_create_unit(f, r);
|
||||
assert(u);
|
||||
i_change(&u->items, rtype->itype, 1);
|
||||
set_level(u, SK_BUILDING, 1);
|
||||
CuAssertIntEquals(tc, 1, build_building(u, btype, 0, 4, 0));
|
||||
CuAssertPtrNotNull(tc, r->buildings);
|
||||
CuAssertPtrEquals(tc, r->buildings, u->building);
|
||||
CuAssertIntEquals(tc, 1, u->building->size);
|
||||
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
|
||||
}
|
||||
|
||||
CuSuite *get_build_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_build_building_success);
|
||||
SUITE_ADD_TEST(suite, test_build_building_no_materials);
|
||||
return suite;
|
||||
}
|
||||
|
|
@ -125,8 +125,8 @@ extern "C" {
|
|||
extern int buildingcapacity(const struct building *b);
|
||||
extern struct building *new_building(const struct building_type *typ,
|
||||
struct region *r, const struct locale *lang);
|
||||
void build_building(struct unit *u, const struct building_type *typ, int size,
|
||||
struct order *ord);
|
||||
int build_building(struct unit *u, const struct building_type *typ,
|
||||
int id, int size, struct order *ord);
|
||||
|
||||
/* Alte Gebäudetypen: */
|
||||
|
||||
|
|
|
@ -329,6 +329,35 @@ void json_ships(cJSON *json) {
|
|||
}
|
||||
}
|
||||
|
||||
void json_locale(cJSON *json, struct locale *lang) {
|
||||
cJSON *child;
|
||||
if (json->type!=cJSON_Object) {
|
||||
log_error_n("strings is not a json object: %d", json->type);
|
||||
return;
|
||||
}
|
||||
for (child=json->child;child;child=child->next) {
|
||||
if (child->type==cJSON_String) {
|
||||
locale_setstring(lang, child->string, child->valuestring);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void json_strings(cJSON *json) {
|
||||
cJSON *child;
|
||||
if (json->type!=cJSON_Object) {
|
||||
log_error_n("strings is not a json object: %d", json->type);
|
||||
return;
|
||||
}
|
||||
for (child=json->child;child;child=child->next) {
|
||||
if ((child->type==cJSON_Object)) {
|
||||
struct locale *lang = get_or_create_locale(child->string);
|
||||
json_locale(child, lang);
|
||||
} else {
|
||||
log_error_n("strings for locale `%s` are not a json object: %d", child->string, child->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void json_direction(cJSON *json, struct locale *lang) {
|
||||
cJSON *child;
|
||||
if (json->type!=cJSON_Object) {
|
||||
|
@ -476,6 +505,9 @@ void json_config(cJSON *json) {
|
|||
else if (strcmp(child->string, "ships")==0) {
|
||||
json_ships(child);
|
||||
}
|
||||
else if (strcmp(child->string, "strings")==0) {
|
||||
json_strings(child);
|
||||
}
|
||||
else if (strcmp(child->string, "directions")==0) {
|
||||
json_directions(child);
|
||||
}
|
||||
|
|
|
@ -262,6 +262,23 @@ static void test_keywords(CuTest * tc)
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static void test_strings(CuTest * tc)
|
||||
{
|
||||
const char * data = "{\"strings\": { \"de\" : { \"move\" : \"NACH\", \"study\" : \"LERNEN\" }}}";
|
||||
const struct locale * lang;
|
||||
|
||||
cJSON *json = cJSON_Parse(data);
|
||||
CuAssertPtrNotNull(tc, json);
|
||||
|
||||
test_cleanup();
|
||||
lang = get_or_create_locale("de");
|
||||
CuAssertPtrNotNull(tc, lang);
|
||||
CuAssertPtrEquals(tc, NULL, (void *)locale_string(lang, "move"));
|
||||
json_config(json);
|
||||
CuAssertStrEquals(tc, "NACH", locale_string(lang, "move"));
|
||||
CuAssertStrEquals(tc, "LERNEN", locale_string(lang, "study"));
|
||||
}
|
||||
|
||||
CuSuite *get_jsonconf_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
@ -273,6 +290,7 @@ CuSuite *get_jsonconf_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_buildings);
|
||||
SUITE_ADD_TEST(suite, test_terrains);
|
||||
SUITE_ADD_TEST(suite, test_races);
|
||||
SUITE_ADD_TEST(suite, test_strings);
|
||||
SUITE_ADD_TEST(suite, test_flags);
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ CuSuite *get_item_suite(void);
|
|||
CuSuite *get_magic_suite(void);
|
||||
CuSuite *get_move_suite(void);
|
||||
CuSuite *get_pool_suite(void);
|
||||
CuSuite *get_build_suite(void);
|
||||
CuSuite *get_reports_suite(void);
|
||||
CuSuite *get_ship_suite(void);
|
||||
CuSuite *get_spellbook_suite(void);
|
||||
|
@ -52,6 +53,7 @@ int RunAllTests(void)
|
|||
CuSuiteAddSuite(suite, get_functions_suite());
|
||||
CuSuiteAddSuite(suite, get_umlaut_suite());
|
||||
/* kernel */
|
||||
CuSuiteAddSuite(suite, get_build_suite());
|
||||
CuSuiteAddSuite(suite, get_pool_suite());
|
||||
CuSuiteAddSuite(suite, get_curse_suite());
|
||||
CuSuiteAddSuite(suite, get_equipment_suite());
|
||||
|
|
21
src/tests.c
21
src/tests.c
|
@ -102,12 +102,20 @@ ship_type * test_create_shiptype(const char ** names)
|
|||
|
||||
building_type * test_create_buildingtype(const char * name)
|
||||
{
|
||||
building_type * btype = (building_type*)calloc(sizeof(building_type), 1);
|
||||
btype->flags = BTF_NAMECHANGE;
|
||||
btype->_name = _strdup(name);
|
||||
locale_setstring(default_locale, name, name);
|
||||
bt_register(btype);
|
||||
return btype;
|
||||
building_type *btype = (building_type *)calloc(sizeof(building_type), 1);
|
||||
btype->flags = BTF_NAMECHANGE;
|
||||
btype->_name = _strdup(name);
|
||||
btype->construction = (construction *)calloc(sizeof(construction), 1);
|
||||
btype->construction->skill = SK_BUILDING;
|
||||
btype->construction->maxsize = -1;
|
||||
btype->construction->minskill = 1;
|
||||
btype->construction->reqsize = 1;
|
||||
btype->construction->materials = (requirement *)calloc(sizeof(requirement), 1);
|
||||
btype->construction->materials->number = 1;
|
||||
btype->construction->materials->rtype = get_resourcetype(R_STONE);
|
||||
locale_setstring(default_locale, name, name);
|
||||
bt_register(btype);
|
||||
return btype;
|
||||
}
|
||||
|
||||
item_type * test_create_itemtype(const char ** names) {
|
||||
|
@ -143,6 +151,7 @@ void test_create_world(void)
|
|||
|
||||
t_plain = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION);
|
||||
t_plain->size = 1000;
|
||||
t_plain->max_road = 100;
|
||||
t_ocean = test_create_terrain("ocean", SEA_REGION | SAIL_INTO | SWIM_INTO);
|
||||
t_ocean->size = 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue