static void test_buildingowner_goes_to_same_faction_after_leave(CuTest * tc) { struct region *r; struct building *bld; struct unit *u, *u2, *u3; struct faction *f1, *f2; test_setup(); f1 = test_create_faction(NULL); f2 = test_create_faction(NULL); r = test_create_plain(0, 0); bld = test_create_building(r, NULL); CuAssertPtrNotNull(tc, bld); u2 = test_create_unit(f2, r); u3 = test_create_unit(f1, r); u = test_create_unit(f1, r); CuAssertPtrNotNull(tc, u); u_set_building(u, bld); u_set_building(u2, bld); u_set_building(u3, bld); CuAssertPtrEquals(tc, u, building_owner(bld)); leave_building(u); CuAssertPtrEquals(tc, u3, building_owner(bld)); leave_building(u3); CuAssertPtrEquals(tc, u2, building_owner(bld)); leave_building(u2); CuAssertPtrEquals(tc, NULL, building_owner(bld)); test_teardown(); }
void test_buildingowner_goes_to_empty_unit_after_leave(CuTest * tc) { struct region *r; struct building *bld; struct unit *u1, *u2, *u3; struct faction *f1; test_setup(); f1 = test_create_faction(NULL); r = test_create_plain(0, 0); bld = test_create_building(r, NULL); CuAssertPtrNotNull(tc, bld); u1 = test_create_unit(f1, r); u2 = test_create_unit(f1, r); u3 = test_create_unit(f1, r); u_set_building(u1, bld); u_set_building(u2, bld); u_set_building(u3, bld); CuAssertPtrEquals(tc, u1, building_owner(bld)); u2->number = 0; leave_building(u1); CuAssertPtrEquals(tc, u3, building_owner(bld)); leave_building(u3); CuAssertPtrEquals(tc, NULL, building_owner(bld)); u2->number = 1; CuAssertPtrEquals(tc, u2, building_owner(bld)); test_teardown(); }
bool leave(unit * u, bool force) { if (!force) { if (!can_leave(u)) { return false; } } if (u->building) { leave_building(u); } else if (u->ship) { leave_ship(u); } return true; }
int destroy_cmd(unit * u, struct order *ord) { char token[128]; ship *sh; unit *u2; region *r = u->region; const construction *con = NULL; int size = 0; const char *s; int n = INT_MAX; if (u->number < 1) return 0; init_order(ord); s = gettoken(token, sizeof(token)); if (findparam(s, u->faction->locale) == P_ROAD) { destroy_road(u, INT_MAX, ord); return 0; } if (s && *s) { n = atoi((const char *)s); if (n <= 0) { cmistake(u, ord, 288, MSG_PRODUCE); return 0; } } if (getparam(u->faction->locale) == P_ROAD) { destroy_road(u, n, ord); return 0; } if (u->building) { building *b = u->building; if (u != building_owner(b)) { cmistake(u, ord, 138, MSG_PRODUCE); return 0; } if (fval(b->type, BTF_INDESTRUCTIBLE)) { cmistake(u, ord, 138, MSG_PRODUCE); return 0; } if (n >= b->size) { /* destroy completly */ /* all units leave the building */ for (u2 = r->units; u2; u2 = u2->next) { if (u2->building == b) { leave_building(u2); } } ADDMSG(&u->faction->msgs, msg_message("destroy", "building unit", b, u)); con = b->type->construction; remove_building(&r->buildings, b); } else { /* partial destroy */ b->size -= n; ADDMSG(&u->faction->msgs, msg_message("destroy_partial", "building unit", b, u)); } } else if (u->ship) { sh = u->ship; if (u != ship_owner(sh)) { cmistake(u, ord, 138, MSG_PRODUCE); return 0; } if (fval(r->terrain, SEA_REGION)) { cmistake(u, ord, 14, MSG_EVENT); return 0; } if (n >= (sh->size * 100) / sh->type->construction->maxsize) { /* destroy completly */ /* all units leave the ship */ for (u2 = r->units; u2; u2 = u2->next) { if (u2->ship == sh) { leave_ship(u2); } } ADDMSG(&u->faction->msgs, msg_message("shipdestroy", "unit region ship", u, r, sh)); con = sh->type->construction; remove_ship(&sh->region->ships, sh); } else { /* partial destroy */ sh->size -= (sh->type->construction->maxsize * n) / 100; ADDMSG(&u->faction->msgs, msg_message("shipdestroy_partial", "unit region ship", u, r, sh)); } } else { cmistake(u, ord, 138, MSG_PRODUCE); return 0; } if (con) { /* TODO: Nicht an ZERSTÖRE mit Punktangabe angepaßt! */ int c; for (c = 0; con->materials[c].number; ++c) { const requirement *rq = con->materials + c; int recycle = (rq->number * size / con->reqsize) / 2; if (recycle) { change_resource(u, rq->rtype, recycle); } } } return 0; }