Freeciv-3.2
Loading...
Searching...
No Matches
cityhand.c
Go to the documentation of this file.
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)
6 any later version.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22/* utility */
23#include "fcintl.h"
24#include "log.h"
25#include "mem.h"
26#include "rand.h"
27#include "support.h"
28
29/* common */
30#include "city.h"
31#include "events.h"
32#include "game.h"
33#include "idex.h"
34#include "map.h"
35#include "player.h"
36#include "specialist.h"
37#include "unit.h"
38#include "worklist.h"
39
40/* common/aicore */
41#include "cm.h"
42
43/* server */
44#include "citytools.h"
45#include "cityturn.h"
46#include "notify.h"
47#include "plrhand.h"
48#include "sanitycheck.h"
49#include "unithand.h"
50#include "unittools.h"
51
52#include "cityhand.h"
53
54/**********************************************************************/
59void handle_city_name_suggestion_req(struct player *pplayer, int unit_id)
60{
61 struct unit *punit = player_unit_by_number(pplayer, unit_id);
62 const struct civ_map *nmap = &(wld.map);
63
64 if (NULL == punit) {
65 /* Probably died or bribed. */
66 log_verbose("handle_city_name_suggestion_req() invalid unit %d",
67 unit_id);
68 return;
69 }
70
72 unit_tile(punit), NULL))) {
73 log_verbose("handle_city_name_suggest_req(unit_pos (%d, %d))",
77
78 /* The rest of this function is error handling. */
79 return;
80 }
81
82 log_verbose("handle_city_name_suggest_req(unit_pos (%d, %d)): "
83 "cannot build there.", TILE_XY(unit_tile(punit)));
84
87}
88
89/**********************************************************************/
92void handle_city_change_specialist(struct player *pplayer, int city_id,
95{
96 struct city *pcity = player_city_by_number(pplayer, city_id);
97
98 if (!pcity) {
99 return;
100 }
101
104 || !city_can_use_specialist(pcity, to)
105 || pcity->specialists[from] == 0) {
106 /* This could easily just be due to clicking faster on the specialist
107 * than the server can cope with. */
108 log_verbose("Error in specialist change request from client.");
109 return;
110 }
111
112 pcity->specialists[from]--;
113 pcity->specialists[to]++;
114
115 city_refresh(pcity);
116 sanity_check_city(pcity);
117 send_city_info(pplayer, pcity);
118}
119
120/**********************************************************************/
124 int city_id, int tile_id)
125{
126 struct tile *ptile = index_to_tile(&(wld.map), tile_id);
127 struct city *pcity = player_city_by_number(pplayer, city_id);
128
129 if (NULL == pcity) {
130 /* Probably lost. */
131 log_verbose("handle_city_make_specialist() bad city number %d.",
132 city_id);
133 return;
134 }
135
136 if (NULL == ptile) {
137 log_error("handle_city_make_specialist() bad tile number %d.", tile_id);
138 return;
139 }
140
141 if (!city_map_includes_tile(pcity, ptile)) {
142 log_error("handle_city_make_specialist() tile (%d, %d) not in the "
143 "city map of \"%s\".", TILE_XY(ptile), city_name_get(pcity));
144 return;
145 }
146
147 /* Disable server side governor being overridden */
148 handle_web_cma_clear(pplayer, pcity->id);
149
150 if (is_free_worked(pcity, ptile)) {
152 } else if (tile_worked(ptile) == pcity) {
153 city_map_update_empty(pcity, ptile);
155 } else {
156 log_verbose("handle_city_make_specialist() not working (%d, %d) "
157 "\"%s\".", TILE_XY(ptile), city_name_get(pcity));
158 }
159
160 city_refresh(pcity);
161 sanity_check_city(pcity);
162 sync_cities();
163}
164
165/**********************************************************************/
170void handle_city_make_worker(struct player *pplayer,
171 int city_id, int tile_id)
172{
173 struct tile *ptile = index_to_tile(&(wld.map), tile_id);
174 struct city *pcity = player_city_by_number(pplayer, city_id);
175
176 if (NULL == pcity) {
177 /* Probably lost. */
178 log_verbose("handle_city_make_worker() bad city number %d.",city_id);
179 return;
180 }
181
182 if (NULL == ptile) {
183 log_error("handle_city_make_worker() bad tile number %d.", tile_id);
184 return;
185 }
186
187 if (!city_map_includes_tile(pcity, ptile)) {
188 log_error("handle_city_make_worker() tile (%d, %d) not in the "
189 "city map of \"%s\".", TILE_XY(ptile), city_name_get(pcity));
190 return;
191 }
192
193 if (is_free_worked(pcity, ptile)) {
194 /* Disable server side governor being overridden */
195 handle_web_cma_clear(pplayer, pcity->id);
196
198 sync_cities();
199 return;
200 }
201
202 if (tile_worked(ptile) == pcity) {
203 log_verbose("handle_city_make_worker() already working (%d, %d) \"%s\".",
204 TILE_XY(ptile), city_name_get(pcity));
205 return;
206 }
207
208 if (0 == city_specialists(pcity)) {
209 log_verbose("handle_city_make_worker() no specialists (%d, %d) \"%s\".",
210 TILE_XY(ptile), city_name_get(pcity));
211 return;
212 }
213
214 if (!city_can_work_tile(pcity, ptile)) {
215 log_verbose("handle_city_make_worker() cannot work here (%d, %d) \"%s\".",
216 TILE_XY(ptile), city_name_get(pcity));
217 return;
218 }
219
220 /* Disable server side governor being overridden */
221 handle_web_cma_clear(pplayer, pcity->id);
222
223 city_map_update_worker(pcity, ptile);
224
226 if (pcity->specialists[i] > 0) {
227 pcity->specialists[i]--;
228 break;
229 }
231
232 city_refresh(pcity);
233 sanity_check_city(pcity);
234 sync_cities();
235}
236
237/**********************************************************************/
241void really_handle_city_sell(struct player *pplayer, struct city *pcity,
242 struct impr_type *pimprove)
243{
245 int price;
246
247 sell_result = test_player_sell_building_now(pplayer, pcity, pimprove);
248
250 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
251 _("You have already sold something here this turn."));
252 return;
253 }
254
255 if (sell_result != TR_SUCCESS) {
256 return;
257 }
258
259 pcity->did_sell = TRUE;
260 price = impr_sell_gold(pimprove);
261 notify_player(pplayer, pcity->tile, E_IMP_SOLD, ftc_server,
262 PL_("You sell %s in %s for %d gold.",
263 "You sell %s in %s for %d gold.", price),
265 city_link(pcity), price);
266 do_sell_building(pplayer, pcity, pimprove, "sold");
267
268 city_refresh(pcity);
269
270 /* If we sold the walls the other players should see it */
271 send_city_info(NULL, pcity);
272 send_player_info_c(pplayer, pplayer->connections);
273}
274
275/**********************************************************************/
279void handle_city_sell(struct player *pplayer, int city_id, int build_id)
280{
281 struct city *pcity = player_city_by_number(pplayer, city_id);
282 struct impr_type *pimprove = improvement_by_number(build_id);
283
284 if (!pcity || !pimprove) {
285 return;
286 }
287 really_handle_city_sell(pplayer, pcity, pimprove);
288}
289
290/**********************************************************************/
294void really_handle_city_buy(struct player *pplayer, struct city *pcity)
295{
296 int cost, total;
297
298 /* This function corresponds to city_can_buy() in the client. */
299
300 fc_assert_ret(pcity && player_owns_city(pplayer, pcity));
301
302 if (pcity->turn_founded == game.info.turn) {
303 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
304 _("Cannot buy in city created this turn."));
305 return;
306 }
307
308 if (pcity->did_buy) {
309 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
310 _("You have already bought this turn."));
311 return;
312 }
313
315 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
316 _("You don't buy %s!"),
318 return;
319 }
320
321 if (VUT_UTYPE == pcity->production.kind && pcity->anarchy != 0) {
322 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
323 _("Can't buy units when city is in disorder."));
324 return;
325 }
326
329 if (cost <= 0) {
330 return; /* sanity */
331 }
332 if (cost > pplayer->economic.gold) {
333 /* In case something changed while player tried to buy, or player
334 * tried to cheat! */
335 /* Split into two to allow localization of two pluralisations. */
336 char buf[MAX_LEN_MSG];
337 /* TRANS: This whole string is only ever used when included in one
338 * other string (search for this string to find it). */
339 fc_snprintf(buf, ARRAY_SIZE(buf), PL_("%d gold required.",
340 "%d gold required.",
341 cost), cost);
342 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
343 /* TRANS: %s is a pre-pluralised string:
344 * "%d gold required." */
345 PL_("%s You only have %d gold.",
346 "%s You only have %d gold.", pplayer->economic.gold),
347 buf, pplayer->economic.gold);
348 return;
349 }
350
351 pplayer->economic.gold -= cost;
352 if (pcity->shield_stock < total) {
353 /* As we never put penalty on disbanded_shields, we can
354 * fully well add the missing shields there. */
355 pcity->disbanded_shields += total - pcity->shield_stock;
356 pcity->shield_stock = total; /* AI wants this -- Syela */
357 pcity->did_buy = TRUE; /* !PS: no need to set buy flag otherwise */
358 }
359 city_refresh(pcity);
360
361 if (VUT_UTYPE == pcity->production.kind) {
362 notify_player(pplayer, pcity->tile, E_UNIT_BUY, ftc_server,
363 /* TRANS: bought an unit. */
364 Q_("?unit:You bought %s in %s."),
366 city_name_get(pcity));
367 } else if (VUT_IMPROVEMENT == pcity->production.kind) {
368 notify_player(pplayer, pcity->tile, E_IMP_BUY, ftc_server,
369 /* TRANS: bought an improvement .*/
370 Q_("?improvement:You bought %s in %s."),
372 city_name_get(pcity));
373 }
374
376 send_city_info(pplayer, pcity);
377 send_player_info_c(pplayer, pplayer->connections);
379}
380
381/**********************************************************************/
384void handle_city_worklist(struct player *pplayer, int city_id,
385 const struct worklist *worklist)
386{
387 struct city *pcity = player_city_by_number(pplayer, city_id);
388
389 if (!pcity) {
390 return;
391 }
392
394
395 send_city_info(pplayer, pcity);
396}
397
398/**********************************************************************/
402void handle_city_buy(struct player *pplayer, int city_id)
403{
404 struct city *pcity = player_city_by_number(pplayer, city_id);
405
406 if (!pcity) {
407 return;
408 }
409
410 really_handle_city_buy(pplayer, pcity);
411}
412
413/**********************************************************************/
416void handle_city_refresh(struct player *pplayer, int city_id)
417{
418 if (city_id != 0) {
419 struct city *pcity = player_city_by_number(pplayer, city_id);
420
421 if (!pcity) {
422 return;
423 }
424
425 city_refresh(pcity);
426 send_city_info(pplayer, pcity);
427 } else {
429 }
430}
431
432/**********************************************************************/
435void handle_city_change(struct player *pplayer, int city_id,
436 int production_kind, int production_value)
437{
438 struct universal prod;
439 struct city *pcity = player_city_by_number(pplayer, city_id);
440 const struct civ_map *nmap = &(wld.map);
441
442 if (!universals_n_is_valid(production_kind)) {
443 log_error("[%s] bad production_kind %d.", __FUNCTION__,
444 production_kind);
445 prod.kind = VUT_NONE;
446 return;
447 } else {
448 prod = universal_by_number(production_kind, production_value);
449 if (!universals_n_is_valid(prod.kind)) {
450 log_error("[%s] production_kind %d with bad production_value %d.",
451 __FUNCTION__, production_kind, production_value);
452 prod.kind = VUT_NONE;
453 return;
454 }
455 }
456
457 if (!pcity) {
458 return;
459 }
460
461 if (are_universals_equal(&pcity->production, &prod)) {
462 /* The client probably shouldn't send such a packet. */
463 return;
464 }
465
466 if (!can_city_build_now(nmap, pcity, &prod)) {
467 return;
468 }
469 if (!city_can_change_build(pcity)) {
470 notify_player(pplayer, pcity->tile, E_BAD_COMMAND, ftc_server,
471 _("You have bought this turn, can't change."));
472 return;
473 }
474
475 change_build_target(pplayer, pcity, &prod, E_CITY_PRODUCTION_CHANGED);
476
477 city_refresh(pcity);
478 sanity_check_city(pcity);
479 send_city_info(pplayer, pcity);
480}
481
482/**********************************************************************/
485void handle_city_rename(struct player *pplayer, int city_id,
486 const char *name)
487{
488 struct city *pcity = player_city_by_number(pplayer, city_id);
489 char message[1024];
490
491 if (pcity == NULL) {
492 return;
493 }
494
495 if (!is_allowed_city_name(pplayer, name, message, sizeof(message))) {
496 notify_player(pplayer, pcity->tile, E_BAD_COMMAND,
497 ftc_server, "%s", message);
498 return;
499 }
500
501 city_name_set(pcity, name);
502 city_refresh(pcity);
503 send_city_info(NULL, pcity);
504}
505
506/**********************************************************************/
510void handle_city_options_req(struct player *pplayer, int city_id,
511 bv_city_options options,
513{
514 struct city *pcity = player_city_by_number(pplayer, city_id);
515
516 if (!pcity) {
517 return;
518 }
519
520 pcity->city_options = options;
521 pcity->wlcb = wlcb;
522
523 send_city_info(pplayer, pcity);
524}
525
526/**********************************************************************/
529void handle_city_rally_point(struct player *pplayer,
530 const struct packet_city_rally_point *packet)
531{
532 struct city *pcity = player_city_by_number(pplayer, packet->id);
533
534 if (NULL != pcity) {
535 city_rally_point_receive(packet, pcity);
536 send_city_info(pplayer, pcity);
537 }
538}
539
540/**********************************************************************/
543void handle_web_cma_set(struct player *pplayer, int id,
544 const struct cm_parameter *param)
545{
546 /* Supported only in freeciv-web builds for now -
547 * Let's be cautious for now, and not give any chance
548 * of client requests of server side CMA to overload
549 * server from a standard build. */
550#ifdef FREECIV_WEB
551 struct city *pcity = player_city_by_number(pplayer, id);
552
553 if (pcity != NULL) {
554 if (pcity->cm_parameter == NULL) {
555 pcity->cm_parameter = fc_calloc(1, sizeof(struct cm_parameter));
556 }
557
558 cm_copy_parameter(pcity->cm_parameter, param);
559 pcity->server.synced = FALSE;
560
562
563 sync_cities();
564 }
565#endif /* FREECIV_WEB */
566}
567
568/**********************************************************************/
571void handle_web_cma_clear(struct player *pplayer, int id)
572{
573 struct city *pcity = player_city_by_number(pplayer, id);
574
575 if (pcity != NULL && pcity->cm_parameter != NULL) {
576 free(pcity->cm_parameter);
577 pcity->cm_parameter = NULL;
578 send_city_info(pplayer, pcity);
579 }
580}
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5821
struct act_prob action_prob_vs_tile(const struct civ_map *nmap, const struct unit *actor_unit, const action_id act_id, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5342
bool is_free_worked(const struct city *pcity, const struct tile *ptile)
Definition city.c:3601
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:737
void city_name_set(struct city *pcity, const char *new_name)
Definition city.c:1145
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Definition city.c:1065
bool city_map_includes_tile(const struct city *const pcity, const struct tile *map_tile)
Definition city.c:293
citizens city_specialists(const struct city *pcity)
Definition city.c:3317
void city_rally_point_receive(const struct packet_city_rally_point *packet, struct city *pcity)
Definition city.c:3641
bool can_city_build_now(const struct civ_map *nmap, const struct city *pcity, const struct universal *target)
Definition city.c:1013
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1456
bool city_production_is_genus(const struct city *pcity, enum impr_genus_id genus)
Definition city.c:717
bool city_can_change_build(const struct city *pcity)
Definition city.c:1079
void handle_city_change(struct player *pplayer, int city_id, int production_kind, int production_value)
Definition cityhand.c:435
void handle_city_rally_point(struct player *pplayer, const struct packet_city_rally_point *packet)
Definition cityhand.c:529
void handle_city_name_suggestion_req(struct player *pplayer, int unit_id)
Definition cityhand.c:59
void handle_city_worklist(struct player *pplayer, int city_id, const struct worklist *worklist)
Definition cityhand.c:384
void handle_city_buy(struct player *pplayer, int city_id)
Definition cityhand.c:402
void handle_city_change_specialist(struct player *pplayer, int city_id, Specialist_type_id from, Specialist_type_id to)
Definition cityhand.c:92
void really_handle_city_buy(struct player *pplayer, struct city *pcity)
Definition cityhand.c:294
void handle_web_cma_set(struct player *pplayer, int id, const struct cm_parameter *param)
Definition cityhand.c:543
void handle_city_sell(struct player *pplayer, int city_id, int build_id)
Definition cityhand.c:279
void handle_city_make_worker(struct player *pplayer, int city_id, int tile_id)
Definition cityhand.c:170
void handle_city_options_req(struct player *pplayer, int city_id, bv_city_options options, enum city_wl_cancel_behavior wlcb)
Definition cityhand.c:510
void handle_city_refresh(struct player *pplayer, int city_id)
Definition cityhand.c:416
void handle_city_make_specialist(struct player *pplayer, int city_id, int tile_id)
Definition cityhand.c:123
void handle_city_rename(struct player *pplayer, int city_id, const char *name)
Definition cityhand.c:485
void really_handle_city_sell(struct player *pplayer, struct city *pcity, struct impr_type *pimprove)
Definition cityhand.c:241
void handle_web_cma_clear(struct player *pplayer, int id)
Definition cityhand.c:571
void city_map_update_empty(struct city *pcity, struct tile *ptile)
Definition citytools.c:3268
const char * city_name_suggestion(struct player *pplayer, struct tile *ptile)
Definition citytools.c:458
int city_production_buy_gold_cost(const struct city *pcity)
Definition citytools.c:3639
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2363
void sync_cities(void)
Definition citytools.c:3342
void change_build_target(struct player *pplayer, struct city *pcity, struct universal *target, enum event_type event)
Definition citytools.c:3179
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:374
void do_sell_building(struct player *pplayer, struct city *pcity, struct impr_type *pimprove, const char *reason)
Definition citytools.c:2997
void city_map_update_worker(struct city *pcity, struct tile *ptile)
Definition citytools.c:3282
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:367
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
void city_refresh_for_player(struct player *pplayer)
Definition cityturn.c:183
void cm_copy_parameter(struct cm_parameter *dest, const struct cm_parameter *const src)
Definition cm.c:2174
char * incite_cost
Definition comments.c:75
#define MAX_LEN_MSG
Definition conn_types.h:37
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:366
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:356
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
int Specialist_type_id
Definition fc_types.h:375
test_result
Definition fc_types.h:1245
@ TR_ALREADY_SOLD
Definition fc_types.h:1248
@ TR_SUCCESS
Definition fc_types.h:1246
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const struct ft_color ftc_server
const char * city_link(const struct city *pcity)
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct impr_type * improvement_by_number(const Impr_type_id id)
int impr_sell_gold(const struct impr_type *pimprove)
enum test_result test_player_sell_building_now(struct player *pplayer, struct city *pcity, const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define log_error(message,...)
Definition log.h:103
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:456
#define fc_calloc(n, esz)
Definition mem.h:38
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:291
void dlsend_packet_city_name_suggestion_info(struct conn_list *dest, int unit_id, const char *name)
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
bool player_owns_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:261
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1146
struct universal universal_by_number(const enum universals_n kind, const int value)
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
#define sanity_check_city(x)
Definition sanitycheck.h:41
#define ARRAY_SIZE(x)
Definition shared.h:85
Specialist_type_id specialist_count(void)
Definition specialist.c:71
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
#define DEFAULT_SPECIALIST
Definition specialist.h:43
Definition city.h:320
enum city_wl_cancel_behavior wlcb
Definition city.h:404
bool did_sell
Definition city.h:380
int id
Definition city.h:326
int disbanded_shields
Definition city.h:391
bv_city_options city_options
Definition city.h:403
int turn_founded
Definition city.h:386
bool did_buy
Definition city.h:379
int anarchy
Definition city.h:384
struct worklist worklist
Definition city.h:401
struct universal production
Definition city.h:396
bool synced
Definition city.h:448
citizens specialists[SP_MAX]
Definition city.h:336
struct tile * tile
Definition city.h:322
int shield_stock
Definition city.h:368
struct city::@17::@19 server
struct cm_parameter * cm_parameter
Definition city.h:425
struct packet_game_info info
Definition game.h:89
struct conn_list * connections
Definition player.h:296
struct player_economic economic
Definition player.h:282
Definition tile.h:50
Definition unit.h:138
enum universals_n kind
Definition fc_types.h:902
universals_u value
Definition fc_types.h:901
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define tile_worked(_tile)
Definition tile.h:114
#define TILE_XY(ptile)
Definition tile.h:43
const struct unit_type * utype
Definition fc_types.h:721
const struct impr_type * building
Definition fc_types.h:714
#define unit_tile(_pu)
Definition unit.h:397
void illegal_action_msg(struct player *pplayer, const enum event_type event, struct unit *actor, const action_id stopped_action, const struct tile *target_tile, const struct city *target_city, const struct unit *target_unit)
Definition unithand.c:2492
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
void worklist_copy(struct worklist *dst, const struct worklist *src)
Definition worklist.c:112