diff --git a/core/scripts/tests/common.lua b/core/scripts/tests/common.lua index 93f2e8c05..32d6e1825 100755 --- a/core/scripts/tests/common.lua +++ b/core/scripts/tests/common.lua @@ -1074,6 +1074,7 @@ function test_lighthouse() local u = unit.create(f, r, 1) local b = building.create(r, "lighthouse") b.size = 100 + b.working = true u.building = b u:set_skill("perception", 9) u:add_item("money", 1000) diff --git a/src/bind_building.c b/src/bind_building.c index 9ecc72a3f..49348c18a 100644 --- a/src/bind_building.c +++ b/src/bind_building.c @@ -56,6 +56,23 @@ static int tolua_building_get_objects(lua_State * L) return 1; } +static int tolua_building_set_working(lua_State * L) +{ + building *self = (building *) tolua_tousertype(L, 1, 0); + bool flag = !!lua_toboolean(L, 2); + if (flag) self->flags |= BLD_WORKING; + else self->flags &= ~BLD_WORKING; + return 1; +} + +static int tolua_building_get_working(lua_State * L) +{ + building *self = (building *) tolua_tousertype(L, 1, 0); + bool flag = (self->flags&BLD_WORKING)!=0; + lua_pushboolean(L, flag); + return 1; +} + static int tolua_building_get_region(lua_State * L) { building *self = (building *) tolua_tousertype(L, 1, 0); @@ -242,7 +259,8 @@ void tolua_building_open(lua_State * L) .property("type", &building_gettype) .def_readwrite("size", &building::size) #endif - tolua_variable(L, TOLUA_CAST "objects", tolua_building_get_objects, 0); + tolua_variable(L, TOLUA_CAST "objects", tolua_building_get_objects, 0); + tolua_variable(L, TOLUA_CAST "working", tolua_building_get_working, tolua_building_set_working); } tolua_endmodule(L); diff --git a/src/kernel/build.c b/src/kernel/build.c index 6fb17c859..0763cbe16 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -769,7 +769,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order * /* build a new building */ b = new_building(btype, r, lang); b->type = btype; - fset(b, BLD_MAINTAINED); + fset(b, BLD_MAINTAINED|BLD_WORKING); /* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */ if (u->number && leave(u, false)) { diff --git a/src/kernel/building.c b/src/kernel/building.c index f56c49fb7..2aa1a0b1a 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -486,7 +486,6 @@ building *new_building(const struct building_type * btype, region * r, init_lighthouse = true; } - b->flags = BLD_WORKING | BLD_MAINTAINED; b->no = newcontainerid(); bhash(b); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index f888ab88e..a73936afd 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -80,6 +80,63 @@ static void json_requirements(cJSON *json, requirement **matp) { *matp = mat; } +static void json_maintenance_i(cJSON *json, maintenance *mt) { + cJSON *child; + for (child = json->child; child; child = child->next) { + switch (child->type) { + case cJSON_Number: + if (strcmp(child->string, "amount") == 0) { + mt->number = child->valueint; + } + else { + log_error_n("maintenance contains unknown attribute %s", child->string); + } + break; + case cJSON_String: + if (strcmp(child->string, "type") == 0) { + mt->rtype = rt_get_or_create(child->valuestring); + } + else { + log_error_n("maintenance contains unknown attribute %s", child->string); + } + break; + case cJSON_Array: + if (strcmp(child->string, "flags") == 0) { + const char * flags[] = { "variable", "required", 0 }; + mt->flags = json_flags(child, flags); + } + else { + log_error_n("maintenance contains unknown attribute %s", child->string); + } + default: + log_error_n("maintenance contains unknown attribute %s", child->string); + } + } +} + +static void json_maintenance(cJSON *json, maintenance **mtp) { + cJSON *child; + maintenance *mt; + int i, size = 1; + + if (json->type == cJSON_Array) { + size = cJSON_GetArraySize(json); + } + else if (json->type != cJSON_Object) { + log_error_n("maintenance is not a json object or array (%d)", json->type); + return; + } + *mtp = mt = (struct maintenance *) calloc(sizeof(struct maintenance), size + 1); + if (json->type == cJSON_Array) { + for (i = 0, child = json->child; child; child = child->next, ++i) { + if (child->type == cJSON_Object) { + json_maintenance_i(child, mt+i); + } + } + } + json_maintenance_i(json, mt); +} + static void json_construction(cJSON *json, construction **consp) { cJSON *child; if (json->type==cJSON_Array) { @@ -159,14 +216,20 @@ static void json_building(cJSON *json, building_type *bt) { for (child=json->child;child;child=child->next) { switch(child->type) { case cJSON_Array: - if (strcmp(child->string, "construction")==0) { + if (strcmp(child->string, "construction") == 0) { json_construction(child, &bt->construction); } + else if (strcmp(child->string, "maintenance") == 0) { + json_maintenance(child, &bt->maintenance); + } break; case cJSON_Object: if (strcmp(child->string, "construction")==0) { json_construction(child, &bt->construction); } + else if (strcmp(child->string, "maintenance") == 0) { + json_maintenance(child, &bt->maintenance); + } break; case cJSON_String: if (strcmp(child->string, "name")==0) { diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index f128acf4a..932b88ac0 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -200,7 +200,11 @@ static void test_spells(CuTest * tc) static void test_buildings(CuTest * tc) { - const char * data = "{\"buildings\": { \"house\" : { " + const char * data = "{\"buildings\": { " + "\"house\" : { " + "\"maintenance\" : " + "{ \"type\" : \"iron\", \"amount\" : 1, \"flags\" : [ \"required\", \"variable\" ] }" + "," "\"construction\" : {" "\"maxsize\" : 20," "\"reqsize\" : 10," @@ -208,7 +212,13 @@ static void test_buildings(CuTest * tc) "\"materials\" : {" "\"stone\" : 2," "\"iron\" : 1" - "}}}}}"; + "}}}," + "\"shed\" : {" + "\"maintenance\" : [" + "{ \"type\" : \"iron\", \"amount\" : 1 }," + "{ \"type\" : \"stone\", \"amount\" : 2 }" + "]}" + "}}"; cJSON *json = cJSON_Parse(data); const building_type *bt; @@ -220,8 +230,24 @@ static void test_buildings(CuTest * tc) json_config(json); CuAssertPtrNotNull(tc, buildingtypes); + bt = bt_find("shed"); + CuAssertPtrNotNull(tc, bt); + CuAssertPtrNotNull(tc, bt->maintenance); + CuAssertPtrEquals(tc, (void *)get_resourcetype(R_IRON), (void *)bt->maintenance[0].rtype); + CuAssertPtrEquals(tc, (void *)get_resourcetype(R_STONE), (void *)bt->maintenance[1].rtype); + CuAssertIntEquals(tc, 1, bt->maintenance[0].number); + CuAssertIntEquals(tc, 2, bt->maintenance[1].number); + CuAssertIntEquals(tc, 0, bt->maintenance[2].number); + bt = bt_find("house"); CuAssertPtrNotNull(tc, bt); + + CuAssertPtrNotNull(tc, bt->maintenance); + CuAssertIntEquals(tc, 1, bt->maintenance[0].number); + CuAssertPtrEquals(tc, (void *)get_resourcetype(R_IRON), (void *)bt->maintenance[0].rtype); + CuAssertIntEquals(tc, MTF_VARIABLE|MTF_VITAL, bt->maintenance[0].flags); + CuAssertIntEquals(tc, 0, bt->maintenance[1].number); + CuAssertPtrNotNull(tc, bt->construction); CuAssertPtrNotNull(tc, bt->construction->materials); CuAssertIntEquals(tc, 2, bt->construction->materials[0].number); diff --git a/src/kernel/move.test.c b/src/kernel/move.test.c index 5e1d0ecae..100d4fc30 100644 --- a/src/kernel/move.test.c +++ b/src/kernel/move.test.c @@ -43,6 +43,7 @@ static void test_ship_allowed_with_harbor(CuTest * tc) ship * sh; terrain_type * ttype; building_type * btype; + building * b; test_cleanup(); test_create_world(); @@ -53,7 +54,8 @@ static void test_ship_allowed_with_harbor(CuTest * tc) r = test_create_region(0, 0, ttype); sh = test_create_ship(0, 0); - test_create_building(r, btype); + b = test_create_building(r, btype); + b->flags |= BLD_WORKING; CuAssertIntEquals(tc, SA_HARBOUR, check_ship_allowed(sh, r)); } @@ -73,9 +75,9 @@ static void test_building_type_exists(CuTest * tc) b = new_building(btype, r, default_locale); CuAssertPtrNotNull(tc, b); - CuAssertTrue(tc, !buildingtype_exists(r, NULL, true)); - CuAssertTrue(tc, buildingtype_exists(r, btype, true)); - CuAssertTrue(tc, !buildingtype_exists(r, btype2, true)); + CuAssertTrue(tc, !buildingtype_exists(r, NULL, false)); + CuAssertTrue(tc, buildingtype_exists(r, btype, false)); + CuAssertTrue(tc, !buildingtype_exists(r, btype2, false)); } CuSuite *get_move_suite(void) diff --git a/tests/init.lua b/tests/init.lua index e54c2229f..2d10882db 100644 --- a/tests/init.lua +++ b/tests/init.lua @@ -3,8 +3,8 @@ require "tests.settings" require "tests.config" require "tests.locale" require "tests.regions" -require "tests.ships" require "tests.study" -require "tests.movement" require "tests.castles" require "tests.spells" +require "tests.movement" +require "tests.ships" diff --git a/tests/ships.lua b/tests/ships.lua index 4dae533b2..d7c223c7f 100644 --- a/tests/ships.lua +++ b/tests/ships.lua @@ -22,7 +22,7 @@ function setup() } }, "buildings" : { - "harbour" : {} + "harbour" : { "maintenance" : { "type" : "money", "amount" : 250, "flags" : [ "required" ] } } }, "terrains" : { "ocean": { "flags" : [ "sea", "sail" ] }, @@ -90,7 +90,27 @@ function test_sail_to_forbidden_shore() assert_equal(ocean, u.region) end -function test_sail_into_harbour() +function test_sail_into_good_harbour() + local ocean = region.create(1, 0, "ocean") + local shore = region.create(0, 0, "glacier") + local f = faction.create("noreply@eressea.de", "human", "de") + local b = building.create(shore, "harbour") + local u + + u = unit.create(f, shore, 1) + u:add_item("money", 250) -- building maintenance fee + u.building = b + + u = unit.create(f, ocean, 1) + u.ship = ship.create(ocean, "boat") + u:set_skill("sailing", 10) + u:add_order("NACH W") + process_orders() + + assert_equal(shore, u.region, "working harbour should let the ship land") +end + +function test_sail_into_bad_harbour() local ocean = region.create(1, 0, "ocean") local shore = region.create(0, 0, "glacier") local f = faction.create("noreply@eressea.de", "human", "de") @@ -103,5 +123,5 @@ function test_sail_into_harbour() assert_not_nil(b) process_orders() - assert_equal(shore, u.region) + assert_equal(ocean, u.region, "harbour without owner should stop ship") end