static struct impr_type improvement_types[B_LAST]; /**********************************************************************//** Initialize building structures. **************************************************************************/ void improvements_init(void) { int i; /* Can't use improvement_iterate() or improvement_by_number() here * because num_impr_types isn't known yet. */ for (i = 0; i < ARRAY_SIZE(improvement_types); i++) { struct impr_type *p = &improvement_types[i]; p->item_number = i; requirement_vector_init(&p->reqs); requirement_vector_init(&p->obsolete_by); p->ruledit_disabled = FALSE; p->ruledit_dlg = NULL; } BV_CLR_ALL(obsoletion_checking); } bool improvement_obsolete(const struct player *pplayer, const struct impr_type *pimprove, const struct city *pcity) { const struct req_context context = { .player = pplayer, .city = pcity, .tile = pcity ? city_tile(pcity) : NULL, .building = pimprove, }; bool result = FALSE; requirement_vector_iterate(&pimprove->obsolete_by, preq) { int id = -1; if (VUT_IMPROVEMENT == preq->source.kind) { /* Avoid cyclical obsoletion */ id = improvement_index(preq->source.value.building); if (BV_ISSET(obsoletion_checking, id)) { /* Building's obsoletion depends on itself. Resolve to present * (that may result in obsoletion on top level). */ BV_CLR(obsoletion_checking, id); return preq->present; } else { BV_SET(obsoletion_checking, id); } } result = is_req_active(&context, NULL, preq, RPT_CERTAIN); if (id >= 0) { BV_CLR(obsoletion_checking, id); } if (result) { break; } } requirement_vector_iterate_end; return result; }