Feature #362 » 0058-Unhardcode-wld.map-from-is_action_enabled_unit_on_un.patch
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. */
|