2706 follow-up

invert the maintenance flag, update lighthouses before writing reports if that hasn't happened before.
This commit is contained in:
Enno Rehling 2020-09-27 15:51:32 +02:00
parent 220045f423
commit 585969bf98
19 changed files with 88 additions and 100 deletions

View File

@ -34,8 +34,9 @@ function test_laen_needs_mine()
assert_equal(1, f:count_msg_type("building_needed")) -- requires building
u.building = building.create(u.region, "mine")
u.building.working = true
u.building.size = 10
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process()
assert_equal(1, u:get_item('laen'))
assert_equal(99, r:get_resource('laen'))
@ -56,15 +57,19 @@ function test_mine_laen_bonus()
u:add_order("MACHE Laen")
u:set_skill('mining', 6)
u.building = building.create(u.region, "mine")
u.building.working = true
u.building.size = 10
u.number = 2
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process() -- T6 is not enough for laen
assert_equal(0, u:get_item('laen'))
assert_equal(100, r:get_resource('laen'))
assert_equal(1, f:count_msg_type("manufacture_skills"))
u:set_skill('mining', 13)
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process() -- T13 is enough, the +1 produces one extra Laen
assert_equal(4, u:get_item('laen')) -- FAIL (3)
assert_equal(96, r:get_resource('laen'))
@ -86,13 +91,14 @@ function test_mine_iron_bonus()
u:add_order("MACHE Eisen")
u:set_skill('mining', 1)
u.building = building.create(u.region, "mine")
u.building.working = false
u.building.size = 10
u.number = 2
turn_process() -- iron can be made without a working mine
assert_equal(2, u:get_item('iron'))
assert_equal(98, r:get_resource('iron'))
u:add_item('money', 500) -- Unterhalt Bergwerk
u.building.working = true
turn_process()
assert_equal(6, u:get_item('iron'))
@ -115,12 +121,13 @@ function test_quarry_bonus()
u:set_skill('quarrying', 1)
u.number = 2
u.building = building.create(u.region, 'quarry')
u.building.working = false
u.building.size = 10
turn_process()
assert_equal(2, u:get_item('stone'))
assert_equal(98, r:get_resource('stone'))
u:add_item('money', 250) -- Unterhalt Steinbruch
u.building.working = true
turn_process()
assert_equal(6, u:get_item('stone'))
@ -138,16 +145,18 @@ function test_smithy_no_bonus()
turn_begin()
u.building = building.create(u.region, 'smithy')
u.building.working = false
u.building.size = 10
u.number = 5
u:set_skill('cartmaking', 1) -- needs 1 min
u:add_item('log', 100)
u:add_order("MACHE Wagen")
turn_process() -- building disabled
turn_process() -- building disabled, money is missing
assert_equal(5, u:get_item('cart'))
assert_equal(75, u:get_item('log'))
u:add_item('money', 300) -- Unterhalt Schmiede
u:add_item('log', 1)
u.building.working = true
turn_process() -- building active
assert_equal(10, u:get_item('cart'))
@ -164,7 +173,7 @@ function test_smithy_bonus_iron()
turn_begin()
u.building = building.create(u.region, 'smithy')
u.building.working = false
u.building.size = 10
u:set_skill('weaponsmithing', 5) -- needs 3
u:add_item('iron', 100)
@ -173,6 +182,8 @@ function test_smithy_bonus_iron()
assert_equal(1, u:get_item('sword'))
assert_equal(99, u:get_item('iron'))
u:add_item('log', 1) -- Unterhalt Schmiede
u:add_item('money', 300) -- Unterhalt Schmiede
u.building.working = true
turn_process() -- building active
assert_equal(3, u:get_item('sword'))
@ -190,7 +201,7 @@ function test_smithy_bonus_mixed()
turn_begin()
u.building = building.create(u.region, 'smithy')
u.building.working = false
u.building.size = 10
u:set_skill('weaponsmithing', 5) -- needs 3
u:add_item('iron', 100)
@ -201,6 +212,8 @@ function test_smithy_bonus_mixed()
assert_equal(99, u:get_item('iron'))
assert_equal(99, u:get_item('log'))
u:add_item('money', 300) -- Unterhalt Schmiede
u:add_item('log', 1) -- Unterhalt Schmiede
u.building.working = true
turn_process() -- building active
assert_equal(3, u:get_item('axe'))

