static void test_shipowner_goes_to_other_after_leave(CuTest * tc) { struct region *r; struct ship *sh; struct unit *u, *u2; struct faction *f; const struct ship_type *stype; const struct race *human; test_setup(); test_create_world(); human = rc_find("human"); CuAssertPtrNotNull(tc, human); stype = st_find("boat"); CuAssertPtrNotNull(tc, stype); f = test_create_faction(human); r = findregion(0, 0); sh = test_create_ship(r, stype); CuAssertPtrNotNull(tc, sh); u2 = test_create_unit(f, r); u = test_create_unit(f, r); CuAssertPtrNotNull(tc, u); u_set_ship(u, sh); u_set_ship(u2, sh); CuAssertPtrEquals(tc, u, ship_owner(sh)); leave_ship(u); CuAssertPtrEquals(tc, u2, ship_owner(sh)); test_teardown(); }
void test_shipowner_goes_to_empty_unit_after_leave(CuTest * tc) { struct region *r; struct ship *sh; struct unit *u1, *u2, *u3; struct faction *f1; const struct ship_type *stype; const struct race *human; test_setup(); test_create_world(); human = rc_find("human"); CuAssertPtrNotNull(tc, human); stype = st_find("boat"); CuAssertPtrNotNull(tc, stype); f1 = test_create_faction(human); r = findregion(0, 0); sh = test_create_ship(r, stype); CuAssertPtrNotNull(tc, sh); u1 = test_create_unit(f1, r); u2 = test_create_unit(f1, r); u3 = test_create_unit(f1, r); u_set_ship(u1, sh); u_set_ship(u2, sh); u_set_ship(u3, sh); CuAssertPtrEquals(tc, u1, ship_owner(sh)); u2->number = 0; leave_ship(u1); CuAssertPtrEquals(tc, u3, ship_owner(sh)); leave_ship(u3); CuAssertPtrEquals(tc, NULL, ship_owner(sh)); u2->number = 1; CuAssertPtrEquals(tc, u2, ship_owner(sh)); test_teardown(); }
static void test_shipowner_goes_to_same_faction_after_leave(CuTest * tc) { struct region *r; struct ship *sh; struct unit *u, *u2, *u3; struct faction *f1, *f2; const struct ship_type *stype; const struct race *human; test_cleanup(); test_create_world(); human = rc_find("human"); CuAssertPtrNotNull(tc, human); stype = st_find("boat"); CuAssertPtrNotNull(tc, stype); f1 = test_create_faction(human); f2 = test_create_faction(human); r = findregion(0, 0); sh = test_create_ship(r, stype); CuAssertPtrNotNull(tc, sh); u2 = test_create_unit(f2, r); u3 = test_create_unit(f1, r); u = test_create_unit(f1, r); CuAssertPtrNotNull(tc, u); u_set_ship(u, sh); u_set_ship(u2, sh); u_set_ship(u3, sh); CuAssertPtrEquals(tc, u, ship_owner(sh)); leave_ship(u); CuAssertPtrEquals(tc, u3, ship_owner(sh)); leave_ship(u3); CuAssertPtrEquals(tc, u2, ship_owner(sh)); leave_ship(u2); CuAssertPtrEquals(tc, 0, ship_owner(sh)); }
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; }
void remove_ship(ship ** slist, ship * sh) { region *r = sh->region; unit *u = r->units; handle_event(sh->attribs, "destroy", sh); while (u) { if (u->ship == sh) { leave_ship(u); } u = u->next; } sunhash(sh); while (*slist && *slist != sh) slist = &(*slist)->next; assert(*slist); *slist = sh->next; sh->next = deleted_ships; deleted_ships = sh; sh->region = NULL; }
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; }