Index: server/ruleset.c =================================================================== --- server/ruleset.c (revisione 21272) +++ server/ruleset.c (copia locale) @@ -1409,9 +1409,16 @@ unit_type_iterate(u) { const int i = utype_index(u); struct unit_class *pclass; + struct requirement_vector *reqs; const char *sec_name = section_name(section_list_get(sec, i)); const char *string; + reqs = lookup_req_list(file, sec_name, "reqs", utype_rule_name(u)); + requirement_vector_copy(&u->reqs, reqs); + + reqs = lookup_req_list(file, sec_name, "nreqs", utype_rule_name(u)); + requirement_vector_copy(&u->nreqs, reqs); + u->need_improvement = lookup_building(file, sec_name, "impr_req", LOG_ERROR, filename, rule_name(&u->name)); @@ -3889,6 +3896,7 @@ int i; unit_type_iterate(u) { + int j; packet.id = utype_number(u); sz_strlcpy(packet.name, untranslated_name(&u->name)); sz_strlcpy(packet.rule_name, rule_name(&u->name)); @@ -3904,6 +3912,16 @@ packet.attack_strength = u->attack_strength; packet.defense_strength = u->defense_strength; packet.move_rate = u->move_rate; + j = 0; + requirement_vector_iterate(&u->reqs, preq) { + packet.reqs[j++] = *preq; + } requirement_vector_iterate_end; + packet.reqs_count = j; + j = 0; + requirement_vector_iterate(&u->nreqs, preq) { + packet.nreqs[j++] = *preq; + } requirement_vector_iterate_end; + packet.nreqs_count = j; packet.tech_requirement = u->require_advance ? advance_number(u->require_advance) : -1; packet.impr_requirement = u->need_improvement @@ -5022,6 +5040,15 @@ } } improvement_iterate_end; + /* Units */ + unit_type_iterate(putype) { + if (!sanity_check_req_nreq_vec(&putype->reqs, &putype->nreqs, -1, + utype_rule_name(putype))) { + ruleset_error(LOG_FATAL, "Units requirements are not sane!"); + ok = FALSE; + } + } unit_type_iterate_end; + /* Governments */ governments_iterate(pgov) { if (!sanity_check_req_vec(&pgov->reqs, -1, Index: common/unittype.c =================================================================== --- common/unittype.c (revisione 21272) +++ common/unittype.c (copia locale) @@ -738,6 +738,20 @@ return TRUE; } +/**************************************************************************** + Whether disaster can happen in given city. +****************************************************************************/ +bool can_unit_happen(struct unit_type *punittype, + struct city *pcity) +{ + return are_reqs_active(city_owner(pcity), pcity, NULL, city_tile(pcity), + NULL, NULL, NULL, &punittype->reqs, + RPT_POSSIBLE) + && !are_reqs_active(city_owner(pcity), pcity, NULL, city_tile(pcity), + NULL, NULL, NULL, &punittype->nreqs, + RPT_CERTAIN); +} + /************************************************************************** Whether player can build given unit somewhere; returns FALSE if unit is obsolete. @@ -965,6 +979,8 @@ for (i = 0; i < ARRAY_SIZE(unit_types); i++) { unit_types[i].item_number = i; unit_types[i].veteran = NULL; + requirement_vector_init(&unit_types[i].reqs); + requirement_vector_init(&unit_types[i].nreqs); } } @@ -987,6 +1003,8 @@ { unit_type_iterate(punittype) { unit_type_free(punittype); + requirement_vector_free(&punittype->reqs); + requirement_vector_free(&punittype->nreqs); } unit_type_iterate_end; } Index: common/unittype.h =================================================================== --- common/unittype.h (revisione 21272) +++ common/unittype.h (copia locale) @@ -233,6 +233,8 @@ struct advance *require_advance; /* may be NULL */ struct impr_type *need_improvement; /* may be NULL */ struct government *need_government; /* may be NULL */ + struct requirement_vector *reqs; + struct requirement_vector *nreqs; int vision_radius_sq; int transport_capacity; @@ -386,6 +388,8 @@ bool can_player_build_unit_now(const struct player *p, const struct unit_type *punittype); +bool can_unit_happen(struct unit_type *punittype, struct city *pcity); + #define utype_fuel(ptype) (ptype)->fuel /* Initialization and iteration */ @@ -398,12 +402,11 @@ #define unit_type_iterate(_p) \ { \ - struct unit_type *_p = unit_type_array_first(); \ - if (NULL != _p) { \ - for (; _p <= unit_type_array_last(); _p++) { + int _i_; \ + for (_i_ = 0; _i_ < unit_type_array_last() ; _i_++) { \ + struct unit_type *_p = utype_by_number(_i_); #define unit_type_iterate_end \ - } \ } \ } Index: common/packets.def =================================================================== --- common/packets.def (revisione 21272) +++ common/packets.def (copia locale) @@ -1170,6 +1170,10 @@ TECH tech_requirement; UINT8 impr_requirement; GOVERNMENT gov_requirement; + UINT8 reqs_count; + REQUIREMENT reqs[MAX_NUM_REQS:reqs_count]; + UINT8 nreqs_count; + REQUIREMENT nreqs[MAX_NUM_REQS:nreqs_count]; UINT16 vision_radius_sq; UINT8 transport_capacity; UINT8 hp; Index: client/packhand.c =================================================================== --- client/packhand.c (revisione 21272) +++ client/packhand.c (copia locale) @@ -2858,6 +2858,17 @@ u->require_advance = advance_by_number(p->tech_requirement); u->need_improvement = improvement_by_number(p->impr_requirement); u->need_government = government_by_number(p->gov_requirement); + + for (i = 0; i < p->reqs_count; i++) { + requirement_vector_append(&u->reqs, p->reqs[i]); + } + fc_assert(u->reqs.size == p->reqs_count); + + for (i = 0; i < p->nreqs_count; i++) { + requirement_vector_append(&u->nreqs, p->nreqs[i]); + } + fc_assert(u->nreqs.size == p->nreqs_count); + u->vision_radius_sq = p->vision_radius_sq; u->transport_capacity = p->transport_capacity; u->hp = p->hp;