View File

@ -97,7 +97,7 @@ end
function test_lighthouse()
eressea.free_game()
local r = region.create(0, 0, "mountain")
local f = faction.create("human", "human@example.com")
local f = faction.create("human", "lighthouse@example.com")
local f2 = faction.create("dwarf")
local r2 = region.create(1, 0, "mountain")
unit.create(f2, r2, 1).name = 'The Babadook'
@ -108,7 +108,6 @@ 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)

View File

@ -39,15 +39,15 @@ 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_MAINTAINED;
else self->flags &= ~BLD_MAINTAINED;
return 1;
if (flag) self->flags &= ~BLD_UNMAINTAINED;
else self->flags |= BLD_UNMAINTAINED;
return 0;
}
static int tolua_building_get_working(lua_State * L)
{
building *self = (building *)tolua_tousertype(L, 1, 0);
bool flag = (self->flags&BLD_MAINTAINED) != 0;
bool flag = (self->flags & BLD_UNMAINTAINED) == 0;
lua_pushboolean(L, flag);
return 1;
}

View File

@ -305,30 +305,33 @@ static int forget_cmd(unit * u, order * ord)
return 0;
}
static int maintain(building * b)
static bool maintain(building * b)
{
int c;
region *r = b->region;
bool paid = true;
unit *u;
if (fval(b, BLD_MAINTAINED) || b->type == NULL || b->type->maintenance == NULL) {
return BLD_MAINTAINED;
}
if (fval(b, BLD_DONTPAY)) {
return 0;
if (b->type == NULL || b->type->maintenance == NULL) {
return true;
}
u = building_owner(b);
if (u == NULL) {
/* no owner - send a message to the entire region */
ADDMSG(&r->msgs, msg_message("maintenance_noowner", "building", b));
return 0;
return false;
}
/* If the owner is the region owner, check if dontpay flag is set for the building he is in */
if (b != u->building) {
if (!config_token("rules.region_owner_pay_building", b->type->_name)) {
/* no owner - send a message to the entire region */
ADDMSG(&r->msgs, msg_message("maintenance_noowner", "building", b));
return false;
}
}
/* If the owner is the region owner, check if dontpay flag is set for the building where he is in */
if (config_token("rules.region_owner_pay_building", b->type->_name)) {
if (fval(u->building, BLD_DONTPAY)) {
return 0;
}
ADDMSG(&r->msgs, msg_message("maintenance_nowork", "building", b));
return false;
}
for (c = 0; b->type->maintenance[c].number && paid; ++c) {
const maintenance *m = b->type->maintenance + c;
@ -341,14 +344,10 @@ static int maintain(building * b)
paid = false;
}
}
if (fval(b, BLD_DONTPAY)) {
ADDMSG(&r->msgs, msg_message("maintenance_nowork", "building", b));
return 0;
}
if (!paid) {
ADDMSG(&u->faction->msgs, msg_message("maintenancefail", "unit building", u, b));
ADDMSG(&r->msgs, msg_message("maintenance_nowork", "building", b));
return 0;
return paid;
}
for (c = 0; b->type->maintenance[c].number; ++c) {
const maintenance *m = b->type->maintenance + c;
@ -363,7 +362,7 @@ static int maintain(building * b)
assert(cost == 0);
}
ADDMSG(&u->faction->msgs, msg_message("maintenance", "unit building", u, b));
return BLD_MAINTAINED;
return true;
}
void maintain_buildings(region * r)
@ -371,12 +370,11 @@ void maintain_buildings(region * r)
building **bp = &r->buildings;
while (*bp) {
building *b = *bp;
int flags = BLD_MAINTAINED;
if (!curse_active(get_curse(b->attribs, &ct_nocostbuilding))) {
flags = maintain(b);
if (!maintain(b)) {
fset(b, BLD_UNMAINTAINED);
}
}
fset(b, flags);
bp = &b->next;
}
}

