void free_region(region * r) { if (last == r) last = NULL; free(r->display); if (r->land) free_land(r->land); if (r->msgs) { free_messagelist(r->msgs->begin); free(r->msgs); r->msgs = 0; } while (r->individual_messages) { struct individual_message *msg = r->individual_messages; r->individual_messages = msg->next; if (msg->msgs) { free_messagelist(msg->msgs->begin); free(msg->msgs); } free(msg); } while (r->attribs) a_remove(&r->attribs, r->attribs); while (r->resources) { rawmaterial *res = r->resources; r->resources = res->next; free(res); } while (r->units) { unit *u = r->units; r->units = u->next; uunhash(u); free_unit(u); free(u); } while (r->buildings) { building *b = r->buildings; assert(b->region == r); r->buildings = b->next; bunhash(b); /* must be done here, because remove_building does it, and wasn't called */ free_building(b); } while (r->ships) { ship *s = r->ships; assert(s->region == r); r->ships = s->next; sunhash(s); free_ship(s); } free(r); }
/** remove a building from the region. * remove_building lets units leave the building */ void remove_building(building ** blist, building * b) { unit *u; const struct building_type *bt_caravan, *bt_dam, *bt_tunnel; assert(bfindhash(b->no)); bt_caravan = bt_find("caravan"); bt_dam = bt_find("dam"); bt_tunnel = bt_find("tunnel"); handle_event(b->attribs, "destroy", b); for (u = b->region->units; u; u = u->next) { if (u->building == b) leave(u, true); } b->size = 0; update_lighthouse(b); bunhash(b); /* Falls Karawanserei, Damm oder Tunnel einstürzen, wird die schon * gebaute Straße zur Hälfte vernichtet */ if (b->type == bt_caravan || b->type == bt_dam || b->type == bt_tunnel) { region *r = b->region; int d; for (d = 0; d != MAXDIRECTIONS; ++d) { direction_t dir = (direction_t)d; if (rroad(r, dir) > 0) { rsetroad(r, dir, rroad(r, dir) / 2); } } } /* Stattdessen nur aus Liste entfernen, aber im Speicher halten. */ while (*blist && *blist != b) { blist = &(*blist)->next; } *blist = b->next; b->region = NULL; b->next = deleted_buildings; deleted_buildings = b; }