Project

General

Profile

Feature #362 » 0058-Unhardcode-wld.map-from-is_action_enabled_unit_on_un.patch

main, S3_2 - Marko Lindqvist, 03/26/2024 12:06 AM

View differences:

ai/default/daitools.c
/* FIXME: try the next action if the unit tried to do an illegal action.
* That would allow the AI to stop using the omniscient
* is_action_enabled_unit_on_*() functions. */
if (is_action_enabled_unit_on_units(ACTION_CAPTURE_UNITS,
if (is_action_enabled_unit_on_units(nmap, ACTION_CAPTURE_UNITS,
punit, ptile)) {
/* Choose capture. */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
0, "", ACTION_CAPTURE_UNITS);
} else if (is_action_enabled_unit_on_units(ACTION_BOMBARD_LETHAL,
} else if (is_action_enabled_unit_on_units(nmap, ACTION_BOMBARD_LETHAL,
punit, ptile)) {
/* Choose "Bombard Lethal". */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
0, "", ACTION_BOMBARD_LETHAL);
} else if (is_action_enabled_unit_on_units(ACTION_BOMBARD,
} else if (is_action_enabled_unit_on_units(nmap, ACTION_BOMBARD,
punit, ptile)) {
/* Choose "Bombard". */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
0, "", ACTION_BOMBARD);
} else if (is_action_enabled_unit_on_units(ACTION_BOMBARD2,
} else if (is_action_enabled_unit_on_units(nmap, ACTION_BOMBARD2,
punit, ptile)) {
/* Choose "Bombard 2". */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
0, "", ACTION_BOMBARD2);
} else if (is_action_enabled_unit_on_units(ACTION_BOMBARD3,
} else if (is_action_enabled_unit_on_units(nmap, ACTION_BOMBARD3,
punit, ptile)) {
/* Choose "Bombard 3". */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
0, "", ACTION_BOMBARD3);
} else if (is_action_enabled_unit_on_units(ACTION_NUKE_UNITS,
} else if (is_action_enabled_unit_on_units(nmap, ACTION_NUKE_UNITS,
punit, ptile)) {
/* Choose "Nuke Units". */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
......
/* Choose "Nuke City". */
unit_do_action(unit_owner(punit), punit->id, tcity->id,
0, "", ACTION_NUKE_CITY);
} else if (is_action_enabled_unit_on_units(ACTION_ATTACK,
} else if (is_action_enabled_unit_on_units(nmap, ACTION_ATTACK,
punit, ptile)) {
/* Choose regular attack. */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
0, "", ACTION_ATTACK);
} else if (is_action_enabled_unit_on_units(ACTION_SUICIDE_ATTACK,
} else if (is_action_enabled_unit_on_units(nmap, ACTION_SUICIDE_ATTACK,
punit, ptile)) {
/* Choose suicide attack (explode missile). */
unit_do_action(unit_owner(punit), punit->id, tile_index(ptile),
common/actions.c
/* Can't be enabled. No target. */
continue;
}
if (is_action_enabled_unit_on_units(blocker->id,
if (is_action_enabled_unit_on_units(nmap, blocker->id,
actor_unit, target_tile)) {
return blocker;
}
......
See note in is_action_enabled() for why the action may still be disabled.
**************************************************************************/
bool is_action_enabled_unit_on_units(const action_id wanted_action,
bool is_action_enabled_unit_on_units(const struct civ_map *nmap,
const action_id wanted_action,
const struct unit *actor_unit,
const struct tile *target_tile)
{
const struct civ_map *nmap = &(wld.map);
return is_action_enabled_unit_on_units_full(nmap, wanted_action, actor_unit,
unit_home(actor_unit),
unit_tile(actor_unit),
common/actions.h
const struct unit *actor_unit,
const struct unit *target_unit);
bool is_action_enabled_unit_on_units(const action_id wanted_action,
bool is_action_enabled_unit_on_units(const struct civ_map *nmap,
const action_id wanted_action,
const struct unit *actor_unit,
const struct tile *target_tile);
common/unit.c
/**********************************************************************//**
Check if the unit's current activity is actually legal.
**************************************************************************/
bool can_unit_continue_current_activity(struct civ_map *nmap,
bool can_unit_continue_current_activity(const struct civ_map *nmap,
struct unit *punit)
{
enum unit_activity current = punit->activity;
common/unit.h
const struct city *pcity);
bool can_unit_change_homecity(const struct unit *punit);
const char *get_activity_text(enum unit_activity activity);
bool can_unit_continue_current_activity(struct civ_map *nmap,
bool can_unit_continue_current_activity(const struct civ_map *nmap,
struct unit *punit);
bool can_unit_do_activity(const struct civ_map *nmap,
const struct unit *punit,
server/actiontools.c
switch (action_id_get_target_kind(act)) {
case ATK_UNITS:
if (tgt_tile
&& is_action_enabled_unit_on_units(act, actor, tgt_tile)) {
&& is_action_enabled_unit_on_units(nmap, act, actor, tgt_tile)) {
perform_action_to(act, actor, tgt_tile->index, EXTRA_NONE);
}
break;
......
switch (action_id_get_target_kind(act)) {
case ATK_UNITS:
if (tgt_tile
&& is_action_enabled_unit_on_units(act, actor, tgt_tile)) {
&& is_action_enabled_unit_on_units(nmap, act, actor, tgt_tile)) {
current = action_prob_vs_units(actor, act, tgt_tile);
}
break;
server/scripting/api_server_edit.c
Action *paction, Tile *tgt)
{
bool enabled = FALSE;
const struct civ_map *nmap = &(wld.map);
LUASCRIPT_CHECK_STATE(L, FALSE);
LUASCRIPT_CHECK_ARG_NIL(L, punit, 2, Unit, FALSE);
......
fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
switch (action_get_target_kind(paction)) {
case ATK_UNITS:
enabled = is_action_enabled_unit_on_units(paction->id, punit, tgt);
enabled = is_action_enabled_unit_on_units(nmap, paction->id, punit, tgt);
break;
case ATK_TILE:
enabled = is_action_enabled_unit_on_tile(paction->id, punit,
......
{
struct extra_type *sub_target;
bool enabled = FALSE;
const struct civ_map *nmap = &(wld.map);
LUASCRIPT_CHECK_STATE(L, FALSE);
LUASCRIPT_CHECK_ARG_NIL(L, punit, 2, Unit, FALSE);
......
fc_assert_ret_val(action_get_actor_kind(paction) == AAK_UNIT, FALSE);
switch (action_get_target_kind(paction)) {
case ATK_UNITS:
enabled = is_action_enabled_unit_on_units(paction->id, punit, tgt);
enabled = is_action_enabled_unit_on_units(nmap, paction->id, punit, tgt);
break;
case ATK_TILE:
enabled = is_action_enabled_unit_on_tile(paction->id, punit,
server/unithand.c
&& unit_perform_action(pplayer, punit->id, pcity->id, 0, "",
paction->id, ACT_REQ_SS_AGENT)) {
number_of_upgraded_units++;
} else if (UU_NO_MONEY == unit_upgrade_test(&(wld.map), punit, FALSE)) {
} else if (UU_NO_MONEY == unit_upgrade_test(nmap, punit, FALSE)) {
break;
}
}
......
const struct unit *target_unit)
{
struct ane_expl *explnat;
const struct civ_map *nmap = &(wld.map);
/* Explain why the action was illegal. */
explnat = expl_act_not_enabl(actor, stopped_action,
......
if (!utype_can_do_act_when_ustate(unit_type_get(actor),
stopped_action, USP_LIVABLE_TILE,
FALSE)
&& !can_unit_exist_at_tile(&(wld.map), actor, unit_tile(actor))) {
&& !can_unit_exist_at_tile(nmap, actor, unit_tile(actor))) {
unit_type_iterate(utype) {
if (utype_can_do_act_when_ustate(utype, stopped_action,
USP_LIVABLE_TILE, FALSE)) {
......
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_tile = index_to_tile(&(wld.map), target_id);
target_tile = index_to_tile(nmap, target_id);
if (target_tile == NULL) {
log_verbose("unit_perform_action() invalid target tile %d",
target_id);
......
#define ACTION_PERFORM_UNIT_UNITS(action, actor, target, action_performer)\
if (target_tile \
&& is_action_enabled_unit_on_units(action_type, \
&& is_action_enabled_unit_on_units(nmap, action_type, \
actor_unit, target_tile)) { \
bool success; \
script_server_signal_emit("action_started_unit_units", \
......
struct player *old_owner = unit_owner(punit);
struct player *new_owner = (new_pcity == NULL ? old_owner
: city_owner(new_pcity));
const struct civ_map *nmap = &(wld.map);
/* Calling this function when new_pcity is same as old_pcity should
* be safe with current implementation, but it is not meant to
......
}
}
if (!can_unit_continue_current_activity(&(wld.map), punit)) {
if (!can_unit_continue_current_activity(nmap, punit)) {
/* This is mainly for cases where unit owner changes to one not knowing
* Railroad tech when unit is already building railroad.
* Does also send_unit_info() */
......
struct player *pplayer = unit_owner(punit);
struct city *pcity = tile_city(ptile);
const struct unit_type *act_utype;
const struct civ_map *nmap = &(wld.map);
/* Sanity check: The actor still exists. */
fc_assert_ret_val(pplayer, FALSE);
......
enum direction8 facing;
int att_hp, def_hp;
adj = base_get_direction_for_step(&(wld.map),
adj = base_get_direction_for_step(nmap,
punit->tile, pdefender->tile, &facing);
if (adj) {
......
moves_used = unit_move_rate(punit) - punit->moves_left;
def_moves_used = unit_move_rate(pdefender) - pdefender->moves_left;
adj = base_get_direction_for_step(&(wld.map),
adj = base_get_direction_for_step(nmap,
punit->tile, pdefender->tile, &facing);
fc_assert(adj);
......
* An attempted move to a tile a unit can't move to is always interpreted
* as trying to perform an action (unless move_do_not_act is TRUE) */
if (!move_do_not_act) {
const bool can_not_move = !unit_can_move_to_tile(&(wld.map),
const bool can_not_move = !unit_can_move_to_tile(nmap,
punit, pdesttile,
FALSE, FALSE, FALSE);
bool one_action_may_be_legal
......
return unit_perform_action(pplayer, punit->id, tile_index(pdesttile),
NO_TARGET, "", ACTION_UNIT_MOVE3,
ACT_REQ_PLAYER);
} else if (!can_unit_survive_at_tile(&(wld.map), punit, pdesttile)
} else if (!can_unit_survive_at_tile(nmap, punit, pdesttile)
&& ((ptrans = transporter_for_unit_at(punit, pdesttile)))
&& is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_EMBARK,
punit, ptrans)) {
......
* perform against the target tile. Action decision state can be set by
* the server it self too. */
if (index_to_tile(&(wld.map), value) == NULL) {
if (index_to_tile(nmap, value) == NULL) {
/* Asked to be reminded to ask what actions the unit can do to a non
* existing target tile. */
log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
......
}
punit->action_decision_want = ACT_DEC_ACTIVE;
punit->action_decision_tile = index_to_tile(&(wld.map), value);
punit->action_decision_tile = index_to_tile(nmap, value);
/* Let the client know that this unit needs the player to decide
* what to do. */
(1-1/2)