View File

@ -497,7 +497,7 @@ static void test_maintain_buildings(CuTest *tc) {
/* this building has no upkeep, it just works: */
b->flags = 0;
maintain_buildings(r);
CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED));
CuAssertIntEquals(tc, 0, fval(b, BLD_UNMAINTAINED));
CuAssertPtrEquals(tc, NULL, f->msgs);
CuAssertPtrEquals(tc, NULL, r->msgs);
@ -509,7 +509,7 @@ static void test_maintain_buildings(CuTest *tc) {
/* we cannot afford to pay: */
b->flags = 0;
maintain_buildings(r);
CuAssertIntEquals(tc, 0, fval(b, BLD_MAINTAINED));
CuAssertIntEquals(tc, BLD_UNMAINTAINED, fval(b, BLD_UNMAINTAINED));
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "maintenancefail"));
CuAssertPtrNotNull(tc, test_find_messagetype(r->msgs, "maintenance_nowork"));
test_clear_messagelist(&f->msgs);
@ -519,7 +519,7 @@ static void test_maintain_buildings(CuTest *tc) {
i_change(&u->items, itype, 100);
b->flags = 0;
maintain_buildings(r);
CuAssertIntEquals(tc, BLD_MAINTAINED, fval(b, BLD_MAINTAINED));
CuAssertIntEquals(tc, 0, fval(b, BLD_UNMAINTAINED));
CuAssertIntEquals(tc, 0, i_get(u->items, itype));
CuAssertPtrEquals(tc, NULL, r->msgs);
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "maintenance_nowork"));
@ -530,7 +530,7 @@ static void test_maintain_buildings(CuTest *tc) {
u_set_building(u, NULL);
b->flags = 0;
maintain_buildings(r);
CuAssertIntEquals(tc, 0, fval(b, BLD_MAINTAINED));
CuAssertIntEquals(tc, BLD_UNMAINTAINED, fval(b, BLD_UNMAINTAINED));
CuAssertPtrEquals(tc, NULL, f->msgs);
CuAssertPtrNotNull(tc, test_find_messagetype(r->msgs, "maintenance_noowner"));
test_clear_messagelist(&r->msgs);

View File

@ -829,7 +829,6 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
/* build a new building */
b = new_building(btype, r, lang, built);
b->type = btype;
fset(b, BLD_MAINTAINED);
/* Die Einheit befindet sich automatisch im Inneren der neuen Burg. */
if (u->number && leave(u, false)) {
@ -879,10 +878,6 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
}
fset(b, BLD_EXPANDED);
if (is_lighthouse(btype)) {
update_lighthouse(b);
}
return built;
}

View File

