Project

General

Profile

Feature #1541 ยป 3_4-specialist_subtarget_kind.patch

Alexandr Ignatiev, 06/27/2025 12:44 AM

View differences:

client/gui-gtk-3.22/action_dialog.c
#include "traderoutes.h"
#include "movement.h"
#include "research.h"
#include "specialist.h"
#include "unit.h"
#include "unitlist.h"
......
int target_building_id;
int target_tech_id;
int target_extra_id;
int target_specialist_id;
};
/* TODO: maybe this should be in the dialog itself? */
......
int target_tile_id,
int target_building_id,
int target_tech_id,
int target_specialist_id,
int tgt_extra_id)
{
struct action_data *data = fc_malloc(sizeof(*data));
......
data->target_tile_id = target_tile_id;
data->target_building_id = target_building_id;
data->target_tech_id = target_tech_id;
data->target_specialist_id = target_specialist_id;
data->target_extra_id = tgt_extra_id;
return data;
......
failed = TRUE;
}
break;
case ASTK_SPECIALIST:
sub_target = args->target_specialist_id;
if (NULL == specialist_by_number(sub_target)) {
/* Did the ruleset change? */
failed = TRUE;
}
break;
case ASTK_NONE:
case ASTK_COUNT:
/* Shouldn't happen. */
......
g_signal_connect(shell, "response", G_CALLBACK(bribe_unit_response),
act_data(paction->id, actor->id,
0, punit->id, 0,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
g_signal_connect(shell, "response", G_CALLBACK(bribe_stack_response),
act_data(paction->id, actor->id,
0, 0, ptile->index,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
create_improvements_list(client.conn.playing, pcity,
act_data(paction->id,
actor->id, pcity->id, 0, 0,
0, 0, 0));
0, 0, 0, 0));
gtk_window_present(GTK_WINDOW(spy_sabotage_shell));
}
}
......
g_signal_connect(shell, "response", G_CALLBACK(incite_response),
act_data(paction->id, actor->id,
pcity->id, 0, 0,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
(target_unit) ? target_unit->id : IDENTITY_NUMBER_ZERO,
(target_tile) ? target_tile->index : TILE_INDEX_NONE,
/* No target_building or target_tech supplied. (Dec 2019) */
B_LAST, A_UNSET,
B_LAST, A_UNSET, -1,
target_extra ? target_extra->id : EXTRA_NONE);
/* Could be caused by the server failing to reply to a request for more
client/gui-gtk-3.22/menu.c
#include "game.h"
#include "government.h"
#include "road.h"
#include "specialist.h"
#include "unit.h"
/* client */
......
sub_target = extra_number(pextra);
}
break;
case ASTK_SPECIALIST:
{
struct specialist *pspec = g_object_get_data(G_OBJECT(item),
"end_specialist");
fc_assert_ret(nullptr != pspec);
sub_target = specialist_number(pspec);
}
break;
case ASTK_NONE:
sub_target = NO_TARGET;
break;
......
extra_name_translation(pextra));
} extra_type_iterate_end;
break;
case ASTK_SPECIALIST:
specialist_type_iterate(spc) {
struct specialist *pspec = specialist_by_number(spc);
CREATE_SUB_ITEM(pspec, "end_specialist",
specialist_plural_translation(pspec));
} specialist_type_iterate_end;
break;
case ASTK_NONE:
/* Should not be here. */
fc_assert(action_get_sub_target_kind(paction) != ASTK_NONE);
client/gui-gtk-4.0/action_dialog.c
#include "traderoutes.h"
#include "movement.h"
#include "research.h"
#include "specialist.h"
#include "unit.h"
#include "unitlist.h"
......
int target_building_id;
int target_tech_id;
int target_extra_id;
int target_specialist_id;
};
/* TODO: Maybe this should be in the dialog itself? */
......
int target_tile_id,
int target_building_id,
int target_tech_id,
int target_specialist_id,
int tgt_extra_id)
{
struct action_data *data = fc_malloc(sizeof(*data));
......
data->target_tile_id = target_tile_id;
data->target_building_id = target_building_id;
data->target_tech_id = target_tech_id;
data->target_specialist_id = target_specialist_id;
data->target_extra_id = tgt_extra_id;
return data;
......
failed = TRUE;
}
break;
case ASTK_SPECIALIST:
sub_target = args->target_specialist_id;
if (NULL == specialist_by_number(sub_target)) {
/* Did the ruleset change? */
failed = TRUE;
}
break;
case ASTK_NONE:
case ASTK_COUNT:
/* Shouldn't happen. */
......
g_signal_connect(shell, "response", G_CALLBACK(bribe_unit_response),
act_data(paction->id, actor->id,
0, punit->id, 0,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
g_signal_connect(shell, "response", G_CALLBACK(bribe_stack_response),
act_data(paction->id, actor->id,
0, 0, ptile->index,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
create_improvements_list(client.conn.playing, pcity,
act_data(paction->id,
actor->id, pcity->id, 0, 0,
0, 0, 0));
0, 0, 0, 0));
gtk_window_present(GTK_WINDOW(spy_sabotage_shell));
}
}
......
g_signal_connect(shell, "response", G_CALLBACK(incite_response),
act_data(paction->id, actor->id,
pcity->id, 0, 0,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
(target_unit) ? target_unit->id : IDENTITY_NUMBER_ZERO,
(target_tile) ? target_tile->index : TILE_INDEX_NONE,
/* No target_building or target_tech supplied. (Dec 2019) */
B_LAST, A_UNSET,
B_LAST, A_UNSET, -1,
target_extra ? target_extra->id : EXTRA_NONE);
/* Could be caused by the server failing to reply to a request for more
client/gui-gtk-4.0/menu.c
#include "game.h"
#include "government.h"
#include "road.h"
#include "specialist.h"
#include "unit.h"
/* client */
......
sub_target = extra_number(pextra);
}
break;
case ASTK_SPECIALIST:
{
struct specialist *pspec = g_object_get_data(G_OBJECT(action),
"end_specialist");
fc_assert_ret(nullptr != pspec);
sub_target = specialist_number(pspec);
}
break;
case ASTK_NONE:
sub_target = NO_TARGET;
break;
......
extra_name_translation(pextra));
} extra_type_iterate_end;
break;
case ASTK_SPECIALIST:
specialist_type_iterate(spc) {
struct specialist *pspec = specialist_by_number(spc);
CREATE_SUB_ITEM(pspec, "end_specialist",
specialist_plural_translation(pspec));
} specialist_type_iterate_end;
break;
case ASTK_NONE:
/* Should not be here. */
fc_assert(action_get_sub_target_kind(paction) != ASTK_NONE);
client/gui-gtk-5.0/action_dialog.c
#include "traderoutes.h"
#include "movement.h"
#include "research.h"
#include "specialist.h"
#include "unit.h"
#include "unitlist.h"
......
int target_building_id;
int target_tech_id;
int target_extra_id;
int target_specialist_id;
};
/* TODO: Maybe this should be in the dialog itself? */
......
int target_tile_id,
int target_building_id,
int target_tech_id,
int target_specialist_id,
int tgt_extra_id)
{
struct action_data *data = fc_malloc(sizeof(*data));
......
data->target_tile_id = target_tile_id;
data->target_building_id = target_building_id;
data->target_tech_id = target_tech_id;
data->target_specialist_id = target_specialist_id;
data->target_extra_id = tgt_extra_id;
return data;
......
failed = TRUE;
}
break;
case ASTK_SPECIALIST:
sub_target = args->target_specialist_id;
if (NULL == specialist_by_number(sub_target)) {
/* Did the ruleset change? */
failed = TRUE;
}
break;
case ASTK_NONE:
case ASTK_COUNT:
/* Shouldn't happen. */
......
g_signal_connect(shell, "response", G_CALLBACK(bribe_unit_response),
act_data(paction->id, actor->id,
0, punit->id, 0,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
g_signal_connect(shell, "response", G_CALLBACK(bribe_stack_response),
act_data(paction->id, actor->id,
0, 0, ptile->index,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
create_improvements_list(client.conn.playing, pcity,
act_data(paction->id,
actor->id, pcity->id, 0, 0,
0, 0, 0));
0, 0, 0, 0));
gtk_window_present(GTK_WINDOW(spy_sabotage_shell));
}
}
......
g_signal_connect(shell, "response", G_CALLBACK(incite_response),
act_data(paction->id, actor->id,
pcity->id, 0, 0,
0, 0, 0));
0, 0, 0, 0));
}
/**********************************************************************//**
......
(target_unit) ? target_unit->id : IDENTITY_NUMBER_ZERO,
(target_tile) ? target_tile->index : TILE_INDEX_NONE,
/* No target_building or target_tech supplied. (Dec 2019) */
B_LAST, A_UNSET,
B_LAST, A_UNSET, -1,
target_extra ? target_extra->id : EXTRA_NONE);
/* Could be caused by the server failing to reply to a request for more
client/gui-gtk-5.0/menu.c
#include "game.h"
#include "government.h"
#include "road.h"
#include "specialist.h"
#include "unit.h"
/* client */
......
sub_target = extra_number(pextra);
}
break;
case ASTK_SPECIALIST:
{
struct specialist *pspec = g_object_get_data(G_OBJECT(action),
"end_specialist");
fc_assert_ret(nullptr != pspec);
sub_target = specialist_number(pspec);
}
break;
case ASTK_NONE:
sub_target = NO_TARGET;
break;
......
extra_name_translation(pextra));
} extra_type_iterate_end;
break;
case ASTK_SPECIALIST:
specialist_type_iterate(spc) {
struct specialist *pspec = specialist_by_number(spc);
CREATE_SUB_ITEM(pspec, "end_specialist",
specialist_plural_translation(pspec));
} specialist_type_iterate_end;
break;
case ASTK_NONE:
/* Should not be here. */
fc_assert(action_get_sub_target_kind(paction) != ASTK_NONE);
client/gui-qt/dialogs.cpp
sub_target_id[ASTK_TECH] = A_UNSET;
sub_target_id[ASTK_EXTRA] = EXTRA_NONE;
sub_target_id[ASTK_EXTRA_NOT_THERE] = EXTRA_NONE;
sub_target_id[ASTK_SPECIALIST] = -1;
targeted_unit = nullptr;
// No buttons are added yet.
client/gui-qt/menu.cpp
#include "goto.h"
#include "name_translation.h"
#include "road.h"
#include "specialist.h"
#include "unit.h"
// client
......
extra_name_translation(pextra));
} extra_type_iterate_end;
break;
case ASTK_SPECIALIST:
specialist_type_iterate(spc) {
CREATE_SUB_ITEM(sub_target_menu, act_id, spc,
specialist_plural_translation(specialist_by_number(spc)));
} specialist_type_iterate_end;
break;
case ASTK_NONE:
// Should not be here.
fc_assert(action_get_sub_target_kind(paction) != ASTK_NONE);
client/gui-sdl2/action_dialog.c
#include "game.h"
#include "movement.h"
#include "research.h"
#include "specialist.h"
#include "traderoutes.h"
#include "unitlist.h"
......
failed = TRUE;
}
break;
case ASTK_SPECIALIST:
sub_target = diplomat_dlg->sub_target_id[ASTK_SPECIALIST];
if (nullptr == specialist_by_number(sub_target)) {
/* Did the ruleset change? */
failed = TRUE;
}
case ASTK_NONE:
case ASTK_COUNT:
/* Shouldn't happen. */
......
/* No target building or target tech supplied. (Feb 2020) */
diplomat_dlg->sub_target_id[ASTK_BUILDING] = B_LAST;
diplomat_dlg->sub_target_id[ASTK_TECH] = A_UNSET;
diplomat_dlg->sub_target_id[ASTK_SPECIALIST] = -1;
if (target_extra) {
diplomat_dlg->sub_target_id[ASTK_EXTRA] = extra_number(target_extra);
client/gui-sdl3/action_dialog.c
#include "game.h"
#include "movement.h"
#include "research.h"
#include "specialist.h"
#include "traderoutes.h"
#include "unitlist.h"
......
failed = TRUE;
}
break;
case ASTK_SPECIALIST:
sub_target = diplomat_dlg->sub_target_id[ASTK_SPECIALIST];
if (nullptr == specialist_by_number(sub_target)) {
/* Did the ruleset change? */
failed = TRUE;
}
case ASTK_NONE:
case ASTK_COUNT:
/* Shouldn't happen. */
......
/* No target building or target tech supplied. (Feb 2020) */
diplomat_dlg->sub_target_id[ASTK_BUILDING] = B_LAST;
diplomat_dlg->sub_target_id[ASTK_TECH] = A_UNSET;
diplomat_dlg->sub_target_id[ASTK_SPECIALIST] = -1;
if (target_extra) {
diplomat_dlg->sub_target_id[ASTK_EXTRA] = extra_number(target_extra);
common/actres.h
#define SPECENUM_VALUE3NAME N_("extras on")
#define SPECENUM_VALUE4 ASTK_EXTRA_NOT_THERE
#define SPECENUM_VALUE4NAME N_("create extras on")
#define SPECENUM_VALUE5 ASTK_SPECIALIST
#define SPECENUM_VALUE5NAME N_("specialist")
#define SPECENUM_COUNT ASTK_COUNT
#include "specenum_gen.h"
common/unit.c
#include "packets.h"
#include "player.h"
#include "road.h"
#include "specialist.h"
#include "tech.h"
#include "traderoutes.h"
#include "unitlist.h"
......
}
}
break;
case ASTK_SPECIALIST:
if (!specialist_by_number(orders[i].sub_target)) {
log_error("at index %d, cannot do %s without a target.", i,
action_id_rule_name(orders[i].action));
return FALSE;
}
break;
case ASTK_NONE:
/* No validation required. */
break;
server/actiontools.c
}
} extra_type_re_active_iterate_end;
break;
case ASTK_SPECIALIST:
/* Implement if a specialist sub targeted action becomes flexible */
fc_assert_ret_val(paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE,
NO_TARGET);
break;
case ASTK_COUNT:
/* Should not exist. */
fc_assert_ret_val(action_get_sub_target_kind(paction) != ASTK_COUNT,
server/savegame/savegame3.c
/* These take an extra. */
action_wants_extra = TRUE;
break;
case ASTK_SPECIALIST:
/* A valid specialist must be supplied. */
if (!loading->specialist.order[order_sub_tgt]) {
log_sg("Cannot find specialist %d for %s to become",
order_sub_tgt, unit_rule_name(punit));
order->sub_target = NO_TARGET;
} else {
order->sub_target = specialist_index(loading->specialist.order[order_sub_tgt]);
}
break;
case ASTK_NONE:
/* None of these can take a sub target. */
fc_assert_msg(order_sub_tgt == -1,
server/unithand.c
struct impr_type *sub_tgt_impr;
struct unit *punit = NULL;
struct city *pcity = NULL;
struct specialist *sub_tgt_spec = nullptr;
const struct civ_map *nmap = &(wld.map);
if (!action_id_exists(action_type)) {
......
}
sub_tgt_impr = improvement_by_number(sub_tgt_id);
sub_tgt_spec = specialist_by_number(sub_tgt_id);
/* Sub targets should now be assigned */
switch (paction->sub_target_kind) {
......
return FALSE;
}
break;
case ASTK_SPECIALIST:
if (sub_tgt_spec == nullptr) {
/* Missing sub target */
return FALSE;
}
break;
case ASTK_COUNT:
break;
}
    (1-1/1)