Project

General

Profile

Bug #344 ยป 0054-Pass-trigger-action-to-can_unit_do_activity_targeted.patch

Marko Lindqvist, 03/12/2025 01:06 AM

View differences:

ai/default/daiunit.c
/* Keep barbarians aggressive and primitive */
if (is_barbarian(pplayer)) {
if (can_unit_do_activity(nmap, punit, ACTIVITY_PILLAGE)
&& is_land_barbarian(pplayer)) {
/* Land barbarians pillage */
unit_activity_handling(punit, ACTIVITY_PILLAGE,
activity_default_action(ACTIVITY_PILLAGE));
if (is_land_barbarian(pplayer)) {
enum gen_action action = activity_default_action(ACTIVITY_PILLAGE);
if (can_unit_do_activity(nmap, punit, ACTIVITY_PILLAGE, action)) {
/* Land barbarians pillage */
unit_activity_handling(punit, ACTIVITY_PILLAGE, action);
}
}
dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
client/control.h
};
#define can_unit_do_activity_client(_punit_, _act_) \
can_unit_do_activity(&(wld.map), _punit_, _act_)
can_unit_do_activity(&(wld.map), _punit_, _act_, activity_default_action(_act_))
#define can_unit_do_activity_targeted_client(_punit_, _act_, _tgt_) \
can_unit_do_activity_targeted(&(wld.map), _punit_, _act_, _tgt_)
can_unit_do_activity_targeted(&(wld.map), _punit_, _act_, activity_default_action(_act_), _tgt_)
#define can_units_do_activity_client(_punits_, _act_) \
can_units_do_activity(&(wld.map), _punits_, _act_)
can_units_do_activity(&(wld.map), _punits_, _act_, activity_default_action(_act_))
#define can_units_do_activity_targeted_client(_punits_, _act_, _tgt_) \
can_units_do_activity_targeted(&(wld.map), _punits_, _act_, _tgt_)
can_units_do_activity_targeted(&(wld.map), _punits_, _act_, activity_default_action(_act_), _tgt_)
void control_init(void);
void control_free(void);
common/unit.c
struct extra_type *target = punit->activity_target;
enum unit_activity current2 =
(current == ACTIVITY_FORTIFIED) ? ACTIVITY_FORTIFYING : current;
enum gen_action action = punit->action;
bool result;
punit->activity = ACTIVITY_IDLE;
punit->activity_target = NULL;
result = can_unit_do_activity_targeted(nmap, punit, current2, target);
result = can_unit_do_activity_targeted(nmap, punit, current2, action,
target);
punit->activity = current;
punit->activity_target = target;
punit->action = action;
return result;
}
......
**************************************************************************/
bool can_unit_do_activity(const struct civ_map *nmap,
const struct unit *punit,
enum unit_activity activity)
enum unit_activity activity,
enum gen_action action)
{
struct extra_type *target = NULL;
......
}
}
return can_unit_do_activity_targeted(nmap, punit, activity, target);
return can_unit_do_activity_targeted(nmap, punit, activity, action,
target);
}
/**********************************************************************//**
......
bool can_unit_do_activity_targeted(const struct civ_map *nmap,
const struct unit *punit,
enum unit_activity activity,
enum gen_action action,
struct extra_type *target)
{
return can_unit_do_activity_targeted_at(nmap, punit, activity, target,
unit_tile(punit));
return can_unit_do_activity_targeted_at(nmap, punit, activity, action,
target, unit_tile(punit));
}
/**********************************************************************//**
......
bool can_unit_do_activity_targeted_at(const struct civ_map *nmap,
const struct unit *punit,
enum unit_activity activity,
enum gen_action action,
struct extra_type *target,
const struct tile *ptile)
{
......
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_CLEAN,
return is_action_enabled_unit_on_tile(nmap, action,
punit, ptile, target);
case ACTIVITY_MINE:
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_MINE, punit,
return is_action_enabled_unit_on_tile(nmap, action, punit,
ptile, target);
case ACTIVITY_PLANT:
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_PLANT,
return is_action_enabled_unit_on_tile(nmap, action,
punit, ptile, NULL);
case ACTIVITY_IRRIGATE:
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_IRRIGATE, punit,
return is_action_enabled_unit_on_tile(nmap, action, punit,
ptile, target);
case ACTIVITY_CULTIVATE:
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_CULTIVATE,
return is_action_enabled_unit_on_tile(nmap, action,
punit, ptile, NULL);
case ACTIVITY_FORTIFYING:
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_self()");
return is_action_enabled_unit_on_self(nmap, ACTION_FORTIFY,
return is_action_enabled_unit_on_self(nmap, action,
punit);
case ACTIVITY_FORTIFIED:
......
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_BASE,
return is_action_enabled_unit_on_tile(nmap, action,
punit, ptile, target);
case ACTIVITY_GEN_ROAD:
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_ROAD,
return is_action_enabled_unit_on_tile(nmap, action,
punit, ptile, target);
case ACTIVITY_SENTRY:
......
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
RETURN_IS_ACTIVITY_ENABLED_UNIT_ON(action_by_number(ACTION_PILLAGE));
RETURN_IS_ACTIVITY_ENABLED_UNIT_ON(action_by_number(action));
case ACTIVITY_EXPLORE:
return (!unit_type_get(punit)->fuel && !is_losing_hp(punit));
......
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_tile()");
return is_action_enabled_unit_on_tile(nmap, ACTION_TRANSFORM_TERRAIN,
return is_action_enabled_unit_on_tile(nmap, action,
punit, ptile, NULL);
case ACTIVITY_CONVERT:
/* The call below doesn't support actor tile speculation. */
fc_assert_msg(unit_tile(punit) == ptile,
"Please use action_speculate_unit_on_self()");
return is_action_enabled_unit_on_self(nmap, ACTION_CONVERT, punit);
return is_action_enabled_unit_on_self(nmap, action, punit);
case ACTIVITY_LAST:
break;
......
log_error("can_unit_do_activity_targeted_at() unknown activity %d",
activity);
return FALSE;
#undef RETURN_IS_ACTIVITY_ENABLED_UNIT_ON
common/unit.h
struct unit *punit);
bool can_unit_do_activity(const struct civ_map *nmap,
const struct unit *punit,
enum unit_activity activity);
enum unit_activity activity,
enum gen_action action);
bool can_unit_do_activity_targeted(const struct civ_map *nmap,
const struct unit *punit,
enum unit_activity activity,
enum gen_action action,
struct extra_type *target);
bool can_unit_do_activity_targeted_at(const struct civ_map *nmap,
const struct unit *punit,
enum unit_activity activity,
enum gen_action action,
struct extra_type *target,
const struct tile *ptile);
void set_unit_activity(struct unit *punit, enum unit_activity new_activity,
common/unitlist.c
****************************************************************************/
bool can_units_do_activity(const struct civ_map *nmap,
const struct unit_list *punits,
enum unit_activity activity)
enum unit_activity activity,
enum gen_action action)
{
unit_list_iterate(punits, punit) {
if (can_unit_do_activity(nmap, punit, activity)) {
if (can_unit_do_activity(nmap, punit, activity, action)) {
return TRUE;
}
} unit_list_iterate_end;
......
bool can_units_do_activity_targeted(const struct civ_map *nmap,
const struct unit_list *punits,
enum unit_activity activity,
enum gen_action action,
struct extra_type *pextra)
{
unit_list_iterate(punits, punit) {
if (can_unit_do_activity_targeted(nmap, punit, activity, pextra)) {
if (can_unit_do_activity_targeted(nmap, punit, activity, action, pextra)) {
return TRUE;
}
} unit_list_iterate_end;
common/unitlist.h
const struct unit *punit));
bool can_units_do_activity(const struct civ_map *nmap,
const struct unit_list *punits,
enum unit_activity activity);
enum unit_activity activity,
enum gen_action action);
bool can_units_do_activity_targeted(const struct civ_map *nmap,
const struct unit_list *punits,
enum unit_activity activity,
enum gen_action action,
struct extra_type *pextra);
bool can_units_do_any_road(const struct civ_map *nmap,
const struct unit_list *punits);
server/actiontools.c
struct extra_type *pextra = NULL;
enum unit_activity activity = action_get_activity(paction);
unit_assign_specific_activity_target(actor_unit, &activity, &pextra);
unit_assign_specific_activity_target(actor_unit, &activity,
action_number(paction), &pextra);
if (pextra != NULL) {
return extra_number(pextra);
server/savegame/savecompat.c
unit_list_iterate(pplayer->units, punit) {
unit_assign_specific_activity_target(punit,
&punit->activity,
punit->action,
&punit->activity_target);
} unit_list_iterate_end;
} players_iterate_alive_end;
server/unithand.c
fc_assert(FALSE);
}
} else if (value == 1) {
if (!can_unit_do_activity(nmap, punit, ACTIVITY_SENTRY)) {
if (!can_unit_do_activity(nmap, punit, ACTIVITY_SENTRY,
activity_default_action(ACTIVITY_SENTRY))) {
return;
}
......
}
break;
case SSA_AUTOEXPLORE:
if (!can_unit_do_activity(nmap, punit, ACTIVITY_EXPLORE)) {
if (!can_unit_do_activity(nmap, punit, ACTIVITY_EXPLORE,
activity_default_action(ACTIVITY_EXPLORE))) {
return FALSE;
}
break;
......
/* Assume untargeted pillaging if no target specified */
unit_activity_handling_targeted(punit, new_activity, &target,
trigger_action);
} else if (can_unit_do_activity(nmap, punit, new_activity)) {
} else if (can_unit_do_activity(nmap, punit, new_activity,
trigger_action)) {
free_unit_orders(punit);
unit_activity_internal(punit, new_activity, trigger_action);
}
......
enum unit_activity new_activity,
enum gen_action trigger_action)
{
if (!can_unit_do_activity(&(wld.map), punit, new_activity)) {
const struct civ_map *nmap = &(wld.map);
if (!can_unit_do_activity(nmap, punit, new_activity,
trigger_action)) {
return FALSE;
} else {
enum unit_activity old_activity = punit->activity;
......
struct extra_type **new_target,
enum gen_action trigger_action)
{
const struct civ_map *nmap = &(wld.map);
if (!activity_requires_target(new_activity)) {
unit_activity_handling(punit, new_activity, trigger_action);
} else if (can_unit_do_activity_targeted(&(wld.map), punit,
new_activity, *new_target)) {
} else if (can_unit_do_activity_targeted(nmap, punit,
new_activity, trigger_action,
*new_target)) {
struct action_list *list = action_list_by_activity(new_activity);
free_unit_orders(punit);
......
struct extra_type **new_target,
enum gen_action trigger_action)
{
if (!can_unit_do_activity_targeted(&(wld.map), punit,
new_activity, *new_target)) {
const struct civ_map *nmap = &(wld.map);
if (!can_unit_do_activity_targeted(nmap, punit,
new_activity, trigger_action,
*new_target)) {
return FALSE;
} else {
enum unit_activity old_activity = punit->activity;
......
enum unit_activity stored_activity = new_activity;
unit_assign_specific_activity_target(punit,
&new_activity, new_target);
&new_activity, trigger_action,
new_target);
if (new_activity != stored_activity
&& !activity_requires_target(new_activity)) {
/* unit_assign_specific_activity_target() changed our target activity
......
} else {
set_unit_activity_targeted(punit, new_activity, *new_target,
trigger_action);
send_unit_info(NULL, punit);
send_unit_info(nullptr, punit);
unit_activity_dependencies(punit, old_activity, old_target);
if (new_activity == ACTIVITY_PILLAGE) {
server/unittools.c
**************************************************************************/
void unit_assign_specific_activity_target(struct unit *punit,
enum unit_activity *activity,
enum gen_action action,
struct extra_type **target)
{
const struct civ_map *nmap = &(wld.map);
if (*activity == ACTIVITY_PILLAGE
&& *target == NULL) {
&& *target == nullptr) {
struct tile *ptile = unit_tile(punit);
struct extra_type *tgt;
bv_extras extras = *tile_extras(ptile);
......
BV_CLR(extras, extra_index(tgt));
if (can_unit_do_activity_targeted(nmap, punit, *activity, tgt)) {
if (can_unit_do_activity_targeted(nmap, punit, *activity, action,
tgt)) {
*target = tgt;
return;
}
......
struct unit *punit;
punit = unit_virtual_prepare(powner, ptile, u_type, 0, 0, -1, -1);
if (can_unit_do_activity(nmap, punit, ACTIVITY_FORTIFYING)) {
if (can_unit_do_activity(nmap, punit, ACTIVITY_FORTIFYING,
activity_default_action(ACTIVITY_FORTIFYING))) {
punit->activity = ACTIVITY_FORTIFIED; /* Yes; directly fortified */
}
......
fc_assert(activity == ACTIVITY_SENTRY);
if (can_unit_do_activity(nmap, punit, activity)) {
if (can_unit_do_activity(nmap, punit, activity, order.action)) {
punit->done_moving = TRUE;
set_unit_activity(punit, activity, order.action);
send_unit_info(NULL, punit);
server/unittools.h
bool unit_activity_needs_target_from_client(enum unit_activity activity);
void unit_assign_specific_activity_target(struct unit *punit,
enum unit_activity *activity,
enum gen_action action,
struct extra_type **target);
void unit_forget_last_activity(struct unit *punit);
void unit_make_contact(const struct unit *punit,
struct tile *ptile, struct player *pplayer);
/* creation/deletion/upgrading */
/* Creation/deletion/upgrading */
void transform_unit(struct unit *punit, const struct unit_type *to_unit,
int vet_loss);
struct unit *create_unit(struct player *pplayer, struct tile *ptile,
    (1-1/1)