@ -404,9 +404,6 @@ building *new_building(const struct building_type * btype, region * r,
bptr = &(*bptr)->next;
*bptr = b;
if (is_lighthouse(b->type)) {
update_lighthouse(b);
}
bname = LOC(lang, btype->_name);
if (!bname) {
bname = LOC(lang, parameters[P_GEBAEUDE]);
@ -445,9 +442,6 @@ void remove_building(building ** blist, building * b)
if (u->building == b) leave(u, true);
}
if (is_lighthouse(b->type)) {
remove_lighthouse(b);
}
b->size = 0;
bunhash(b);
@ -639,7 +633,7 @@ buildingtype_exists(const region * r, const building_type * bt, bool working)
building *b;
for (b = rbuildings(r); b; b = b->next) {
if (b->type == bt && (!working || fval(b, BLD_MAINTAINED)) && building_finished(b)) {
if (b->type == bt && !(working && fval(b, BLD_UNMAINTAINED)) && building_finished(b)) {
return true;
}
}
@ -652,7 +646,7 @@ bool building_finished(const struct building *b) {
}
bool building_is_active(const struct building *b) {
return b && fval(b, BLD_MAINTAINED) && building_finished(b);
return b && !fval(b, BLD_UNMAINTAINED) && building_finished(b);
}
building *active_building(const unit *u, const struct building_type *btype) {

View File

@ -79,7 +79,7 @@ extern "C" {
bool in_safe_building(struct unit *u1, struct unit *u2);
#define BFL_NONE 0x00
#define BLD_MAINTAINED 0x01 /* vital maintenance paid for */
#define BLD_UNMAINTAINED 0x01 /* vital maintenance not paid for */
#define BLD_DONTPAY 0x02 /* PAY NOT */
#define BLD_UNGUARDED 0x04 /* you can enter this building anytime */
#define BLD_EXPANDED 0x08 /* has been expanded this turn */

View File

@ -332,17 +332,16 @@ static void test_buildingtype_exists(CuTest * tc)
CuAssertTrue(tc, buildingtype_exists(r, btype, false));
b->size = 9;
fset(b, BLD_MAINTAINED);
CuAssertTrue(tc, !buildingtype_exists(r, btype, false));
btype->maxsize = 0;
freset(b, BLD_MAINTAINED);
fset(b, BLD_UNMAINTAINED);
CuAssertTrue(tc, buildingtype_exists(r, btype, false));
btype->maxsize = 10;
b->size = 10;
fset(b, BLD_MAINTAINED);
freset(b, BLD_UNMAINTAINED);
CuAssertTrue(tc, buildingtype_exists(r, btype, true));
freset(b, BLD_MAINTAINED);
fset(b, BLD_UNMAINTAINED);
CuAssertTrue(tc, !buildingtype_exists(r, btype, true));
test_teardown();
}
@ -359,10 +358,7 @@ static void test_active_building(CuTest *tc) {
assert(btype && btype->maxsize == -1);
b = test_create_building(r = test_create_region(0, 0, NULL), btype);
u = test_create_unit(test_create_faction(NULL), r);
CuAssertIntEquals(tc, false, building_is_active(b));
CuAssertPtrEquals(tc, NULL, active_building(u, btype));
b->flags |= BLD_MAINTAINED;
CuAssertIntEquals(tc, true, building_is_active(b));
CuAssertPtrEquals(tc, NULL, active_building(u, btype));
u_set_building(u, b);
@ -376,7 +372,7 @@ static void test_active_building(CuTest *tc) {
CuAssertIntEquals(tc, false, building_is_active(b));
CuAssertPtrEquals(tc, NULL, active_building(u, btype));
btype->maxsize = -1;
b->flags &= ~BLD_MAINTAINED;
b->flags |= BLD_UNMAINTAINED;
CuAssertIntEquals(tc, false, building_is_active(b));
CuAssertPtrEquals(tc, NULL, active_building(u, btype));
test_teardown();

View File

@ -1563,18 +1563,6 @@ static void read_regions(gamedata *data) {
}
}
}
log_debug("updating area information for lighthouses.");
for (r = regions; r; r = r->next) {
if (r->flags & RF_LIGHTHOUSE) {
building *b;
for (b = r->buildings; b; b = b->next) {
if (is_lighthouse(b->type)) {
update_lighthouse(b);
}
}
}
}
}
static void init_factions(int data_version)

View File

@ -59,8 +59,9 @@ void update_lighthouse(building * lh)
a = a_find(r2->attribs, &at_lighthouse);
while (a && a->type == &at_lighthouse) {
building *b = (building *)a->data.v;
if (b == lh)
if (b == lh) {
break;
}
a = a->next;
}
if (!a) {
@ -72,16 +73,17 @@ void update_lighthouse(building * lh)
}
}
void remove_lighthouse(const building *lh) {
bool update_lighthouses(region *r) {
if ((r->flags & RF_LIGHTHOUSE) == 0) {
building *b;
region * r = lh->region;
r->flags &= ~RF_LIGHTHOUSE;
for (b = r->buildings; b; b = b->next) {
if (b != lh && is_lighthouse(b->type)) {
if (is_lighthouse(b->type)) {
update_lighthouse(b);
}
}
return true;
}
return false;
}
int lighthouse_range(const building * b)
@ -94,7 +96,7 @@ int lighthouse_range(const building * b)
int lighthouse_view_distance(const building * b, const unit *u)
{
if (b->size >= 10 && (b->flags & BLD_MAINTAINED)) {
if (b->size >= 10 && building_is_active(b)) {
int maxd = lighthouse_range(b);
if (maxd > 0 && u && skill_enabled(SK_PERCEPTION)) {
@ -117,7 +119,7 @@ bool lighthouse_guarded(const region * r)
for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse;
a = a->next) {
building *b = (building *)a->data.v;
if (b->flags & BLD_MAINTAINED) {
if (building_is_active(b)) {
if (r == b->region) {
return true;
}

View File

@ -20,7 +20,7 @@ extern "C" {
bool is_lighthouse(const struct building_type *btype);
bool lighthouse_guarded(const struct region *r);
void update_lighthouse(struct building *b);
void remove_lighthouse(const struct building *lh);
bool update_lighthouses(struct region *r);
int lighthouse_range(const struct building *b);
int lighthouse_view_distance(const struct building *b, const struct unit *u);

View File

@ -37,8 +37,6 @@ static void test_lighthouse_range(CuTest * tc)
set_level(u1, SK_PERCEPTION, 3);
set_level(u2, SK_PERCEPTION, 3);
CuAssertIntEquals(tc, 0, lighthouse_view_distance(b, u1));
b->flags |= BLD_MAINTAINED;
CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u1));
set_level(u1, SK_PERCEPTION, 6);
CuAssertIntEquals(tc, 1, lighthouse_view_distance(b, u2));
@ -53,6 +51,9 @@ static void test_lighthouse_range(CuTest * tc)
b->size = 99;
CuAssertIntEquals(tc, 2, lighthouse_view_distance(b, u1));
b->flags |= BLD_UNMAINTAINED;
CuAssertIntEquals(tc, 0, lighthouse_view_distance(b, u1));
test_teardown();
}
@ -70,7 +71,7 @@ static void test_lighthouse_update(CuTest * tc)
r3 = test_create_region(2, 0, t_ocean);
r4 = test_create_region(0, 1, t_plain);
b = test_create_building(r1, test_create_buildingtype("lighthouse"));
b->flags |= BLD_MAINTAINED;
update_lighthouse(b);
CuAssertIntEquals(tc, RF_LIGHTHOUSE, r1->flags&RF_LIGHTHOUSE);
CuAssertPtrEquals(tc, NULL, r1->attribs);
CuAssertPtrEquals(tc, NULL, r2->attribs);
@ -112,7 +113,6 @@ static void test_lighthouse_guard(CuTest * tc) {
r3 = test_create_region(2, 0, t_ocean);
r4 = test_create_region(0, 1, t_plain);
b = test_create_building(r1, test_create_buildingtype("lighthouse"));
b->flags |= BLD_MAINTAINED;
b->size = 10;
CuAssertIntEquals(tc, 2, lighthouse_range(b));
update_lighthouse(b);

View File

@ -65,7 +65,6 @@ static void test_market_curse(CuTest * tc)
}
r = findregion(1, 1);
b = test_create_building(r, btype);
b->flags |= BLD_MAINTAINED;
b->size = b->type->maxsize;
f = test_create_faction(NULL);

View File

@ -1157,12 +1157,19 @@ static bool can_move(const unit * u)
return true;
}
static void init_transportation(void)
static void init_movement(void)
{
region *r;
for (r = regions; r; r = r->next) {
unit *u;
building *b;
for (b = r->buildings; b; b = b->next) {
if (is_lighthouse(b->type)) {
update_lighthouse(b);
}
}
/* This is just a simple check for non-corresponding K_TRANSPORT/
* K_DRIVE. This is time consuming for an error check, but there
@ -2409,8 +2416,8 @@ void movement(void)
{
int ships;
/* Initialize the additional encumbrance by transported units */
init_transportation();
/* Initialize lighthouses and additional encumbrance by transported units */
init_movement();
/* Move ships in last phase, others first
* This is to make sure you can't land someplace and then get off the ship

View File

@ -84,7 +84,6 @@ static void setup_harbor(move_fixture *mf) {
r = test_create_region(0, 0, ttype);
b = test_create_building(r, btype);
b->flags |= BLD_MAINTAINED;
u = test_create_unit(test_create_faction(NULL), r);
u->ship = sh;

View File

@ -1652,9 +1652,13 @@ static void check_messages_exist(void) {
int init_reports(void)
{
region *r;
bool update = true;
check_messages_exist();
create_directories();
for (r = regions; r; r = r->next) {
if (update) {
update = update_lighthouses(r);
}
reorder_units(r);
}
return 0;

View File

@ -503,7 +503,6 @@ void test_prepare_lighthouse_capacity(CuTest *tc) {
r1 = test_create_region(0, 0, t_plain);
r2 = test_create_region(1, 0, t_ocean);
b = test_create_building(r1, btype);
b->flags |= BLD_MAINTAINED;
b->size = 10;
update_lighthouse(b);
u1 = test_create_unit(test_create_faction(NULL), r1);
@ -561,7 +560,6 @@ static void test_prepare_lighthouse(CuTest *tc) {
r4 = test_create_region(0, 1, t_plain);
btype = test_create_buildingtype("lighthouse");
b = test_create_building(r1, btype);
b->flags |= BLD_MAINTAINED;
b->size = 10;
update_lighthouse(b);
u = test_create_unit(f, r1);
@ -605,7 +603,6 @@ static void test_prepare_lighthouse_owners(CuTest *tc)
r3 = test_create_region(3, 0, t_ocean);
btype = test_create_buildingtype("lighthouse");
b = test_create_building(r1, btype);
b->flags |= BLD_MAINTAINED;
b->size = 10;
update_lighthouse(b);
test_create_unit(f, r1);

View File

@ -204,7 +204,6 @@ static void test_study_bug_2194(CuTest *tc) {
u_set_building(u2, b);
i_change(&u1->items, get_resourcetype(R_SILVER)->itype, 50);
i_change(&u2->items, get_resourcetype(R_SILVER)->itype, 50);
b->flags = BLD_MAINTAINED;
learn_inject();
teach_cmd(u, u->thisorder);
learn_reset();
@ -280,7 +279,6 @@ static void test_academy_building(CuTest *tc) {
u_set_building(u2, b);
i_change(&u1->items, get_resourcetype(R_SILVER)->itype, 50);
i_change(&u2->items, get_resourcetype(R_SILVER)->itype, 50);
b->flags = BLD_MAINTAINED;
learn_inject();
teach_cmd(u, u->thisorder);
learn_reset();
@ -335,7 +333,6 @@ static void test_academy_bonus(CuTest *tc) {
scale_number(u1, 9);
scale_number(u3, 2);
i_change(&u1->items, get_resourcetype(R_SILVER)->itype, 5000);
b->flags = BLD_MAINTAINED;
learn_inject();
teach_cmd(u0, u0->thisorder);