Project

Profile

Help

HostedRedmine.com has moved to the Planio platform. All logins and passwords remained the same. All users will be able to login and use Redmine just as before. *Read more...*

Feature #918887 ยป 0016-Introduce-tile-extras-targeted-actions.patch

Sveinung Kvilhaugsvik, 2021-02-01 02:08 PM

View differences:

client/control.c
request_do_action(act, punit->id, ptile->index, 0, "");
}
break;
case ATK_EXTRAS:
if ((ptile = unit_tile(punit))
&& action_prob_possible(action_prob_vs_extras(punit, act,
ptile, NULL))) {
request_do_action(act, punit->id, ptile->index, 0, "");
}
break;
case ATK_SELF:
if (action_prob_possible(action_prob_self(punit, act))) {
request_do_action(act, punit->id, punit->id, 0, "");
client/gui-gtk-3.0/action_dialog.c
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_id = args->target_tile_id;
if (NULL == index_to_tile(&(wld.map), target_id)) {
/* TODO: Should this be possible at all? If not: add assertion. */
......
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_id = args->target_tile_id;
if (NULL == index_to_tile(&(wld.map), target_id)) {
/* TODO: Should this be possible at all? If not: add assertion. */
......
target_ids[ATK_TILE] = target_tile ?
tile_index(target_tile) :
TILE_INDEX_NONE;
target_ids[ATK_EXTRAS] = target_tile ?
tile_index(target_tile) :
TILE_INDEX_NONE;
target_extra_id = target_extra ?
extra_number(target_extra) :
EXTRA_NONE;
......
}
} action_iterate_end;
/* Unit acting against a tile's extras */
action_iterate(act) {
if (action_id_get_actor_kind(act) == AAK_UNIT
&& action_id_get_target_kind(act) == ATK_EXTRAS) {
action_entry(shl, act, act_probs,
get_act_sel_action_custom_text(action_by_number(act),
act_probs[act],
actor_unit,
target_city),
act);
}
} action_iterate_end;
/* Unit acting against itself. */
action_iterate(act) {
client/gui-gtk-3.22/action_dialog.c
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_id = args->target_tile_id;
if (NULL == index_to_tile(&(wld.map), target_id)) {
/* TODO: Should this be possible at all? If not: add assertion. */
......
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_id = args->target_tile_id;
if (NULL == index_to_tile(&(wld.map), target_id)) {
/* TODO: Should this be possible at all? If not: add assertion. */
......
target_ids[ATK_TILE] = target_tile ?
tile_index(target_tile) :
TILE_INDEX_NONE;
target_ids[ATK_EXTRAS] = target_tile ?
tile_index(target_tile) :
TILE_INDEX_NONE;
target_extra_id = target_extra ?
extra_number(target_extra) :
EXTRA_NONE;
......
}
} action_iterate_end;
/* Unit acting against a tile's extras */
action_iterate(act) {
if (action_id_get_actor_kind(act) == AAK_UNIT
&& action_id_get_target_kind(act) == ATK_EXTRAS) {
action_entry(shl, act, act_probs,
get_act_sel_action_custom_text(action_by_number(act),
act_probs[act],
actor_unit,
target_city),
act);
}
} action_iterate_end;
/* Unit acting against itself. */
action_iterate(act) {
client/gui-gtk-4.0/action_dialog.c
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_id = args->target_tile_id;
if (NULL == index_to_tile(&(wld.map), target_id)) {
/* TODO: Should this be possible at all? If not: add assertion. */
......
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_id = args->target_tile_id;
if (NULL == index_to_tile(&(wld.map), target_id)) {
/* TODO: Should this be possible at all? If not: add assertion. */
......
target_ids[ATK_TILE] = target_tile ?
tile_index(target_tile) :
TILE_INDEX_NONE;
target_ids[ATK_EXTRAS] = target_tile ?
tile_index(target_tile) :
TILE_INDEX_NONE;
target_extra_id = target_extra ?
extra_number(target_extra) :
EXTRA_NONE;
......
}
} action_iterate_end;
/* Unit acting against a tile's extras */
action_iterate(act) {
if (action_id_get_actor_kind(act) == AAK_UNIT
&& action_id_get_target_kind(act) == ATK_EXTRAS) {
action_entry(shl, act, act_probs,
get_act_sel_action_custom_text(action_by_number(act),
act_probs[act],
actor_unit,
target_city),
act);
}
} action_iterate_end;
/* Unit acting against itself. */
action_iterate(act) {
client/gui-qt/dialogs.cpp
target_id[ATK_UNIT] = IDENTITY_NUMBER_ZERO;
target_id[ATK_UNITS] = TILE_INDEX_NONE;
target_id[ATK_TILE] = TILE_INDEX_NONE;
target_id[ATK_EXTRAS] = TILE_INDEX_NONE;
sub_target_id[ASTK_BUILDING] = B_LAST;
sub_target_id[ASTK_TECH] = A_UNSET;
sub_target_id[ASTK_EXTRA] = EXTRA_NONE;
......
cd->target_id[ATK_TILE] = TILE_INDEX_NONE;
}
if (target_tile) {
cd->target_id[ATK_EXTRAS] = tile_index(target_tile);
} else {
cd->target_id[ATK_EXTRAS] = TILE_INDEX_NONE;
}
/* No target building or target tech supplied. (Feb 2020) */
cd->sub_target_id[ASTK_BUILDING] = B_LAST;
cd->sub_target_id[ASTK_TECH] = A_UNSET;
......
}
} action_iterate_end;
/* Unit acting against a tile's extras. */
/* Set the correct target for the following actions. */
qv2 = cd->target_id[ATK_EXTRAS];
action_iterate(act) {
if (action_id_get_actor_kind(act) == AAK_UNIT
&& action_id_get_target_kind(act) == ATK_EXTRAS) {
action_entry(cd, act, act_probs,
get_act_sel_action_custom_text(action_by_number(act),
act_probs[act],
actor_unit,
target_city),
qv1, qv2);
}
} action_iterate_end;
/* Unit acting against itself */
/* Set the correct target for the following actions. */
......
}
break;
case ATK_TILE:
case ATK_EXTRAS:
case ATK_UNITS:
if (target_tile != NULL) {
qv2 = tile_index(target_tile);
client/gui-sdl2/action_dialog.c
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
target_id = diplomat_dlg->target_ids[ATK_TILE];
if (NULL == index_to_tile(&(wld.map), target_id)) {
/* TODO: Should this be possible at all? If not: add assertion. */
......
buf->data.unit = tgt_unit;
break;
case ATK_TILE:
case ATK_EXTRAS:
case ATK_UNITS:
buf->data.tile = tgt_tile;
break;
......
diplomat_dlg->target_ids[ATK_UNITS] = tile_index(target_tile);
diplomat_dlg->target_ids[ATK_TILE] = tile_index(target_tile);
diplomat_dlg->target_ids[ATK_EXTRAS] = tile_index(target_tile);
/* No target building or target tech supplied. (Feb 2020) */
diplomat_dlg->sub_target_id[ASTK_BUILDING] = B_LAST;
......
}
} action_iterate_end;
/* Unit acting against a tile's extras. */
action_iterate(act) {
if (action_id_get_actor_kind(act) == AAK_UNIT
&& action_id_get_target_kind(act) == ATK_EXTRAS) {
action_entry(act, act_probs,
actor_unit, target_tile, NULL, NULL,
pwindow, &area);
}
} action_iterate_end;
/* Unit acting against itself. */
action_iterate(act) {
client/packhand.c
switch (action_id_get_target_kind(auto_action)) {
case ATK_TILE:
case ATK_UNITS:
case ATK_EXTRAS:
request_do_action(auto_action,
packet->actor_unit_id, packet->target_tile_id,
0, "");
common/actions.c
}
/* Fall through. */
case ATK_TILE:
case ATK_EXTRAS:
fc_assert_ret_val(target_tile_arg, NULL);
return target_tile_arg;
case ATK_SELF:
......
}
/* Fall through. */
case ATK_TILE:
case ATK_EXTRAS:
fc_assert_ret_val(target_tile, NULL);
return tile_city(target_tile);
case ATK_SELF:
......
return action_by_number(blocker_id);
}
break;
case ATK_EXTRAS:
if (!target_tile) {
/* Can't be enabled. No target. */
continue;
}
if (is_action_enabled_unit_on_extras(blocker_id,
actor_unit, target_tile, NULL)) {
return action_by_number(blocker_id);
}
break;
case ATK_SELF:
if (is_action_enabled_unit_on_self(blocker_id, actor_unit)) {
return action_by_number(blocker_id);
......
&& target_city != NULL)
|| (action_id_get_target_kind(wanted_action) == ATK_TILE
&& target_tile != NULL)
|| (action_id_get_target_kind(wanted_action) == ATK_EXTRAS
&& target_tile != NULL)
|| (action_id_get_target_kind(wanted_action) == ATK_UNIT
&& target_unit != NULL)
|| (action_id_get_target_kind(wanted_action) == ATK_UNITS
......
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
case ATK_SELF:
/* No special player knowledge checks. */
break;
......
target_tile, target_extra);
}
/**********************************************************************//**
Returns TRUE if actor_unit can do wanted_action to the extras at
target_tile as far as action enablers are concerned.
See note in is_action_enabled for why the action may still be disabled.
**************************************************************************/
static bool
is_action_enabled_unit_on_extras_full(const action_id wanted_action,
const struct unit *actor_unit,
const struct city *actor_home,
const struct tile *actor_tile,
const struct tile *target_tile,
const struct extra_type *target_extra)
{
if (actor_unit == NULL || target_tile == NULL) {
/* Can't do an action when actor or target are missing. */
return FALSE;
}
fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(wanted_action),
FALSE, "Action %s is performed by %s not %s",
action_id_rule_name(wanted_action),
action_actor_kind_name(
action_id_get_actor_kind(wanted_action)),
action_actor_kind_name(AAK_UNIT));
fc_assert_ret_val_msg(ATK_EXTRAS
== action_id_get_target_kind(wanted_action),
FALSE, "Action %s is against %s not %s",
action_id_rule_name(wanted_action),
action_target_kind_name(
action_id_get_target_kind(wanted_action)),
action_target_kind_name(ATK_EXTRAS));
fc_assert_ret_val(actor_tile, FALSE);
if (!unit_can_do_action(actor_unit, wanted_action)) {
/* No point in continuing. */
return FALSE;
}
return is_action_enabled(wanted_action,
unit_owner(actor_unit), tile_city(actor_tile),
NULL, actor_tile,
actor_unit, unit_type_get(actor_unit),
NULL, NULL,
target_tile->extras_owner,
tile_city(target_tile),
NULL, target_tile, NULL, NULL, NULL, NULL,
target_extra,
actor_home);
}
/**********************************************************************//**
Returns TRUE if actor_unit can do wanted_action to the extras at
target_tile as far as action enablers are concerned.
See note in is_action_enabled for why the action may still be disabled.
**************************************************************************/
bool is_action_enabled_unit_on_extras(const action_id wanted_action,
const struct unit *actor_unit,
const struct tile *target_tile,
const struct extra_type *target_extra)
{
return is_action_enabled_unit_on_extras_full(wanted_action, actor_unit,
unit_home(actor_unit),
unit_tile(actor_unit),
target_tile, target_extra);
}
/**********************************************************************//**
Returns TRUE if actor_unit can do wanted_action to itself as far as
action enablers are concerned.
......
act_id, target_tile, target_extra);
}
/**********************************************************************//**
Get the actor unit's probability of successfully performing the chosen
action on the extras at the target tile.
**************************************************************************/
static struct act_prob
action_prob_vs_extras_full(const struct unit *actor_unit,
const struct city *actor_home,
const struct tile *actor_tile,
const action_id act_id,
const struct tile *target_tile,
const struct extra_type *target_extra)
{
if (actor_unit == NULL || target_tile == NULL) {
/* Can't do an action when actor or target are missing. */
return ACTPROB_IMPOSSIBLE;
}
fc_assert_ret_val_msg(AAK_UNIT == action_id_get_actor_kind(act_id),
ACTPROB_IMPOSSIBLE,
"Action %s is performed by %s not %s",
action_id_rule_name(act_id),
action_actor_kind_name(
action_id_get_actor_kind(act_id)),
action_actor_kind_name(AAK_UNIT));
fc_assert_ret_val_msg(ATK_EXTRAS == action_id_get_target_kind(act_id),
ACTPROB_IMPOSSIBLE,
"Action %s is against %s not %s",
action_id_rule_name(act_id),
action_target_kind_name(
action_id_get_target_kind(act_id)),
action_target_kind_name(ATK_EXTRAS));
fc_assert_ret_val(actor_tile, ACTPROB_IMPOSSIBLE);
if (!unit_can_do_action(actor_unit, act_id)) {
/* No point in continuing. */
return ACTPROB_IMPOSSIBLE;
}
/* Doesn't leak information about tile position since an unknown tile's
* position is known. */
if (!action_id_distance_accepted(act_id,
real_map_distance(actor_tile,
target_tile))) {
/* No point in continuing. */
return ACTPROB_IMPOSSIBLE;
}
return action_prob(act_id,
unit_owner(actor_unit), tile_city(actor_tile),
NULL, actor_tile, actor_unit, NULL,
NULL, NULL, actor_home,
target_tile->extras_owner, tile_city(target_tile),
NULL,
target_tile, NULL, NULL, NULL, NULL, target_extra);
}
/**********************************************************************//**
Get the actor unit's probability of successfully performing the chosen
action on the extras at the target tile.
**************************************************************************/
struct act_prob action_prob_vs_extras(const struct unit *actor_unit,
const action_id act_id,
const struct tile *target_tile,
const struct extra_type *target_extra)
{
return action_prob_vs_extras_full(actor_unit,
unit_home(actor_unit),
unit_tile(actor_unit),
act_id, target_tile, target_extra);
}
/**********************************************************************//**
Get the actor unit's probability of successfully performing the chosen
action on itself.
......
prob = action_prob_vs_tile(act_unit, paction->id, tgt_tile, extra_tgt);
}
break;
case ATK_EXTRAS:
if (tgt_tile) {
prob = action_prob_vs_extras(act_unit, paction->id,
tgt_tile, extra_tgt);
}
break;
case ATK_CITY:
if (tgt_city) {
prob = action_prob_vs_city(act_unit, paction->id, tgt_city);
......
}
}
/**********************************************************************//**
Returns a speculation about the actor unit's probability of successfully
performing the chosen action to the extras at the target tile (and, if
specified, specific extra) given the specified game state changes.
**************************************************************************/
struct act_prob
action_speculate_unit_on_extras(action_id act_id,
const struct unit *actor,
const struct city *actor_home,
const struct tile *actor_tile,
bool omniscient_cheat,
const struct tile *target_tile,
const struct extra_type *target_extra)
{
/* FIXME: some unit state requirements still depend on the actor unit's
* current position rather than on actor_tile. Maybe this function should
* return ACTPROB_NOT_IMPLEMENTED when one of those is detected and no
* other requirement makes the action ACTPROB_IMPOSSIBLE? */
if (omniscient_cheat) {
if (is_action_enabled_unit_on_extras_full(act_id,
actor, actor_home, actor_tile,
target_tile, target_extra)) {
return ACTPROB_CERTAIN;
} else {
return ACTPROB_IMPOSSIBLE;
}
} else {
return action_prob_vs_extras_full(actor, actor_home, actor_tile,
act_id, target_tile, target_extra);
}
}
/**********************************************************************//**
Returns a speculation about the actor unit's probability of successfully
performing the chosen action on itself given the specified game state
common/actions.h
#define SPECENUM_VALUE2NAME N_("unit stacks")
#define SPECENUM_VALUE3 ATK_TILE
#define SPECENUM_VALUE3NAME N_("tiles")
#define SPECENUM_VALUE4 ATK_EXTRAS
#define SPECENUM_VALUE4NAME N_("tile extras")
/* No target except the actor itself. */
#define SPECENUM_VALUE4 ATK_SELF
#define SPECENUM_VALUE4NAME N_("itself")
#define SPECENUM_VALUE5 ATK_SELF
#define SPECENUM_VALUE5NAME N_("itself")
#define SPECENUM_COUNT ATK_COUNT
#include "specenum_gen.h"
......
const struct tile *target_tile,
const struct extra_type *target_extra);
bool is_action_enabled_unit_on_extras(const action_id wanted_action,
const struct unit *actor_unit,
const struct tile *target,
const struct extra_type *tgt_extra);
bool is_action_enabled_unit_on_self(const action_id wanted_action,
const struct unit *actor_unit);
......
const struct tile *victims,
const struct extra_type *target_extra);
struct act_prob action_prob_vs_extras(const struct unit *actor,
const action_id act_id,
const struct tile *target,
const struct extra_type *tgt_extra);
struct act_prob action_prob_self(const struct unit *actor,
const action_id act_id);
......
const struct tile *target_tile,
const struct extra_type *target_extra);
struct act_prob
action_speculate_unit_on_extras(action_id act_id,
const struct unit *actor,
const struct city *actor_home,
const struct tile *actor_tile,
bool omniscient_cheat,
const struct tile *target_tile,
const struct extra_type *target_extra);
struct act_prob
action_speculate_unit_on_self(action_id act_id,
const struct unit *actor,
common/unittype.c
if (requirement_fulfilled_by_unit_type(putype,
&(enabler->actor_reqs))
&& action_id_get_actor_kind(enabler->action) == AAK_UNIT
&& (action_id_get_target_kind(enabler->action) != ATK_TILE
&& ((action_id_get_target_kind(enabler->action) != ATK_TILE
&& action_id_get_target_kind(enabler->action) != ATK_EXTRAS)
/* No diplomatic relation to Nature */
|| !does_req_contradicts_reqs(&tile_is_claimed,
&enabler->target_reqs))) {
doc/README.actions
signal.connect("action_started_unit_unit", "action_started_callback")
signal.connect("action_started_unit_units", "action_started_callback")
signal.connect("action_started_unit_tile", "action_started_callback")
signal.connect("action_started_unit_extras", "action_started_callback")
signal.connect("action_started_unit_self", "action_started_callback")
Example 2
......
* A copy of "Transport Disembark".
* See "Transport Disembark" for everything else.
Actions done by a unit against all extras at a tile
===================================================
Actions done by a unit to it self
=================================
"Disband Unit" - Disband the unit.
server/actiontools.c
victim_link);
break;
case ATK_TILE:
case ATK_EXTRAS:
notify_player(receiver, victim_tile,
E_DIPLOMATIC_INCIDENT, ftc_server,
/* TRANS: Explode Nuclear ... (54, 26) */
......
victim_link);
break;
case ATK_TILE:
case ATK_EXTRAS:
notify_player(receiver, victim_tile,
E_DIPLOMATIC_INCIDENT, ftc_server,
/* TRANS: Europeans ... Explode Nuclear ... (54, 26) */
......
victim_link);
break;
case ATK_TILE:
case ATK_EXTRAS:
notify_player(receiver, victim_tile,
E_DIPLOMATIC_INCIDENT, ftc_server,
/* TRANS: Explode Nuclear ... (54, 26) */
......
victim_link);
break;
case ATK_TILE:
case ATK_EXTRAS:
notify_player(receiver, victim_tile,
E_DIPLOMATIC_INCIDENT, ftc_server,
/* TRANS: Europeans ... Explode Nuclear ... (54, 26) */
......
case ATK_TILE:
prob = action_prob_vs_tile(actor, act, target, target_extra);
break;
case ATK_EXTRAS:
prob = action_prob_vs_extras(actor, act, target, target_extra);
break;
case ATK_UNITS:
prob = action_prob_vs_units(actor, act, target);
break;
......
action_iterate(act) {
if (!(action_id_get_actor_kind(act) == AAK_UNIT
&& action_id_get_target_kind(act) == ATK_TILE
&& (action_id_get_target_kind(act) == ATK_TILE
|| action_id_get_target_kind(act) == ATK_EXTRAS)
&& action_id_has_complex_target(act))) {
/* Not a relevant action. */
continue;
......
perform_action_to(act, actor, tgt_tile->index, extra_number(target_extra));
}
break;
case ATK_EXTRAS:
if (tgt_tile
&& is_action_enabled_unit_on_extras(act, actor,
tgt_tile, target_extra)) {
perform_action_to(act, actor,
tgt_tile->index, extra_number(target_extra));
}
break;
case ATK_CITY:
if (tgt_city
&& is_action_enabled_unit_on_city(act, actor, tgt_city)) {
......
current = action_prob_vs_tile(actor, act, tgt_tile, target_extra);
}
break;
case ATK_EXTRAS:
if (tgt_tile
&& is_action_enabled_unit_on_extras(act, actor,
tgt_tile, target_extra)) {
current = action_prob_vs_extras(actor, act,
tgt_tile, target_extra);
}
break;
case ATK_CITY:
if (tgt_city
&& is_action_enabled_unit_on_city(act, actor, tgt_city)) {
server/advisors/autosettlers.c
punit, unit_home(punit), ptile,
omniscient_cheat,
ptile, target));
case ATK_EXTRAS:
return action_prob_possible(action_speculate_unit_on_extras(
paction->id,
punit, unit_home(punit), ptile,
omniscient_cheat,
ptile, target));
case ATK_SELF:
return action_prob_possible(action_speculate_unit_on_self(
paction->id,
server/diplomats.c
: tile_link(ptile);
break;
case ATK_TILE:
case ATK_EXTRAS:
victim_link = tile_link(ptile);
break;
case ATK_SELF:
server/scripting/script_server.c
API_TYPE_ACTION,
API_TYPE_UNIT, API_TYPE_TILE);
luascript_signal_create(fcl_main, "action_started_unit_extras", 3,
API_TYPE_ACTION,
API_TYPE_UNIT, API_TYPE_TILE);
luascript_signal_create(fcl_main, "action_started_unit_self", 2,
API_TYPE_ACTION,
API_TYPE_UNIT);
server/unithand.c
}
target_player = tile_owner(target_tile);
break;
case ATK_EXTRAS:
if (target_tile == NULL) {
/* No target tile. */
return NULL;
}
target_player = target_tile->owner;
break;
case ATK_SELF:
/* Can't declare war on itself. */
return NULL;
......
break;
case ATK_UNITS:
case ATK_TILE:
case ATK_EXTRAS:
if (target_tile == NULL) {
explnat->kind = ANEK_MISSING_TARGET;
}
......
case ATK_TILE:
tgt_player = tile_owner(target_tile);
break;
case ATK_EXTRAS:
tgt_player = target_tile->extras_owner;
break;
case ATK_UNITS:
/* A unit stack may contain units with multiple owners. Pick the
* first one. */
......
probabilities[act] = ACTPROB_IMPOSSIBLE;
}
break;
case ATK_EXTRAS:
if (target_tile) {
/* Calculate the probabilities. */
probabilities[act] = action_prob_vs_extras(actor_unit, act,
target_tile,
target_extra);
} else {
/* No target to act against. */
probabilities[act] = ACTPROB_IMPOSSIBLE;
}
break;
case ATK_SELF:
if (actor_target_distance == 0) {
/* Calculate the probabilities. */
......
target_unit_id = target_unit->id;
break;
case ATK_TILE:
case ATK_EXTRAS:
/* The target tile isn't selected here so it hasn't changed. */
fc_assert(target_tile != NULL);
......
TRUE, requester); \
}
#define ACTION_STARTED_UNIT_EXTRAS(action, actor, target, action_performer)\
if (target_tile \
&& is_action_enabled_unit_on_extras(action_type, \
actor_unit, target_tile, \
target_extra)) { \
bool success; \
script_server_signal_emit("action_started_unit_extras", \
action_by_number(action), actor, target); \
if (!actor || !unit_is_alive(actor_id)) { \
/* Actor unit was destroyed during pre action Lua. */ \
return FALSE; \
} \
success = action_performer; \
if (success) { \
action_success_actor_price(paction, actor_id, actor); \
} \
return success; \
} else { \
illegal_action(pplayer, actor_unit, action_type, \
target_tile ? target_tile->extras_owner : NULL, \
target_tile, NULL, NULL, \
TRUE, requester); \
}
switch (paction->result) {
case ACTRES_SPY_BRIBE_UNIT:
ACTION_STARTED_UNIT_UNIT(action_type, actor_unit, punit,
......
case ATK_TILE:
ACTION_STARTED_UNIT_TILE(action_type, actor_unit, target_tile, TRUE);
break;
case ATK_EXTRAS:
ACTION_STARTED_UNIT_EXTRAS(action_type, actor_unit, target_tile,
TRUE);
break;
case ATK_SELF:
ACTION_STARTED_UNIT_SELF(action_type, actor_unit, TRUE);
break;
server/unittools.c
dst_tile, pextra);
tgt_id = dst_tile->index;
break;
case ATK_EXTRAS:
prob = action_prob_vs_extras(punit, order.action,
dst_tile, pextra);
tgt_id = dst_tile->index;
break;
case ATK_CITY:
prob = action_prob_vs_city(punit, order.action,
tgt_city);
    (1-1/1)