1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
42 #include "specialist.h"
43 #include "traderoutes.h"
47 /* common/scriptcore */
48 #include "luascript_types.h"
51 #include "actiontools.h"
52 #include "barbarian.h"
53 #include "citizenshand.h"
54 #include "citytools.h"
56 #include "diplomats.h"
60 #include "sanitycheck.h"
61 #include "spacerace.h"
63 #include "techtools.h"
64 #include "unittools.h"
67 #include "autoexplorer.h"
68 #include "autosettlers.h"
70 /* server/scripting */
71 #include "script_server.h"
75 /* An explanation why an action isn't enabled. */
77 /* The kind of reason why an action isn't enabled. */
81 /* The city without the needed capacity- */
82 struct city
*capacity_city
;
84 /* The bad terrain in question. */
85 struct terrain
*no_act_terrain
;
87 /* The player to advice declaring war on. */
88 struct player
*no_war_with
;
90 /* The nation that can't be involved. */
91 struct nation_type
*no_act_nation
;
93 /* The action that blocks the action. */
94 struct action
*blocker
;
96 /* The required distance. */
101 static void illegal_action(struct player
*pplayer
,
103 enum gen_action stopped_action
,
104 struct player
*tgt_player
,
105 const struct tile
*target_tile
,
106 const struct city
*target_city
,
107 const struct unit
*target_unit
,
108 const enum action_requester requester
);
109 static bool city_add_unit(struct player
*pplayer
, struct unit
*punit
,
111 static bool city_build(struct player
*pplayer
, struct unit
*punit
,
112 struct tile
*ptile
, const char *name
);
113 static bool do_unit_establish_trade(struct player
*pplayer
,
115 struct city
*pcity_dest
,
118 static bool unit_do_recycle(struct player
*pplayer
,
121 static bool do_unit_help_build_wonder(struct player
*pplayer
,
123 struct city
*pcity_dest
);
124 static bool unit_bombard(struct unit
*punit
, struct tile
*ptile
);
125 static bool unit_nuke(struct player
*pplayer
, struct unit
*punit
,
126 struct tile
*def_tile
);
127 static bool unit_do_destroy_city(struct player
*act_player
,
128 struct unit
*act_unit
,
129 struct city
*tgt_city
);
130 static bool do_unit_disband(struct player
*pplayer
, struct unit
*punit
);
131 static bool do_unit_change_homecity(struct unit
*punit
,
133 static bool do_unit_upgrade(struct player
*pplayer
,
134 struct unit
*punit
, struct city
*pcity
,
135 enum action_requester ordered_by
);
136 static bool do_attack(struct unit
*actor_unit
, struct tile
*target_tile
,
137 const struct action
*paction
);
138 static bool do_unit_conquer_city(struct player
*act_player
,
139 struct unit
*act_unit
,
140 struct city
*tgt_city
,
141 struct action
*paction
);
143 /**************************************************************************
144 Upgrade all units of a given type.
145 **************************************************************************/
146 void handle_unit_type_upgrade(struct player
*pplayer
, Unit_type_id uti
)
148 struct unit_type
*to_unittype
;
149 struct unit_type
*from_unittype
= utype_by_number(uti
);
150 int number_of_upgraded_units
= 0;
152 if (NULL
== from_unittype
) {
153 /* Probably died or bribed. */
154 log_verbose("handle_unit_type_upgrade() invalid unit type %d", uti
);
158 to_unittype
= can_upgrade_unittype(pplayer
, from_unittype
);
160 notify_player(pplayer
, NULL
, E_BAD_COMMAND
, ftc_server
,
161 _("Illegal packet, can't upgrade %s (yet)."),
162 utype_name_translation(from_unittype
));
167 * Try to upgrade units. The order we upgrade in is arbitrary (if
168 * the player really cared they should have done it manually).
170 conn_list_do_buffer(pplayer
->connections
);
171 unit_list_iterate(pplayer
->units
, punit
) {
172 if (unit_type_get(punit
) == from_unittype
) {
173 struct city
*pcity
= tile_city(unit_tile(punit
));
175 if (is_action_enabled_unit_on_city(ACTION_UPGRADE_UNIT
, punit
, pcity
)
176 && unit_perform_action(pplayer
, punit
->id
, pcity
->id
, 0, "",
177 ACTION_UPGRADE_UNIT
, ACT_REQ_SS_AGENT
)) {
178 number_of_upgraded_units
++;
179 } else if (UU_NO_MONEY
== unit_upgrade_test(punit
, FALSE
)) {
183 } unit_list_iterate_end
;
184 conn_list_do_unbuffer(pplayer
->connections
);
186 /* Alert the player about what happened. */
187 if (number_of_upgraded_units
> 0) {
188 const int cost
= unit_upgrade_price(pplayer
, from_unittype
, to_unittype
);
189 notify_player(pplayer
, NULL
, E_UNIT_UPGRADED
, ftc_server
,
190 /* FIXME: plurality of number_of_upgraded_units ignored!
191 * (Plurality of unit names is messed up anyway.) */
192 /* TRANS: "2 Musketeers upgraded to Riflemen for 100 gold."
193 * Plurality is in gold (second %d), not units. */
194 PL_("%d %s upgraded to %s for %d gold.",
195 "%d %s upgraded to %s for %d gold.",
196 cost
* number_of_upgraded_units
),
197 number_of_upgraded_units
,
198 utype_name_translation(from_unittype
),
199 utype_name_translation(to_unittype
),
200 cost
* number_of_upgraded_units
);
201 send_player_info_c(pplayer
, pplayer
->connections
);
203 notify_player(pplayer
, NULL
, E_UNIT_UPGRADED
, ftc_server
,
204 _("No units could be upgraded."));
208 /**************************************************************************
209 Upgrade the unit to a newer unit type.
211 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
212 this returns TRUE, unit may have died during the action.
213 **************************************************************************/
214 static bool do_unit_upgrade(struct player
*pplayer
,
215 struct unit
*punit
, struct city
*pcity
,
216 enum action_requester ordered_by
)
220 if (UU_OK
== unit_upgrade_info(punit
, buf
, sizeof(buf
))) {
221 struct unit_type
*from_unit
= unit_type_get(punit
);
222 struct unit_type
*to_unit
= can_upgrade_unittype(pplayer
, from_unit
);
224 transform_unit(punit
, to_unit
, FALSE
);
225 send_player_info_c(pplayer
, pplayer
->connections
);
227 if (ordered_by
== ACT_REQ_PLAYER
) {
228 int cost
= unit_upgrade_price(pplayer
, from_unit
, to_unit
);
230 notify_player(pplayer
, unit_tile(punit
), E_UNIT_UPGRADED
, ftc_server
,
231 PL_("%s upgraded to %s for %d gold.",
232 "%s upgraded to %s for %d gold.", cost
),
233 utype_name_translation(from_unit
),
240 if (ordered_by
== ACT_REQ_PLAYER
) {
241 notify_player(pplayer
, unit_tile(punit
), E_UNIT_UPGRADED
, ftc_server
,
249 /**************************************************************************
250 Capture all the units at pdesttile using punit.
252 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
253 this returns TRUE, unit may have died during the action.
254 **************************************************************************/
255 static bool do_capture_units(struct player
*pplayer
,
257 struct tile
*pdesttile
)
260 char capturer_link
[MAX_LEN_LINK
];
261 const char *capturer_nation
= nation_plural_for_player(pplayer
);
262 bv_unit_types unique_on_tile
;
264 /* Sanity check: The actor still exists. */
265 fc_assert_ret_val(pplayer
, FALSE
);
266 fc_assert_ret_val(punit
, FALSE
);
268 /* Sanity check: make sure that the capture won't result in the actor
269 * ending up with more than one unit of each unique unit type. */
270 BV_CLR_ALL(unique_on_tile
);
271 unit_list_iterate(pdesttile
->units
, to_capture
) {
272 bool unique_conflict
= FALSE
;
274 /* Check what the player already has. */
275 if (utype_player_already_has_this_unique(pplayer
,
276 unit_type_get(to_capture
))) {
277 /* The player already has a unit of this kind. */
278 unique_conflict
= TRUE
;
281 if (utype_has_flag(unit_type_get(to_capture
), UTYF_UNIQUE
)) {
282 /* The type of the units at the tile must also be checked. Two allied
283 * players can both have their unique unit at the same tile.
284 * Capturing them both would give the actor two units of a kind that
285 * is supposed to be unique. */
287 if (BV_ISSET(unique_on_tile
, utype_index(unit_type_get(to_capture
)))) {
288 /* There is another unit of the same kind at this tile. */
289 unique_conflict
= TRUE
;
291 /* Remember the unit type in case another unit of the same kind is
292 * encountered later. */
293 BV_SET(unique_on_tile
, utype_index(unit_type_get(to_capture
)));
297 if (unique_conflict
) {
298 log_debug("capture units: already got unique unit");
299 notify_player(pplayer
, pdesttile
, E_UNIT_ILLEGAL_ACTION
, ftc_server
,
300 /* TRANS: You can only have one Leader. */
301 _("You can only have one %s."),
302 unit_link(to_capture
));
306 } unit_list_iterate_end
;
308 /* N.B: unit_link() always returns the same pointer. */
309 sz_strlcpy(capturer_link
, unit_link(punit
));
311 pcity
= tile_city(pdesttile
);
312 unit_list_iterate(pdesttile
->units
, to_capture
) {
313 struct player
*uplayer
= unit_owner(to_capture
);
314 const char *victim_link
;
316 unit_owner(to_capture
)->score
.units_lost
++;
317 to_capture
= unit_change_owner(to_capture
, pplayer
,
318 (game
.server
.homecaughtunits
320 : IDENTITY_NUMBER_ZERO
),
322 /* As unit_change_owner() currently remove the old unit and
323 * replace by a new one (with a new id), we want to make link to
325 victim_link
= unit_link(to_capture
);
328 notify_player(pplayer
, pdesttile
, E_MY_DIPLOMAT_BRIBE
, ftc_server
,
329 /* TRANS: <unit> ... <unit> */
330 _("Your %s succeeded in capturing the %s %s."),
331 capturer_link
, nation_adjective_for_player(uplayer
),
333 notify_player(uplayer
, pdesttile
,
334 E_ENEMY_DIPLOMAT_BRIBE
, ftc_server
,
335 /* TRANS: <unit> ... <Poles> */
336 _("Your %s was captured by the %s."),
337 victim_link
, capturer_nation
);
339 /* May cause an incident */
340 action_id_consequence_success(ACTION_CAPTURE_UNITS
, pplayer
,
341 unit_owner(to_capture
),
342 pdesttile
, victim_link
);
345 /* The captured unit is in a city. Bounce it. */
346 bounce_unit(to_capture
, TRUE
);
348 } unit_list_iterate_end
;
350 /* Subtract movement point from capturer */
351 punit
->moves_left
-= SINGLE_MOVE
;
352 if (punit
->moves_left
< 0) {
353 punit
->moves_left
= 0;
356 send_unit_info(NULL
, punit
);
361 /**************************************************************************
362 Expel the target unit to his owner's capital.
364 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
365 this returns TRUE, unit may have died during the action.
366 **************************************************************************/
367 static bool do_expel_unit(struct player
*pplayer
,
371 char target_link
[MAX_LEN_LINK
];
372 struct player
*uplayer
;
373 struct tile
*target_tile
;
376 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
377 * the caller? Check in the code that emits the signal. */
378 fc_assert_ret_val(target
, FALSE
);
380 uplayer
= unit_owner(target
);
382 /* A unit is supposed to have an owner. */
383 fc_assert_ret_val(uplayer
, FALSE
);
385 /* Maybe it didn't survive the Lua call back. Why wasn't this caught by
386 * the caller? Check in the code that emits the signal. */
387 fc_assert_ret_val(actor
, FALSE
);
389 /* Where is the actor player? */
390 fc_assert_ret_val(pplayer
, FALSE
);
392 /* The price of attempting an expulsion is a single move. Applies before
393 * the player is told if the target has a capital. */
394 actor
->moves_left
= MAX(0, actor
->moves_left
- SINGLE_MOVE
);
395 send_unit_info(NULL
, actor
);
397 target_tile
= unit_tile(target
);
399 /* Expel the target unit to his owner's capital. */
400 pcity
= player_capital(uplayer
);
402 /* N.B: unit_link() always returns the same pointer. */
403 sz_strlcpy(target_link
, unit_link(target
));
406 /* No where to send the expelled unit. */
408 /* Notify the actor player. */
409 notify_player(pplayer
, target_tile
, E_UNIT_ACTION_FAILED
, ftc_server
,
410 /* TRANS: <Poles> <Spy> */
411 _("The %s don't have a capital to expel their %s to."),
412 nation_plural_for_player(uplayer
), target_link
);
414 /* Nothing more could be done. */
418 /* Please review the code below and above (including the strings sent to
419 * the players) before allowing expulsion to non capital cities. */
420 fc_assert(is_capital(pcity
));
422 /* Notify everybody involved. */
423 notify_player(pplayer
, target_tile
, E_UNIT_DID_EXPEL
, ftc_server
,
424 /* TRANS: <Border Patrol> ... <Spy> */
425 _("Your %s succeeded in expelling the %s %s."),
426 unit_link(actor
), nation_adjective_for_player(uplayer
),
428 notify_player(uplayer
, target_tile
, E_UNIT_WAS_EXPELLED
, ftc_server
,
429 /* TRANS: <unit> ... <Poles> */
430 _("Your %s was expelled by the %s."),
431 target_link
, nation_plural_for_player(pplayer
));
433 /* Being expelled destroys all remaining movement. */
434 if (!teleport_unit_to_city(target
, pcity
, -1, FALSE
)) {
435 log_error("Bug in unit expulsion: unit can't teleport.");
440 /* This may cause a diplomatic incident */
441 action_id_consequence_success(ACTION_EXPEL_UNIT
, pplayer
, uplayer
,
442 target_tile
, target_link
);
444 /* Mission accomplished. */
448 /**************************************************************************
449 Restore some of the target unit's hit points.
451 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
452 this returns TRUE, unit may have died during the action.
453 **************************************************************************/
454 static bool do_heal_unit(struct player
*act_player
,
455 struct unit
*act_unit
,
456 struct unit
*tgt_unit
)
460 struct player
*tgt_player
;
461 struct tile
*tgt_tile
;
463 /* Sanity checks: got all the needed input. */
464 fc_assert_ret_val(act_player
, FALSE
);
465 fc_assert_ret_val(act_unit
, FALSE
);
466 fc_assert_ret_val(tgt_unit
, FALSE
);
468 /* The target unit can't have more HP than this. */
469 tgt_hp_max
= unit_type_get(tgt_unit
)->hp
;
471 /* Sanity check: target isn't at full health and can therefore can be
473 fc_assert_ret_val(tgt_unit
->hp
< tgt_hp_max
, FALSE
);
475 /* Fetch the target unit's owner. */
476 tgt_player
= unit_owner(tgt_unit
);
477 fc_assert_ret_val(tgt_player
, FALSE
);
479 /* Fetch the target unit's tile. */
480 tgt_tile
= unit_tile(tgt_unit
);
481 fc_assert_ret_val(tgt_tile
, FALSE
);
483 /* The max amount of HP that can be added. */
484 healing_limit
= tgt_hp_max
/ 4;
486 /* Heal the target unit. */
487 tgt_unit
->hp
= MIN(tgt_unit
->hp
+ healing_limit
, tgt_hp_max
);
488 send_unit_info(NULL
, tgt_unit
);
490 /* Healing a unit spends the actor's movement. */
491 act_unit
->moves_left
= 0;
492 send_unit_info(NULL
, act_unit
);
494 /* This may have diplomatic consequences. */
495 action_id_consequence_success(ACTION_HEAL_UNIT
, act_player
, tgt_player
,
496 tgt_tile
, unit_link(tgt_unit
));
501 /**************************************************************************
502 Returns TRUE iff the player is able to change his diplomatic
503 relationship to the other player to war.
505 Note that the player can't declare war on someone he already is at war
507 **************************************************************************/
508 static bool rel_may_become_war(const struct player
*pplayer
,
509 const struct player
*oplayer
)
511 enum diplstate_type ds
;
513 fc_assert_ret_val(pplayer
, FALSE
);
514 fc_assert_ret_val(oplayer
, FALSE
);
516 ds
= player_diplstate_get(pplayer
, oplayer
)->type
;
518 /* The player can't declare war on someone he already is at war with. */
520 /* The player can't declare war on a teammate or on himself. */
521 && ds
!= DS_TEAM
&& pplayer
!= oplayer
;
524 /**************************************************************************
525 Returns the first player that may enable the specified action if war is
528 Helper for need_war_player(). Use it in stead.
529 **************************************************************************/
530 static struct player
*need_war_player_hlp(const struct unit
*actor
,
532 const struct tile
*target_tile
,
533 const struct city
*target_city
,
534 const struct unit
*target_unit
)
536 if (action_id_get_actor_kind(act
) != AAK_UNIT
) {
537 /* No unit can ever do this action so it isn't relevant. */
541 if (!unit_can_do_action(actor
, act
)) {
542 /* The unit can't do the action no matter if there is war or not. */
546 /* Look for hard coded war requirements that can't be an action enabler
548 switch ((enum gen_action
)act
) {
552 /* Target is tile or unit stack but a city (or unit) can block it. */
553 if ((act
!= ACTION_NUKE
|| unit_tile(actor
) != target_tile
)
555 /* This isn't nuking the actor's own tile so hard coded restrictions
561 if ((tcity
= tile_city(target_tile
))
562 && rel_may_become_war(unit_owner(actor
), city_owner(tcity
))) {
563 return city_owner(tcity
);
566 if ((tunit
= is_non_attack_unit_tile(target_tile
, unit_owner(actor
)))
567 && rel_may_become_war(unit_owner(actor
), unit_owner(tunit
))) {
568 return unit_owner(tunit
);
573 case ACTION_ESTABLISH_EMBASSY
:
574 case ACTION_ESTABLISH_EMBASSY_STAY
:
575 case ACTION_SPY_INVESTIGATE_CITY
:
576 case ACTION_INV_CITY_SPEND
:
577 case ACTION_SPY_POISON
:
578 case ACTION_SPY_STEAL_GOLD
:
579 case ACTION_SPY_SABOTAGE_CITY
:
580 case ACTION_SPY_TARGETED_SABOTAGE_CITY
:
581 case ACTION_SPY_STEAL_TECH
:
582 case ACTION_SPY_TARGETED_STEAL_TECH
:
583 case ACTION_SPY_INCITE_CITY
:
584 case ACTION_SPY_INCITE_CITY_ESC
:
585 case ACTION_TRADE_ROUTE
:
586 case ACTION_MARKETPLACE
:
587 case ACTION_HELP_WONDER
:
588 case ACTION_SPY_BRIBE_UNIT
:
589 case ACTION_SPY_SABOTAGE_UNIT
:
590 case ACTION_CAPTURE_UNITS
: /* Only foreign is a hard req. */
591 case ACTION_FOUND_CITY
:
592 case ACTION_JOIN_CITY
:
593 case ACTION_STEAL_MAPS
:
594 case ACTION_SPY_NUKE
:
595 case ACTION_SPY_NUKE_ESC
:
596 case ACTION_DESTROY_CITY
:
597 case ACTION_EXPEL_UNIT
:
598 case ACTION_RECYCLE_UNIT
:
599 case ACTION_DISBAND_UNIT
:
600 case ACTION_HOME_CITY
:
601 case ACTION_UPGRADE_UNIT
:
602 case ACTION_PARADROP
:
604 case ACTION_HEAL_UNIT
:
605 case ACTION_CONQUER_CITY
:
606 /* No special help. */
610 fc_assert(act
!= ACTION_COUNT
);
614 /* Look for war requirements from the action enablers. */
615 if (can_utype_do_act_if_tgt_diplrel(unit_type_get(actor
),
616 act
, DS_WAR
, FALSE
)) {
617 /* The unit can do the action even if there isn't war. */
621 switch (action_id_get_target_kind(act
)) {
623 if (target_city
== NULL
) {
624 /* No target city. */
628 if (rel_may_become_war(unit_owner(actor
), city_owner(target_city
))) {
629 return city_owner(target_city
);
633 if (target_unit
== NULL
) {
634 /* No target unit. */
638 if (rel_may_become_war(unit_owner(actor
), unit_owner(target_unit
))) {
639 return unit_owner(target_unit
);
643 if (target_tile
== NULL
) {
644 /* No target units since no target tile. */
648 unit_list_iterate(target_tile
->units
, tunit
) {
649 if (rel_may_become_war(unit_owner(actor
), unit_owner(tunit
))) {
650 return unit_owner(tunit
);
652 } unit_list_iterate_end
;
655 if (target_tile
== NULL
) {
656 /* No target tile. */
660 if (rel_may_become_war(unit_owner(actor
), tile_owner(target_tile
))) {
661 return tile_owner(target_tile
);
665 /* Can't declare war on itself. */
669 /* Nothing to check. */
670 fc_assert(action_id_get_target_kind(act
) != ATK_COUNT
);
674 /* Declaring war won't enable the specified action. */
678 /**************************************************************************
679 Returns the first player that may enable the specified action if war is
680 declared. If the specified action is ACTION_ANY the first player that
681 may enable any action at all if war is declared will be returned.
682 **************************************************************************/
683 static struct player
*need_war_player(const struct unit
*actor
,
685 const struct tile
*target_tile
,
686 const struct city
*target_city
,
687 const struct unit
*target_unit
)
689 if (action_id
== ACTION_ANY
) {
690 /* Any action at all will do. */
691 action_iterate(act
) {
692 struct player
*war_player
;
694 war_player
= need_war_player_hlp(actor
, act
,
695 target_tile
, target_city
,
698 if (war_player
!= NULL
) {
699 /* Declaring war on this player may enable this action. */
702 } action_iterate_end
;
704 /* No action at all may be enabled by declaring war. */
707 /* Look for the specified action. */
708 return need_war_player_hlp(actor
, action_id
,
709 target_tile
, target_city
,
714 /**************************************************************************
715 Returns TRUE iff the specified terrain type blocks the specified action.
717 If the "action" is ACTION_ANY all actions are checked.
718 **************************************************************************/
719 static bool does_terrain_block_action(const int action_id
,
721 struct unit
*actor_unit
,
722 struct terrain
*pterrain
)
724 if (action_id
== ACTION_ANY
) {
725 /* Any action is OK. */
726 action_iterate(alt_act
) {
727 if (utype_can_do_action(unit_type_get(actor_unit
), alt_act
)
728 && !does_terrain_block_action(alt_act
, is_target
,
729 actor_unit
, pterrain
)) {
730 /* Only one action has to be possible. */
733 } action_iterate_end
;
735 /* No action enabled. */
739 /* ACTION_ANY is handled above. */
740 fc_assert_ret_val(action_id_exists(action_id
), FALSE
);
742 action_enabler_list_iterate(action_enablers_for_action(action_id
),
744 if (requirement_fulfilled_by_terrain(pterrain
,
745 (is_target
? &enabler
->target_reqs
: &enabler
->actor_reqs
))
746 && requirement_fulfilled_by_unit_type(unit_type_get(actor_unit
),
747 &enabler
->actor_reqs
)) {
748 /* This terrain kind doesn't block this action enabler. */
751 } action_enabler_list_iterate_end
;
756 /**************************************************************************
757 Returns TRUE iff the specified nation blocks the specified action.
759 If the "action" is ACTION_ANY all actions are checked.
760 **************************************************************************/
761 static bool does_nation_block_action(const int action_id
,
763 struct unit
*actor_unit
,
764 struct nation_type
*pnation
)
766 if (action_id
== ACTION_ANY
) {
767 /* Any action is OK. */
768 action_iterate(alt_act
) {
769 if (utype_can_do_action(unit_type_get(actor_unit
), alt_act
)
770 && !does_nation_block_action(alt_act
, is_target
,
771 actor_unit
, pnation
)) {
772 /* Only one action has to be possible. */
775 } action_iterate_end
;
777 /* No action enabled. */
781 /* ACTION_ANY is handled above. */
782 fc_assert_ret_val(action_id_exists(action_id
), FALSE
);
784 action_enabler_list_iterate(action_enablers_for_action(action_id
),
786 if (requirement_fulfilled_by_nation(pnation
,
787 (is_target
? &enabler
->target_reqs
788 : &enabler
->actor_reqs
))
789 && requirement_fulfilled_by_unit_type(unit_type_get(actor_unit
),
790 &enabler
->actor_reqs
)) {
791 /* This nation doesn't block this action enabler. */
794 } action_enabler_list_iterate_end
;
799 /**************************************************************************
800 Returns an explaination why punit can't perform the specified action
801 based on the current game state.
802 **************************************************************************/
803 static struct ane_expl
*expl_act_not_enabl(struct unit
*punit
,
805 const struct tile
*target_tile
,
806 const struct city
*target_city
,
807 const struct unit
*target_unit
)
809 struct player
*must_war_player
;
810 struct action
*blocker
;
811 struct player
*tgt_player
= NULL
;
812 struct ane_expl
*explnat
= fc_malloc(sizeof(struct ane_expl
));
813 bool can_exist
= can_unit_exist_at_tile(&(wld
.map
), punit
, unit_tile(punit
));
814 bool on_native
= is_native_tile(unit_type_get(punit
), unit_tile(punit
));
817 /* Not know yet. (Initialize before the below check.) */
818 explnat
->kind
= ANEK_UNKNOWN
;
820 if (action_id
!= ACTION_ANY
) {
821 /* A specific action should have a suitable target. */
822 switch (action_id_get_target_kind(action_id
)) {
824 if (target_city
== NULL
) {
825 explnat
->kind
= ANEK_MISSING_TARGET
;
829 if (target_unit
== NULL
) {
830 explnat
->kind
= ANEK_MISSING_TARGET
;
835 if (target_tile
== NULL
) {
836 explnat
->kind
= ANEK_MISSING_TARGET
;
840 /* No other target. */
843 fc_assert(action_id_get_target_kind(action_id
) != ATK_COUNT
);
848 if (explnat
->kind
== ANEK_MISSING_TARGET
) {
849 /* No point continuing. */
853 if (action_id
== ACTION_ANY
) {
854 /* Find the target player of some actions. */
856 /* Individual city targets have the highest priority. */
857 tgt_player
= city_owner(target_city
);
858 } else if (target_unit
) {
859 /* Individual unit targets have the next priority. */
860 tgt_player
= unit_owner(target_unit
);
861 } else if (target_tile
) {
862 /* Tile targets have the lowest priority. */
863 tgt_player
= tile_owner(target_tile
);
866 /* Find the target player of this action. */
867 switch (action_id_get_target_kind(action_id
)) {
869 tgt_player
= city_owner(target_city
);
872 tgt_player
= unit_owner(target_unit
);
875 tgt_player
= tile_owner(target_tile
);
878 /* A unit stack may contain units with multiple owners. Pick the
881 && unit_list_size(target_tile
->units
) > 0) {
882 tgt_player
= unit_owner(unit_list_get(target_tile
->units
, 0));
886 /* A unit acting against itself. */
887 tgt_player
= unit_owner(punit
);
890 fc_assert(action_id_get_target_kind(action_id
) != ATK_COUNT
);
896 case ACTION_FOUND_CITY
:
897 /* Detects that the target is closer to a city than citymindist allows.
898 * Detects that the target tile is claimed by a foreigner even when it
899 * is legal to found a city on an unclaimed or domestic tile. */
900 action_custom
= city_build_here_test(target_tile
, punit
);
903 action_custom
= test_unit_can_airlift_to(NULL
, punit
, target_city
);
906 if (target_tile
!= unit_tile(punit
)) {
907 /* unit_attack_units_at_tile_result() matters for neighbor tiles. */
908 action_custom
= unit_attack_units_at_tile_result(punit
, target_tile
);
910 action_custom
= ATT_OK
;
914 action_custom
= unit_attack_units_at_tile_result(punit
, target_tile
);
916 case ACTION_CONQUER_CITY
:
918 action_custom
= unit_move_to_tile_test(&(wld
.map
), punit
,
921 city_tile(target_city
),
924 action_custom
= MR_OK
;
932 if (!unit_can_do_action(punit
, action_id
)) {
933 explnat
->kind
= ANEK_ACTOR_UNIT
;
934 } else if (action_id
== ACTION_FOUND_CITY
935 && tile_city(target_tile
)) {
936 explnat
->kind
= ANEK_BAD_TARGET
;
937 } else if ((!can_exist
938 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
939 USP_LIVABLE_TILE
, FALSE
))
941 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
942 USP_LIVABLE_TILE
, TRUE
))) {
943 explnat
->kind
= ANEK_BAD_TERRAIN_ACT
;
944 explnat
->no_act_terrain
= tile_terrain(unit_tile(punit
));
945 } else if ((!on_native
946 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
947 USP_NATIVE_TILE
, FALSE
))
949 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
950 USP_NATIVE_TILE
, TRUE
))) {
951 explnat
->kind
= ANEK_BAD_TERRAIN_ACT
;
952 explnat
->no_act_terrain
= tile_terrain(unit_tile(punit
));
954 && does_terrain_block_action(action_id
, FALSE
,
955 punit
, tile_terrain(unit_tile(punit
)))) {
956 /* No action enabler allows acting against this terrain kind. */
957 explnat
->kind
= ANEK_BAD_TERRAIN_ACT
;
958 explnat
->no_act_terrain
= tile_terrain(unit_tile(punit
));
959 } else if (action_id
== ACTION_FOUND_CITY
961 && terrain_has_flag(tile_terrain(target_tile
),
963 explnat
->kind
= ANEK_BAD_TERRAIN_TGT
;
964 explnat
->no_act_terrain
= tile_terrain(target_tile
);
965 } else if (target_tile
966 && does_terrain_block_action(action_id
, TRUE
,
967 punit
, tile_terrain(target_tile
))) {
968 /* No action enabler allows acting against this terrain kind. */
969 explnat
->kind
= ANEK_BAD_TERRAIN_TGT
;
970 explnat
->no_act_terrain
= tile_terrain(target_tile
);
971 } else if (unit_transported(punit
)
972 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
973 USP_TRANSPORTED
, TRUE
)) {
974 explnat
->kind
= ANEK_IS_TRANSPORTED
;
975 } else if (!unit_transported(punit
)
976 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
977 USP_TRANSPORTED
, FALSE
)) {
978 explnat
->kind
= ANEK_IS_NOT_TRANSPORTED
;
979 } else if (0 < get_transporter_occupancy(punit
)
980 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
981 USP_TRANSPORTING
, TRUE
)) {
982 explnat
->kind
= ANEK_IS_TRANSPORTING
;
983 } else if (!(0 < get_transporter_occupancy(punit
))
984 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
985 USP_TRANSPORTING
, FALSE
)) {
986 explnat
->kind
= ANEK_IS_NOT_TRANSPORTING
;
987 } else if ((punit
->homecity
> 0)
988 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
989 USP_HAS_HOME_CITY
, TRUE
)) {
990 explnat
->kind
= ANEK_ACTOR_HAS_HOME_CITY
;
991 } else if ((punit
->homecity
<= 0)
992 && !utype_can_do_act_when_ustate(unit_type_get(punit
), action_id
,
993 USP_HAS_HOME_CITY
, FALSE
)) {
994 explnat
->kind
= ANEK_ACTOR_HAS_NO_HOME_CITY
;
995 } else if ((punit
->homecity
<= 0)
996 && (action_id
== ACTION_TRADE_ROUTE
997 || action_id
== ACTION_MARKETPLACE
)) {
998 explnat
->kind
= ANEK_ACTOR_HAS_NO_HOME_CITY
;
999 } else if ((must_war_player
= need_war_player(punit
,
1004 explnat
->kind
= ANEK_NO_WAR
;
1005 explnat
->no_war_with
= must_war_player
;
1006 } else if (action_mp_full_makes_legal(punit
, action_id
)) {
1007 explnat
->kind
= ANEK_LOW_MP
;
1008 } else if (tgt_player
1009 && unit_owner(punit
) != tgt_player
1010 && !can_utype_do_act_if_tgt_diplrel(unit_type_get(punit
),
1014 explnat
->kind
= ANEK_FOREIGN
;
1015 } else if (action_id
== ACTION_FOUND_CITY
1016 && action_custom
== CB_BAD_BORDERS
) {
1017 explnat
->kind
= ANEK_FOREIGN
;
1018 } else if (tgt_player
1019 && unit_owner(punit
) == tgt_player
1020 && !can_utype_do_act_if_tgt_diplrel(unit_type_get(punit
),
1024 explnat
->kind
= ANEK_DOMESTIC
;
1026 && does_nation_block_action(action_id
, FALSE
,
1027 punit
, unit_owner(punit
)->nation
)) {
1028 explnat
->kind
= ANEK_NATION_ACT
;
1029 explnat
->no_act_nation
= unit_owner(punit
)->nation
;
1030 } else if (tgt_player
1031 && does_nation_block_action(action_id
, TRUE
,
1032 punit
, tgt_player
->nation
)) {
1033 explnat
->kind
= ANEK_NATION_TGT
;
1034 explnat
->no_act_nation
= tgt_player
->nation
;
1035 } else if ((target_tile
&& tile_city(target_tile
))
1036 && !utype_may_act_tgt_city_tile(unit_type_get(punit
),
1040 explnat
->kind
= ANEK_IS_CITY_CENTER
;
1041 } else if ((target_tile
&& !tile_city(target_tile
))
1042 && !utype_may_act_tgt_city_tile(unit_type_get(punit
),
1046 explnat
->kind
= ANEK_IS_NOT_CITY_CENTER
;
1047 } else if ((target_tile
&& tile_owner(target_tile
) != NULL
)
1048 && !utype_may_act_tgt_city_tile(unit_type_get(punit
),
1052 explnat
->kind
= ANEK_TGT_IS_CLAIMED
;
1053 } else if ((target_tile
&& tile_owner(target_tile
) == NULL
)
1054 && !utype_may_act_tgt_city_tile(unit_type_get(punit
),
1058 explnat
->kind
= ANEK_TGT_IS_UNCLAIMED
;
1059 } else if (action_id_exists(action_id
) && punit
1061 && !action_id_distance_inside_max(action_id
,
1062 real_map_distance(unit_tile(punit
), target_tile
)))
1064 && !action_id_distance_inside_max(action_id
,
1065 real_map_distance(unit_tile(punit
),
1066 city_tile(target_city
))))
1068 && !action_id_distance_inside_max(action_id
,
1069 real_map_distance(unit_tile(punit
),
1070 unit_tile(target_unit
)))))) {
1071 explnat
->kind
= ANEK_DISTANCE_FAR
;
1072 explnat
->distance
= action_by_number(action_id
)->max_distance
;
1073 } else if (action_id
== ACTION_PARADROP
&& punit
&& target_tile
1074 && real_map_distance(unit_tile(punit
), target_tile
)
1075 > unit_type_get(punit
)->paratroopers_range
) {
1076 explnat
->kind
= ANEK_DISTANCE_FAR
;
1077 explnat
->distance
= unit_type_get(punit
)->paratroopers_range
;
1078 } else if (action_id_exists(action_id
) && punit
1080 && real_map_distance(unit_tile(punit
), target_tile
)
1081 < action_by_number(action_id
)->min_distance
)
1083 && real_map_distance(unit_tile(punit
),
1084 city_tile(target_city
))
1085 < action_by_number(action_id
)->min_distance
)
1087 && real_map_distance(unit_tile(punit
),
1088 unit_tile(target_unit
))
1089 < action_by_number(action_id
)->min_distance
))) {
1090 explnat
->kind
= ANEK_DISTANCE_NEAR
;
1091 explnat
->distance
= action_by_number(action_id
)->min_distance
;
1092 } else if (target_city
1093 && (action_id
== ACTION_JOIN_CITY
1094 && action_actor_utype_hard_reqs_ok(ACTION_JOIN_CITY
,
1095 unit_type_get(punit
))
1096 && (city_size_get(target_city
) + unit_pop_value(punit
)
1097 > game
.info
.add_to_size_limit
))) {
1098 /* TODO: Check max city size requirements from action enabler target
1100 explnat
->kind
= ANEK_CITY_TOO_BIG
;
1101 } else if (target_city
1102 && (action_id
== ACTION_JOIN_CITY
1103 && action_actor_utype_hard_reqs_ok(ACTION_JOIN_CITY
,
1104 unit_type_get(punit
))
1105 && (!city_can_grow_to(target_city
,
1106 city_size_get(target_city
)
1107 + unit_pop_value(punit
))))) {
1108 explnat
->kind
= ANEK_CITY_POP_LIMIT
;
1109 } else if ((action_id
== ACTION_NUKE
1110 || action_id
== ACTION_ATTACK
)
1111 && action_custom
!= ATT_OK
) {
1112 switch (action_custom
) {
1113 case ATT_NON_ATTACK
:
1114 explnat
->kind
= ANEK_ACTOR_UNIT
;
1116 case ATT_UNREACHABLE
:
1117 explnat
->kind
= ANEK_TGT_UNREACHABLE
;
1119 case ATT_NONNATIVE_SRC
:
1120 explnat
->kind
= ANEK_BAD_TERRAIN_ACT
;
1121 explnat
->no_act_terrain
= tile_terrain(unit_tile(punit
));
1123 case ATT_NONNATIVE_DST
:
1124 explnat
->kind
= ANEK_BAD_TERRAIN_TGT
;
1125 explnat
->no_act_terrain
= tile_terrain(target_tile
);
1128 fc_assert(action_custom
!= ATT_OK
);
1129 explnat
->kind
= ANEK_UNKNOWN
;
1132 } else if (action_id
== ACTION_AIRLIFT
1133 && action_custom
== AR_SRC_NO_FLIGHTS
) {
1134 explnat
->kind
= ANEK_CITY_NO_CAPACITY
;
1135 explnat
->capacity_city
= tile_city(unit_tile(punit
));
1136 } else if (action_id
== ACTION_AIRLIFT
1137 && action_custom
== AR_DST_NO_FLIGHTS
) {
1138 explnat
->kind
= ANEK_CITY_NO_CAPACITY
;
1139 explnat
->capacity_city
= game_city_by_number(target_city
->id
);
1140 } else if (action_id
== ACTION_FOUND_CITY
1141 && action_custom
== CB_NO_MIN_DIST
) {
1142 explnat
->kind
= ANEK_CITY_TOO_CLOSE_TGT
;
1143 } else if (action_id
== ACTION_PARADROP
1145 && !map_is_known(target_tile
, unit_owner(punit
))) {
1146 explnat
->kind
= ANEK_TGT_TILE_UNKNOWN
;
1147 } else if (action_id
== ACTION_CONQUER_CITY
1148 && action_custom
!= MR_OK
) {
1149 switch (action_custom
) {
1150 case MR_CANNOT_DISEMBARK
:
1151 explnat
->kind
= ANEK_DISEMBARK_ACT
;
1154 explnat
->kind
= ANEK_TRIREME_MOVE
;
1157 fc_assert(action_custom
!= MR_OK
);
1158 explnat
->kind
= ANEK_UNKNOWN
;
1161 } else if ((game
.scenario
.prevent_new_cities
1162 && utype_can_do_action(unit_type_get(punit
), ACTION_FOUND_CITY
))
1163 && (action_id
== ACTION_FOUND_CITY
1164 || action_id
== ACTION_ANY
)) {
1165 /* Please add a check for any new action forbidding scenario setting
1166 * above this comment. */
1167 explnat
->kind
= ANEK_SCENARIO_DISABLED
;
1168 } else if (action_id_exists(action_id
)
1169 && (blocker
= action_is_blocked_by(action_id
, punit
,
1170 target_tile
, target_city
,
1172 explnat
->kind
= ANEK_ACTION_BLOCKS
;
1173 explnat
->blocker
= blocker
;
1175 explnat
->kind
= ANEK_UNKNOWN
;
1181 /**************************************************************************
1182 Give the reason kind why an action isn't enabled.
1183 **************************************************************************/
1184 enum ane_kind
action_not_enabled_reason(struct unit
*punit
,
1185 enum gen_action action_id
,
1186 const struct tile
*target_tile
,
1187 const struct city
*target_city
,
1188 const struct unit
*target_unit
)
1190 struct ane_expl
*explnat
= expl_act_not_enabl(punit
, action_id
,
1192 target_city
, target_unit
);
1193 enum ane_kind out
= explnat
->kind
;
1200 /**************************************************************************
1201 Explain why punit can't perform any action at all based on its current
1203 **************************************************************************/
1204 static void explain_why_no_action_enabled(struct unit
*punit
,
1205 const struct tile
*target_tile
,
1206 const struct city
*target_city
,
1207 const struct unit
*target_unit
)
1209 struct player
*pplayer
= unit_owner(punit
);
1210 struct ane_expl
*explnat
= expl_act_not_enabl(punit
, ACTION_ANY
,
1212 target_city
, target_unit
);
1214 switch (explnat
->kind
) {
1215 case ANEK_ACTOR_UNIT
:
1216 /* This shouldn't happen unless the client is buggy given the current
1218 fc_assert_msg(explnat
->kind
!= ANEK_ACTOR_UNIT
,
1219 "Asked to explain why a non actor can't act.");
1221 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1222 _("Unit cannot do anything."));
1224 case ANEK_MISSING_TARGET
:
1225 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1226 _("Your %s found no suitable target."),
1227 unit_name_translation(punit
));
1229 case ANEK_BAD_TARGET
:
1230 /* This shouldn't happen at the moment. Only specific action checks
1231 * will trigger bad target checks. This is a reply to a question about
1233 fc_assert(explnat
->kind
!= ANEK_BAD_TARGET
);
1235 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1236 _("Your %s found no suitable target."),
1237 unit_name_translation(punit
));
1239 case ANEK_BAD_TERRAIN_ACT
:
1241 const char *types
[utype_count()];
1244 if (!utype_can_do_act_when_ustate(unit_type_get(punit
),
1245 ACTION_ANY
, USP_LIVABLE_TILE
,
1247 && !can_unit_exist_at_tile(&(wld
.map
), punit
, unit_tile(punit
))) {
1248 unit_type_iterate(utype
) {
1249 if (utype_can_do_act_when_ustate(utype
, ACTION_ANY
,
1250 USP_LIVABLE_TILE
, FALSE
)) {
1251 types
[i
++] = utype_name_translation(utype
);
1253 } unit_type_iterate_end
;
1257 struct astring astr
= ASTRING_INIT
;
1259 notify_player(pplayer
, unit_tile(punit
),
1260 E_BAD_COMMAND
, ftc_server
,
1261 _("Your %s cannot act from %s. "
1262 "Only %s can act from a non livable tile."),
1263 unit_name_translation(punit
),
1264 terrain_name_translation(explnat
->no_act_terrain
),
1265 astr_build_or_list(&astr
, types
, i
));
1269 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1270 _("Unit cannot act from %s."),
1271 terrain_name_translation(explnat
->no_act_terrain
));
1275 case ANEK_BAD_TERRAIN_TGT
:
1276 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1277 _("Unit cannot act against %s."),
1278 terrain_name_translation(explnat
->no_act_terrain
));
1280 case ANEK_IS_TRANSPORTED
:
1281 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1282 _("This unit is being transported, and"
1283 " so cannot act."));
1285 case ANEK_IS_NOT_TRANSPORTED
:
1286 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1287 _("This unit cannot act when it isn't being "
1290 case ANEK_IS_TRANSPORTING
:
1291 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1292 _("This unit is transporting, and"
1293 " so cannot act."));
1295 case ANEK_IS_NOT_TRANSPORTING
:
1296 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1297 _("This unit cannot act when it isn't transporting."));
1299 case ANEK_ACTOR_HAS_HOME_CITY
:
1300 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1301 _("This unit has a home city, and so cannot act."));
1303 case ANEK_ACTOR_HAS_NO_HOME_CITY
:
1304 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1305 _("This unit cannot act unless it has a home city."));
1308 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1309 _("You must declare war on %s first. Try using "
1310 "the Nations report (F3)."),
1311 player_name(explnat
->no_war_with
));
1314 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1315 _("This unit cannot act against domestic targets."));
1318 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1319 _("This unit cannot act against foreign targets."));
1321 case ANEK_NATION_ACT
:
1322 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1323 /* TRANS: Swedish ... Riflemen */
1324 _("%s %s cannot act."),
1325 nation_adjective_translation(explnat
->no_act_nation
),
1326 unit_name_translation(punit
));
1328 case ANEK_NATION_TGT
:
1329 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1330 /* TRANS: ... Pirate ... */
1331 _("This unit cannot act against %s targets."),
1332 nation_adjective_translation(explnat
->no_act_nation
));
1335 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1336 _("This unit has too few moves left to act."));
1338 case ANEK_IS_CITY_CENTER
:
1339 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1340 _("This unit cannot act against city centers."));
1342 case ANEK_IS_NOT_CITY_CENTER
:
1343 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1344 _("This unit cannot act against non city centers."));
1346 case ANEK_TGT_IS_CLAIMED
:
1347 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1348 _("This unit cannot act against claimed tiles."));
1350 case ANEK_TGT_IS_UNCLAIMED
:
1351 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1352 _("This unit cannot act against unclaimed tiles."));
1354 case ANEK_DISTANCE_NEAR
:
1355 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1356 _("This unit is to near its target to act."));
1358 case ANEK_DISTANCE_FAR
:
1359 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1360 _("This unit is to far away from its target to act."));
1362 case ANEK_SCENARIO_DISABLED
:
1363 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1364 _("Can't perform any action this scenario permits."));
1366 case ANEK_CITY_TOO_CLOSE_TGT
:
1367 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1368 _("Can't perform any action this close to a city."));
1370 case ANEK_CITY_TOO_BIG
:
1371 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1372 /* TRANS: Settler ... Berlin */
1373 _("%s can't do anything to %s. It is too big."),
1374 unit_name_translation(punit
),
1375 city_name_get(target_city
));
1377 case ANEK_CITY_POP_LIMIT
:
1378 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1379 /* TRANS: London ... Settlers */
1380 _("%s needs an improvement to grow, so "
1381 "%s cannot do anything to it."),
1382 city_name_get(target_city
),
1383 unit_name_translation(punit
));
1385 case ANEK_CITY_NO_CAPACITY
:
1386 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1387 /* TRANS: Paris ... Warriors (think: airlift) */
1388 _("%s don't have enough capacity, so "
1389 "%s cannot do anything."),
1390 city_name_get(explnat
->capacity_city
),
1391 unit_name_translation(punit
));
1393 case ANEK_TGT_TILE_UNKNOWN
:
1394 notify_player(pplayer
, target_tile
, E_BAD_COMMAND
, ftc_server
,
1395 /* TRANS: Paratroopers ... */
1396 _("%s can't do anything to an unknown target tile."),
1397 unit_name_translation(punit
));
1399 case ANEK_TRIREME_MOVE
:
1400 notify_player(pplayer
, target_tile
, E_BAD_COMMAND
, ftc_server
,
1401 _("%s cannot move that far from the coast line."),
1404 case ANEK_DISEMBARK_ACT
:
1405 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1406 _("%s cannot disembark outside of a city or a native base "
1409 utype_name_translation(
1410 unit_type_get(unit_transport_get(punit
))));
1412 case ANEK_TGT_UNREACHABLE
:
1413 notify_player(pplayer
, target_tile
, E_BAD_COMMAND
, ftc_server
,
1414 _("%s can't do anything since there is an unreachable "
1416 unit_name_translation(punit
));
1418 case ANEK_ACTION_BLOCKS
:
1419 /* If an action blocked another action the blocking action must be
1421 fc_assert(explnat
->kind
!= ANEK_ACTION_BLOCKS
);
1422 /* Fall through to unknown cause. */
1424 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
1425 _("No action possible."));
1432 /**************************************************************************
1433 Handle a query for what actions a unit may do.
1435 MUST always send a reply so the client can move on in the queue. This
1436 includes when the client give invalid input. That the acting unit died
1437 before the server received a request for what actions it could do should
1438 not stop the client from processing the next unit in the queue.
1439 **************************************************************************/
1440 void handle_unit_get_actions(struct connection
*pc
,
1441 const int actor_unit_id
,
1442 const int target_unit_id_client
,
1443 const int target_tile_id
,
1444 const bool disturb_player
)
1446 struct player
*actor_player
;
1447 struct unit
*actor_unit
;
1448 struct tile
*target_tile
;
1449 struct act_prob probabilities
[MAX_NUM_ACTIONS
];
1451 struct unit
*target_unit
;
1452 struct city
*target_city
;
1454 int actor_target_distance
;
1455 const struct player_tile
*plrtile
;
1457 /* No potentially legal action is known yet. If none is found the player
1458 * should get an explanation. */
1459 bool at_least_one_action
= FALSE
;
1461 /* A target should only be sent if it is possible to act against it */
1462 int target_city_id
= IDENTITY_NUMBER_ZERO
;
1463 int target_unit_id
= IDENTITY_NUMBER_ZERO
;
1465 actor_player
= pc
->playing
;
1466 actor_unit
= game_unit_by_number(actor_unit_id
);
1467 target_tile
= index_to_tile(&(wld
.map
), target_tile_id
);
1469 /* Initialize the action probabilities. */
1470 action_iterate(act
) {
1471 probabilities
[act
] = ACTPROB_NA
;
1472 } action_iterate_end
;
1474 /* Check if the request is valid. */
1475 if (!target_tile
|| !actor_unit
|| !actor_player
1476 || actor_unit
->owner
!= actor_player
) {
1477 dsend_packet_unit_actions(pc
, actor_unit_id
,
1478 IDENTITY_NUMBER_ZERO
, IDENTITY_NUMBER_ZERO
,
1485 /* Select the targets. */
1487 if (target_unit_id_client
== IDENTITY_NUMBER_ZERO
) {
1488 /* Find a new target unit. */
1489 target_unit
= action_tgt_unit(actor_unit
, target_tile
, TRUE
);
1491 /* Prepare the client selected target unit. */
1492 target_unit
= game_unit_by_number(target_unit_id_client
);
1495 /* Find the target city. */
1496 target_city
= action_tgt_city(actor_unit
, target_tile
, TRUE
);
1498 /* The specified target unit must be located at the target tile. */
1499 if (target_unit
&& unit_tile(target_unit
) != target_tile
) {
1500 notify_player(actor_player
, unit_tile(actor_unit
),
1501 E_BAD_COMMAND
, ftc_server
,
1502 _("Target not at target tile."));
1503 dsend_packet_unit_actions(pc
, actor_unit_id
,
1504 IDENTITY_NUMBER_ZERO
, IDENTITY_NUMBER_ZERO
,
1511 /* The player may have outdated information about the target tile.
1512 * Limiting the player knowledge look up to the target tile is OK since
1513 * all targets must be located at it. */
1514 plrtile
= map_get_player_tile(target_tile
, actor_player
);
1516 /* Distance between actor and target tile. */
1517 actor_target_distance
= real_map_distance(unit_tile(actor_unit
),
1520 /* Find out what can be done to the targets. */
1522 /* Set the probability for the actions. */
1523 action_iterate(act
) {
1524 if (action_id_get_actor_kind(act
) != AAK_UNIT
) {
1529 switch (action_id_get_target_kind(act
)) {
1531 if (plrtile
&& plrtile
->site
) {
1532 /* Only a known city may be targeted. */
1534 /* Calculate the probabilities. */
1535 probabilities
[act
] = action_prob_vs_city(actor_unit
, act
,
1537 } else if (!tile_is_seen(target_tile
, actor_player
)
1538 && action_maybe_possible_actor_unit(act
, actor_unit
)
1539 && action_id_distance_accepted(act
,
1540 actor_target_distance
)) {
1541 /* The target city is non existing. The player isn't aware of this
1542 * fact because he can't see the tile it was located on. The
1543 * actor unit it self doesn't contradict the requirements to
1544 * perform the action. The (no longer existing) target city was
1545 * known to be close enough. */
1546 probabilities
[act
] = ACTPROB_NOT_KNOWN
;
1548 /* The actor unit is known to be unable to act or the target city
1549 * is known to be too far away. */
1550 probabilities
[act
] = ACTPROB_IMPOSSIBLE
;
1553 /* No target to act against. */
1554 probabilities
[act
] = ACTPROB_IMPOSSIBLE
;
1559 /* Calculate the probabilities. */
1560 probabilities
[act
] = action_prob_vs_unit(actor_unit
, act
,
1563 /* No target to act against. */
1564 probabilities
[act
] = ACTPROB_IMPOSSIBLE
;
1569 /* Calculate the probabilities. */
1570 probabilities
[act
] = action_prob_vs_units(actor_unit
, act
,
1573 /* No target to act against. */
1574 probabilities
[act
] = ACTPROB_IMPOSSIBLE
;
1579 /* Calculate the probabilities. */
1580 probabilities
[act
] = action_prob_vs_tile(actor_unit
, act
,
1583 /* No target to act against. */
1584 probabilities
[act
] = ACTPROB_IMPOSSIBLE
;
1588 if (actor_target_distance
== 0) {
1589 /* Calculate the probabilities. */
1590 probabilities
[act
] = action_prob_self(actor_unit
, act
);
1592 /* Don't bother with self targeted actions unless the actor is
1593 * asking about what can be done to its own tile. */
1594 probabilities
[act
] = ACTPROB_IMPOSSIBLE
;
1598 fc_assert_action(action_id_get_target_kind(act
) != ATK_COUNT
,
1599 probabilities
[act
] = ACTPROB_IMPOSSIBLE
);
1602 } action_iterate_end
;
1604 /* Analyze the probabilities. Decide what targets to send and if an
1605 * explanation is needed. */
1606 action_iterate(act
) {
1607 if (action_prob_possible(probabilities
[act
])) {
1608 /* An action can be done. No need to explain why no action can be
1610 at_least_one_action
= TRUE
;
1612 switch (action_id_get_target_kind(act
)) {
1614 /* The city should be sent as a target since it is possible to act
1617 /* All city targeted actions requires that the player is aware of
1618 * the target city. It is therefore in the player's map. */
1619 fc_assert_action(plrtile
, continue);
1620 fc_assert_action(plrtile
->site
, continue);
1622 target_city_id
= plrtile
->site
->identity
;
1625 /* The unit should be sent as a target since it is possible to act
1627 fc_assert(target_unit
!= NULL
);
1628 target_unit_id
= target_unit
->id
;
1632 /* The target tile aren't selected here so it haven't changed. */
1633 fc_assert(target_tile
!= NULL
);
1636 /* The target unit is the actor unit. It is already sent. */
1637 fc_assert(actor_unit
!= NULL
);
1640 fc_assert_msg(action_id_get_target_kind(act
) != ATK_COUNT
,
1641 "Invalid action target kind.");
1645 if (target_city_id
!= IDENTITY_NUMBER_ZERO
1646 && target_unit_id
!= IDENTITY_NUMBER_ZERO
) {
1647 /* No need to find out more. */
1651 } action_iterate_end
;
1653 /* Send possible actions and targets. */
1654 dsend_packet_unit_actions(pc
,
1655 actor_unit_id
, target_unit_id
, target_city_id
,
1660 if (disturb_player
&& !at_least_one_action
) {
1661 /* The user should get an explanation why no action is possible. */
1662 explain_why_no_action_enabled(actor_unit
,
1663 target_tile
, target_city
, target_unit
);
1667 /**************************************************************************
1668 Try to explain to the player why an action is illegal.
1670 Event type should be E_BAD_COMMAND if the player should know that the
1671 action is illegal or E_UNIT_ILLEGAL_ACTION if the player potentially new
1672 information is being revealed.
1673 **************************************************************************/
1674 void illegal_action_msg(struct player
*pplayer
,
1675 const enum event_type event
,
1677 const int stopped_action
,
1678 const struct tile
*target_tile
,
1679 const struct city
*target_city
,
1680 const struct unit
*target_unit
)
1682 struct ane_expl
*explnat
;
1684 /* Explain why the action was illegal. */
1685 explnat
= expl_act_not_enabl(actor
, stopped_action
,
1686 target_tile
, target_city
, target_unit
);
1687 switch (explnat
->kind
) {
1688 case ANEK_ACTOR_UNIT
:
1690 struct astring astr
= ASTRING_INIT
;
1692 if (role_units_translations(&astr
,
1693 action_id_get_role(stopped_action
),
1695 notify_player(pplayer
, unit_tile(actor
),
1697 /* TRANS: Only Diplomat or Spy can do Steal Gold. */
1698 _("Only %s can do %s."),
1700 action_id_name_translation(stopped_action
));
1703 notify_player(pplayer
, unit_tile(actor
),
1705 /* TRANS: Spy can't do Capture Units. */
1706 _("%s can't do %s."),
1707 unit_name_translation(actor
),
1708 action_id_name_translation(stopped_action
));
1712 case ANEK_MISSING_TARGET
:
1713 notify_player(pplayer
, unit_tile(actor
), event
, ftc_server
,
1714 _("Your %s found no target suitable for %s."),
1715 unit_name_translation(actor
),
1716 action_id_name_translation(stopped_action
));
1718 case ANEK_BAD_TARGET
:
1719 notify_player(pplayer
, unit_tile(actor
), event
, ftc_server
,
1720 _("Having your %s do %s to this target is redundant."),
1721 unit_name_translation(actor
),
1722 action_id_name_translation(stopped_action
));
1724 case ANEK_BAD_TERRAIN_ACT
:
1726 const char *types
[utype_count()];
1729 if (!utype_can_do_act_when_ustate(unit_type_get(actor
),
1730 stopped_action
, USP_LIVABLE_TILE
,
1732 && !can_unit_exist_at_tile(&(wld
.map
), actor
, unit_tile(actor
))) {
1733 unit_type_iterate(utype
) {
1734 if (utype_can_do_act_when_ustate(utype
, stopped_action
,
1735 USP_LIVABLE_TILE
, FALSE
)) {
1736 types
[i
++] = utype_name_translation(utype
);
1738 } unit_type_iterate_end
;
1742 struct astring astr
= ASTRING_INIT
;
1744 notify_player(pplayer
, unit_tile(actor
),
1746 _("Your %s can't do %s from %s. "
1747 "Only %s can do %s from a non livable tile."),
1748 unit_name_translation(actor
),
1749 action_id_name_translation(stopped_action
),
1750 terrain_name_translation(explnat
->no_act_terrain
),
1751 action_id_name_translation(stopped_action
),
1752 astr_build_or_list(&astr
, types
, i
));
1756 notify_player(pplayer
, unit_tile(actor
),
1758 _("Your %s can't do %s from %s."),
1759 unit_name_translation(actor
),
1760 action_id_name_translation(stopped_action
),
1761 terrain_name_translation(explnat
->no_act_terrain
));
1765 case ANEK_BAD_TERRAIN_TGT
:
1766 notify_player(pplayer
, unit_tile(actor
),
1768 _("Your %s can't do %s to %s."),
1769 unit_name_translation(actor
),
1770 action_id_name_translation(stopped_action
),
1771 terrain_name_translation(explnat
->no_act_terrain
));
1773 case ANEK_IS_TRANSPORTED
:
1774 notify_player(pplayer
, unit_tile(actor
),
1776 _("Your %s can't do %s while being transported."),
1777 unit_name_translation(actor
),
1778 action_id_name_translation(stopped_action
));
1780 case ANEK_IS_NOT_TRANSPORTED
:
1781 notify_player(pplayer
, unit_tile(actor
),
1783 _("Your %s can't do %s while not being transported."),
1784 unit_name_translation(actor
),
1785 action_id_name_translation(stopped_action
));
1787 case ANEK_IS_TRANSPORTING
:
1788 notify_player(pplayer
, unit_tile(actor
),
1790 _("Your %s can't do %s while transporting."),
1791 unit_name_translation(actor
),
1792 action_id_name_translation(stopped_action
));
1794 case ANEK_IS_NOT_TRANSPORTING
:
1795 notify_player(pplayer
, unit_tile(actor
),
1797 _("Your %s can't do %s while not transporting."),
1798 unit_name_translation(actor
),
1799 action_id_name_translation(stopped_action
));
1801 case ANEK_ACTOR_HAS_HOME_CITY
:
1802 notify_player(pplayer
, unit_tile(actor
),
1804 _("Your %s can't do %s because it has a home city."),
1805 unit_name_translation(actor
),
1806 action_id_name_translation(stopped_action
));
1808 case ANEK_ACTOR_HAS_NO_HOME_CITY
:
1809 notify_player(pplayer
, unit_tile(actor
),
1811 _("Your %s can't do %s because it is homeless."),
1812 unit_name_translation(actor
),
1813 action_id_name_translation(stopped_action
));
1816 notify_player(pplayer
, unit_tile(actor
),
1818 _("Your %s can't do %s while you"
1819 " aren't at war with %s."),
1820 unit_name_translation(actor
),
1821 action_id_name_translation(stopped_action
),
1822 player_name(explnat
->no_war_with
));
1825 notify_player(pplayer
, unit_tile(actor
),
1827 _("Your %s can't do %s to domestic %s."),
1828 unit_name_translation(actor
),
1829 action_id_name_translation(stopped_action
),
1830 action_target_kind_translated_name(
1831 action_id_get_target_kind(stopped_action
)));
1834 notify_player(pplayer
, unit_tile(actor
),
1836 _("Your %s can't do %s to foreign %s."),
1837 unit_name_translation(actor
),
1838 action_id_name_translation(stopped_action
),
1839 action_target_kind_translated_name(
1840 action_id_get_target_kind(stopped_action
)));
1842 case ANEK_NATION_ACT
:
1843 notify_player(pplayer
, unit_tile(actor
),
1845 /* TRANS: Swedish ... Riflemen ... Expel Unit */
1846 _("%s %s can't do %s."),
1847 nation_adjective_translation(explnat
->no_act_nation
),
1848 unit_name_translation(actor
),
1849 action_id_name_translation(stopped_action
));
1851 case ANEK_NATION_TGT
:
1852 notify_player(pplayer
, unit_tile(actor
),
1854 /* TRANS: Riflemen... Expel Unit... Pirate... Migrants */
1855 _("Your %s can't do %s to %s %s."),
1856 unit_name_translation(actor
),
1857 action_id_name_translation(stopped_action
),
1858 nation_adjective_translation(explnat
->no_act_nation
),
1859 action_target_kind_translated_name(
1860 action_id_get_target_kind(stopped_action
)));
1863 notify_player(pplayer
, unit_tile(actor
),
1865 _("Your %s has too few moves left to %s."),
1866 unit_name_translation(actor
),
1867 action_id_name_translation(stopped_action
));
1869 case ANEK_IS_CITY_CENTER
:
1870 notify_player(pplayer
, unit_tile(actor
),
1872 _("Your %s can't do %s to city centers."),
1873 unit_name_translation(actor
),
1874 action_id_name_translation(stopped_action
));
1876 case ANEK_IS_NOT_CITY_CENTER
:
1877 notify_player(pplayer
, unit_tile(actor
),
1879 _("Your %s can only do %s to city centers."),
1880 unit_name_translation(actor
),
1881 action_id_name_translation(stopped_action
));
1883 case ANEK_TGT_IS_CLAIMED
:
1884 notify_player(pplayer
, unit_tile(actor
),
1886 _("Your %s can't do %s to claimed tiles."),
1887 unit_name_translation(actor
),
1888 action_id_name_translation(stopped_action
));
1890 case ANEK_TGT_IS_UNCLAIMED
:
1891 notify_player(pplayer
, unit_tile(actor
),
1893 _("Your %s can't do %s to unclaimed tiles."),
1894 unit_name_translation(actor
),
1895 action_id_name_translation(stopped_action
));
1897 case ANEK_DISTANCE_NEAR
:
1898 notify_player(pplayer
, unit_tile(actor
),
1900 PL_("Your %s must be at least %d tile away to do %s.",
1901 "Your %s must be at least %d tiles away to do %s.",
1903 unit_name_translation(actor
),
1905 action_id_name_translation(stopped_action
));
1907 case ANEK_DISTANCE_FAR
:
1908 notify_player(pplayer
, unit_tile(actor
),
1910 PL_("Your %s can't be more than %d tile away to do %s.",
1911 "Your %s can't be more than %d tiles away to do %s.",
1913 unit_name_translation(actor
),
1915 action_id_name_translation(stopped_action
));
1917 case ANEK_SCENARIO_DISABLED
:
1918 notify_player(pplayer
, unit_tile(actor
),
1920 /* TRANS: Can't do Build City in this scenario. */
1921 _("Can't do %s in this scenario."),
1922 action_id_name_translation(stopped_action
));
1924 case ANEK_CITY_TOO_CLOSE_TGT
:
1925 notify_player(pplayer
, unit_tile(actor
),
1927 /* TRANS: Can't do Build City this close to a city. */
1928 _("Can't do %s this close to a city."),
1929 action_id_name_translation(stopped_action
));
1931 case ANEK_CITY_TOO_BIG
:
1932 notify_player(pplayer
, unit_tile(actor
),
1934 /* TRANS: Settlers ... Join City ... London */
1935 _("%s can't do %s to %s. It is too big."),
1936 unit_name_translation(actor
),
1937 action_id_name_translation(stopped_action
),
1938 city_name_get(target_city
));
1940 case ANEK_CITY_POP_LIMIT
:
1941 notify_player(pplayer
, unit_tile(actor
),
1943 /* TRANS: London ... Settlers ... Join City */
1944 _("%s needs an improvement to grow, so "
1945 "%s cannot do %s."),
1946 city_name_get(target_city
),
1947 unit_name_translation(actor
),
1948 action_id_name_translation(stopped_action
));
1950 case ANEK_CITY_NO_CAPACITY
:
1951 notify_player(pplayer
, unit_tile(actor
),
1953 /* TRANS: Paris ... Airlift to City ... Warriors */
1954 _("%s has no capacity to %s %s."),
1955 city_name_get(explnat
->capacity_city
),
1956 action_id_name_translation(stopped_action
),
1957 unit_name_translation(actor
));
1959 case ANEK_TGT_TILE_UNKNOWN
:
1960 notify_player(pplayer
, unit_tile(actor
),
1962 /* TRANS: Paratroopers ... Drop Paratrooper */
1963 _("%s can't do %s to an unknown tile."),
1964 unit_name_translation(actor
),
1965 action_id_name_translation(stopped_action
));
1967 case ANEK_TRIREME_MOVE
:
1968 notify_player(pplayer
, target_tile
, event
, ftc_server
,
1969 _("%s cannot move that far from the coast line."),
1972 case ANEK_DISEMBARK_ACT
:
1973 notify_player(pplayer
, unit_tile(actor
), event
, ftc_server
,
1974 _("%s cannot disembark outside of a city or a native base "
1977 utype_name_translation(
1978 unit_type_get(unit_transport_get(actor
))));
1980 case ANEK_TGT_UNREACHABLE
:
1981 notify_player(pplayer
, target_tile
,
1983 _("Your %s can't do %s there since there's an "
1984 "unreachable unit."),
1985 unit_name_translation(actor
),
1986 action_id_name_translation(stopped_action
));
1988 case ANEK_ACTION_BLOCKS
:
1989 notify_player(pplayer
, unit_tile(actor
),
1991 /* TRANS: Freight ... Recycle Unit ... Help Wonder ... */
1992 _("Your %s can't do %s when %s is legal."),
1993 unit_name_translation(actor
),
1994 action_id_name_translation(stopped_action
),
1995 action_id_name_translation(explnat
->blocker
->id
));
1998 notify_player(pplayer
, unit_tile(actor
),
2000 _("Your %s was unable to %s."),
2001 unit_name_translation(actor
),
2002 action_id_name_translation(stopped_action
));
2009 /**************************************************************************
2010 Tell the client that the action it requested is illegal. This can be
2011 caused by the player (and therefore the client) not knowing that some
2012 condition of an action no longer is true.
2013 **************************************************************************/
2014 static void illegal_action(struct player
*pplayer
,
2016 enum gen_action stopped_action
,
2017 struct player
*tgt_player
,
2018 const struct tile
*target_tile
,
2019 const struct city
*target_city
,
2020 const struct unit
*target_unit
,
2021 const enum action_requester requester
)
2023 /* Why didn't the game check before trying something illegal? Did a good
2024 * reason to not call is_action_enabled_unit_on...() appear? The game is
2026 fc_assert(requester
!= ACT_REQ_RULES
);
2028 /* Don't punish the player for something the game did. Don't tell the
2029 * player that the rules required the game to try to do something
2031 fc_assert_ret_msg((requester
== ACT_REQ_PLAYER
2032 || requester
== ACT_REQ_SS_AGENT
),
2033 "The player wasn't responsible for this.");
2035 /* The mistake may have a cost. */
2036 actor
->moves_left
= MAX(0, actor
->moves_left
2037 - get_target_bonus_effects(NULL
,
2044 unit_type_get(actor
),
2047 action_by_number(stopped_action
),
2048 EFT_ILLEGAL_ACTION_MOVE_COST
));
2050 send_unit_info(NULL
, actor
);
2052 illegal_action_msg(pplayer
, E_UNIT_ILLEGAL_ACTION
,
2053 actor
, stopped_action
,
2054 target_tile
, target_city
, target_unit
);
2057 /**************************************************************************
2058 Inform the client that something went wrong during a unit diplomat query
2059 **************************************************************************/
2060 static void unit_query_impossible(struct connection
*pc
,
2061 const int diplomat_id
,
2062 const int target_id
)
2064 dsend_packet_unit_action_answer(pc
,
2065 diplomat_id
, target_id
,
2070 /**************************************************************************
2071 Tell the client the cost of bribing a unit, inciting a revolt, or
2072 any other parameters needed for action.
2074 Only send result back to the requesting connection, not all
2075 connections for that player.
2076 **************************************************************************/
2077 void handle_unit_action_query(struct connection
*pc
,
2079 const int target_id
,
2080 const enum gen_action action_type
)
2082 struct player
*pplayer
= pc
->playing
;
2083 struct unit
*pactor
= player_unit_by_number(pplayer
, actor_id
);
2084 struct unit
*punit
= game_unit_by_number(target_id
);
2085 struct city
*pcity
= game_city_by_number(target_id
);
2087 if (!action_id_exists(action_type
)) {
2088 /* Non existing action */
2089 log_error("handle_unit_action_query() the action %d doesn't exist.",
2092 unit_query_impossible(pc
, actor_id
, target_id
);
2096 if (NULL
== pactor
) {
2097 /* Probably died or bribed. */
2098 log_verbose("handle_unit_action_query() invalid actor %d",
2100 unit_query_impossible(pc
, actor_id
, target_id
);
2104 if (!utype_may_act_at_all(unit_type_get(pactor
))) {
2105 /* Shouldn't happen */
2106 log_error("handle_unit_action_query() %s (%d) is not an actor",
2107 unit_rule_name(pactor
), actor_id
);
2108 unit_query_impossible(pc
, actor_id
, target_id
);
2112 switch (action_type
) {
2113 case ACTION_SPY_BRIBE_UNIT
:
2115 && is_action_enabled_unit_on_unit(action_type
,
2117 dsend_packet_unit_action_answer(pc
,
2118 actor_id
, target_id
,
2119 unit_bribe_cost(punit
, pplayer
),
2122 illegal_action(pplayer
, pactor
, action_type
,
2123 punit
? unit_owner(punit
) : NULL
,
2124 NULL
, NULL
, punit
, ACT_REQ_PLAYER
);
2125 unit_query_impossible(pc
, actor_id
, target_id
);
2129 case ACTION_SPY_INCITE_CITY
:
2130 case ACTION_SPY_INCITE_CITY_ESC
:
2132 && is_action_enabled_unit_on_city(action_type
,
2134 dsend_packet_unit_action_answer(pc
,
2135 actor_id
, target_id
,
2136 city_incite_cost(pplayer
, pcity
),
2139 illegal_action(pplayer
, pactor
, action_type
,
2140 pcity
? city_owner(pcity
) : NULL
,
2141 NULL
, pcity
, NULL
, ACT_REQ_PLAYER
);
2142 unit_query_impossible(pc
, actor_id
, target_id
);
2146 case ACTION_SPY_TARGETED_SABOTAGE_CITY
:
2148 && is_action_enabled_unit_on_city(action_type
,
2150 spy_send_sabotage_list(pc
, pactor
, pcity
,
2151 action_by_number(action_type
));
2153 illegal_action(pplayer
, pactor
, action_type
,
2154 pcity
? city_owner(pcity
) : NULL
,
2155 NULL
, pcity
, NULL
, ACT_REQ_PLAYER
);
2156 unit_query_impossible(pc
, actor_id
, target_id
);
2161 unit_query_impossible(pc
, actor_id
, target_id
);
2166 /**************************************************************************
2167 Handle a request to do an action.
2169 action_type must be a valid action.
2170 **************************************************************************/
2171 void handle_unit_do_action(struct player
*pplayer
,
2173 const int target_id
,
2176 const enum gen_action action_type
)
2178 (void) unit_perform_action(pplayer
, actor_id
, target_id
, value
, name
,
2179 action_type
, ACT_REQ_PLAYER
);
2182 /**************************************************************************
2183 Execute a request to perform an action and let the caller know if it was
2186 The action must be a valid action.
2188 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
2189 this returns TRUE, unit may have died during the action.
2190 **************************************************************************/
2191 bool unit_perform_action(struct player
*pplayer
,
2193 const int target_id
,
2196 const enum gen_action action_type
,
2197 const enum action_requester requester
)
2199 struct action
*paction
;
2200 struct unit
*actor_unit
= player_unit_by_number(pplayer
, actor_id
);
2201 struct tile
*target_tile
= index_to_tile(&(wld
.map
), target_id
);
2202 struct unit
*punit
= game_unit_by_number(target_id
);
2203 struct city
*pcity
= game_city_by_number(target_id
);
2205 if (!action_id_exists(action_type
)) {
2206 /* Non existing action */
2207 log_error("unit_perform_action() the action %d doesn't exist.",
2213 paction
= action_by_number(action_type
);
2215 if (NULL
== actor_unit
) {
2216 /* Probably died or bribed. */
2217 log_verbose("handle_unit_do_action() invalid actor %d",
2222 if (!utype_may_act_at_all(unit_type_get(actor_unit
))) {
2223 /* Shouldn't happen */
2224 log_error("handle_unit_do_action() %s (%d) is not an actor unit",
2225 unit_rule_name(actor_unit
), actor_id
);
2229 if (paction
->unitwaittime_controlled
2230 && !unit_can_do_action_now(actor_unit
)) {
2231 /* Action not possible due to unitwaittime setting. */
2235 #define ACTION_STARTED_UNIT_CITY(action, actor, target, action_performer) \
2237 && is_action_enabled_unit_on_city(action_type, \
2238 actor_unit, pcity)) { \
2240 script_server_signal_emit("action_started_unit_city", 3, \
2241 API_TYPE_ACTION, action_by_number(action), \
2242 API_TYPE_UNIT, actor, \
2243 API_TYPE_CITY, target); \
2244 if (!actor || !unit_is_alive(actor_id)) { \
2245 /* Actor unit was destroyed during pre action Lua. */ \
2248 if (!target || !city_exist(target_id)) { \
2249 /* Target city was destroyed during pre action Lua. */ \
2252 success = action_performer; \
2254 action_success_actor_consume(paction, actor_id, actor); \
2258 illegal_action(pplayer, actor_unit, action_type, \
2259 pcity ? city_owner(pcity) : NULL, NULL, pcity, NULL, \
2263 #define ACTION_STARTED_UNIT_SELF(action, actor, action_performer) \
2265 && is_action_enabled_unit_on_self(action_type, actor_unit)) { \
2267 script_server_signal_emit("action_started_unit_self", 2, \
2268 API_TYPE_ACTION, action_by_number(action), \
2269 API_TYPE_UNIT, actor); \
2270 if (!actor || !unit_is_alive(actor_id)) { \
2271 /* Actor unit was destroyed during pre action Lua. */ \
2274 success = action_performer; \
2276 action_success_actor_consume(paction, actor_id, actor); \
2280 illegal_action(pplayer, actor_unit, action_type, \
2281 unit_owner(actor_unit), NULL, NULL, actor_unit, \
2285 #define ACTION_STARTED_UNIT_UNIT(action, actor, target, action_performer) \
2287 && is_action_enabled_unit_on_unit(action_type, actor_unit, punit)) {\
2289 script_server_signal_emit("action_started_unit_unit", 3, \
2290 API_TYPE_ACTION, action_by_number(action), \
2291 API_TYPE_UNIT, actor, \
2292 API_TYPE_UNIT, target); \
2293 if (!actor || !unit_is_alive(actor_id)) { \
2294 /* Actor unit was destroyed during pre action Lua. */ \
2297 if (!target || !unit_is_alive(target_id)) { \
2298 /* Target unit was destroyed during pre action Lua. */ \
2301 success = action_performer; \
2303 action_success_actor_consume(paction, actor_id, actor); \
2307 illegal_action(pplayer, actor_unit, action_type, \
2308 punit ? unit_owner(punit) : NULL, NULL, NULL, punit, \
2312 #define ACTION_STARTED_UNIT_UNITS(action, actor, target, action_performer)\
2314 && is_action_enabled_unit_on_units(action_type, \
2315 actor_unit, target_tile)) { \
2317 script_server_signal_emit("action_started_unit_units", 3, \
2318 API_TYPE_ACTION, action_by_number(action), \
2319 API_TYPE_UNIT, actor, \
2320 API_TYPE_TILE, target); \
2321 if (!actor || !unit_is_alive(actor_id)) { \
2322 /* Actor unit was destroyed during pre action Lua. */ \
2325 success = action_performer; \
2327 action_success_actor_consume(paction, actor_id, actor); \
2331 illegal_action(pplayer, actor_unit, action_type, \
2332 target_tile ? tile_owner(target_tile) : NULL, \
2333 target_tile, NULL, NULL, \
2337 #define ACTION_STARTED_UNIT_TILE(action, actor, target, action_performer) \
2339 && is_action_enabled_unit_on_tile(action_type, \
2340 actor_unit, target_tile)) { \
2342 script_server_signal_emit("action_started_unit_tile", 3, \
2343 API_TYPE_ACTION, action_by_number(action), \
2344 API_TYPE_UNIT, actor, \
2345 API_TYPE_TILE, target); \
2346 if (!actor || !unit_is_alive(actor_id)) { \
2347 /* Actor unit was destroyed during pre action Lua. */ \
2350 success = action_performer; \
2352 action_success_actor_consume(paction, actor_id, actor); \
2356 illegal_action(pplayer, actor_unit, action_type, \
2357 NULL, target_tile, NULL, NULL, \
2361 switch(action_type
) {
2362 case ACTION_SPY_BRIBE_UNIT
:
2363 ACTION_STARTED_UNIT_UNIT(action_type
, actor_unit
, punit
,
2364 diplomat_bribe(pplayer
, actor_unit
, punit
,
2367 case ACTION_SPY_SABOTAGE_UNIT
:
2368 ACTION_STARTED_UNIT_UNIT(action_type
, actor_unit
, punit
,
2369 spy_sabotage_unit(pplayer
, actor_unit
,
2372 case ACTION_EXPEL_UNIT
:
2373 ACTION_STARTED_UNIT_UNIT(action_type
, actor_unit
, punit
,
2374 do_expel_unit(pplayer
, actor_unit
, punit
));
2376 case ACTION_HEAL_UNIT
:
2377 ACTION_STARTED_UNIT_UNIT(action_type
, actor_unit
, punit
,
2378 do_heal_unit(pplayer
, actor_unit
, punit
));
2380 case ACTION_DISBAND_UNIT
:
2381 ACTION_STARTED_UNIT_SELF(action_type
, actor_unit
,
2382 do_unit_disband(pplayer
, actor_unit
));
2384 case ACTION_SPY_SABOTAGE_CITY
:
2385 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2386 diplomat_sabotage(pplayer
, actor_unit
, pcity
,
2389 case ACTION_SPY_TARGETED_SABOTAGE_CITY
:
2390 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2391 diplomat_sabotage(pplayer
, actor_unit
, pcity
,
2392 value
- 1, paction
));
2394 case ACTION_SPY_POISON
:
2395 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2396 spy_poison(pplayer
, actor_unit
, pcity
,
2399 case ACTION_SPY_INVESTIGATE_CITY
:
2400 case ACTION_INV_CITY_SPEND
:
2401 /* Difference is caused by data in the action structure. */
2402 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2403 diplomat_investigate(pplayer
,
2407 case ACTION_ESTABLISH_EMBASSY
:
2408 case ACTION_ESTABLISH_EMBASSY_STAY
:
2409 /* Difference is caused by data in the action structure. */
2410 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2411 diplomat_embassy(pplayer
, actor_unit
, pcity
,
2414 case ACTION_SPY_INCITE_CITY
:
2415 case ACTION_SPY_INCITE_CITY_ESC
:
2416 /* Difference is caused by data in the action structure. */
2417 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2418 diplomat_incite(pplayer
, actor_unit
, pcity
,
2421 case ACTION_SPY_STEAL_TECH
:
2422 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2423 diplomat_get_tech(pplayer
, actor_unit
, pcity
,
2426 case ACTION_SPY_TARGETED_STEAL_TECH
:
2427 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2428 diplomat_get_tech(pplayer
, actor_unit
, pcity
,
2431 case ACTION_SPY_STEAL_GOLD
:
2432 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2433 spy_steal_gold(pplayer
, actor_unit
, pcity
,
2436 case ACTION_STEAL_MAPS
:
2437 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2438 spy_steal_some_maps(pplayer
, actor_unit
,
2441 case ACTION_TRADE_ROUTE
:
2442 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2443 do_unit_establish_trade(pplayer
, actor_unit
,
2446 case ACTION_MARKETPLACE
:
2447 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2448 do_unit_establish_trade(pplayer
, actor_unit
,
2451 case ACTION_HELP_WONDER
:
2452 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2453 do_unit_help_build_wonder(pplayer
,
2454 actor_unit
, pcity
));
2456 case ACTION_SPY_NUKE
:
2457 case ACTION_SPY_NUKE_ESC
:
2458 /* Difference is caused by data in the action structure. */
2459 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2460 spy_nuke_city(pplayer
, actor_unit
, pcity
,
2463 case ACTION_JOIN_CITY
:
2464 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2465 city_add_unit(pplayer
, actor_unit
, pcity
));
2467 case ACTION_DESTROY_CITY
:
2468 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2469 unit_do_destroy_city(pplayer
,
2470 actor_unit
, pcity
));
2472 case ACTION_RECYCLE_UNIT
:
2473 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2474 unit_do_recycle(pplayer
, actor_unit
, pcity
));
2476 case ACTION_HOME_CITY
:
2477 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2478 do_unit_change_homecity(actor_unit
, pcity
));
2480 case ACTION_UPGRADE_UNIT
:
2481 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2482 do_unit_upgrade(pplayer
, actor_unit
,
2485 case ACTION_CONQUER_CITY
:
2486 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2487 do_unit_conquer_city(pplayer
, actor_unit
,
2490 case ACTION_AIRLIFT
:
2491 ACTION_STARTED_UNIT_CITY(action_type
, actor_unit
, pcity
,
2492 do_airline(actor_unit
, pcity
));
2494 case ACTION_CAPTURE_UNITS
:
2495 ACTION_STARTED_UNIT_UNITS(action_type
, actor_unit
, target_tile
,
2496 do_capture_units(pplayer
, actor_unit
,
2499 case ACTION_BOMBARD
:
2500 ACTION_STARTED_UNIT_UNITS(action_type
, actor_unit
, target_tile
,
2501 unit_bombard(actor_unit
, target_tile
));
2503 case ACTION_FOUND_CITY
:
2504 ACTION_STARTED_UNIT_TILE(action_type
, actor_unit
, target_tile
,
2505 city_build(pplayer
, actor_unit
,
2506 target_tile
, name
));
2509 ACTION_STARTED_UNIT_TILE(action_type
, actor_unit
, target_tile
,
2510 unit_nuke(pplayer
, actor_unit
, target_tile
));
2512 case ACTION_PARADROP
:
2513 ACTION_STARTED_UNIT_TILE(action_type
, actor_unit
, target_tile
,
2514 do_paradrop(actor_unit
, target_tile
));
2517 ACTION_STARTED_UNIT_TILE(action_type
, actor_unit
, target_tile
,
2518 do_attack(actor_unit
, target_tile
, paction
));
2521 log_error("handle_unit_do_action() %s (%d) ordered to perform an "
2523 unit_rule_name(actor_unit
), actor_id
);
2527 /* Something must have gone wrong. */
2531 /**************************************************************************
2532 Transfer a unit from one city (and possibly player) to another.
2533 If 'rehome' is not set, only change the player which owns the unit
2534 (the new owner is new_pcity's owner). Otherwise the new unit will be
2535 given a homecity, even if it was homeless before.
2536 This new homecity must be valid for this unit.
2537 **************************************************************************/
2538 void unit_change_homecity_handling(struct unit
*punit
, struct city
*new_pcity
,
2541 struct city
*old_pcity
= game_city_by_number(punit
->homecity
);
2542 struct player
*old_owner
= unit_owner(punit
);
2543 struct player
*new_owner
= city_owner(new_pcity
);
2545 /* Calling this function when new_pcity is same as old_pcity should
2546 * be safe with current implementation, but it is not meant to
2547 * be used that way. */
2548 fc_assert_ret(new_pcity
!= old_pcity
);
2550 /* If 'rehome' is not set, this function should only be used to change
2551 * which player owns the unit */
2552 fc_assert_ret(rehome
|| new_owner
!= old_owner
);
2554 if (old_owner
!= new_owner
) {
2555 struct city
*pcity
= tile_city(punit
->tile
);
2557 fc_assert(!utype_player_already_has_this_unique(new_owner
,
2558 unit_type_get(punit
)));
2560 vision_clear_sight(punit
->server
.vision
);
2561 vision_free(punit
->server
.vision
);
2564 && !can_player_see_units_in_city(old_owner
, pcity
)) {
2565 /* Special case when city is being transferred. At this point city
2566 * itself has changed owner, so it's enemy city now that old owner
2567 * cannot see inside. All the normal methods of removing transferred
2568 * unit from previous owner's client think that there's no need to
2569 * remove unit as client shouldn't have it in first place. */
2570 unit_goes_out_of_sight(old_owner
, punit
);
2573 /* Remove AI control of the old owner. */
2574 CALL_PLR_AI_FUNC(unit_lost
, old_owner
, punit
);
2576 unit_list_remove(old_owner
->units
, punit
);
2577 unit_list_prepend(new_owner
->units
, punit
);
2578 punit
->owner
= new_owner
;
2580 /* Activate AI control of the new owner. */
2581 CALL_PLR_AI_FUNC(unit_got
, new_owner
, punit
);
2583 punit
->server
.vision
= vision_new(new_owner
, unit_tile(punit
));
2584 unit_refresh_vision(punit
);
2588 fc_assert(!unit_has_type_flag(punit
, UTYF_NOHOME
));
2590 /* Remove from old city first and add to new city only after that.
2591 * This is more robust in case old_city == new_city (currently
2592 * prohibited by fc_assert in the beginning of the function).
2595 /* Even if unit is dead, we have to unlink unit pointer (punit). */
2596 unit_list_remove(old_pcity
->units_supported
, punit
);
2597 /* update unit upkeep */
2598 city_units_upkeep(old_pcity
);
2601 unit_list_prepend(new_pcity
->units_supported
, punit
);
2603 /* update unit upkeep */
2604 city_units_upkeep(new_pcity
);
2606 punit
->homecity
= new_pcity
->id
;
2609 if (!can_unit_continue_current_activity(punit
)) {
2610 /* This is mainly for cases where unit owner changes to one not knowing
2611 * Railroad tech when unit is already building railroad. */
2612 set_unit_activity(punit
, ACTIVITY_IDLE
);
2615 /* Send info to players and observers. */
2616 send_unit_info(NULL
, punit
);
2618 city_refresh(new_pcity
);
2619 send_city_info(new_owner
, new_pcity
);
2622 fc_assert(city_owner(old_pcity
) == old_owner
);
2623 city_refresh(old_pcity
);
2624 send_city_info(old_owner
, old_pcity
);
2627 unit_get_goods(punit
);
2629 fc_assert(unit_owner(punit
) == city_owner(new_pcity
));
2632 /**************************************************************************
2633 Change a unit's home city.
2635 Returns TRUE iff the action could be done, FALSE if it couldn't.
2636 **************************************************************************/
2637 static bool do_unit_change_homecity(struct unit
*punit
,
2640 unit_change_homecity_handling(punit
, pcity
, TRUE
);
2642 return punit
->homecity
== pcity
->id
;
2645 /**************************************************************************
2648 No shields spent to build the unit is added to the shield stock of any
2649 city even if the unit is located inside it.
2651 Returns TRUE iff the action could be done, FALSE if it couldn't. Even if
2652 this returns TRUE, the unit may have died during the action.
2653 **************************************************************************/
2654 static bool do_unit_disband(struct player
*pplayer
, struct unit
*punit
)
2656 /* Sanity check: The actor still exists. */
2657 fc_assert_ret_val(pplayer
, FALSE
);
2658 fc_assert_ret_val(punit
, FALSE
);
2660 /* The unit is now disbanded. */
2664 /**************************************************************************
2665 Recycle a unit in a city.
2667 1/2 of the shields used to build the unit is added to the city's shield
2668 stock for the current production.
2670 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
2671 this returns TRUE, unit may have died during the action.
2672 **************************************************************************/
2673 static bool unit_do_recycle(struct player
*pplayer
,
2679 /* Sanity check: The actor still exists. */
2680 fc_assert_ret_val(pplayer
, FALSE
);
2681 fc_assert_ret_val(punit
, FALSE
);
2683 /* Sanity check: The target city still exists. */
2684 fc_assert_ret_val(pcity
, FALSE
);
2686 shields
= unit_disband_shields(punit
);
2688 /* Add the shields from recycling the unit to the city's current
2690 pcity
->shield_stock
+= shields
;
2692 /* If we change production later at this turn. No penalty is added. */
2693 pcity
->disbanded_shields
+= shields
;
2695 notify_player(pplayer
, city_tile(pcity
), E_CARAVAN_ACTION
, ftc_server
,
2696 /* TRANS: ... Ironclad ... New York */
2697 _("Recyled your %s to help the current production in %s."),
2701 send_city_info(city_owner(pcity
), pcity
);
2703 /* The unit is now recycled. */
2707 /**************************************************************************
2708 This function assumes that the target city is valid. It should only be
2709 called after checking that the unit legally can join the target city.
2711 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
2712 this returns TRUE, unit may have died during the action.
2713 **************************************************************************/
2714 static bool city_add_unit(struct player
*pplayer
, struct unit
*punit
,
2717 int amount
= unit_pop_value(punit
);
2719 /* Sanity check: The actor is still alive. */
2720 fc_assert_ret_val(punit
, FALSE
);
2722 /* Sanity check: The target city still exists. */
2723 fc_assert_ret_val(pcity
, FALSE
);
2725 fc_assert_ret_val(amount
> 0, FALSE
);
2727 script_server_signal_emit("city_size_change", 3,
2728 API_TYPE_CITY
, pcity
,
2729 API_TYPE_INT
, amount
,
2730 API_TYPE_STRING
, "unit_added");
2731 city_size_add(pcity
, amount
);
2732 /* Make the new people something, otherwise city fails the checks */
2733 pcity
->specialists
[DEFAULT_SPECIALIST
] += amount
;
2734 citizens_update(pcity
, unit_nationality(punit
));
2735 /* Refresh the city data. */
2736 city_refresh(pcity
);
2738 /* Notify the unit owner that the unit successfully joined the city. */
2739 notify_player(pplayer
, city_tile(pcity
), E_CITY_BUILD
, ftc_server
,
2740 _("%s added to aid %s in growing."),
2741 unit_tile_link(punit
),
2743 if (pplayer
!= city_owner(pcity
)) {
2744 /* Notify the city owner when a foreign unit joins a city. */
2745 notify_player(city_owner(pcity
), city_tile(pcity
), E_CITY_BUILD
,
2747 /* TRANS: another player had his unit joint your city. */
2748 _("%s adds %s to your city %s."),
2749 player_name(unit_owner(punit
)),
2750 unit_tile_link(punit
),
2754 action_id_consequence_success(ACTION_JOIN_CITY
, pplayer
,
2755 city_owner(pcity
), city_tile(pcity
),
2758 sanity_check_city(pcity
);
2760 send_city_info(NULL
, pcity
);
2765 /**************************************************************************
2766 This function assumes a certain level of consistency checking: There
2767 is no city under punit->(x,y), and that location is a valid one on
2768 which to build a city. It should only be called after a call to a
2769 function like test_unit_add_or_build_city, which does the checking.
2771 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
2772 this returns TRUE, unit may have died during the action.
2773 **************************************************************************/
2774 static bool city_build(struct player
*pplayer
, struct unit
*punit
,
2775 struct tile
*ptile
, const char *name
)
2779 struct player
*nationality
;
2780 struct player
*towner
;
2782 /* Sanity check: The actor still exists. */
2783 fc_assert_ret_val(pplayer
, FALSE
);
2784 fc_assert_ret_val(punit
, FALSE
);
2786 towner
= tile_owner(ptile
);
2788 if (!is_allowed_city_name(pplayer
, name
, message
, sizeof(message
))) {
2789 notify_player(pplayer
, ptile
, E_BAD_COMMAND
, ftc_server
,
2794 nationality
= unit_nationality(punit
);
2796 create_city(pplayer
, ptile
, name
, nationality
);
2797 size
= unit_type_get(punit
)->city_size
;
2799 struct city
*pcity
= tile_city(ptile
);
2801 fc_assert_ret_val(pcity
!= NULL
, FALSE
);
2803 city_change_size(pcity
, size
, nationality
, NULL
);
2806 /* May cause an incident even if the target tile is unclaimed. A ruleset
2807 * could give everyone a casus belli against the city founder. A rule
2808 * like that would make sense in a story where deep ecology is on the
2809 * table. (See also Voluntary Human Extinction Movement) */
2810 action_id_consequence_success(ACTION_FOUND_CITY
, pplayer
, towner
,
2811 ptile
, tile_link(ptile
));
2816 /**************************************************************************
2817 Handle change in unit activity.
2818 **************************************************************************/
2819 static void handle_unit_change_activity_real(struct player
*pplayer
,
2821 enum unit_activity activity
,
2822 struct extra_type
*activity_target
)
2824 struct unit
*punit
= player_unit_by_number(pplayer
, unit_id
);
2826 if (NULL
== punit
) {
2827 /* Probably died or bribed. */
2828 log_verbose("handle_unit_change_activity() invalid unit %d", unit_id
);
2832 if (punit
->activity
== activity
2833 && punit
->activity_target
== activity_target
2834 && !punit
->ai_controlled
) {
2835 /* Treat change in ai.control as change in activity, so
2836 * idle autosettlers behave correctly when selected --dwp
2841 /* Remove city spot reservations for AI settlers on city founding
2842 * mission, before goto_tile reset. */
2843 if (punit
->server
.adv
->task
!= AUT_NONE
) {
2844 adv_unit_new_task(punit
, AUT_NONE
, NULL
);
2847 punit
->ai_controlled
= FALSE
;
2848 punit
->goto_tile
= NULL
;
2850 if (activity
== ACTIVITY_GOTO
) {
2851 /* Don't permit a client to set a unit's activity to ACTIVITY_GOTO.
2852 * Setting ACTIVITY_GOTO from the client results in a unit indicating
2853 * it is going somewhere while it is standing still. The appearance of
2854 * the unit doing something can trick the user to not make use of it.
2856 * Handled here because adv_follow_path() uses unit_activity_handling()
2857 * to set a unit's activity to ACTIVITY_GOTO. */
2861 /* The activity can now be set. */
2862 unit_activity_handling_targeted(punit
, activity
, &activity_target
);
2864 if (activity
== ACTIVITY_EXPLORE
) {
2865 /* Exploring is handled here explicitly, since the player expects to
2866 * see an immediate response from setting a unit to auto-explore.
2867 * Handling it deeper in the code leads to some tricky recursive loops -
2869 if (punit
->moves_left
> 0) {
2875 /**************************************************************************
2876 Handle change in unit activity.
2877 **************************************************************************/
2878 void handle_unit_change_activity(struct player
*pplayer
, int unit_id
,
2879 enum unit_activity activity
,
2882 struct extra_type
*activity_target
;
2884 if (target_id
< 0 || target_id
>= game
.control
.num_extra_types
) {
2885 activity_target
= NULL
;
2887 activity_target
= extra_by_number(target_id
);
2891 /* Web-client is not capable of selecting target, so we do it server side */
2892 if (activity_target
== NULL
) {
2893 struct unit
*punit
= player_unit_by_number(pplayer
, unit_id
);
2894 bool required
= TRUE
;
2896 if (punit
== NULL
) {
2900 if (activity
== ACTIVITY_IRRIGATE
) {
2901 struct tile
*ptile
= unit_tile(punit
);
2902 struct terrain
*pterrain
= tile_terrain(ptile
);
2904 if (pterrain
->irrigation_result
!= pterrain
) {
2907 activity_target
= next_extra_for_tile(ptile
, EC_IRRIGATION
,
2910 } else if (activity
== ACTIVITY_MINE
) {
2911 struct tile
*ptile
= unit_tile(punit
);
2912 struct terrain
*pterrain
= tile_terrain(ptile
);
2914 if (pterrain
->mining_result
!= pterrain
) {
2917 activity_target
= next_extra_for_tile(ptile
, EC_MINE
,
2920 } else if (activity
== ACTIVITY_BASE
) {
2921 struct tile
*ptile
= unit_tile(punit
);
2922 struct base_type
*pbase
=
2923 get_base_by_gui_type(BASE_GUI_FORTRESS
, punit
, ptile
);
2925 if (pbase
!= NULL
) {
2926 activity_target
= base_extra_get(pbase
);
2929 } else if (activity
== ACTIVITY_POLLUTION
) {
2930 activity_target
= prev_extra_in_tile(unit_tile(punit
), ERM_CLEANPOLLUTION
,
2932 } else if (activity
== ACTIVITY_FALLOUT
) {
2933 activity_target
= prev_extra_in_tile(unit_tile(punit
), ERM_CLEANFALLOUT
,
2939 if (activity_target
== NULL
&& required
) {
2940 /* Nothing more we can do */
2944 #endif /* FREECIV_WEB */
2946 handle_unit_change_activity_real(pplayer
, unit_id
, activity
, activity_target
);
2949 /**************************************************************************
2950 Make sure everyone who can see combat does.
2951 **************************************************************************/
2952 static void see_combat(struct unit
*pattacker
, struct unit
*pdefender
)
2954 struct packet_unit_short_info unit_att_short_packet
, unit_def_short_packet
;
2955 struct packet_unit_info unit_att_packet
, unit_def_packet
;
2958 * Special case for attacking/defending:
2960 * Normally the player doesn't get the information about the units inside a
2961 * city. However for attacking/defending the player has to know the unit of
2962 * the other side. After the combat a remove_unit packet will be sent
2963 * to the client to tidy up.
2965 * Note these packets must be sent out before unit_versus_unit is called,
2966 * so that the original unit stats (HP) will be sent.
2968 package_short_unit(pattacker
, &unit_att_short_packet
,
2969 UNIT_INFO_IDENTITY
, 0);
2970 package_short_unit(pdefender
, &unit_def_short_packet
,
2971 UNIT_INFO_IDENTITY
, 0);
2972 package_unit(pattacker
, &unit_att_packet
);
2973 package_unit(pdefender
, &unit_def_packet
);
2975 conn_list_iterate(game
.est_connections
, pconn
) {
2976 struct player
*pplayer
= pconn
->playing
;
2978 if (pplayer
!= NULL
) {
2980 /* NOTE: this means the player can see combat between submarines even
2981 * if neither sub is visible. See similar comment in send_combat. */
2982 if (map_is_known_and_seen(unit_tile(pattacker
), pplayer
, V_MAIN
)
2983 || map_is_known_and_seen(unit_tile(pdefender
), pplayer
,
2986 /* Units are sent even if they were visible already. They may
2987 * have changed orientation for combat. */
2988 if (pplayer
== unit_owner(pattacker
)) {
2989 send_packet_unit_info(pconn
, &unit_att_packet
);
2991 send_packet_unit_short_info(pconn
, &unit_att_short_packet
, FALSE
);
2994 if (pplayer
== unit_owner(pdefender
)) {
2995 send_packet_unit_info(pconn
, &unit_def_packet
);
2997 send_packet_unit_short_info(pconn
, &unit_def_short_packet
, FALSE
);
3000 } else if (pconn
->observer
) {
3001 /* Global observer sees everything... */
3002 send_packet_unit_info(pconn
, &unit_att_packet
);
3003 send_packet_unit_info(pconn
, &unit_def_packet
);
3005 } conn_list_iterate_end
;
3008 /**************************************************************************
3009 Send combat info to players.
3010 **************************************************************************/
3011 static void send_combat(struct unit
*pattacker
, struct unit
*pdefender
,
3012 int veteran
, int bombard
)
3014 struct packet_unit_combat_info combat
;
3016 combat
.attacker_unit_id
=pattacker
->id
;
3017 combat
.defender_unit_id
=pdefender
->id
;
3018 combat
.attacker_hp
=pattacker
->hp
;
3019 combat
.defender_hp
=pdefender
->hp
;
3020 combat
.make_winner_veteran
=veteran
;
3022 players_iterate(other_player
) {
3023 /* NOTE: this means the player can see combat between submarines even
3024 * if neither sub is visible. See similar comment in see_combat. */
3025 if (map_is_known_and_seen(unit_tile(pattacker
), other_player
, V_MAIN
)
3026 || map_is_known_and_seen(unit_tile(pdefender
), other_player
,
3028 lsend_packet_unit_combat_info(other_player
->connections
, &combat
);
3031 * Remove the client knowledge of the units. This corresponds to the
3032 * send_packet_unit_short_info calls up above.
3034 if (!can_player_see_unit(other_player
, pattacker
)) {
3035 unit_goes_out_of_sight(other_player
, pattacker
);
3037 if (!can_player_see_unit(other_player
, pdefender
)) {
3038 unit_goes_out_of_sight(other_player
, pdefender
);
3041 } players_iterate_end
;
3043 /* Send combat info to non-player observers as well. They already know
3044 * about the unit so no unit_info is needed. */
3045 conn_list_iterate(game
.est_connections
, pconn
) {
3046 if (NULL
== pconn
->playing
&& pconn
->observer
) {
3047 send_packet_unit_combat_info(pconn
, &combat
);
3049 } conn_list_iterate_end
;
3052 /**************************************************************************
3053 This function assumes the bombard is legal. The calling function should
3054 have already made all necessary checks.
3056 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
3057 this returns TRUE, unit may have died during the action.
3058 **************************************************************************/
3059 static bool unit_bombard(struct unit
*punit
, struct tile
*ptile
)
3061 struct player
*pplayer
= unit_owner(punit
);
3062 struct city
*pcity
= tile_city(ptile
);
3064 /* Sanity check: The actor still exists. */
3065 fc_assert_ret_val(pplayer
, FALSE
);
3066 fc_assert_ret_val(punit
, FALSE
);
3068 log_debug("Start bombard: %s %s to %d, %d.",
3069 nation_rule_name(nation_of_player(pplayer
)),
3070 unit_rule_name(punit
), TILE_XY(ptile
));
3072 unit_list_iterate_safe(ptile
->units
, pdefender
) {
3075 fc_assert_ret_val_msg(!pplayers_non_attack(unit_owner(punit
),
3076 unit_owner(pdefender
)),
3078 "Trying to attack a unit with which you have "
3079 "peace or cease-fire at (%d, %d).",
3080 TILE_XY(unit_tile(pdefender
)));
3081 fc_assert_ret_val_msg(!pplayers_allied(unit_owner(punit
),
3082 unit_owner(pdefender
)),
3084 "Trying to attack a unit with which you have "
3085 "alliance at (%d, %d).",
3086 TILE_XY(unit_tile(pdefender
)));
3088 if (is_unit_reachable_at(pdefender
, punit
, ptile
)) {
3090 enum direction8 facing
;
3093 adj
= base_get_direction_for_step(&(wld
.map
),
3094 punit
->tile
, pdefender
->tile
, &facing
);
3097 punit
->facing
= facing
;
3099 /* Unlike with normal attack, we don't change orientation of
3100 * defenders when bombarding */
3103 unit_bombs_unit(punit
, pdefender
, &att_hp
, &def_hp
);
3105 see_combat(punit
, pdefender
);
3108 pdefender
->hp
= def_hp
;
3110 send_combat(punit
, pdefender
, 0, 1);
3112 send_unit_info(NULL
, pdefender
);
3114 /* May cause an incident */
3115 action_id_consequence_success(ACTION_BOMBARD
, unit_owner(punit
),
3116 unit_owner(pdefender
),
3117 unit_tile(pdefender
),
3118 unit_link(pdefender
));
3121 } unit_list_iterate_safe_end
;
3123 punit
->moves_left
= 0;
3125 unit_did_action(punit
);
3126 unit_forget_last_activity(punit
);
3129 && city_size_get(pcity
) > 1
3130 && get_city_bonus(pcity
, EFT_UNIT_NO_LOSE_POP
) <= 0
3131 && kills_citizen_after_attack(punit
)) {
3132 city_reduce_size(pcity
, 1, pplayer
, "bombard");
3133 city_refresh(pcity
);
3134 send_city_info(NULL
, pcity
);
3137 send_unit_info(NULL
, punit
);
3142 /**************************************************************************
3143 Do a "regular" nuclear attack.
3145 Can be stopped by an EFT_NUKE_PROOF (SDI defended) city.
3147 This function assumes the attack is legal. The calling function should
3148 have already made all necessary checks.
3150 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
3151 this returns TRUE, unit may have died during the action.
3152 **************************************************************************/
3153 static bool unit_nuke(struct player
*pplayer
, struct unit
*punit
,
3154 struct tile
*def_tile
)
3158 /* Sanity check: The actor still exists. */
3159 fc_assert_ret_val(pplayer
, FALSE
);
3160 fc_assert_ret_val(punit
, FALSE
);
3162 log_debug("Start nuclear attack: %s %s against (%d, %d).",
3163 nation_rule_name(nation_of_player(pplayer
)),
3164 unit_rule_name(punit
),
3167 if ((pcity
= sdi_try_defend(pplayer
, def_tile
))) {
3168 /* FIXME: Remove the hard coded reference to SDI defense. */
3169 notify_player(pplayer
, unit_tile(punit
), E_UNIT_LOST_ATT
, ftc_server
,
3170 _("Your %s was shot down by "
3171 "SDI defenses, what a waste."), unit_tile_link(punit
));
3172 notify_player(city_owner(pcity
), def_tile
, E_UNIT_WIN
, ftc_server
,
3173 _("The nuclear attack on %s was avoided by"
3174 " your SDI defense."), city_link(pcity
));
3176 /* Trying to nuke something this close can be... unpopular. */
3177 action_id_consequence_caught(ACTION_NUKE
, pplayer
,
3179 def_tile
, unit_tile_link(punit
));
3181 /* Remove the destroyed nuke. */
3182 wipe_unit(punit
, ULR_SDI
, city_owner(pcity
));
3187 dlsend_packet_nuke_tile_info(game
.est_connections
, tile_index(def_tile
));
3189 /* A nuke is always consumed when it detonates. See below. */
3190 fc_assert(action_by_number(ACTION_NUKE
)->actor_consuming_always
);
3192 /* The nuke must be wiped here so it won't be seen as a victim of its own
3194 wipe_unit(punit
, ULR_DETONATED
, NULL
);
3196 do_nuclear_explosion(pplayer
, def_tile
);
3198 /* May cause an incident even if the target tile is unclaimed. A ruleset
3199 * could give everyone a casus belli against the tile nuker. A rule
3200 * like that would make sense in a story where detonating any nuke at all
3201 * could be forbidden. */
3202 action_id_consequence_success(ACTION_NUKE
, pplayer
,
3203 tile_owner(def_tile
),
3205 tile_link(def_tile
));
3210 /**************************************************************************
3211 Destroy the target city.
3213 This function assumes the destruction is legal. The calling function
3214 should have already made all necessary checks.
3216 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
3217 this returns TRUE, unit may have died during the action.
3218 **************************************************************************/
3219 static bool unit_do_destroy_city(struct player
*act_player
,
3220 struct unit
*act_unit
,
3221 struct city
*tgt_city
)
3224 struct player
*tgt_player
;
3225 bool try_civil_war
= FALSE
;
3227 /* Sanity check: The actor still exists. */
3228 fc_assert_ret_val(act_player
, FALSE
);
3229 fc_assert_ret_val(act_unit
, FALSE
);
3231 /* Sanity check: The target city still exists. */
3232 fc_assert_ret_val(tgt_city
, FALSE
);
3234 tgt_player
= city_owner(tgt_city
);
3236 /* How can a city be ownerless? */
3237 fc_assert_ret_val(tgt_player
, FALSE
);
3240 tgt_city_id
= tgt_city
->id
;
3242 if (is_capital(tgt_city
)
3243 && (tgt_player
->spaceship
.state
== SSHIP_STARTED
3244 || tgt_player
->spaceship
.state
== SSHIP_LAUNCHED
)) {
3245 /* Destroying this city destroys the victim's space ship. */
3246 spaceship_lost(tgt_player
);
3249 if (is_capital(tgt_city
)
3250 && civil_war_possible(tgt_player
, TRUE
, TRUE
)
3251 && normal_player_count() < MAX_NUM_PLAYERS
3252 && civil_war_triggered(tgt_player
)) {
3253 /* Destroying this city can trigger a civil war. */
3254 try_civil_war
= TRUE
;
3257 /* Let the actor know. */
3258 notify_player(act_player
, city_tile(tgt_city
),
3259 E_UNIT_WIN
, ftc_server
,
3260 _("You destroy %s completely."),
3261 city_tile_link(tgt_city
));
3263 if (tgt_player
!= act_player
) {
3264 /* This was done to a foreign city. Inform the victim player. */
3265 notify_player(tgt_player
, city_tile(tgt_city
),
3266 E_CITY_LOST
, ftc_server
,
3267 _("%s has been destroyed by %s."),
3268 city_tile_link(tgt_city
),
3269 player_name(act_player
));
3272 /* May cause an incident */
3273 action_id_consequence_success(ACTION_DESTROY_CITY
, act_player
,
3274 tgt_player
, city_tile(tgt_city
),
3275 city_link(tgt_city
));
3277 /* Run post city destruction Lua script. */
3278 script_server_signal_emit("city_destroyed", 3,
3279 API_TYPE_CITY
, tgt_city
,
3280 API_TYPE_PLAYER
, tgt_player
,
3281 API_TYPE_PLAYER
, act_player
);
3283 /* Can't be sure of city existence after running script. */
3284 if (city_exist(tgt_city_id
)) {
3285 remove_city(tgt_city
);
3288 if (try_civil_war
) {
3289 /* Try to start the civil war. */
3290 (void) civil_war(tgt_player
);
3293 /* The city is no more. */
3297 /**************************************************************************
3298 Do a "regular" attack.
3300 This function assumes the attack is legal. The calling function should
3301 have already made all necessary checks.
3303 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
3304 this returns TRUE, unit may have died during the action.
3305 **************************************************************************/
3306 static bool do_attack(struct unit
*punit
, struct tile
*def_tile
,
3307 const struct action
*paction
)
3309 char loser_link
[MAX_LEN_LINK
], winner_link
[MAX_LEN_LINK
];
3310 struct unit
*ploser
, *pwinner
;
3312 int moves_used
, def_moves_used
;
3313 int old_unit_vet
, old_defender_vet
, vet
;
3315 struct player
*pplayer
= unit_owner(punit
);
3317 enum direction8 facing
;
3319 struct unit
*pdefender
;
3321 if (!(pdefender
= get_defender(punit
, def_tile
))) {
3322 /* Can't fight air... */
3326 log_debug("Start attack: %s %s against %s %s.",
3327 nation_rule_name(nation_of_player(pplayer
)),
3328 unit_rule_name(punit
),
3329 nation_rule_name(nation_of_unit(pdefender
)),
3330 unit_rule_name(pdefender
));
3333 fc_assert_ret_val_msg(!pplayers_non_attack(pplayer
,
3334 unit_owner(pdefender
)),
3336 "Trying to attack a unit with which you have peace "
3337 "or cease-fire at (%d, %d).", TILE_XY(def_tile
));
3338 fc_assert_ret_val_msg(!pplayers_allied(pplayer
, unit_owner(pdefender
)),
3340 "Trying to attack a unit with which you have "
3341 "alliance at (%d, %d).", TILE_XY(def_tile
));
3343 moves_used
= unit_move_rate(punit
) - punit
->moves_left
;
3344 def_moves_used
= unit_move_rate(pdefender
) - pdefender
->moves_left
;
3346 adj
= base_get_direction_for_step(&(wld
.map
),
3347 punit
->tile
, pdefender
->tile
, &facing
);
3351 punit
->facing
= facing
;
3352 pdefender
->facing
= opposite_direction(facing
);
3355 old_unit_vet
= punit
->veteran
;
3356 old_defender_vet
= pdefender
->veteran
;
3357 unit_versus_unit(punit
, pdefender
, &att_hp
, &def_hp
);
3359 if ((att_hp
<= 0 || utype_is_consumed_by_action(paction
, punit
->utype
))
3360 && unit_transported(punit
)) {
3361 /* Dying attacker must be first unloaded so it doesn't die insider transport */
3362 unit_transport_unload_send(punit
);
3365 see_combat(punit
, pdefender
);
3368 pdefender
->hp
= def_hp
;
3370 combat_veterans(punit
, pdefender
);
3372 /* Adjust attackers moves_left _after_ unit_versus_unit() so that
3373 * the movement attack modifier is correct! --dwp
3375 * For greater Civ2 compatibility (and game balance issues), we recompute
3376 * the new total MP based on the HP the unit has left after being damaged,
3377 * and subtract the MPs that had been used before the combat (plus the
3378 * points used in the attack itself, for the attacker). -GJW, Glip
3380 punit
->moves_left
= unit_move_rate(punit
) - moves_used
- SINGLE_MOVE
;
3381 pdefender
->moves_left
= unit_move_rate(pdefender
) - def_moves_used
;
3383 if (punit
->moves_left
< 0) {
3384 punit
->moves_left
= 0;
3386 if (pdefender
->moves_left
< 0) {
3387 pdefender
->moves_left
= 0;
3389 unit_did_action(punit
);
3390 unit_forget_last_activity(punit
);
3393 && (pcity
= tile_city(def_tile
))
3394 && city_size_get(pcity
) > 1
3395 && get_city_bonus(pcity
, EFT_UNIT_NO_LOSE_POP
) <= 0
3396 && kills_citizen_after_attack(punit
)) {
3397 city_reduce_size(pcity
, 1, pplayer
, "attack");
3398 city_refresh(pcity
);
3399 send_city_info(NULL
, pcity
);
3401 if (unit_has_type_flag(punit
, UTYF_ONEATTACK
)) {
3402 punit
->moves_left
= 0;
3404 pwinner
= (punit
->hp
> 0) ? punit
: pdefender
;
3405 winner_id
= pwinner
->id
;
3406 ploser
= (pdefender
->hp
> 0) ? punit
: pdefender
;
3408 vet
= (pwinner
->veteran
== ((punit
->hp
> 0) ? old_unit_vet
:
3409 old_defender_vet
)) ? 0 : 1;
3411 send_combat(punit
, pdefender
, vet
, 0);
3413 /* N.B.: unit_link always returns the same pointer. */
3414 sz_strlcpy(loser_link
, unit_tile_link(ploser
));
3415 sz_strlcpy(winner_link
,
3416 utype_is_consumed_by_action(paction
, pwinner
->utype
)
3417 ? unit_tile_link(pwinner
) : unit_link(pwinner
));
3419 if (punit
== ploser
) {
3420 /* The attacker lost */
3421 log_debug("Attacker lost: %s %s against %s %s.",
3422 nation_rule_name(nation_of_player(pplayer
)),
3423 unit_rule_name(punit
),
3424 nation_rule_name(nation_of_unit(pdefender
)),
3425 unit_rule_name(pdefender
));
3427 notify_player(unit_owner(pwinner
), unit_tile(pwinner
),
3428 E_UNIT_WIN
, ftc_server
,
3429 /* TRANS: "Your Cannon ... the Polish Destroyer." */
3430 _("Your %s survived the pathetic attack from the %s %s."),
3432 nation_adjective_for_player(unit_owner(ploser
)),
3435 notify_unit_experience(pwinner
);
3437 notify_player(unit_owner(ploser
), def_tile
,
3438 E_UNIT_LOST_ATT
, ftc_server
,
3439 /* TRANS: "... Cannon ... the Polish Destroyer." */
3440 _("Your attacking %s failed against the %s %s!"),
3442 nation_adjective_for_player(unit_owner(pwinner
)),
3444 wipe_unit(ploser
, ULR_KILLED
, unit_owner(pwinner
));
3446 /* The defender lost, the attacker punit lives! */
3448 log_debug("Defender lost: %s %s against %s %s.",
3449 nation_rule_name(nation_of_player(pplayer
)),
3450 unit_rule_name(punit
),
3451 nation_rule_name(nation_of_unit(pdefender
)),
3452 unit_rule_name(pdefender
));
3454 punit
->moved
= TRUE
; /* We moved */
3455 kill_unit(pwinner
, ploser
,
3456 vet
&& !utype_is_consumed_by_action(paction
, punit
->utype
));
3457 if (unit_is_alive(winner_id
)) {
3458 if (utype_is_consumed_by_action(paction
, pwinner
->utype
)) {
3466 /* If attacker wins, and occupychance > 0, it might move in. Don't move in
3467 * if there are enemy units in the tile (a fortress, city or air base with
3468 * multiple defenders and unstacked combat). Note that this could mean
3469 * capturing (or destroying) a city. */
3471 if (pwinner
== punit
&& fc_rand(100) < game
.server
.occupychance
3472 && !is_non_allied_unit_tile(def_tile
, pplayer
)) {
3474 /* Hack: make sure the unit has enough moves_left for the move to succeed,
3475 and adjust moves_left to afterward (if successful). */
3477 int old_moves
= punit
->moves_left
;
3478 int full_moves
= unit_move_rate(punit
);
3480 punit
->moves_left
= full_moves
;
3481 /* Post attack occupy move. */
3482 if (((pcity
= tile_city(def_tile
))
3483 && is_action_enabled_unit_on_city(ACTION_CONQUER_CITY
,
3485 && unit_perform_action(unit_owner(punit
), punit
->id
, pcity
->id
,
3486 0, "", ACTION_CONQUER_CITY
, ACT_REQ_RULES
))
3487 || (unit_move_handling(punit
, def_tile
, FALSE
, TRUE
, NULL
))) {
3488 int mcost
= MAX(0, full_moves
- punit
->moves_left
- SINGLE_MOVE
);
3490 /* Move cost is bigger of attack (SINGLE_MOVE) and occupying move costs.
3491 * Attack SINGLE_COST is already calculated in to old_moves. */
3492 punit
->moves_left
= old_moves
- mcost
;
3493 if (punit
->moves_left
< 0) {
3494 punit
->moves_left
= 0;
3497 punit
->moves_left
= old_moves
;
3501 /* The attacker may have died for many reasons */
3502 if (game_unit_by_number(winner_id
) != NULL
) {
3503 send_unit_info(NULL
, pwinner
);
3509 /**************************************************************************
3510 Have the unit conquer a city.
3512 This function assumes the attack is legal. The calling function should
3513 have already made all necessary checks.
3515 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
3516 this returns TRUE, unit may have died during the action.
3517 **************************************************************************/
3518 static bool do_unit_conquer_city(struct player
*act_player
,
3519 struct unit
*act_unit
,
3520 struct city
*tgt_city
,
3521 struct action
*paction
)
3524 struct tile
*tgt_tile
= city_tile(tgt_city
);
3525 int move_cost
= map_move_cost_unit(&(wld
.map
), act_unit
, tgt_tile
);
3526 int tgt_city_id
= tgt_city
->id
;
3527 struct player
*tgt_player
= city_owner(tgt_city
);
3528 const char *victim_link
= city_link(tgt_city
);
3531 fc_assert_ret_val(tgt_tile
, FALSE
);
3533 unit_move(act_unit
, tgt_tile
, move_cost
, NULL
, TRUE
);
3535 /* The city may have been destroyed during the conquest. */
3536 success
= (!city_exist(tgt_city_id
)
3537 || city_owner(tgt_city
) == act_player
);
3540 /* May cause an incident */
3541 action_consequence_success(paction
, act_player
, tgt_player
, tgt_tile
,
3548 /**************************************************************************
3549 see also aiunit could_unit_move_to_tile()
3550 **************************************************************************/
3551 static bool can_unit_move_to_tile_with_notify(struct unit
*punit
,
3552 struct tile
*dest_tile
,
3554 struct unit
*embark_to
,
3555 bool enter_enemy_city
)
3557 struct tile
*src_tile
= unit_tile(punit
);
3558 enum unit_move_result reason
=
3559 unit_move_to_tile_test(&(wld
.map
), punit
, punit
->activity
,
3560 src_tile
, dest_tile
, igzoc
, embark_to
,
3568 notify_player(unit_owner(punit
), src_tile
, E_BAD_COMMAND
, ftc_server
,
3569 _("Cannot attack unless you declare war first."));
3573 notify_player(unit_owner(punit
), src_tile
, E_BAD_COMMAND
, ftc_server
,
3574 _("%s can only move into your own zone of control."),
3579 notify_player(unit_owner(punit
), src_tile
, E_BAD_COMMAND
, ftc_server
,
3580 _("%s cannot move that far from the coast line."),
3585 if (tile_owner(dest_tile
)) {
3586 notify_player(unit_owner(punit
), src_tile
, E_BAD_COMMAND
, ftc_server
,
3587 _("Cannot invade unless you break peace with "
3589 player_name(tile_owner(dest_tile
)));
3593 case MR_CANNOT_DISEMBARK
:
3594 notify_player(unit_owner(punit
), src_tile
, E_BAD_COMMAND
, ftc_server
,
3595 _("%s cannot disembark outside of a city or a native base "
3598 utype_name_translation(
3599 unit_type_get(unit_transport_get(punit
))));
3602 case MR_NON_NATIVE_MOVE
:
3603 notify_player(unit_owner(punit
), src_tile
, E_BAD_COMMAND
, ftc_server
,
3604 _("Terrain is unsuitable for %s units."),
3605 uclass_name_translation(unit_class_get(punit
)));
3609 /* FIXME: need more explanations someday! */
3616 /**************************************************************************
3617 Will try to move to/attack the tile dest_x,dest_y. Returns TRUE if this
3618 was done, FALSE if it wasn't for some reason. Even if this returns TRUE,
3619 the unit may have died upon arrival to new tile.
3621 'igzoc' means ignore ZOC rules - not necessary for igzoc units etc, but
3622 done in some special cases (moving barbarians out of initial hut).
3623 Should normally be FALSE.
3625 'move_do_not_act' is another special case which should normally be
3626 FALSE. If TRUE any enabler controlled actions punit can perform to
3627 pdesttile it self or something located at it will be ignored. If FALSE
3628 the system will check if punit can perform any enabler controlled action
3629 to pdesttile. If it can the player will be asked to choose what to do. If
3630 it can't and punit is unable to move (or perform another non enabler
3631 controlled action) to pdesttile the game will try to explain why.
3633 FIXME: This function needs a good cleaning.
3634 **************************************************************************/
3635 bool unit_move_handling(struct unit
*punit
, struct tile
*pdesttile
,
3636 bool igzoc
, bool move_do_not_act
,
3637 struct unit
*embark_to
)
3639 struct player
*pplayer
= unit_owner(punit
);
3640 struct city
*pcity
= tile_city(pdesttile
);
3642 /*** Phase 1: Basic checks ***/
3644 /* this occurs often during lag, and to the AI due to some quirks -- Syela */
3645 if (!is_tiles_adjacent(unit_tile(punit
), pdesttile
)) {
3646 log_debug("tiles not adjacent in move request");
3651 if (punit
->moves_left
<= 0) {
3652 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
3653 _("This unit has no moves left."));
3657 if (!unit_can_do_action_now(punit
)) {
3661 /*** Phase 2: Special abilities checks ***/
3663 /* Actors. Pop up an action selection dialog in the client.
3664 * If the AI has used a goto to send an actor to a target do not
3665 * pop up a dialog in the client.
3666 * For tiles occupied by allied cities or units, keep moving if
3667 * move_do_not_act tells us to, or if the unit is on goto and the tile
3668 * is not the final destination. */
3669 if (!move_do_not_act
) {
3670 const bool can_not_move
= !unit_can_move_to_tile(&(wld
.map
),
3673 struct tile
*ttile
= action_tgt_tile(punit
, pdesttile
, can_not_move
);
3675 /* Consider to pop up the action selection dialog if a potential city,
3676 * unit or units target exists at the destination tile. A tile target
3677 * will only trigger the pop up if it may be legal. */
3678 if ((0 < unit_list_size(pdesttile
->units
) || pcity
|| ttile
)) {
3679 /* A target (unit or city) exists at the tile. If a target is an ally
3680 * it still looks like a target since move_do_not_act isn't set.
3681 * Assume that the intention is to do an action. */
3683 if ((action_tgt_unit(punit
, pdesttile
, can_not_move
)
3684 || action_tgt_city(punit
, pdesttile
, can_not_move
)
3685 || action_tgt_tile_units(punit
, pdesttile
, can_not_move
)
3688 /* There is a target punit, from the player's point of view, may be
3689 * able to act against OR punit can't do any non action move. The
3690 * client should therefore ask what action(s) the unit can perform
3691 * to any targets at pdesttile.
3693 * In the first case the unit needs a decision about what action, if
3694 * any at all, to take. Asking what actions the unit can perform
3695 * will return a list of actions that may, from the players point of
3696 * view, be possible. The client can then show this list to the
3697 * player or, if configured to do so, make the choice it self.
3699 * In the last case the player may need an explanation about why no
3700 * action could be taken. Asking what actions the unit can perform
3701 * will provide this explanation. */
3702 punit
->action_decision_want
= ACT_DEC_ACTIVE
;
3703 punit
->action_decision_tile
= pdesttile
;
3704 send_unit_info(player_reply_dest(pplayer
), punit
);
3706 /* The move wasn't done because the unit wanted the player to
3707 * decide what to do or because the unit couldn't move to the
3714 /*** Phase 3: OK now move the unit ***/
3716 /* We cannot move a transport into a tile that holds
3717 * units or cities not allied with all of our cargo. */
3718 if (get_transporter_capacity(punit
) > 0) {
3719 unit_list_iterate(unit_tile(punit
)->units
, pcargo
) {
3720 if (unit_contained_in(pcargo
, punit
)
3721 && (is_non_allied_unit_tile(pdesttile
, unit_owner(pcargo
))
3722 || is_non_allied_city_tile(pdesttile
,
3723 unit_owner(pcargo
)))) {
3724 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
3725 _("A transported unit is not allied to all "
3726 "units or city on target tile."));
3729 } unit_list_iterate_end
;
3732 if (can_unit_move_to_tile_with_notify(punit
, pdesttile
, igzoc
,
3733 embark_to
, FALSE
)) {
3734 int move_cost
= map_move_cost_unit(&(wld
.map
), punit
, pdesttile
);
3736 unit_move(punit
, pdesttile
, move_cost
, embark_to
,
3745 /**************************************************************************
3746 Handle request to help in wonder building.
3748 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
3749 this returns TRUE, unit may have died during the action.
3750 **************************************************************************/
3751 static bool do_unit_help_build_wonder(struct player
*pplayer
,
3753 struct city
*pcity_dest
)
3757 /* Sanity check: The actor still exists. */
3758 fc_assert_ret_val(pplayer
, FALSE
);
3759 fc_assert_ret_val(punit
, FALSE
);
3761 /* Sanity check: The target city still exists. */
3762 fc_assert_ret_val(pcity_dest
, FALSE
);
3764 pcity_dest
->shield_stock
+= unit_build_shield_cost(punit
);
3765 pcity_dest
->caravan_shields
+= unit_build_shield_cost(punit
);
3767 conn_list_do_buffer(pplayer
->connections
);
3769 if (build_points_left(pcity_dest
) >= 0) {
3770 /* TRANS: Your Caravan helps build the Pyramids in Bergen (4
3771 * remaining). You can reorder '4' and 'remaining' in the actual
3773 work
= _("remaining");
3775 /* TRANS: Your Caravan helps build the Pyramids in Bergen (4
3776 * surplus). You can reorder '4' and 'surplus' in the actual
3778 work
= _("surplus");
3781 /* Let the player that just donated shields to the wonder building know
3782 * the result of his donation. */
3783 notify_player(pplayer
, city_tile(pcity_dest
), E_CARAVAN_ACTION
,
3785 /* TRANS: Your Caravan helps build the Pyramids in Bergen
3787 _("Your %s helps build the %s in %s (%d %s)."),
3789 improvement_name_translation(
3790 pcity_dest
->production
.value
.building
),
3791 city_link(pcity_dest
),
3792 abs(build_points_left(pcity_dest
)),
3795 /* May cause an incident */
3796 action_id_consequence_success(ACTION_HELP_WONDER
, pplayer
,
3797 city_owner(pcity_dest
),
3798 city_tile(pcity_dest
),
3799 city_link(pcity_dest
));
3801 if (city_owner(pcity_dest
) != unit_owner(punit
)) {
3802 /* Tell the city owner about the gift he just received. */
3804 notify_player(city_owner(pcity_dest
), city_tile(pcity_dest
),
3805 E_CARAVAN_ACTION
, ftc_server
,
3806 /* TRANS: Help building the Pyramids in Bergen received
3807 * from Persian Caravan (4 surplus). */
3808 _("Help building the %s in %s received from %s %s "
3810 improvement_name_translation(
3811 pcity_dest
->production
.value
.building
),
3812 city_link(pcity_dest
),
3813 nation_adjective_for_player(pplayer
),
3815 abs(build_points_left(pcity_dest
)),
3819 send_player_info_c(pplayer
, pplayer
->connections
);
3820 send_city_info(pplayer
, pcity_dest
);
3821 conn_list_do_unbuffer(pplayer
->connections
);
3826 /**************************************************************************
3827 Handle request to establish traderoute. If pcity_dest is NULL, assumes
3828 that unit is inside target city.
3830 Returns TRUE iff action could be done, FALSE if it couldn't. Even if
3831 this returns TRUE, unit may have died during the action.
3832 **************************************************************************/
3833 static bool do_unit_establish_trade(struct player
*pplayer
,
3835 struct city
*pcity_dest
,
3838 char homecity_link
[MAX_LEN_LINK
], destcity_link
[MAX_LEN_LINK
];
3839 char punit_link
[MAX_LEN_LINK
];
3842 int home_overbooked
= 0;
3843 int dest_overbooked
= 0;
3846 struct city
*pcity_homecity
;
3847 struct trade_route_list
*routes_out_of_dest
;
3848 struct trade_route_list
*routes_out_of_home
;
3849 enum traderoute_bonus_type bonus_type
;
3850 const char *bonus_str
;
3851 struct goods_type
*goods
;
3852 const char *goods_str
;
3854 /* Sanity check: The actor still exists. */
3855 fc_assert_ret_val(pplayer
, FALSE
);
3856 fc_assert_ret_val(punit
, FALSE
);
3858 /* Sanity check: The target city still exists. */
3859 fc_assert_ret_val(pcity_dest
, FALSE
);
3861 pcity_homecity
= player_city_by_number(pplayer
, punit
->homecity
);
3863 if (!pcity_homecity
) {
3864 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
3865 _("Sorry, your %s cannot establish"
3866 " a trade route because it has no home city."),
3871 if (game
.info
.goods_selection
== GSM_ARRIVAL
) {
3872 goods
= goods_from_city_to_unit(pcity_homecity
, punit
);
3874 goods
= punit
->carrying
;
3876 if (goods
== NULL
) {
3877 notify_player(pplayer
, unit_tile(punit
), E_BAD_COMMAND
, ftc_server
,
3878 _("Sorry, your %s cannot establish"
3879 " a trade route because it's not carrying any goods."),
3884 sz_strlcpy(homecity_link
, city_link(pcity_homecity
));
3885 sz_strlcpy(destcity_link
, city_link(pcity_dest
));
3887 if (!can_cities_trade(pcity_homecity
, pcity_dest
)) {
3888 notify_player(pplayer
, city_tile(pcity_dest
), E_BAD_COMMAND
, ftc_server
,
3889 _("Sorry, your %s cannot establish"
3890 " a trade route between %s and %s."),
3897 sz_strlcpy(punit_link
, unit_tile_link(punit
));
3898 routes_out_of_home
= trade_route_list_new();
3899 routes_out_of_dest
= trade_route_list_new();
3901 /* This part of code works like can_establish_trade_route, except
3902 * that we actually do the action of making the trade route. */
3904 /* If we can't make a new trade route we can still get the trade bonus. */
3905 can_establish
= est_if_able
3906 && !have_cities_trade_route(pcity_homecity
, pcity_dest
);
3908 if (can_establish
) {
3909 home_max
= max_trade_routes(pcity_homecity
);
3910 dest_max
= max_trade_routes(pcity_dest
);
3911 home_overbooked
= city_num_trade_routes(pcity_homecity
) - home_max
;
3912 dest_overbooked
= city_num_trade_routes(pcity_dest
) - dest_max
;
3915 if (can_establish
&& (home_overbooked
>= 0 || dest_overbooked
>= 0)) {
3916 int trade
= trade_base_between_cities(pcity_homecity
, pcity_dest
);
3918 /* See if there's a trade route we can cancel at the home city. */
3919 if (home_overbooked
>= 0) {
3921 || (city_trade_removable(pcity_homecity
, routes_out_of_home
)
3923 notify_player(pplayer
, city_tile(pcity_dest
),
3924 E_BAD_COMMAND
, ftc_server
,
3925 _("Sorry, your %s cannot establish"
3926 " a trade route here!"),
3929 notify_player(pplayer
, city_tile(pcity_dest
),
3930 E_BAD_COMMAND
, ftc_server
,
3931 PL_(" The city of %s already has %d "
3932 "better trade route!",
3933 " The city of %s already has %d "
3934 "better trade routes!", home_max
),
3938 can_establish
= FALSE
;
3942 /* See if there's a trade route we can cancel at the dest city. */
3943 if (can_establish
&& dest_overbooked
>= 0) {
3945 || (city_trade_removable(pcity_dest
, routes_out_of_dest
)
3947 notify_player(pplayer
, city_tile(pcity_dest
),
3948 E_BAD_COMMAND
, ftc_server
,
3949 _("Sorry, your %s cannot establish"
3950 " a trade route here!"),
3953 notify_player(pplayer
, city_tile(pcity_dest
),
3954 E_BAD_COMMAND
, ftc_server
,
3955 PL_(" The city of %s already has %d "
3956 "better trade route!",
3957 " The city of %s already has %d "
3958 "better trade routes!", dest_max
),
3962 can_establish
= FALSE
;
3967 /* We now know for sure whether we can establish a trade route. */
3969 /* Calculate and announce initial revenue. */
3970 revenue
= get_caravan_enter_city_trade_bonus(pcity_homecity
, pcity_dest
,
3973 bonus_type
= trade_route_settings_by_type(cities_trade_route_type(pcity_homecity
, pcity_dest
))->bonus_type
;
3976 switch (bonus_type
) {
3980 /* TRANS: used as part of caravan revenue sentence. */
3981 bonus_str
= Q_("?tradebonustype:gold");
3983 case TBONUS_SCIENCE
:
3984 /* TRANS: used as part of caravan revenue sentence. */
3985 bonus_str
= Q_("?tradebonustype:research");
3988 /* TRANS: used as part of caravan revenue sentence. */
3989 bonus_str
= Q_("?tradebonustype:gold and research");
3993 conn_list_do_buffer(pplayer
->connections
);
3995 goods_str
= goods_name_translation(goods
);
3997 if (bonus_str
!= NULL
) {
3998 notify_player(pplayer
, city_tile(pcity_dest
),
3999 E_CARAVAN_ACTION
, ftc_server
,
4000 /* TRANS: ... Caravan ... Paris ... Stockholm, ... Goods... gold and research. */
4001 PL_("Your %s from %s has arrived in %s carrying %s,"
4002 " and revenues amount to %d in %s.",
4003 "Your %s from %s has arrived in %s carrying %s,"
4004 " and revenues amount to %d in %s.",
4013 notify_player(pplayer
, city_tile(pcity_dest
),
4014 E_CARAVAN_ACTION
, ftc_server
,
4015 /* TRANS: ... Caravan ... Paris ... Stockholm ... Goods */
4016 _("Your %s from %s has arrived in %s carrying %s."),
4023 if (bonus_type
== TBONUS_GOLD
|| bonus_type
== TBONUS_BOTH
) {
4024 pplayer
->economic
.gold
+= revenue
;
4026 send_player_info_c(pplayer
, pplayer
->connections
);
4029 if (bonus_type
== TBONUS_SCIENCE
|| bonus_type
== TBONUS_BOTH
) {
4030 /* add bulbs and check for finished research */
4031 update_bulbs(pplayer
, revenue
, TRUE
);
4033 /* Inform everyone about tech changes */
4034 send_research_info(research_get(pplayer
), NULL
);
4037 if (can_establish
) {
4038 struct trade_route
*proute_from
, *proute_to
;
4039 struct city_list
*cities_out_of_home
;
4040 struct city_list
*cities_out_of_dest
;
4042 /* Announce creation of trade route (it's not actually created until
4043 * later in this function, as we have to cancel existing routes, but
4044 * it makes more sense to announce in this order) */
4046 /* Always tell the unit owner */
4047 notify_player(pplayer
, NULL
,
4048 E_CARAVAN_ACTION
, ftc_server
,
4049 _("New trade route established from %s to %s."),
4052 if (pplayer
!= city_owner(pcity_dest
)) {
4053 notify_player(city_owner(pcity_dest
), city_tile(pcity_dest
),
4054 E_CARAVAN_ACTION
, ftc_server
,
4055 _("The %s established a trade route between their "
4057 nation_plural_for_player(pplayer
),
4062 cities_out_of_home
= city_list_new();
4063 cities_out_of_dest
= city_list_new();
4065 /* Now cancel any less profitable trade route from the home city. */
4066 trade_route_list_iterate(routes_out_of_home
, premove
) {
4067 struct trade_route
*pback
;
4069 city_list_append(cities_out_of_home
, game_city_by_number(premove
->partner
));
4071 pback
= remove_trade_route(pcity_homecity
, premove
, TRUE
, FALSE
);
4074 } trade_route_list_iterate_end
;
4076 /* And the same for the dest city. */
4077 trade_route_list_iterate(routes_out_of_dest
, premove
) {
4078 struct trade_route
*pback
;
4080 city_list_append(cities_out_of_dest
, game_city_by_number(premove
->partner
));
4082 pback
= remove_trade_route(pcity_dest
, premove
, TRUE
, FALSE
);
4085 } trade_route_list_iterate_end
;
4087 /* Actually create the new trade route */
4088 proute_from
= fc_malloc(sizeof(struct trade_route
));
4089 proute_from
->partner
= pcity_dest
->id
;
4090 proute_from
->goods
= goods
;
4092 proute_to
= fc_malloc(sizeof(struct trade_route
));
4093 proute_to
->partner
= pcity_homecity
->id
;
4094 proute_to
->goods
= goods
;
4096 if (goods_has_flag(goods
, GF_BIDIRECTIONAL
)) {
4097 proute_from
->dir
= RDIR_BIDIRECTIONAL
;
4098 proute_to
->dir
= RDIR_BIDIRECTIONAL
;
4100 proute_from
->dir
= RDIR_FROM
;
4101 proute_to
->dir
= RDIR_TO
;
4103 trade_route_list_append(pcity_homecity
->routes
, proute_from
);
4104 trade_route_list_append(pcity_dest
->routes
, proute_to
);
4106 /* Refresh the cities. */
4107 city_refresh(pcity_homecity
);
4108 city_refresh(pcity_dest
);
4109 city_list_iterate(cities_out_of_home
, pcity
) {
4110 city_refresh(pcity
);
4111 } city_list_iterate_end
;
4112 city_list_iterate(cities_out_of_dest
, pcity
) {
4113 city_refresh(pcity
);
4114 } city_list_iterate_end
;
4116 /* Notify the owners of the cities. */
4117 send_city_info(pplayer
, pcity_homecity
);
4118 send_city_info(city_owner(pcity_dest
), pcity_dest
);
4119 city_list_iterate(cities_out_of_home
, pcity
) {
4120 send_city_info(city_owner(pcity
), pcity
);
4121 } city_list_iterate_end
;
4122 city_list_iterate(cities_out_of_dest
, pcity
) {
4123 send_city_info(city_owner(pcity
), pcity
);
4124 } city_list_iterate_end
;
4126 /* Notify each player about the other cities so that they know about
4127 * its size for the trade calculation . */
4128 if (pplayer
!= city_owner(pcity_dest
)) {
4129 send_city_info(city_owner(pcity_dest
), pcity_homecity
);
4130 send_city_info(pplayer
, pcity_dest
);
4133 city_list_iterate(cities_out_of_home
, pcity
) {
4134 if (city_owner(pcity_dest
) != city_owner(pcity
)) {
4135 send_city_info(city_owner(pcity_dest
), pcity
);
4136 send_city_info(city_owner(pcity
), pcity_dest
);
4138 if (pplayer
!= city_owner(pcity
)) {
4139 send_city_info(pplayer
, pcity
);
4140 send_city_info(city_owner(pcity
), pcity_homecity
);
4142 } city_list_iterate_end
;
4144 city_list_iterate(cities_out_of_dest
, pcity
) {
4145 if (city_owner(pcity_dest
) != city_owner(pcity
)) {
4146 send_city_info(city_owner(pcity_dest
), pcity
);
4147 send_city_info(city_owner(pcity
), pcity_dest
);
4149 if (pplayer
!= city_owner(pcity
)) {
4150 send_city_info(pplayer
, pcity
);
4151 send_city_info(city_owner(pcity
), pcity_homecity
);
4153 } city_list_iterate_end
;
4155 city_list_destroy(cities_out_of_home
);
4156 city_list_destroy(cities_out_of_dest
);
4159 /* May cause an incident */
4160 action_id_consequence_success(est_if_able
?
4161 ACTION_TRADE_ROUTE
:
4163 pplayer
, city_owner(pcity_dest
),
4164 city_tile(pcity_dest
),
4165 city_link(pcity_dest
));
4167 conn_list_do_unbuffer(pplayer
->connections
);
4170 trade_route_list_destroy(routes_out_of_home
);
4171 trade_route_list_destroy(routes_out_of_dest
);
4176 /**************************************************************************
4177 Change various unit server side client state.
4179 The server keeps various unit state that is owned by the client. The only
4180 consequence this state has for the game is how the client reacts to it.
4181 The state may be server side because the server writes to it or simply to
4182 have it end up in the save game.
4183 **************************************************************************/
4184 void handle_unit_sscs_set(struct player
*pplayer
,
4186 enum unit_ss_data_type type
,
4189 struct unit
*punit
= player_unit_by_number(pplayer
, unit_id
);
4191 if (NULL
== punit
) {
4192 /* Being asked to unqueue a "spent" unit because the client haven't
4193 * been told that it's gone is expected. */
4194 if (type
!= USSDT_UNQUEUE
) {
4195 /* Probably died or bribed. */
4196 log_verbose("handle_unit_sscs_set() invalid unit %d", unit_id
);
4204 /* Reminds the client to ask the server about what actions the unit can
4205 * perform against the target tile. Action decision state can be set by
4206 * the server it self too. */
4208 if (index_to_tile(&(wld
.map
), value
) == NULL
) {
4209 /* Asked to be reminded to ask what actions the unit can do to a non
4210 * existing target tile. */
4211 log_verbose("unit_sscs_set() invalid target tile %d for unit %d",
4216 punit
->action_decision_want
= ACT_DEC_ACTIVE
;
4217 punit
->action_decision_tile
= index_to_tile(&(wld
.map
), value
);
4219 /* Let the client know that this unit needs the player to decide
4221 send_unit_info(player_reply_dest(pplayer
), punit
);
4225 /* Delete the reminder for the client to ask the server about what
4226 * actions the unit can perform against a certain target tile.
4227 * Action decision state can be set by the server it self too. */
4229 punit
->action_decision_want
= ACT_DEC_NOTHING
;
4230 punit
->action_decision_tile
= NULL
;
4232 /* Let the client know that this unit no longer needs the player to
4233 * decide what to do. */
4234 send_unit_info(player_reply_dest(pplayer
), punit
);
4237 case USSDT_BATTLE_GROUP
:
4238 /* Battlegroups are handled entirely by the client, so all we have to
4239 do here is save the battlegroup ID so that it'll be persistent. */
4241 punit
->battlegroup
= CLIP(-1, value
, MAX_NUM_BATTLEGROUPS
);
4247 /**************************************************************************
4248 Handle request to set unit to autosettler mode.
4249 **************************************************************************/
4250 void handle_unit_autosettlers(struct player
*pplayer
, int unit_id
)
4252 struct unit
*punit
= player_unit_by_number(pplayer
, unit_id
);
4254 if (NULL
== punit
) {
4255 /* Probably died or bribed. */
4256 log_verbose("handle_unit_autosettlers() invalid unit %d", unit_id
);
4260 if (!can_unit_do_autosettlers(punit
)) {
4264 punit
->ai_controlled
= TRUE
;
4265 send_unit_info(NULL
, punit
);
4268 /**************************************************************************
4269 Update everything that needs changing when unit activity changes from
4270 old activity to new one.
4271 **************************************************************************/
4272 static void unit_activity_dependencies(struct unit
*punit
,
4273 enum unit_activity old_activity
,
4274 struct extra_type
*old_target
)
4276 switch (punit
->activity
) {
4278 switch (old_activity
) {
4279 case ACTIVITY_PILLAGE
:
4281 if (old_target
!= NULL
) {
4282 unit_list_iterate_safe(unit_tile(punit
)->units
, punit2
) {
4283 if (punit2
->activity
== ACTIVITY_PILLAGE
) {
4284 extra_deps_iterate(&(punit2
->activity_target
->reqs
), pdep
) {
4285 if (pdep
== old_target
) {
4286 set_unit_activity(punit2
, ACTIVITY_IDLE
);
4287 send_unit_info(NULL
, punit2
);
4290 } extra_deps_iterate_end
;
4292 } unit_list_iterate_safe_end
;
4296 case ACTIVITY_EXPLORE
:
4297 /* Restore unit's control status */
4298 punit
->ai_controlled
= FALSE
;
4304 case ACTIVITY_EXPLORE
:
4305 punit
->ai_controlled
= TRUE
;
4306 set_unit_activity(punit
, ACTIVITY_EXPLORE
);
4307 send_unit_info(NULL
, punit
);
4315 /**************************************************************************
4316 Handle request for changing activity.
4317 **************************************************************************/
4318 void unit_activity_handling(struct unit
*punit
,
4319 enum unit_activity new_activity
)
4321 /* Must specify target for ACTIVITY_BASE */
4322 fc_assert_ret(new_activity
!= ACTIVITY_BASE
4323 && new_activity
!= ACTIVITY_GEN_ROAD
);
4325 if (new_activity
== ACTIVITY_PILLAGE
) {
4326 struct extra_type
*target
= NULL
;
4328 /* Assume untargeted pillaging if no target specified */
4329 unit_activity_handling_targeted(punit
, new_activity
, &target
);
4330 } else if (can_unit_do_activity(punit
, new_activity
)) {
4331 enum unit_activity old_activity
= punit
->activity
;
4332 struct extra_type
*old_target
= punit
->activity_target
;
4334 free_unit_orders(punit
);
4335 set_unit_activity(punit
, new_activity
);
4336 send_unit_info(NULL
, punit
);
4337 unit_activity_dependencies(punit
, old_activity
, old_target
);
4341 /**************************************************************************
4342 Handle request for targeted activity.
4343 **************************************************************************/
4344 void unit_activity_handling_targeted(struct unit
*punit
,
4345 enum unit_activity new_activity
,
4346 struct extra_type
**new_target
)
4348 if (!activity_requires_target(new_activity
)) {
4349 unit_activity_handling(punit
, new_activity
);
4350 } else if (can_unit_do_activity_targeted(punit
, new_activity
, *new_target
)) {
4351 enum unit_activity old_activity
= punit
->activity
;
4352 struct extra_type
*old_target
= punit
->activity_target
;
4353 enum unit_activity stored_activity
= new_activity
;
4355 free_unit_orders(punit
);
4356 unit_assign_specific_activity_target(punit
,
4357 &new_activity
, new_target
);
4358 if (new_activity
!= stored_activity
4359 && !activity_requires_target(new_activity
)) {
4360 /* unit_assign_specific_activity_target() changed our target activity
4361 * (to ACTIVITY_IDLE in practice) */
4362 unit_activity_handling(punit
, new_activity
);
4364 set_unit_activity_targeted(punit
, new_activity
, *new_target
);
4365 send_unit_info(NULL
, punit
);
4366 unit_activity_dependencies(punit
, old_activity
, old_target
);
4371 /****************************************************************************
4372 Handle a client request to load the given unit into the given transporter.
4373 ****************************************************************************/
4374 void handle_unit_load(struct player
*pplayer
, int cargo_id
, int trans_id
,
4377 struct unit
*pcargo
= player_unit_by_number(pplayer
, cargo_id
);
4378 struct unit
*ptrans
= game_unit_by_number(trans_id
);
4379 struct tile
*ptile
= index_to_tile(&(wld
.map
), ttile_idx
);
4385 if (NULL
== pcargo
) {
4386 /* Probably died or bribed. */
4387 log_verbose("handle_unit_load() invalid cargo %d", cargo_id
);
4391 if (NULL
== ptrans
) {
4392 /* Probably died or bribed. */
4393 log_verbose("handle_unit_load() invalid transport %d", trans_id
);
4397 ttile
= unit_tile(ptrans
);
4398 if (!same_pos(ttile
, ptile
)) {
4399 /* Transport no longer in where client assumed it to be. */
4403 ctile
= unit_tile(pcargo
);
4405 if (!same_pos(ctile
, ttile
)) {
4406 if (pcargo
->moves_left
<= 0
4407 || !unit_can_move_to_tile(&(wld
.map
), pcargo
, ttile
, FALSE
, FALSE
)) {
4414 if (unit_transported(pcargo
)) {
4415 if (!can_unit_unload(pcargo
, ptrans
)) {
4416 /* Can't leave current transport */
4423 /* A player may only load their units, but they may be loaded into
4424 * other player's transporters, depending on the rules in
4425 * could_unit_load(). */
4426 if (!could_unit_load(pcargo
, ptrans
)) {
4430 /* It's possible. Let's make all the necessary steps. */
4432 unit_transport_unload(pcargo
);
4436 /* Pre load move. */
4437 unit_move_handling(pcargo
, ttile
, FALSE
, TRUE
, ptrans
);
4441 /* Load the unit and send out info to clients. */
4442 unit_transport_load_send(pcargo
, ptrans
);
4445 /****************************************************************************
4446 Handle a client request to unload the given unit from the given
4448 ****************************************************************************/
4449 void handle_unit_unload(struct player
*pplayer
, int cargo_id
, int trans_id
)
4451 struct unit
*pcargo
= game_unit_by_number(cargo_id
);
4452 struct unit
*ptrans
= game_unit_by_number(trans_id
);
4454 if (NULL
== pcargo
) {
4455 /* Probably died or bribed. */
4456 log_verbose("handle_unit_unload() invalid cargo %d", cargo_id
);
4460 if (NULL
== ptrans
) {
4461 /* Probably died or bribed. */
4462 log_verbose("handle_unit_unload() invalid transport %d", trans_id
);
4466 /* You are allowed to unload a unit if it is yours or if the transporter
4468 if (unit_owner(pcargo
) != pplayer
&& unit_owner(ptrans
) != pplayer
) {
4472 if (!can_unit_unload(pcargo
, ptrans
)) {
4476 if (!can_unit_survive_at_tile(&(wld
.map
), pcargo
, unit_tile(pcargo
))) {
4480 /* Unload the unit and send out info to clients. */
4481 unit_transport_unload_send(pcargo
);
4484 /****************************************************************************
4485 Receives route packages.
4486 ****************************************************************************/
4487 void handle_unit_orders(struct player
*pplayer
,
4488 const struct packet_unit_orders
*packet
)
4490 int length
= packet
->length
, i
;
4491 struct unit
*punit
= player_unit_by_number(pplayer
, packet
->unit_id
);
4492 struct tile
*src_tile
= index_to_tile(&(wld
.map
), packet
->src_tile
);
4494 if (NULL
== punit
) {
4495 /* Probably died or bribed. */
4496 log_verbose("handle_unit_orders() invalid unit %d", packet
->unit_id
);
4500 if (0 > length
|| MAX_LEN_ROUTE
< length
) {
4501 /* Shouldn't happen */
4502 log_error("handle_unit_orders() invalid %s (%d) "
4503 "packet length %d (max %d)", unit_rule_name(punit
),
4504 packet
->unit_id
, length
, MAX_LEN_ROUTE
);
4508 if (src_tile
!= unit_tile(punit
)) {
4509 /* Failed sanity check. Usually this happens if the orders were sent
4510 * in the previous turn, and the client thought the unit was in a
4511 * different position than it's actually in. The easy solution is to
4512 * discard the packet. We don't send an error message to the client
4513 * here (though maybe we should?). */
4514 log_verbose("handle_unit_orders() invalid %s (%d) tile (%d, %d) "
4515 "!= (%d, %d)", unit_rule_name(punit
), punit
->id
,
4516 TILE_XY(src_tile
), TILE_XY(unit_tile(punit
)));
4520 if (ACTIVITY_IDLE
!= punit
->activity
) {
4521 /* New orders implicitly abandon current activity */
4522 unit_activity_handling(punit
, ACTIVITY_IDLE
);
4525 for (i
= 0; i
< length
; i
++) {
4526 if (packet
->orders
[i
] < 0 || packet
->orders
[i
] > ORDER_LAST
) {
4527 log_error("%s() %s (player nb %d) has sent an invalid order %d "
4528 "at index %d, truncating", __FUNCTION__
,
4529 player_name(pplayer
), player_number(pplayer
),
4530 packet
->orders
[i
], i
);
4534 switch (packet
->orders
[i
]) {
4536 case ORDER_ACTION_MOVE
:
4537 if (!map_untrusted_dir_is_valid(packet
->dir
[i
])) {
4538 log_error("handle_unit_orders() %d isn't a valid move direction. "
4539 "Sent in order number %d from %s to unit number %d.",
4541 player_name(pplayer
), packet
->unit_id
);
4546 case ORDER_ACTIVITY
:
4547 switch (packet
->activity
[i
]) {
4548 case ACTIVITY_FALLOUT
:
4549 case ACTIVITY_POLLUTION
:
4550 case ACTIVITY_PILLAGE
:
4552 case ACTIVITY_IRRIGATE
:
4553 case ACTIVITY_TRANSFORM
:
4554 case ACTIVITY_CONVERT
:
4555 /* Simple activities. */
4557 case ACTIVITY_FORTIFYING
:
4558 case ACTIVITY_SENTRY
:
4559 if (i
!= length
- 1) {
4560 /* Only allowed as the last order. */
4561 log_error("handle_unit_orders() activity %d is only allowed in "
4563 "Sent in order number %d from %s to unit number %d.",
4564 packet
->activity
[i
], i
,
4565 player_name(pplayer
), packet
->unit_id
);
4571 if (!is_extra_caused_by(extra_by_number(packet
->target
[i
]), EC_BASE
)) {
4572 log_error("handle_unit_orders() %s isn't a base. "
4573 "Sent in order number %d from %s to unit number %d.",
4574 extra_rule_name(extra_by_number(packet
->target
[i
])), i
,
4575 player_name(pplayer
), packet
->unit_id
);
4580 case ACTIVITY_GEN_ROAD
:
4581 if (!is_extra_caused_by(extra_by_number(packet
->target
[i
]), EC_ROAD
)) {
4582 log_error("handle_unit_orders() %s isn't a road. "
4583 "Sent in order number %d from %s to unit number %d.",
4584 extra_rule_name(extra_by_number(packet
->target
[i
])), i
,
4585 player_name(pplayer
), packet
->unit_id
);
4590 /* Not supported yet. */
4591 case ACTIVITY_EXPLORE
:
4593 /* Not set from the client. */
4595 case ACTIVITY_FORTIFIED
:
4596 /* Compatiblity, used in savegames. */
4597 case ACTIVITY_OLD_ROAD
:
4598 case ACTIVITY_OLD_RAILROAD
:
4599 case ACTIVITY_FORTRESS
:
4600 case ACTIVITY_AIRBASE
:
4602 case ACTIVITY_PATROL_UNUSED
:
4604 case ACTIVITY_UNKNOWN
:
4605 log_error("handle_unit_orders() unsupported activity %d. "
4606 "Sent in order number %d from %s to unit number %d.",
4607 packet
->activity
[i
], i
,
4608 player_name(pplayer
), packet
->unit_id
);
4613 if (packet
->target
[i
] == EXTRA_NONE
4614 && unit_activity_needs_target_from_client(packet
->activity
[i
])) {
4615 /* The orders system can't do server side target assignment for
4617 log_error("handle_unit_orders() can't assign target for %d. "
4618 "Sent in order number %d from %s to unit number %d.",
4619 packet
->activity
[i
], i
,
4620 player_name(pplayer
), packet
->unit_id
);
4626 case ORDER_PERFORM_ACTION
:
4627 if (!action_id_exists(packet
->action
[i
])) {
4628 /* Non existing action */
4629 log_error("handle_unit_orders() the action %d doesn't exist. "
4630 "Sent in order number %d from %s to unit number %d.",
4631 packet
->action
[i
], i
,
4632 player_name(pplayer
), packet
->unit_id
);
4637 if (action_id_distance_inside_max(packet
->action
[i
], 2)) {
4638 /* Long range actions aren't supported in unit orders. Clients
4639 * should order them performed via the unit_do_action packet.
4641 * Reason: A unit order stores an action's target as the tile it is
4642 * located on. The tile is stored as a direction (when the target
4643 * is at a tile adjacent to the actor unit tile) or as no
4644 * direction (when the target is at the same tile as the actor
4645 * unit). The order system will pick a suitable target at the
4646 * specified tile during order execution. This makes it impossible
4647 * to target something that isn't at or next to the actors tile.
4648 * Being unable to exploit the full range of an action handicaps
4651 * A patch that allows a distant target in an order should remove
4652 * this check and update the comment in the Qt client's
4653 * go_act_menu::create(). */
4655 log_error("handle_unit_orders() the action %s isn't supported in "
4657 "Sent in order number %d from %s to unit number %d.",
4658 action_id_name_translation(packet
->action
[i
]), i
,
4659 player_name(pplayer
), packet
->unit_id
);
4664 if (!action_id_distance_inside_max(packet
->action
[i
], 1)
4665 && map_untrusted_dir_is_valid(packet
->dir
[i
])) {
4666 /* Actor must be on the target tile. */
4667 log_error("handle_unit_orders() can't do %s to a neighbor tile. "
4668 "Sent in order number %d from %s to unit number %d.",
4669 action_id_rule_name(packet
->action
[i
]), i
,
4670 player_name(pplayer
), packet
->unit_id
);
4675 /* Validate individual actions. */
4676 switch ((enum gen_action
) packet
->action
[i
]) {
4677 case ACTION_SPY_TARGETED_SABOTAGE_CITY
:
4678 /* Sabotage target is production (-1) or a building. */
4679 if (!(packet
->target
[i
] - 1 == -1
4680 || improvement_by_number(packet
->target
[i
] - 1))) {
4681 /* Sabotage target is invalid. */
4683 log_error("handle_unit_orders() can't do %s without a target. "
4684 "Sent in order number %d from %s to unit number %d.",
4685 action_id_rule_name(packet
->action
[i
]), i
,
4686 player_name(pplayer
), packet
->unit_id
);
4691 case ACTION_SPY_TARGETED_STEAL_TECH
:
4692 if (packet
->target
[i
] == A_NONE
4693 || (!valid_advance_by_number(packet
->target
[i
])
4694 && packet
->target
[i
] != A_FUTURE
)) {
4695 /* Target tech is invalid. */
4697 log_error("handle_unit_orders() can't do %s without a target. "
4698 "Sent in order number %d from %s to unit number %d.",
4699 action_id_rule_name(packet
->action
[i
]), i
,
4700 player_name(pplayer
), packet
->unit_id
);
4705 case ACTION_ESTABLISH_EMBASSY
:
4706 case ACTION_ESTABLISH_EMBASSY_STAY
:
4707 case ACTION_SPY_INVESTIGATE_CITY
:
4708 case ACTION_INV_CITY_SPEND
:
4709 case ACTION_SPY_POISON
:
4710 case ACTION_SPY_STEAL_GOLD
:
4711 case ACTION_SPY_SABOTAGE_CITY
:
4712 case ACTION_SPY_STEAL_TECH
:
4713 case ACTION_SPY_INCITE_CITY
:
4714 case ACTION_SPY_INCITE_CITY_ESC
:
4715 case ACTION_TRADE_ROUTE
:
4716 case ACTION_MARKETPLACE
:
4717 case ACTION_HELP_WONDER
:
4718 case ACTION_SPY_BRIBE_UNIT
:
4719 case ACTION_SPY_SABOTAGE_UNIT
:
4720 case ACTION_CAPTURE_UNITS
:
4721 case ACTION_FOUND_CITY
:
4722 case ACTION_JOIN_CITY
:
4723 case ACTION_STEAL_MAPS
:
4724 case ACTION_BOMBARD
:
4725 case ACTION_SPY_NUKE
:
4726 case ACTION_SPY_NUKE_ESC
:
4728 case ACTION_DESTROY_CITY
:
4729 case ACTION_EXPEL_UNIT
:
4730 case ACTION_RECYCLE_UNIT
:
4731 case ACTION_DISBAND_UNIT
:
4732 case ACTION_HOME_CITY
:
4733 case ACTION_UPGRADE_UNIT
:
4735 case ACTION_CONQUER_CITY
:
4736 case ACTION_PARADROP
:
4737 case ACTION_AIRLIFT
:
4738 case ACTION_HEAL_UNIT
:
4739 /* No validation required. */
4741 /* Invalid action. Should have been caught above. */
4743 fc_assert_ret_msg(packet
->action
[i
] != ACTION_NONE
,
4744 "ACTION_NONE in ORDER_PERFORM_ACTION order. "
4745 "Order number %d from %s to unit number %d.",
4746 i
, player_name(pplayer
), packet
->unit_id
);
4749 /* Don't validate that the target tile really contains a target or
4750 * that the actor player's map think the target tile has one.
4751 * The player may target a something from his player map that isn't
4752 * there any more, a target he thinks is there even if his player map
4753 * doesn't have it or even a target he assumes will be there when the
4754 * unit reaches the target tile.
4756 * With that said: The client should probably at least have an
4757 * option to only aim city targeted actions at cities. */
4763 /* An invalid order. This is handled in execute_orders. */
4768 /* This must be before old orders are freed. If this is is
4769 * settlers on city founding mission, city spot reservation
4770 * from goto_tile must be freed, and free_unit_orders() loses
4771 * goto_tile information */
4772 adv_unit_new_task(punit
, AUT_NONE
, NULL
);
4774 free_unit_orders(punit
);
4775 /* If we waited on a tile, reset punit->done_moving */
4776 punit
->done_moving
= (punit
->moves_left
<= 0);
4778 /* Make sure that the unit won't keep its old ai_controlled state after
4779 * it has recieved new orders from the client. */
4780 punit
->ai_controlled
= FALSE
;
4783 fc_assert(!unit_has_orders(punit
));
4784 send_unit_info(NULL
, punit
);
4788 punit
->has_orders
= TRUE
;
4789 punit
->orders
.length
= length
;
4790 punit
->orders
.index
= 0;
4791 punit
->orders
.repeat
= packet
->repeat
;
4792 punit
->orders
.vigilant
= packet
->vigilant
;
4794 = fc_malloc(length
* sizeof(*(punit
->orders
.list
)));
4795 for (i
= 0; i
< length
; i
++) {
4796 punit
->orders
.list
[i
].order
= packet
->orders
[i
];
4797 punit
->orders
.list
[i
].dir
= packet
->dir
[i
];
4798 punit
->orders
.list
[i
].activity
= packet
->activity
[i
];
4799 punit
->orders
.list
[i
].target
= packet
->target
[i
];
4800 punit
->orders
.list
[i
].action
= packet
->action
[i
];
4803 if (!packet
->repeat
) {
4804 punit
->goto_tile
= index_to_tile(&(wld
.map
), packet
->dest_tile
);
4806 /* Make sure that no old goto_tile remains. */
4807 punit
->goto_tile
= NULL
;
4810 #ifdef FREECIV_DEBUG
4811 log_debug("Orders for unit %d: length:%d", packet
->unit_id
, length
);
4812 for (i
= 0; i
< length
; i
++) {
4813 log_debug(" %d,%s", packet
->orders
[i
], dir_get_name(packet
->dir
[i
]));
4815 #endif /* FREECIV_DEBUG */
4817 if (!is_player_phase(unit_owner(punit
), game
.info
.phase
)
4818 || execute_orders(punit
, TRUE
)) {
4819 /* Looks like the unit survived. */
4820 send_unit_info(NULL
, punit
);
4824 /**************************************************************************
4825 Handle worker task assigned to the city
4826 **************************************************************************/
4827 void handle_worker_task(struct player
*pplayer
,
4828 const struct packet_worker_task
*packet
)
4830 struct city
*pcity
= game_city_by_number(packet
->city_id
);
4831 struct worker_task
*ptask
= NULL
;
4832 struct tile
*ptile
= index_to_tile(&(wld
.map
), packet
->tile_id
);
4834 if (pcity
== NULL
|| pcity
->owner
!= pplayer
|| ptile
== NULL
) {
4838 worker_task_list_iterate(pcity
->task_reqs
, ptask_old
) {
4839 if (tile_index(ptask_old
->ptile
) == packet
->tile_id
) {
4842 } worker_task_list_iterate_end
;
4844 if (ptask
== NULL
) {
4845 if (packet
->activity
== ACTIVITY_LAST
) {
4849 ptask
= fc_malloc(sizeof(struct worker_task
));
4850 worker_task_init(ptask
);
4851 worker_task_list_append(pcity
->task_reqs
, ptask
);
4853 if (packet
->activity
== ACTIVITY_LAST
) {
4854 worker_task_list_remove(pcity
->task_reqs
, ptask
);
4860 if (ptask
!= NULL
) {
4861 ptask
->ptile
= ptile
;
4862 ptask
->act
= packet
->activity
;
4863 if (packet
->tgt
>= 0) {
4864 if (packet
->tgt
< MAX_EXTRA_TYPES
) {
4865 ptask
->tgt
= extra_by_number(packet
->tgt
);
4867 log_debug("Illegal worker task target %d", packet
->tgt
);
4873 ptask
->want
= packet
->want
;
4876 lsend_packet_worker_task(pplayer
->connections
, packet
);