From e0ee82e977ad5570a167e8d8cd12a3b2fd84e2e4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 Jul 2014 16:13:48 -0700 Subject: [PATCH 1/7] Do not default newly created buildings to being maintained and working (do that in the create order instead). This was mucking up one of the new tests. --- src/kernel/build.c | 2 +- src/kernel/building.c | 1 - src/kernel/move.test.c | 10 ++++++---- 3 files changed, 7 insertions(+), 6 deletions(-) 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/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) From 26d6808ea1889868e5dcfec6ca37d64568b8d1d9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 Jul 2014 21:48:17 -0700 Subject: [PATCH 2/7] read building-maintenance requirements from JSON. --- src/kernel/jsonconf.c | 65 +++++++++++++++++++++++++++++++++++++- src/kernel/jsonconf.test.c | 30 ++++++++++++++++-- 2 files changed, 92 insertions(+), 3 deletions(-) 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); From 8fc137d7805552ce9b1f4567dc295f89f08e1acd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 Jul 2014 22:07:57 -0700 Subject: [PATCH 3/7] Expose the "working" flag for buildings to Lua. Test working vs. unpaid harbour landigns with a ship. --- core/scripts/tests/common.lua | 1 + scripts/tests/e3a.lua | 1 + src/bind_building.c | 20 +++++++++++++++++++- tests/init.lua | 4 ++-- tests/ships.lua | 26 +++++++++++++++++++++++--- 5 files changed, 46 insertions(+), 6 deletions(-) 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/scripts/tests/e3a.lua b/scripts/tests/e3a.lua index a656c50a4..e3f6ad725 100644 --- a/scripts/tests/e3a.lua +++ b/scripts/tests/e3a.lua @@ -283,6 +283,7 @@ function test_market() for i = 0, 5 do local rn = r:next(i) end + b.working = true eressea.process.markets() u:add_item("money", -u:get_item("money")) -- now we only have herbs local len = 0 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/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 From 783df8405587aa1f2b678813bb4ef0fac16cba2e Mon Sep 17 00:00:00 2001 From: TomBraun Date: Thu, 3 Jul 2014 15:30:59 +0200 Subject: [PATCH 4/7] BUG owner of a building can't enter ship If owner of a building want to enter a ship or other building, he must first leave the bulding. Commands are "leave" and "enter ". For buildings was that OK but not for ships. The building owner was inside the region after that commans and not in the ship. --- scripts/tests/e3a.lua | 22 ++++++++++++++++++++++ src/laws.c | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/scripts/tests/e3a.lua b/scripts/tests/e3a.lua index e3f6ad725..de9902883 100644 --- a/scripts/tests/e3a.lua +++ b/scripts/tests/e3a.lua @@ -711,3 +711,25 @@ function test_golem_use_four_iron() assert_equal(4, u1:get_item("towershield")) end +function test_building_owner_can_enter_ship() + local r1 = region.create(1, 2, "plain") + local f1 = faction.create("noreply@tteessttiinngg.de", "human", "de") + local b1 = building.create(r1, "castle") + b1.size = 10 + local s1 = ship.create(r1, "cutter") + + local u1 = unit.create(f1, r1, 10) + u1.building = b1 + u1:add_item("money", u1.number * 100) + u1:clear_orders() + u1:add_order("VERLASSEN") + u1:add_order("BETRETE SCHIFF " .. itoa36(s1.id)) + + local u2 = unit.create(f1, r1, 10) + u2.ship = s1 + u2:add_item("money", u1.number * 100) + u2:clear_orders() + process_orders() + assert_equal(s1.id, u1.ship.id) + assert_not_equal(b1.id, u1.ship.id, "BUG owner of the building can not go into a ship") +end diff --git a/src/laws.c b/src/laws.c index 89dc41e08..49e02613c 100755 --- a/src/laws.c +++ b/src/laws.c @@ -1259,10 +1259,11 @@ int enter_ship(unit * u, struct order *ord, int id, int report) if (leave(u, false)) { u_set_ship(u, sh); fset(u, UFL_ENTER); + return 1; } else if (report) { cmistake(u, ord, 150, MSG_MOVE); } - return 1; + return 0; } int enter_building(unit * u, order * ord, int id, int report) From 5011d3f6ffc2803a364ddeebe5a5b551c1d6f446 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 4 Jul 2014 22:42:13 -0700 Subject: [PATCH 5/7] some touching up to the new test here --- scripts/tests/e3a.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/tests/e3a.lua b/scripts/tests/e3a.lua index de9902883..d37cae476 100644 --- a/scripts/tests/e3a.lua +++ b/scripts/tests/e3a.lua @@ -730,6 +730,6 @@ function test_building_owner_can_enter_ship() u2:add_item("money", u1.number * 100) u2:clear_orders() process_orders() - assert_equal(s1.id, u1.ship.id) - assert_not_equal(b1.id, u1.ship.id, "BUG owner of the building can not go into a ship") + assert_equal(s1, u1.ship) + assert_equal(null, u1.building, "owner of the building can not go into a ship") end From 993032461992f4addbe80407e3833747afaf63f5 Mon Sep 17 00:00:00 2001 From: TomBraun Date: Wed, 2 Jul 2014 15:17:09 +0200 Subject: [PATCH 6/7] Change test for bug 0001976 Conflicts: scripts/tests/eressea.lua --- scripts/tests/eressea.lua | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/scripts/tests/eressea.lua b/scripts/tests/eressea.lua index e2825d973..547f23955 100644 --- a/scripts/tests/eressea.lua +++ b/scripts/tests/eressea.lua @@ -335,3 +335,26 @@ function test_stonegolems() -- end test Stone Golems four stones end +function test_only_building_owner_can_set_not_paid() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f, r, 1) + local u2 = unit.create(f, r, 1) + local mine = building.create(r, "mine") + mine.size = 2 + u1:add_item("money", 500) + u1.building = mine + u2.building = mine + u1:clear_orders() + u2:clear_orders() +-- Test that Bezahle nicht is working + u1:add_order("Bezahle nicht") + process_orders() + assert_equal(500, u1:get_item("money")) + u1:clear_orders() +-- Test that bug fix 0001976 is working +-- Bezahle nicht is not working + u2:add_order("Bezahle nicht") + process_orders() + assert_equal(0, u1:get_item("money")) +end From 990b6505bf5b1c3e7d2549a180bb00e3e504cad3 Mon Sep 17 00:00:00 2001 From: TomBraun Date: Wed, 2 Jul 2014 13:58:10 +0200 Subject: [PATCH 7/7] Fix BUG 0001976 http://bugs.eressea.de/view.php?id=1976 Check that only buling owner set k_pay disable If other unit inside the building set k_pay disable it have now no effect, before only fraction was check Conflicts: scripts/tests/eressea.lua --- src/laws.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laws.c b/src/laws.c index 49e02613c..c02be826f 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4028,7 +4028,7 @@ int pay_cmd(unit * u, struct order *ord) p = getparam(u->faction->locale); if (p == P_NOT) { unit *owner = building_owner(u->building); - if (owner->faction != u->faction) { + if (owner->no != u->no) { cmistake(u, ord, 1222, MSG_EVENT); } else { u->building->flags |= BLD_DONTPAY;