2407 |
2407 |
}
|
2408 |
2408 |
|
2409 |
2409 |
/**********************************************************************//**
|
2410 |
|
Tell the client that the action it requested is illegal. This can be
|
2411 |
|
caused by the player (and therefore the client) not knowing that some
|
2412 |
|
condition of an action no longer is true.
|
|
2410 |
Punish a player for trying to perform an action that turned out to be
|
|
2411 |
illegal. The punishment, if any at all, is specified by the ruleset.
|
|
2412 |
@param pplayer the player to punish.
|
|
2413 |
@param information_revealed if finding out that the action is illegal
|
|
2414 |
reveals new information.
|
|
2415 |
@param act_unit the actor unit performing the action.
|
|
2416 |
@param stopped_action the illegal action.
|
|
2417 |
@param tgt_player the intended target of the action.
|
|
2418 |
@param requester who ordered the action performed?
|
|
2419 |
@return TRUE iff player was punished for trying to do the illegal action.
|
2413 |
2420 |
**************************************************************************/
|
2414 |
|
static void illegal_action(struct player *pplayer,
|
2415 |
|
struct unit *actor,
|
2416 |
|
action_id stopped_action,
|
2417 |
|
struct player *tgt_player,
|
2418 |
|
const struct tile *target_tile,
|
2419 |
|
const struct city *target_city,
|
2420 |
|
const struct unit *target_unit,
|
2421 |
|
bool disturb_player,
|
2422 |
|
const enum action_requester requester)
|
|
2421 |
static bool illegal_action_pay_price(struct player *pplayer,
|
|
2422 |
bool information_revealed,
|
|
2423 |
struct unit *act_unit,
|
|
2424 |
struct action *stopped_action,
|
|
2425 |
struct player *tgt_player,
|
|
2426 |
const enum action_requester requester)
|
2423 |
2427 |
{
|
2424 |
2428 |
int punishment_mp;
|
2425 |
2429 |
|
2426 |
|
/* Why didn't the game check before trying something illegal? Did a good
|
2427 |
|
* reason to not call is_action_enabled_unit_on...() appear? The game is
|
2428 |
|
* omniscient... */
|
2429 |
|
fc_assert(requester != ACT_REQ_RULES);
|
2430 |
|
|
2431 |
2430 |
/* Don't punish the player for something the game did. Don't tell the
|
2432 |
2431 |
* player that the rules required the game to try to do something
|
2433 |
2432 |
* illegal. */
|
2434 |
|
fc_assert_ret_msg((requester == ACT_REQ_PLAYER
|
2435 |
|
|| requester == ACT_REQ_SS_AGENT),
|
2436 |
|
"The player wasn't responsible for this.");
|
|
2433 |
fc_assert_ret_val_msg((requester == ACT_REQ_PLAYER
|
|
2434 |
|| requester == ACT_REQ_SS_AGENT),
|
|
2435 |
FALSE,
|
|
2436 |
"The player wasn't responsible for this.");
|
|
2437 |
|
|
2438 |
if (!information_revealed) {
|
|
2439 |
/* The player already had enough information to determine that this
|
|
2440 |
* action is illegal. Don't punish a client error or an accident. */
|
|
2441 |
return FALSE;
|
|
2442 |
}
|
2437 |
2443 |
|
2438 |
2444 |
/* The mistake may have a cost. */
|
2439 |
2445 |
punishment_mp = get_target_bonus_effects(NULL,
|
2440 |
|
unit_owner(actor),
|
|
2446 |
unit_owner(act_unit),
|
2441 |
2447 |
tgt_player,
|
2442 |
2448 |
NULL,
|
2443 |
2449 |
NULL,
|
2444 |
2450 |
NULL,
|
2445 |
|
actor,
|
2446 |
|
unit_type_get(actor),
|
|
2451 |
act_unit,
|
|
2452 |
unit_type_get(act_unit),
|
2447 |
2453 |
NULL,
|
2448 |
2454 |
NULL,
|
2449 |
|
action_by_number(stopped_action),
|
|
2455 |
stopped_action,
|
2450 |
2456 |
EFT_ILLEGAL_ACTION_MOVE_COST);
|
2451 |
2457 |
|
2452 |
|
actor->moves_left = MAX(0, actor->moves_left - punishment_mp);
|
|
2458 |
/* Stay in range */
|
|
2459 |
punishment_mp = MAX(0, punishment_mp);
|
2453 |
2460 |
|
2454 |
|
send_unit_info(NULL, actor);
|
|
2461 |
/* Punish the unit's move fragments. */
|
|
2462 |
act_unit->moves_left = MAX(0, act_unit->moves_left - punishment_mp);
|
|
2463 |
send_unit_info(NULL, act_unit);
|
2455 |
2464 |
|
2456 |
|
if (punishment_mp) {
|
|
2465 |
if (punishment_mp != 0) {
|
2457 |
2466 |
/* The player probably wants to be disturbed if his unit was punished
|
2458 |
2467 |
* with the loss of movement points. */
|
2459 |
|
notify_player(pplayer, unit_tile(actor),
|
|
2468 |
notify_player(pplayer, unit_tile(act_unit),
|
2460 |
2469 |
E_UNIT_ILLEGAL_ACTION, ftc_server,
|
2461 |
2470 |
/* TRANS: Spy ... movement point text that may include
|
2462 |
2471 |
* fractions. */
|
2463 |
2472 |
_("Your %s lost %s MP for attempting an illegal action."),
|
2464 |
|
unit_name_translation(actor),
|
|
2473 |
unit_name_translation(act_unit),
|
2465 |
2474 |
move_points_text(punishment_mp, TRUE));
|
2466 |
2475 |
}
|
2467 |
2476 |
|
2468 |
|
if (disturb_player || punishment_mp) {
|
|
2477 |
return punishment_mp != 0;
|
|
2478 |
}
|
|
2479 |
|
|
2480 |
/**********************************************************************//**
|
|
2481 |
Tell the client that the action it requested is illegal. This can be
|
|
2482 |
caused by the player (and therefore the client) not knowing that some
|
|
2483 |
condition of an action no longer is true.
|
|
2484 |
**************************************************************************/
|
|
2485 |
static void illegal_action(struct player *pplayer,
|
|
2486 |
struct unit *actor,
|
|
2487 |
action_id stopped_action_id,
|
|
2488 |
struct player *tgt_player,
|
|
2489 |
const struct tile *target_tile,
|
|
2490 |
const struct city *target_city,
|
|
2491 |
const struct unit *target_unit,
|
|
2492 |
bool disturb_player,
|
|
2493 |
const enum action_requester requester)
|
|
2494 |
{
|
|
2495 |
bool information_revealed;
|
|
2496 |
bool was_punished;
|
|
2497 |
|
|
2498 |
struct action *stopped_action = action_by_number(stopped_action_id);
|
|
2499 |
|
|
2500 |
/* Why didn't the game check before trying something illegal? Did a good
|
|
2501 |
* reason to not call is_action_enabled_unit_on...() appear? The game is
|
|
2502 |
* omniscient... */
|
|
2503 |
fc_assert(requester != ACT_REQ_RULES);
|
|
2504 |
|
|
2505 |
|
|
2506 |
information_revealed = action_prob_possible(action_prob_unit_vs_tgt(
|
|
2507 |
stopped_action,
|
|
2508 |
actor,
|
|
2509 |
target_city, target_unit,
|
|
2510 |
target_tile, NULL));
|
|
2511 |
|
|
2512 |
was_punished = illegal_action_pay_price(pplayer, information_revealed,
|
|
2513 |
actor, stopped_action, tgt_player,
|
|
2514 |
requester);
|
|
2515 |
|
|
2516 |
if (disturb_player || was_punished) {
|
2469 |
2517 |
/* This is a foreground request or the actor unit was punished with
|
2470 |
2518 |
* the loss of movement points. */
|
2471 |
|
illegal_action_msg(pplayer, E_UNIT_ILLEGAL_ACTION,
|
2472 |
|
actor, stopped_action,
|
|
2519 |
illegal_action_msg(pplayer, (information_revealed
|
|
2520 |
? E_UNIT_ILLEGAL_ACTION : E_BAD_COMMAND),
|
|
2521 |
actor, stopped_action_id,
|
2473 |
2522 |
target_tile, target_city, target_unit);
|
2474 |
2523 |
}
|
2475 |
2524 |
}
|
2476 |
|
-
|