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 #876377 ยป 0002-Action-server-side-sub-target-assignment.patch

Sveinung Kvilhaugsvik, 2020-06-05 08:49 AM

View differences:

server/actiontools.c
return NULL;
}
/**********************************************************************//**
Find an sub target for the specified action.
**************************************************************************/
int action_sub_target_id_for_action(const struct action *paction,
struct unit *actor_unit)
{
const struct tile *tgt_tile = unit_tile(actor_unit);
fc_assert_ret_val(paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE,
NO_TARGET);
switch (action_get_sub_target_kind(paction)) {
case ASTK_NONE:
/* Should not be reached */
fc_assert_ret_val(action_get_sub_target_kind(paction) != ASTK_NONE,
NO_TARGET);
break;
case ASTK_BUILDING:
/* Implement if a building sub targeted action becomes flexible */
fc_assert_ret_val(paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE,
NO_TARGET);
break;
case ASTK_TECH:
/* Implement if a tech sub targeted action becomes flexible */
fc_assert_ret_val(paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE,
NO_TARGET);
break;
case ASTK_EXTRA:
case ASTK_EXTRA_NOT_THERE:
if (action_has_result(paction, ACTRES_PILLAGE)) {
/* Special treatment for "Pillage" */
struct extra_type *pextra;
enum unit_activity activity = action_get_activity(paction);
unit_assign_specific_activity_target(actor_unit, &activity, &pextra);
if (pextra != NULL) {
return extra_number(pextra);
}
}
extra_type_re_active_iterate(tgt_extra) {
if (action_prob_possible(action_prob_vs_tile(actor_unit, paction->id,
tgt_tile, tgt_extra))) {
/* The actor unit may be able to do this action to the target
* extra. */
return extra_number(tgt_extra);
}
} extra_type_re_active_iterate_end;
break;
case ASTK_COUNT:
/* Should not exist. */
fc_assert_ret_val(action_get_sub_target_kind(paction) != ASTK_COUNT,
NO_TARGET);
break;
}
return NO_TARGET;
}
/**********************************************************************//**
Returns the action auto performer that the specified cause can force the
specified actor to perform. Returns NULL if no such action auto performer
server/actiontools.h
const struct tile *target_tile,
bool accept_all_actions);
int action_sub_target_id_for_action(const struct action *paction,
struct unit *actor_unit);
const struct action_auto_perf *
action_auto_perf_unit_sel(const enum action_auto_perf_cause cause,
const struct unit *actor,
server/unithand.c
bool unit_perform_action(struct player *pplayer,
const int actor_id,
const int target_id,
const int sub_tgt_id,
const int sub_tgt_id_incoming,
const char *name,
const action_id action_type,
const enum action_requester requester)
{
struct action *paction;
int sub_tgt_id;
struct unit *actor_unit = player_unit_by_number(pplayer, actor_id);
struct tile *target_tile = index_to_tile(&(wld.map), target_id);
struct extra_type *target_extra;
......
return FALSE;
}
paction = action_by_number(action_type);
/* Server side sub target assignment */
if (paction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
&& sub_tgt_id_incoming == NO_TARGET) {
sub_tgt_id = action_sub_target_id_for_action(paction, actor_unit);
} else {
sub_tgt_id = sub_tgt_id_incoming;
}
if (sub_tgt_id >= 0 && sub_tgt_id < MAX_EXTRA_TYPES
&& sub_tgt_id != EXTRA_NONE) {
&& sub_tgt_id != NO_TARGET) {
target_extra = extra_by_number(sub_tgt_id);
fc_assert(!(target_extra->ruledit_disabled));
} else {
target_extra = NULL;
}
paction = action_by_number(action_type);
if (action_get_activity(paction) != ACTIVITY_LAST
&& unit_activity_needs_target_from_client(
action_get_activity(paction))
server/unittools.c
struct city *tgt_city;
struct unit *tgt_unit;
int tgt_id;
int sub_tgt_id;
struct extra_type *pextra;
if (punit->done_moving) {
......
return TRUE;
}
/* Server side sub target assignment */
if (oaction->target_complexity == ACT_TGT_COMPL_FLEXIBLE
&& order.sub_target == NO_TARGET) {
/* Try to find a sub target. */
sub_tgt_id = action_sub_target_id_for_action(oaction, punit);
} else {
/* The client should have specified a sub target if needed */
sub_tgt_id = order.sub_target;
}
/* Get a target extra at the target tile */
pextra = (sub_tgt_id == NO_TARGET ?
NULL :
extra_by_number(sub_tgt_id));
if (action_get_sub_target_kind(oaction) == ASTK_EXTRA_NOT_THERE
&& pextra != NULL
&& action_creates_extra(oaction, pextra)
......
performed = unit_perform_action(pplayer,
unitid,
tgt_id,
order.sub_target,
sub_tgt_id,
name,
order.action,
ACT_REQ_PLAYER);
......
case ASTK_EXTRA:
case ASTK_EXTRA_NOT_THERE:
/* Sub target is an extra. */
if (orders[i].sub_target == EXTRA_NONE
|| (orders[i].sub_target < 0
|| orders[i].sub_target >= game.control.num_extra_types)
|| !(pextra = extra_by_number(orders[i].sub_target))
|| pextra->ruledit_disabled) {
/* Target extra is invalid. */
log_error("at index %d, cannot do %s without a target.", i,
action_id_rule_name(orders[i].action));
return FALSE;
}
if (!(action_removes_extra(paction, pextra)
|| action_creates_extra(paction, pextra))) {
/* Target extra is irrelevant for the action. */
log_error("at index %d, cannot do %s to %s.", i,
action_id_rule_name(orders[i].action),
extra_rule_name(pextra));
return FALSE;
pextra = (!(orders[i].sub_target == NO_TARGET
|| (orders[i].sub_target < 0
|| (orders[i].sub_target
>= game.control.num_extra_types)))
? extra_by_number(orders[i].sub_target) : NULL);
fc_assert(pextra == NULL || !(pextra->ruledit_disabled));
if (pextra == NULL) {
if (paction->target_complexity != ACT_TGT_COMPL_FLEXIBLE) {
/* Target extra is invalid. */
log_error("at index %d, cannot do %s without a target.", i,
action_id_rule_name(orders[i].action));
return FALSE;
}
} else {
if (!(action_removes_extra(paction, pextra)
|| action_creates_extra(paction, pextra))) {
/* Target extra is irrelevant for the action. */
log_error("at index %d, cannot do %s to %s.", i,
action_id_rule_name(orders[i].action),
extra_rule_name(pextra));
return FALSE;
}
}
break;
case ASTK_NONE:
    (1-1/1)