Project

General

Profile

Feature #594 » 0076-Unhardcode-wld.map-from-can_city_build_unit_direct.patch

main, S3_2 - Marko Lindqvist, 05/12/2024 05:17 AM

View differences:

ai/default/daimilitary.c
if (dai_can_unit_type_follow_unit_type(punittype, orig_utype, ait)
&& is_native_near_tile(&(wld.map), utype_class(punittype), ptile)
&& (U_NOT_OBSOLETED == punittype->obsoleted_by
|| !can_city_build_unit_direct(pcity, punittype->obsoleted_by))
&& punittype->attack_strength > 0 /* or we'll get SIGFPE */) {
|| !can_city_build_unit_direct(nmap, pcity, punittype->obsoleted_by))
&& punittype->attack_strength > 0 /* Or we'll get SIGFPE */) {
/* Values to be computed */
adv_want desire;
adv_want want;
common/aicore/aisupport.c
struct player *pplayer = city_owner(pcity);
int worth = 0, i;
struct unit_type *u = NULL;
const struct civ_map *nmap = &(wld.map);
if (!game.scenario.prevent_new_cities) {
u = best_role_unit_for_player(city_owner(pcity),
......
}
if (u != NULL) {
worth += utype_buy_gold_cost(pcity, u, 0); /* cost of settler */
worth += utype_buy_gold_cost(pcity, u, 0); /* Cost of settler */
}
for (i = 1; i < city_size_get(pcity); i++) {
worth += city_granary_size(i); /* cost of growing city */
worth += city_granary_size(i); /* Cost of growing city */
}
output_type_iterate(o) {
worth += pcity->prod[o] * 10;
......
if (same_pos(unit_tile(punit), pcity->tile)) {
const struct unit_type *punittype = unit_type_get(punit)->obsoleted_by;
if (punittype && can_city_build_unit_direct(pcity, punittype)) {
/* obsolete, candidate for disbanding */
if (punittype && can_city_build_unit_direct(nmap, pcity, punittype)) {
/* Obsolete, candidate for disbanding */
worth += unit_shield_value(punit, unit_type_get(punit),
action_by_number(ACTION_DISBAND_UNIT_RECOVER));
} else {
worth += unit_build_shield_cost(pcity, punit); /* good stuff */
worth += unit_build_shield_cost(pcity, punit); /* Good stuff */
}
}
} unit_list_iterate_end;
city_built_iterate(pcity, pimprove) {
if (improvement_obsolete(pplayer, pimprove, pcity)) {
worth += impr_sell_gold(pimprove); /* obsolete, candidate for selling */
worth += impr_sell_gold(pimprove); /* Obsolete, candidate for selling */
} else if (!is_wonder(pimprove)) {
/* Buy cost, with nonzero shield amount */
worth += impr_build_shield_cost(pcity, pimprove) * 2;
......
if (city_unhappy(pcity)) {
worth *= 0.75;
}
return worth;
}
common/city.c
Return whether given city can build given unit, ignoring whether unit
is obsolete.
**************************************************************************/
bool can_city_build_unit_direct(const struct city *pcity,
bool can_city_build_unit_direct(const struct civ_map *nmap,
const struct city *pcity,
const struct unit_type *punittype)
{
const struct civ_map *nmap = &(wld.map);
if (!can_player_build_unit_direct(city_owner(pcity), punittype, FALSE)) {
return FALSE;
}
......
obsolete.
**************************************************************************/
bool can_city_build_unit_now(const struct city *pcity,
const struct unit_type *punittype)
{
if (!can_city_build_unit_direct(pcity, punittype)) {
const struct unit_type *punittype)
{
const struct civ_map *nmap = &(wld.map);
if (!can_city_build_unit_direct(nmap, pcity, punittype)) {
return FALSE;
}
while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
/* TODO: Decide if fulfilled impr_req is needed to make unit obsolete,
* i.e., should the 'consider_reg_impr_req' be TRUE or FALSE. */
......
return FALSE;
}
}
return TRUE;
}
......
bool can_city_build_direct(const struct city *pcity,
const struct universal *target)
{
const struct civ_map *nmap = &(wld.map);
switch (target->kind) {
case VUT_UTYPE:
return can_city_build_unit_direct(pcity, target->value.utype);
return can_city_build_unit_direct(nmap, pcity, target->value.utype);
case VUT_IMPROVEMENT:
return can_city_build_improvement_direct(pcity, target->value.building);
default:
......
**************************************************************************/
void city_choose_build_default(struct city *pcity)
{
const struct civ_map *nmap = &(wld.map);
if (NULL == city_tile(pcity)) {
/* When a "dummy" city is created with no tile, then choosing a build
* target could fail. This currently might happen during map editing.
* target could fail. This currently might happen during map editing.
* FIXME: assumes the first unit is always "valid", so check for
* obsolete units elsewhere. */
pcity->production.kind = VUT_UTYPE;
......
if (!found) {
unit_type_iterate(punittype) {
if (can_city_build_unit_direct(pcity, punittype)) {
if (can_city_build_unit_direct(nmap, pcity, punittype)) {
#ifndef FREECIV_NDEBUG
/* Later than this, 'found' is only needed in an fc_assert() */
found = TRUE;
common/city.h
bool city_rapture_grow(const struct city *pcity);
bool city_is_occupied(const struct city *pcity);
/* city related improvement and unit functions */
/* City related improvement and unit functions */
int city_improvement_upkeep(const struct city *pcity,
const struct impr_type *pimprove);
......
bool can_city_build_improvement_now(const struct city *pcity,
const struct impr_type *pimprove);
bool can_city_build_unit_direct(const struct city *pcity,
bool can_city_build_unit_direct(const struct civ_map *nmap,
const struct city *pcity,
const struct unit_type *punittype);
bool can_city_build_unit_later(const struct city *pcity,
const struct unit_type *punittype);
......
void city_choose_build_default(struct city *pcity);
/* textual representation of buildings */
/* Textual representation of buildings */
const char *city_improvement_name_translation(const struct city *pcity,
const struct impr_type *pimprove);
const char *city_production_name_translation(const struct city *pcity);
/* city map functions */
/* City map functions */
bool is_valid_city_coords(const int city_radius_sq, const int city_map_x,
const int city_map_y);
bool city_map_includes_tile(const struct city *const pcity,
server/cityturn.c
.player = pplayer,
.city = pcity,
.tile = city_tile(pcity)
/* FIXME: Setting .unittype is currently redundant
* but can_city_build_unit_direct() does it */
/* FIXME: Setting .unittype is currently redundant,
* but can_city_build_unit_direct() does it */
};
bool purge = FALSE;
bool known = FALSE;
......
{
const struct unit_type *check = punittype;
const struct unit_type *best_upgrade = U_NOT_OBSOLETED;
const struct civ_map *nmap = &(wld.map);
if (!can_city_build_unit_direct(pcity, punittype)) {
if (!can_city_build_unit_direct(nmap, pcity, punittype)) {
return U_NOT_OBSOLETED;
}
while ((check = check->obsoleted_by) != U_NOT_OBSOLETED) {
if (can_city_build_unit_direct(pcity, check)) {
if (can_city_build_unit_direct(nmap, pcity, check)) {
best_upgrade = check;
}
}
......
{
const struct unit_type *producing = pcity->production.value.utype;
const struct unit_type *upgrading = unit_upgrades_to(pcity, producing);
const struct civ_map *nmap = &(wld.map);
if (upgrading && can_city_build_unit_direct(pcity, upgrading)) {
if (upgrading && can_city_build_unit_direct(nmap, pcity, upgrading)) {
notify_player(city_owner(pcity), city_tile(pcity),
E_UNIT_UPGRADED, ftc_server,
_("Production of %s is upgraded to %s in %s."),
......
struct worklist *pwl = &pcity->worklist;
int unit_shield_cost, num_units, i;
int saved_city_id = pcity->id;
const struct civ_map *nmap = &(wld.map);
fc_assert_ret_val(pcity->production.kind == VUT_UTYPE, FALSE);
......
/* We must make a special case for barbarians here, because they are
so dumb. Really. They don't know the prerequisite techs for units
they build!! - Per */
if (!can_city_build_unit_direct(pcity, utype)
if (!can_city_build_unit_direct(nmap, pcity, utype)
&& !is_barbarian(pplayer)) {
notify_player(pplayer, city_tile(pcity), E_CITY_CANTBUILD, ftc_server,
_("%s is building %s, which is no longer available."),
(1-1/2)