Freeciv-3.1
Loading...
Searching...
No Matches
edithand.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
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 <limits.h> /* USHRT_MAX */
19
20/* utility */
21#include "bitvector.h"
22#include "capability.h"
23#include "fcintl.h"
24#include "log.h"
25#include "shared.h"
26#include "support.h"
27
28/* common */
29#include "events.h"
30#include "game.h"
31#include "government.h"
32#include "map.h"
33#include "movement.h"
34#include "nation.h"
35#include "terrain.h"
36#include "research.h"
37#include "unitlist.h"
38
39/* server */
40#include "aiiface.h"
41#include "citytools.h"
42#include "cityturn.h"
43#include "connecthand.h"
44#include "gamehand.h"
45#include <hand_gen.h> /* <> so looked from the build directory first. */
46#include "maphand.h"
47#include "plrhand.h"
48#include "notify.h"
49#include "sanitycheck.h"
50#include "stdinhand.h"
51#include "techtools.h"
52#include "unittools.h"
53
54/* server/generator */
55#include "mapgen_utils.h"
56
57/* server/savegame */
58#include "savemain.h"
59
60#include "edithand.h"
61
62/* Set if anything in a sequence of edits triggers the expensive
63 * assign_continent_numbers() check, which will be done once when the
64 * sequence is complete. */
66/* Hold pointers to tiles which were changed during the edit sequence,
67 * so that they can be sanity-checked when the sequence is complete
68 * and final global fix-ups have been done. */
69static struct tile_hash *modified_tile_table = NULL;
70
71/* Array of size player_slot_count() indexed by player
72 * number to tell whether a given player has fog of war
73 * disabled in edit mode. */
74static bool *unfogged_players;
75
76/************************************************************************/
79void edithand_init(void)
80{
81 if (NULL != modified_tile_table) {
82 tile_hash_destroy(modified_tile_table);
83 }
84 modified_tile_table = tile_hash_new();
85
87
88 if (unfogged_players != NULL) {
89 free(unfogged_players);
90 }
92}
93
94/************************************************************************/
97void edithand_free(void)
98{
99 if (NULL != modified_tile_table) {
100 tile_hash_destroy(modified_tile_table);
101 modified_tile_table = NULL;
102 }
103
104 if (unfogged_players != NULL) {
105 free(unfogged_players);
106 unfogged_players = NULL;
107 }
108}
109
110/************************************************************************/
113void edithand_send_initial_packets(struct conn_list *dest)
114{
116 struct packet_edit_startpos_full startpos_full;
117
118 if (NULL == dest) {
119 dest = game.est_connections;
120 }
121
122 /* Send map start positions. */
125 startpos.removal = FALSE;
126 startpos.tag = 0;
127
128 startpos_pack(psp, &startpos_full);
129
130 conn_list_iterate(dest, pconn) {
131 if (can_conn_edit(pconn)) {
133 send_packet_edit_startpos_full(pconn, &startpos_full);
134 }
137}
138
139/************************************************************************/
144{
149
150 /* FIXME: adv / ai phase handling like in check_terrain_change() */
151 }
152
153#ifdef SANITY_CHECKING
155 sanity_check_tile(ptile);
157#endif /* SANITY_CHECKING */
158 tile_hash_clear(modified_tile_table);
159}
160
161/************************************************************************/
165static void check_leaving_edit_mode(void)
166{
167 bool unfogged;
168
170 players_iterate(pplayer) {
171 unfogged = unfogged_players[player_number(pplayer)];
172 if (unfogged && game.info.fogofwar) {
174 } else if (!unfogged && !game.info.fogofwar) {
176 }
178
179 /* Clear the whole array. */
180 memset(unfogged_players, 0, player_slot_count() * sizeof(bool));
181
184}
185
186/************************************************************************/
189void handle_edit_mode(struct connection *pc, bool is_edit_mode)
190{
191 if (!can_conn_enable_editing(pc)) {
192 return;
193 }
194
195 if (!game.info.is_edit_mode && is_edit_mode) {
196 /* Someone could be cheating! Warn people. */
197 notify_conn(NULL, NULL, E_SETTING, ftc_editor,
198 _(" *** Server set to edit mode by %s! *** "),
199 conn_description(pc));
200 }
201
202 if (game.info.is_edit_mode && !is_edit_mode) {
203 notify_conn(NULL, NULL, E_SETTING, ftc_editor,
204 _(" *** Edit mode canceled by %s. *** "),
205 conn_description(pc));
206
208 }
209
210 if (game.info.is_edit_mode != is_edit_mode) {
211 game.info.is_edit_mode = is_edit_mode;
212
213 send_game_info(NULL);
215 }
216}
217
218/************************************************************************/
222static bool edit_tile_terrain_handling(struct tile *ptile,
223 struct terrain *pterrain,
224 bool send_info)
225{
226 struct terrain *old_terrain = tile_terrain(ptile);
227
228 if (old_terrain == pterrain
229 || (terrain_has_flag(pterrain, TER_NO_CITIES)
230 && NULL != tile_city(ptile))) {
231 return FALSE;
232 }
233
234 tile_change_terrain(ptile, pterrain);
235 fix_tile_on_terrain_change(ptile, old_terrain, FALSE);
236 tile_hash_insert(modified_tile_table, ptile, NULL);
237 if (need_to_reassign_continents(old_terrain, pterrain)) {
239 }
240
241 if (send_info) {
243 }
244
246
247 return TRUE;
248}
249
250/************************************************************************/
254static bool edit_tile_extra_handling(struct tile *ptile,
255 struct extra_type *pextra,
256 bool remove_mode, bool send_info)
257{
258 if (remove_mode) {
259 if (!tile_has_extra(ptile, pextra)) {
260 return FALSE;
261 }
262
263 if (!tile_extra_rm_apply(ptile, pextra)) {
264 return FALSE;
265 }
266
267 terrain_changed(ptile);
268
269 } else {
270 if (tile_has_extra(ptile, pextra)) {
271 return FALSE;
272 }
273
274 if (!tile_extra_apply(ptile, pextra)) {
275 return FALSE;
276 }
277
278 if (is_extra_caused_by(pextra, EC_RESOURCE)
279 && terrain_has_resource(ptile->terrain, pextra)) {
280 tile_set_resource(ptile, pextra);
281 }
282 }
283
284 if (send_info) {
286 }
287
289
290 return TRUE;
291}
292
293/************************************************************************/
301{
302 struct terrain *pterrain;
303 struct tile *ptile_center;
304
305 ptile_center = index_to_tile(&(wld.map), tile);
306 if (!ptile_center) {
307 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
308 _("Cannot edit the tile because %d is not a valid "
309 "tile index on this map!"), tile);
310 return;
311 }
312
313 pterrain = terrain_by_number(terrain);
314 if (!pterrain) {
315 notify_conn(pc->self, ptile_center, E_BAD_COMMAND, ftc_editor,
316 /* TRANS: ..." the tile <tile-coordinates> because"... */
317 _("Cannot modify terrain for the tile %s because "
318 "%d is not a valid terrain id."),
319 tile_link(ptile_center), terrain);
320 return;
321 }
322
324 /* This iterates outward, which gives any units that can't survive on
325 * changed terrain the best chance of survival. */
326 square_iterate(&(wld.map), ptile_center, size - 1, ptile) {
327 edit_tile_terrain_handling(ptile, pterrain, TRUE);
330}
331
332/************************************************************************/
337 int id, bool removal, int eowner, int size)
338{
339 struct tile *ptile_center;
340 struct player *plr_eowner;
341
342 ptile_center = index_to_tile(&(wld.map), tile);
343 if (!ptile_center) {
344 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
345 _("Cannot edit the tile because %d is not a valid "
346 "tile index on this map!"), tile);
347 return;
348 }
349
350 if (id < 0 || id >= game.control.num_extra_types) {
351 notify_conn(pc->self, ptile_center, E_BAD_COMMAND, ftc_editor,
352 /* TRANS: ..." the tile <tile-coordinates> because"... */
353 _("Cannot modify extras for the tile %s because "
354 "%d is not a valid extra id."),
355 tile_link(ptile_center), id);
356 return;
357 }
358
359 if (eowner != MAP_TILE_OWNER_NULL
360 && (eowner != MAX_UINT8
361 || has_capability("ownernull16", pc->capability))) {
362 plr_eowner = player_by_number(eowner);
363 } else {
364 plr_eowner = NULL;
365 }
366
368 square_iterate(&(wld.map), ptile_center, size - 1, ptile) {
369 ptile->extras_owner = plr_eowner;
370 edit_tile_extra_handling(ptile, extra_by_number(id), removal, TRUE);
373}
374
375/************************************************************************/
379 const struct packet_edit_tile *packet)
380{
381 struct tile *ptile;
382 struct player *eowner;
383 bool changed = FALSE;
384
385 ptile = index_to_tile(&(wld.map), packet->tile);
386 if (!ptile) {
387 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
388 _("Cannot edit the tile because %d is not a valid "
389 "tile index on this map!"), packet->tile);
390 return;
391 }
392
393 if (packet->eowner != MAP_TILE_OWNER_NULL
394 && (packet->eowner != MAX_UINT8
395 || has_capability("ownernull16", pc->capability))) {
396 eowner = player_by_number(packet->eowner);
397 } else {
398 eowner = NULL;
399 }
400
401 /* Handle changes in extras. */
402 if (!BV_ARE_EQUAL(packet->extras, ptile->extras)) {
403 extra_type_iterate(pextra) {
404 if (edit_tile_extra_handling(ptile, pextra,
405 !BV_ISSET(packet->extras, extra_number(pextra)),
406 FALSE)) {
407 changed = TRUE;
408 }
410 }
411
412 if (ptile->extras_owner != eowner) {
413 ptile->extras_owner = eowner;
414 changed = TRUE;
415 }
416
417 /* Handle changes in label */
418 if (tile_set_label(ptile, packet->label)) {
419 changed = TRUE;
420 }
421
422 /* TODO: Handle more property edits. */
423
424
425 /* Send the new state to all affected. */
426 if (changed) {
428 send_tile_info(NULL, ptile, FALSE);
429 }
430
432}
433
434/************************************************************************/
439 Unit_type_id utid, int count, int tag)
440{
441 struct tile *ptile;
442 struct unit_type *punittype;
443 struct player *pplayer;
444 struct city *homecity;
445 struct unit *punit;
446 int id, i;
447
448 ptile = index_to_tile(&(wld.map), tile);
449 if (!ptile) {
450 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
451 _("Cannot create units because %d is not a valid "
452 "tile index on this map!"), tile);
453 return;
454 }
455
456 punittype = utype_by_number(utid);
457 if (!punittype) {
458 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
459 /* TRANS: ..." at <tile-coordinates> because"... */
460 _("Cannot create a unit at %s because the "
461 "given unit type id %d is invalid."),
462 tile_link(ptile), utid);
463 return;
464 }
465
466 pplayer = player_by_number(owner);
467 if (!pplayer) {
468 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
469 /* TRANS: ..." type <unit-type> at <tile-coordinates>"... */
470 _("Cannot create a unit of type %s at %s "
471 "because the given owner's player id %d is "
472 "invalid."), utype_name_translation(punittype),
473 tile_link(ptile), owner);
474 return;
475 }
476
477 if (utype_has_flag(punittype, UTYF_UNIQUE)) {
478 if (utype_player_already_has_this_unique(pplayer, punittype)) {
479 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
480 _("Cannot create another instance of unique unit type %s. "
481 "Player already has one such unit."),
482 utype_name_translation(punittype));
483 return;
484 }
485 if (count > 1) {
486 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
487 _("Cannot create multiple instances of unique unit type %s."),
488 utype_name_translation(punittype));
489 return;
490 }
491 }
492
493 if (is_non_allied_unit_tile(ptile, pplayer)
494 || (tile_city(ptile)
495 && !pplayers_allied(pplayer, city_owner(tile_city(ptile))))) {
496 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
497 /* TRANS: ..." type <unit-type> on enemy tile
498 * <tile-coordinates>"... */
499 _("Cannot create unit of type %s on enemy tile "
500 "%s."), utype_name_translation(punittype),
501 tile_link(ptile));
502 return;
503 }
504
505 if (!can_exist_at_tile(&(wld.map), punittype, ptile)) {
506 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
507 /* TRANS: ..." type <unit-type> on the terrain at
508 * <tile-coordinates>"... */
509 _("Cannot create a unit of type %s on the terrain "
510 "at %s."),
511 utype_name_translation(punittype), tile_link(ptile));
512 return;
513 }
514
515 if (count > 0 && !pplayer->is_alive) {
516 pplayer->is_alive = TRUE;
517 send_player_info_c(pplayer, NULL);
518 }
519
520 homecity = find_closest_city(ptile, NULL, pplayer, FALSE, FALSE, FALSE,
521 TRUE, FALSE, utype_class(punittype));
522 id = homecity ? homecity->id : 0;
523
525 map_show_circle(pplayer, ptile, punittype->vision_radius_sq);
526 for (i = 0; i < count; i++) {
527 /* As far as I can see create_unit is guaranteed to
528 * never return NULL. */
529 punit = create_unit(pplayer, ptile, punittype, 0, id, -1);
530 if (tag > 0) {
532 }
533 }
535}
536
537/************************************************************************/
542 int tile, Unit_type_id utid, int count)
543{
544 struct tile *ptile;
545 struct unit_type *punittype;
546 struct player *pplayer;
547 int i;
548
549 ptile = index_to_tile(&(wld.map), tile);
550 if (!ptile) {
551 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
552 _("Cannot remove units because %d is not a valid "
553 "tile index on this map!"), tile);
554 return;
555 }
556
557 punittype = utype_by_number(utid);
558 if (!punittype) {
559 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
560 /* TRANS: ..." at <tile-coordinates> because"... */
561 _("Cannot remove a unit at %s because the "
562 "given unit type id %d is invalid."),
563 tile_link(ptile), utid);
564 return;
565 }
566
567 pplayer = player_by_number(owner);
568 if (!pplayer) {
569 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
570 /* TRANS: ..." type <unit-type> at <tile-coordinates>
571 * because"... */
572 _("Cannot remove a unit of type %s at %s "
573 "because the given owner's player id %d is "
574 "invalid."), utype_name_translation(punittype),
575 tile_link(ptile), owner);
576 return;
577 }
578
579 i = 0;
581 if (i >= count) {
582 break;
583 }
584 if (unit_type_get(punit) != punittype
585 || unit_owner(punit) != pplayer) {
586 continue;
587 }
588 wipe_unit(punit, ULR_EDITOR, NULL);
589 i++;
591}
592
593/************************************************************************/
597 Unit_type_id id32)
598{
599 struct unit *punit;
600
601 if (!has_capability("ids32", pc->capability)) {
602 id32 = id16;
603 }
604
606 if (punit == NULL) {
607 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
608 _("No such unit (ID %d)."), id32);
609 return;
610 }
611
612 wipe_unit(punit, ULR_EDITOR, NULL);
613}
614
615/************************************************************************/
619 const struct packet_edit_unit *packet)
620{
621 const struct unit_type *putype;
622 struct unit *punit;
623 int id;
624 bool changed = FALSE;
625 int fuel, hp;
626
627 if (!has_capability("ids32", pc->capability)) {
628 id = packet->id16;
629 } else {
630 id = packet->id32;
631 }
632
634 if (punit == NULL) {
635 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
636 _("No such unit (ID %d)."), id);
637 return;
638 }
639
640 putype = unit_type_get(punit);
641
642 if (packet->moves_left != punit->moves_left) {
643 punit->moves_left = packet->moves_left;
644 changed = TRUE;
645 }
646
647 fuel = CLIP(0, packet->fuel, utype_fuel(putype));
648 if (fuel != punit->fuel) {
649 punit->fuel = fuel;
650 changed = TRUE;
651 }
652
653 if (packet->moved != punit->moved) {
654 punit->moved = packet->moved;
655 changed = TRUE;
656 }
657
658 if (packet->done_moving != punit->done_moving) {
659 punit->done_moving = packet->done_moving;
660 changed = TRUE;
661 }
662
663 hp = CLIP(1, packet->hp, putype->hp);
664 if (hp != punit->hp) {
665 punit->hp = hp;
666 changed = TRUE;
667 }
668
669 if (packet->veteran != punit->veteran) {
670 int v = packet->veteran;
671
672 if (utype_veteran_level(putype, v) == NULL) {
673 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
674 _("Invalid veteran level %d for unit %d (%s)."),
675 v, id, unit_link(punit));
676 } else {
677 punit->veteran = v;
678 changed = TRUE;
679 }
680 }
681
682 if (packet->stay != punit->stay) {
683 punit->stay = packet->stay;
684 changed = TRUE;
685 }
686
687 /* TODO: Handle more property edits. */
688
689
690 /* Send the new state to all affected. */
691 if (changed) {
692 send_unit_info(NULL, punit);
693 }
694}
695
696/************************************************************************/
701 int size, int tag)
702{
703 struct tile *ptile;
704 struct city *pcity;
705 struct player *pplayer;
706
707 ptile = index_to_tile(&(wld.map), tile);
708 if (!ptile) {
709 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
710 _("Cannot create a city because %d is not a valid "
711 "tile index on this map!"), tile);
712 return;
713 }
714
715 pplayer = player_by_number(owner);
716 if (!pplayer) {
717 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
718 /* TRANS: ..." at <tile-coordinates> because"... */
719 _("Cannot create a city at %s because the "
720 "given owner's player id %d is invalid"),
721 tile_link(ptile), owner);
722 return;
723
724 }
725
727
728 if (!create_city_for_player(pplayer, ptile, NULL)) {
729 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
730 /* TRANS: ..." at <tile-coordinates>." */
731 _("A city may not be built at %s."), tile_link(ptile));
733
734 return;
735 }
736
737 pcity = tile_city(ptile);
738
739 if (size > 1) {
740 /* FIXME: Slow and inefficient for large size changes. */
741 city_change_size(pcity, CLIP(1, size, MAX_CITY_SIZE), pplayer, NULL);
742 send_city_info(NULL, pcity);
743 }
744
745 if (tag > 0) {
746 dsend_packet_edit_object_created(pc, tag, pcity->id);
747 }
748
750}
751
752
753/************************************************************************/
757 const struct packet_edit_city *packet)
758{
759 struct tile *ptile;
760 struct city *pcity, *oldcity;
761 struct player *pplayer;
762 char buf[1024];
763 int id;
764 bool changed = FALSE;
765 bool need_game_info = FALSE;
766 bv_player need_player_info;
767 int cid;
768
769 if (!has_capability("ids32", pc->capability)) {
770 cid = packet->id16;
771 } else {
772 cid = packet->id32;
773 }
774
775 pcity = game_city_by_number(cid);
776 if (pcity == NULL) {
777 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
778 _("Cannot edit city with invalid city ID %d."),
779 cid);
780 return;
781 }
782
783 pplayer = city_owner(pcity);
784 ptile = city_tile(pcity);
785 BV_CLR_ALL(need_player_info);
786
787 /* Handle name change. */
788 if (0 != strcmp(pcity->name, packet->name)) {
789 if (!is_allowed_city_name(pplayer, packet->name, buf, sizeof(buf))) {
790 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
791 _("Cannot edit city name: %s"), buf);
792 } else {
793 city_name_set(pcity, packet->name);
794 changed = TRUE;
795 }
796 }
797
798 /* Handle size change. */
799 if (packet->size != city_size_get(pcity)) {
800 if (!(0 < packet->size && packet->size <= MAX_CITY_SIZE)) {
801 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
802 _("Invalid city size %d for city %s."),
803 packet->size, city_link(pcity));
804 } else {
805 /* FIXME: Slow and inefficient for large size changes. */
806 city_change_size(pcity, packet->size, NULL, NULL);
807 changed = TRUE;
808 }
809 }
810
811 if (packet->history != pcity->history) {
812 pcity->history = packet->history;
813 changed = TRUE;
814 }
815
816 /* Handle city improvement changes. */
817 improvement_iterate(pimprove) {
818 oldcity = NULL;
819 id = improvement_number(pimprove);
820
821 if (is_special_improvement(pimprove)) {
822 if (packet->built[id] >= 0) {
823 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
824 _("It is impossible for a city to have %s!"),
826 }
827 continue;
828 }
829
830 /* FIXME: game.info.great_wonder_owners and pplayer->wonders
831 * logic duplication with city_build_building. */
832
833 if (city_has_building(pcity, pimprove) && packet->built[id] < 0) {
834
835 city_remove_improvement(pcity, pimprove);
836 changed = TRUE;
837
838 } else if (!city_has_building(pcity, pimprove)
839 && packet->built[id] >= 0) {
840 struct player *old_owner = NULL;
841
842 oldcity = build_or_move_building(pcity, pimprove, &old_owner);
843 if (oldcity != pcity) {
844 BV_SET(need_player_info, player_index(pplayer));
845 }
846 if (oldcity && old_owner != pplayer) {
847 /* Great wonders make more changes. */
848 need_game_info = TRUE;
849 if (old_owner) {
850 BV_SET(need_player_info, player_index(old_owner));
851 }
852 }
853
854 if (oldcity) {
855 city_refresh_queue_add(oldcity);
856 }
857 changed = TRUE;
858 }
860
861 /* Handle food stock change. */
862 if (packet->food_stock != pcity->food_stock) {
863 int max = city_granary_size(city_size_get(pcity));
864 if (!(0 <= packet->food_stock && packet->food_stock <= max)) {
865 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
866 _("Invalid city food stock amount %d for city %s "
867 "(allowed range is %d to %d)."),
868 packet->food_stock, city_link(pcity), 0, max);
869 } else {
870 pcity->food_stock = packet->food_stock;
871 changed = TRUE;
872 }
873 }
874
875 /* Handle shield stock change. */
876 if (packet->shield_stock != pcity->shield_stock) {
877 int max = USHRT_MAX; /* Limited to uint16 by city info packet. */
878
879 if (!(0 <= packet->shield_stock && packet->shield_stock <= max)) {
880 notify_conn(pc->self, ptile, E_BAD_COMMAND, ftc_editor,
881 _("Invalid city shield stock amount %d for city %s "
882 "(allowed range is %d to %d)."),
883 packet->shield_stock, city_link(pcity), 0, max);
884 } else {
885 pcity->shield_stock = packet->shield_stock;
886 /* Make sure the shields stay if changing production back and forth */
887 pcity->before_change_shields = packet->shield_stock;
888 changed = TRUE;
889 }
890 }
891
892 /* TODO: Handle more property edits. */
893
894
895 if (changed) {
899
900 /* FIXME: city_refresh_queue_processing only sends to city owner? */
901 send_city_info(NULL, pcity);
902
904 }
905
906 /* Update wonder infos. */
907 if (need_game_info) {
908 send_game_info(NULL);
909 }
910 if (BV_ISSET_ANY(need_player_info)) {
911 players_iterate(aplayer) {
912 if (BV_ISSET(need_player_info, player_index(aplayer))) {
913 /* No need to send to detached connections. */
914 send_player_info_c(aplayer, NULL);
915 }
917 }
918}
919
920/************************************************************************/
923void handle_edit_player_create(struct connection *pc, int tag)
924{
925 struct player *pplayer;
926 struct nation_type *pnation;
927 struct research *presearch;
928 int existing = player_count();
929
930 if (existing >= player_slot_count()) {
931 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
932 _("No more players can be added because the maximum "
933 "number of players (%d) has been reached."),
935 return;
936 }
937
938 if (existing >= game.server.max_players) {
939 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
940 _("No more players can be added because there's "
941 "already maximum number of players allowed by maxplayers setting (value %d)"),
943 return;
944 }
945
946 if (existing >= nation_count() ) {
947 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
948 _("No more players can be added because there are "
949 "no available nations (%d used)."),
950 nation_count());
951 return;
952 }
953
954 pnation = pick_a_nation(NULL, TRUE, TRUE, NOT_A_BARBARIAN);
955 if (!pnation) {
956 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
957 _("Player cannot be created because random nation "
958 "selection failed."));
959 return;
960 }
961
963 NULL, FALSE);
964 if (!pplayer) {
965 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
966 _("Player creation failed."));
967 return;
968 }
969 server_player_init(pplayer, TRUE, TRUE);
970
971 player_nation_defaults(pplayer, pnation, TRUE);
972 if (game_was_started()) {
973 /* Find a color for the new player. */
975 }
977 pplayer->unassigned_user = TRUE;
978 pplayer->is_connected = FALSE;
979 pplayer->government = init_government_of_nation(pnation);
980 pplayer->server.got_first_city = FALSE;
981
982 pplayer->economic.gold = 0;
983 pplayer->economic.infra_points = 0;
985
986 presearch = research_get(pplayer);
987 init_tech(presearch, TRUE);
988 give_initial_techs(presearch, 0);
989
990 send_player_all_c(pplayer, NULL);
991 /* Send research info after player info, else the client will complain
992 * about invalid team. */
993 send_research_info(presearch, NULL);
994 if (tag > 0) {
996 }
997}
998
999/************************************************************************/
1003{
1004 struct player *pplayer;
1005
1006 pplayer = player_by_number(id);
1007 if (pplayer == NULL) {
1008 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1009 _("No such player (ID %d)."), id);
1010 return;
1011 }
1012
1013 /* Don't use conn_list_iterate here because connection_detach() can be
1014 * recursive and free the next connection pointer. */
1015 while (conn_list_size(pplayer->connections) > 0) {
1016 connection_detach(conn_list_get(pplayer->connections, 0), FALSE);
1017 }
1018
1019 kill_player(pplayer);
1020 server_remove_player(pplayer);
1021}
1022
1023/************************************************************************/
1027 const struct packet_edit_player *packet)
1028{
1029 struct player *pplayer;
1030 bool changed = FALSE, update_research = FALSE;
1031 struct nation_type *pnation;
1032 struct research *research;
1033 enum tech_state known;
1034 struct government *gov;
1035
1036 pplayer = player_by_number(packet->id);
1037 if (!pplayer) {
1038 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1039 _("Cannot edit player with invalid player ID %d."),
1040 packet->id);
1041 return;
1042 }
1043
1044 research = research_get(pplayer);
1045
1046
1047 /* Handle player name change. */
1048 if (0 != strcmp(packet->name, player_name(pplayer))) {
1049 char error_buf[256];
1050
1051 if (server_player_set_name_full(pc, pplayer, NULL, packet->name,
1052 error_buf, sizeof(error_buf))) {
1053 changed = TRUE;
1054 } else {
1055 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1056 _("Cannot change name of player (%d) '%s' to '%s': %s"),
1057 player_number(pplayer), player_name(pplayer),
1058 packet->name, error_buf);
1059 }
1060 }
1061
1062 /* Handle nation change. */
1063 pnation = nation_by_number(packet->nation);
1064 if (nation_of_player(pplayer) != pnation) {
1065 if (pnation == NULL) {
1066 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1067 _("Cannot change nation for player %d (%s) "
1068 "because the given nation ID %d is invalid."),
1069 player_number(pplayer), player_name(pplayer),
1070 packet->nation);
1071 } else if (pnation->player != NULL) {
1072 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1073 _("Cannot change nation for player %d (%s) "
1074 "to nation %d (%s) because that nation is "
1075 "already assigned to player %d (%s)."),
1076 player_number(pplayer), player_name(pplayer),
1077 packet->nation, nation_plural_translation(pnation),
1078 player_number(pnation->player),
1079 player_name(pnation->player));
1080 } else if (!nation_is_in_current_set(pnation)) {
1081 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1082 _("Cannot change nation for player %d (%s) "
1083 "to nation %d (%s) because that nation is "
1084 "not in the current nation set."),
1085 player_number(pplayer), player_name(pplayer),
1086 packet->nation, nation_plural_translation(pnation));
1087 } else if (pplayer->ai_common.barbarian_type
1088 != nation_barbarian_type(pnation)
1089 || (!is_barbarian(pplayer) && !is_nation_playable(pnation))) {
1090 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1091 _("Cannot change nation for player %d (%s) "
1092 "to nation %d (%s) because that nation is "
1093 "unsuitable for this player."),
1094 player_number(pplayer), player_name(pplayer),
1095 packet->nation, nation_plural_translation(pnation));
1096 } else {
1097 changed = player_set_nation(pplayer, pnation);
1098 }
1099 }
1100
1101 /* Handle a change in research progress. */
1102 if (packet->bulbs_researched != research->bulbs_researched) {
1104 changed = TRUE;
1105 update_research = TRUE;
1106 }
1107
1108 /* Handle a change in known inventions. */
1110 known = research_invention_state(research, tech);
1111 if ((packet->inventions[tech] && known == TECH_KNOWN)
1112 || (!packet->inventions[tech] && known != TECH_KNOWN)) {
1113 continue;
1114 }
1115 if (packet->inventions[tech]) {
1116 /* FIXME: Side-effect modifies game.info.global_advances. */
1117 research_invention_set(research, tech, TECH_KNOWN);
1119 } else {
1120 research_invention_set(research, tech, TECH_UNKNOWN);
1122 }
1123 changed = TRUE;
1124 update_research = TRUE;
1126
1127 /* Handle a change in the player's gold. */
1128 if (packet->gold != pplayer->economic.gold) {
1129 if (!(0 <= packet->gold && packet->gold <= 1000000)) {
1130 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1131 _("Cannot set gold for player %d (%s) because "
1132 "the value %d is outside the allowed range."),
1133 player_number(pplayer), player_name(pplayer),
1134 packet->gold);
1135 } else {
1136 pplayer->economic.gold = packet->gold;
1137 changed = TRUE;
1138 }
1139 }
1140
1141 /* Handle player government change */
1142 gov = government_by_number(packet->government);
1143 if (gov != pplayer->government) {
1145 government_change(pplayer, gov, FALSE);
1146 } else {
1147 int turns = revolution_length(gov, pplayer);
1148
1149 if (turns >= 0) {
1150 pplayer->government = gov;
1151 pplayer->revolution_finishes = game.info.turn + turns;
1152 }
1153 }
1154
1155 changed = TRUE;
1156 }
1157
1158 if (packet->scenario_reserved) {
1159 if (!player_has_flag(pplayer, PLRF_SCENARIO_RESERVED)) {
1160 changed = TRUE;
1161 BV_SET(pplayer->flags, PLRF_SCENARIO_RESERVED);
1162 }
1163 } else {
1164 if (player_has_flag(pplayer, PLRF_SCENARIO_RESERVED)) {
1165 changed = TRUE;
1166 BV_CLR(pplayer->flags, PLRF_SCENARIO_RESERVED);
1167 }
1168 }
1169
1170 /* TODO: Handle more property edits. */
1171
1172 if (update_research) {
1173 Tech_type_id current, goal;
1174
1176
1177 /* FIXME: Modifies struct research directly. */
1178
1179 current = research->researching;
1180 goal = research->tech_goal;
1181
1182 if (current != A_UNSET) {
1183 if (current != A_FUTURE) {
1184 known = research_invention_state(research, current);
1185 if (known != TECH_PREREQS_KNOWN) {
1187 }
1188 } else {
1189 /* Future Tech is legal only if all techs are known */
1191 known = research_invention_state(research, tech_i);
1192 if (known != TECH_KNOWN) {
1194 break;
1195 }
1197 }
1198 }
1199 if (goal != A_UNSET) {
1200 if (goal != A_FUTURE) {
1201 known = research_invention_state(research, goal);
1202 if (known == TECH_KNOWN) {
1204 }
1205 }
1206 }
1207 changed = TRUE;
1208
1209 /* Inform everybody about global advances */
1210 send_game_info(NULL);
1212 }
1213
1214 if (changed) {
1215 send_player_all_c(pplayer, NULL);
1216 }
1217}
1218
1219/************************************************************************/
1222void handle_edit_player_vision(struct connection *pc, int plr_no,
1223 int tile, bool known, int size)
1224{
1225 struct player *pplayer;
1226 struct tile *ptile_center;
1227
1228 ptile_center = index_to_tile(&(wld.map), tile);
1229 if (!ptile_center) {
1230 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1231 _("Cannot edit vision because %d is not a valid "
1232 "tile index on this map!"), tile);
1233 return;
1234 }
1235
1236 pplayer = player_by_number(plr_no);
1237 if (!pplayer) {
1238 notify_conn(pc->self, ptile_center, E_BAD_COMMAND, ftc_editor,
1239 /* TRANS: ..." at <tile-coordinates> because"... */
1240 _("Cannot edit vision for the tile at %s because "
1241 "given player id %d is invalid."),
1242 tile_link(ptile_center), plr_no);
1243 return;
1244 }
1245
1247 square_iterate(&(wld.map), ptile_center, size - 1, ptile) {
1248
1249 if (!known) {
1250 struct city *pcity = tile_city(ptile);
1251 bool cannot_make_unknown = FALSE;
1252
1253 if (pcity && city_owner(pcity) == pplayer) {
1254 continue;
1255 }
1256
1257 unit_list_iterate(ptile->units, punit) {
1258 if (unit_owner(punit) == pplayer
1259 || really_gives_vision(pplayer, unit_owner(punit))) {
1260 cannot_make_unknown = TRUE;
1261 break;
1262 }
1264
1265 if (cannot_make_unknown) {
1266 continue;
1267 }
1268
1269 /* The client expects tiles which become unseen to
1270 * contain no units (client/packhand.c +2368).
1271 * So here we tell it to remove units that do
1272 * not give it vision. */
1273 unit_list_iterate(ptile->units, punit) {
1274 conn_list_iterate(pplayer->connections, pconn) {
1278 }
1279
1280 if (known) {
1281 map_show_tile(pplayer, ptile);
1282 } else {
1283 map_hide_tile(pplayer, ptile);
1284 }
1287}
1288
1289/************************************************************************/
1298
1299/************************************************************************/
1302void handle_edit_city_remove(struct connection *pc, int id16, int id32)
1303{
1304 struct city *pcity;
1305
1306 if (!has_capability("ids32", pc->capability)) {
1307 id32 = id16;
1308 }
1309
1310 pcity = game_city_by_number(id32);
1311 if (pcity == NULL) {
1312 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1313 _("No such city (ID %d)."), id32);
1314 return;
1315 }
1316
1317 remove_city(pcity);
1318}
1319
1320/************************************************************************/
1327
1328/************************************************************************/
1333void handle_edit_toggle_fogofwar(struct connection *pc, int plr_no)
1334{
1335 struct player *pplayer;
1336
1337 if (!game.info.fogofwar) {
1338 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1339 _("Cannot toggle fog-of-war when it is already "
1340 "disabled."));
1341 return;
1342 }
1343
1344 pplayer = player_by_number(plr_no);
1345 if (!pplayer) {
1346 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1347 _("Cannot toggle fog-of-war for invalid player ID %d."),
1348 plr_no);
1349 return;
1350 }
1351
1353 if (unfogged_players[player_number(pplayer)]) {
1354 enable_fog_of_war_player(pplayer);
1356 } else {
1359 }
1361}
1362
1363/************************************************************************/
1367 const struct packet_edit_startpos *packet)
1368{
1369 struct tile *ptile = index_to_tile(&(wld.map), packet->id);
1370 bool changed;
1371
1372 /* Check. */
1373 if (NULL == ptile) {
1374 notify_conn(pconn->self, NULL, E_BAD_COMMAND, ftc_editor,
1375 _("Invalid tile index %d for start position."), packet->id);
1376 return;
1377 }
1378
1379 /* Handle. */
1380 if (packet->removal) {
1381 changed = map_startpos_remove(ptile);
1382 } else {
1383 if (NULL != map_startpos_get(ptile)) {
1384 changed = FALSE;
1385 } else {
1386 map_startpos_new(ptile);
1387 changed = TRUE;
1388 }
1389 }
1390
1391 /* Notify. */
1392 if (changed) {
1394 if (can_conn_edit(aconn)) {
1395 send_packet_edit_startpos(aconn, packet);
1396 }
1398 }
1399}
1400
1401/************************************************************************/
1405 const struct packet_edit_startpos_full *
1406 packet)
1407{
1408 struct tile *ptile = index_to_tile(&(wld.map), packet->id);
1409 struct startpos *psp;
1410
1411 /* Check. */
1412 if (NULL == ptile) {
1413 notify_conn(pconn->self, NULL, E_BAD_COMMAND, ftc_editor,
1414 _("Invalid tile index %d for start position."),
1415 packet->id);
1416 return;
1417 }
1418
1419 psp = map_startpos_get(ptile);
1420 if (NULL == psp) {
1421 notify_conn(pconn->self, ptile, E_BAD_COMMAND, ftc_editor,
1422 _("Cannot edit start position nations at (%d, %d) "
1423 "because there is no start position there."),
1424 TILE_XY(ptile));
1425 return;
1426 }
1427
1428 /* Handle. */
1429 if (startpos_unpack(psp, packet)) {
1430 /* Notify. */
1432 if (can_conn_edit(aconn)) {
1433 send_packet_edit_startpos_full(aconn, packet);
1434 }
1436 }
1437}
1438
1439/************************************************************************/
1443 const struct packet_edit_game *packet)
1444{
1445 bool changed = FALSE;
1446
1447 if (packet->scenario != game.scenario.is_scenario) {
1449 changed = TRUE;
1450 }
1451
1452 if (0 != strncmp(packet->scenario_name, game.scenario.name, 256)) {
1454 changed = TRUE;
1455 }
1456
1457 FC_STATIC_ASSERT(sizeof(packet->scenario_authors) == sizeof(game.scenario.authors),
1458 scen_authors_field_size_mismatch);
1459
1460 if (0 != strncmp(packet->scenario_authors, game.scenario.authors,
1461 sizeof(game.scenario.authors))) {
1463 changed = TRUE;
1464 }
1465
1466 if (packet->scenario_random != game.scenario.save_random) {
1468 changed = TRUE;
1469 }
1470
1471 if (packet->scenario_players != game.scenario.players) {
1473 changed = TRUE;
1474 }
1475
1478 changed = TRUE;
1479 }
1480
1483 changed = TRUE;
1484 }
1485
1486 if (packet->lake_flooding != game.scenario.lake_flooding) {
1488 changed = TRUE;
1489 }
1490
1491 if (packet->ruleset_locked != game.scenario.ruleset_locked) {
1493 changed = TRUE;
1494 }
1495
1496 if (changed) {
1497 send_scenario_info(NULL);
1498 send_game_info(NULL);
1499 }
1500}
1501
1502/************************************************************************/
1505void handle_edit_scenario_desc(struct connection *pc, const char *scenario_desc)
1506{
1507 if (0 != strncmp(scenario_desc, game.scenario_desc.description,
1508 MAX_LEN_PACKET)) {
1509 sz_strlcpy(game.scenario_desc.description, scenario_desc);
1511 }
1512}
1513
1514/************************************************************************/
1517void handle_save_scenario(struct connection *pc, const char *name)
1518{
1519 if (pc->access_level != ALLOW_HACK) {
1520 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1521 _("No permissions to remotely save scenario."));
1522 return;
1523 }
1524
1525 if (!game.scenario.is_scenario) {
1526 /* Scenario information not available */
1527 notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
1528 _("Scenario information not set. Cannot save scenario."));
1529 return;
1530 }
1531
1532 /* Client initiated scenario saving is not handmade */
1534
1535 save_game(name, "Scenario", TRUE);
1536}
const char * default_ai_type_name(void)
Definition aiiface.c:262
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ARE_EQUAL(vec1, vec2)
Definition bitvector.h:113
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_ISSET_ANY(vec)
Definition bitvector.h:109
#define BV_CLR(bv, bit)
Definition bitvector.h:86
bool has_capability(const char *cap, const char *capstr)
Definition capability.c:77
void city_name_set(struct city *pcity, const char *new_name)
Definition city.c:1123
int city_granary_size(int city_size)
Definition city.c:2104
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1216
void city_remove_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3284
#define city_tile(_pcity_)
Definition city.h:544
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
#define city_owner(_pcity_)
Definition city.h:543
#define MAX_CITY_SIZE
Definition city.h:98
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2327
struct city * build_or_move_building(struct city *pcity, struct impr_type *pimprove, struct player **oldcity_owner)
Definition citytools.c:2932
struct city * find_closest_city(const struct tile *ptile, const struct city *pexclcity, const struct player *pplayer, bool only_ocean, bool only_continent, bool only_known, bool only_player, bool only_enemy, const struct unit_class *pclass)
Definition citytools.c:854
bool is_allowed_city_name(struct player *pplayer, const char *cityname, char *error_buf, size_t bufsz)
Definition citytools.c:372
void remove_city(struct city *pcity)
Definition citytools.c:1684
bool create_city_for_player(struct player *pplayer, struct tile *ptile, const char *name)
Definition citytools.c:1656
void city_refresh_queue_add(struct city *pcity)
Definition cityturn.c:200
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, const char *reason)
Definition cityturn.c:1061
void city_refresh_queue_processing(void)
Definition cityturn.c:216
int cid
Definition climisc.h:31
void connection_detach(struct connection *pconn, bool remove_unused_player)
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:365
bool can_conn_edit(const struct connection *pconn)
Definition connection.c:510
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:355
bool can_conn_enable_editing(const struct connection *pconn)
Definition connection.c:520
const char * conn_description(const struct connection *pconn)
Definition connection.c:473
#define MAX_LEN_PACKET
Definition connection.h:56
#define conn_list_iterate(connlist, pconn)
Definition connection.h:113
#define conn_list_iterate_end
Definition connection.h:115
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:73
int int id
Definition editgui_g.h:28
void handle_edit_tile(struct connection *pc, const struct packet_edit_tile *packet)
Definition edithand.c:378
void handle_edit_scenario_desc(struct connection *pc, const char *scenario_desc)
Definition edithand.c:1505
void handle_edit_check_tiles(struct connection *pc)
Definition edithand.c:1323
void handle_edit_mode(struct connection *pc, bool is_edit_mode)
Definition edithand.c:189
void handle_edit_tile_terrain(struct connection *pc, int tile, Terrain_type_id terrain, int size)
Definition edithand.c:299
void handle_edit_player(struct connection *pc, const struct packet_edit_player *packet)
Definition edithand.c:1026
static bool need_continents_reassigned
Definition edithand.c:65
void edithand_send_initial_packets(struct conn_list *dest)
Definition edithand.c:113
static bool * unfogged_players
Definition edithand.c:74
static struct tile_hash * modified_tile_table
Definition edithand.c:69
void handle_edit_player_remove(struct connection *pc, int id)
Definition edithand.c:1002
static bool edit_tile_terrain_handling(struct tile *ptile, struct terrain *pterrain, bool send_info)
Definition edithand.c:222
void edithand_free(void)
Definition edithand.c:97
void handle_edit_player_vision(struct connection *pc, int plr_no, int tile, bool known, int size)
Definition edithand.c:1222
void handle_edit_city(struct connection *pc, const struct packet_edit_city *packet)
Definition edithand.c:756
void edithand_init(void)
Definition edithand.c:79
void handle_edit_city_create(struct connection *pc, int owner, int tile, int size, int tag)
Definition edithand.c:700
void handle_edit_unit_remove_by_id(struct connection *pc, Unit_type_id id16, Unit_type_id id32)
Definition edithand.c:596
static bool edit_tile_extra_handling(struct tile *ptile, struct extra_type *pextra, bool remove_mode, bool send_info)
Definition edithand.c:254
void handle_edit_game(struct connection *pc, const struct packet_edit_game *packet)
Definition edithand.c:1442
void handle_edit_city_remove(struct connection *pc, int id16, int id32)
Definition edithand.c:1302
void handle_edit_unit_remove(struct connection *pc, int owner, int tile, Unit_type_id utid, int count)
Definition edithand.c:541
void handle_edit_toggle_fogofwar(struct connection *pc, int plr_no)
Definition edithand.c:1333
void handle_edit_startpos_full(struct connection *pconn, const struct packet_edit_startpos_full *packet)
Definition edithand.c:1404
static void check_leaving_edit_mode(void)
Definition edithand.c:165
void handle_edit_player_create(struct connection *pc, int tag)
Definition edithand.c:923
void handle_edit_recalculate_borders(struct connection *pc)
Definition edithand.c:1294
void handle_save_scenario(struct connection *pc, const char *name)
Definition edithand.c:1517
void handle_edit_tile_extra(struct connection *pc, int tile, int id, bool removal, int eowner, int size)
Definition edithand.c:336
void handle_edit_unit_create(struct connection *pc, int owner, int tile, Unit_type_id utid, int count, int tag)
Definition edithand.c:438
void handle_edit_unit(struct connection *pc, const struct packet_edit_unit *packet)
Definition edithand.c:618
static void check_edited_tile_terrains(void)
Definition edithand.c:143
void handle_edit_startpos(struct connection *pconn, const struct packet_edit_startpos *packet)
Definition edithand.c:1366
int extra_number(const struct extra_type *pextra)
Definition extras.c:153
struct extra_type * extra_by_number(int id)
Definition extras.c:175
#define extra_type_iterate(_p)
Definition extras.h:291
#define extra_type_iterate_end
Definition extras.h:297
#define is_extra_caused_by(e, c)
Definition extras.h:196
int Tech_type_id
Definition fc_types.h:347
int Terrain_type_id
Definition fc_types.h:343
int Unit_type_id
Definition fc_types.h:352
#define _(String)
Definition fcintl.h:67
const char * tile_link(const struct tile *ptile)
const struct ft_color ftc_editor
const char * city_link(const struct city *pcity)
const char * unit_link(const struct unit *punit)
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
struct city * game_city_by_number(int id)
Definition game.c:102
void send_scenario_description(struct conn_list *dest)
Definition gamehand.c:962
void send_scenario_info(struct conn_list *dest)
Definition gamehand.c:948
void send_game_info(struct conn_list *dest)
Definition gamehand.c:905
struct government * government_by_number(const Government_type_id gov)
Definition government.c:102
struct city * owner
Definition citydlg.c:219
bool is_special_improvement(const struct impr_type *pimprove)
Impr_type_id improvement_number(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
const char * name
Definition inputfile.c:127
#define FC_STATIC_ASSERT(cond, tag)
Definition log.h:235
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1686
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1669
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1479
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1509
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:454
bool map_startpos_remove(struct tile *ptile)
Definition map.c:1702
bool startpos_unpack(struct startpos *psp, const struct packet_edit_startpos_full *packet)
Definition map.c:1529
#define map_startpos_iterate(NAME_psp)
Definition map.h:124
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:385
#define square_iterate_end
Definition map.h:388
#define map_startpos_iterate_end
Definition map.h:127
#define MAP_TILE_OWNER_NULL
Definition map.h:568
void assign_continent_numbers(void)
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:342
void send_tile_info(struct conn_list *dest, struct tile *ptile, bool send_unknown)
Definition maphand.c:488
void send_all_known_tiles(struct conn_list *dest)
Definition maphand.c:441
bool need_to_reassign_continents(const struct terrain *oldter, const struct terrain *newter)
Definition maphand.c:1921
void disable_fog_of_war_player(struct player *pplayer)
Definition maphand.c:1759
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:760
void tile_change_side_effects(struct tile *ptile, bool refresh_city)
Definition maphand.c:2708
void terrain_changed(struct tile *ptile)
Definition maphand.c:1940
void map_calculate_borders(void)
Definition maphand.c:2357
void fix_tile_on_terrain_change(struct tile *ptile, struct terrain *oldter, bool extend_rivers)
Definition maphand.c:1959
void enable_fog_of_war_player(struct player *pplayer)
Definition maphand.c:1735
void map_show_circle(struct player *pplayer, struct tile *ptile, int radius_sq)
Definition maphand.c:856
void update_tile_knowledge(struct tile *ptile)
Definition maphand.c:1427
void map_hide_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:812
#define fc_calloc(n, esz)
Definition mem.h:38
bool can_exist_at_tile(const struct civ_map *nmap, const struct unit_type *utype, const struct tile *ptile)
Definition movement.c:264
Nation_type_id nation_count(void)
Definition nation.c:506
struct nation_type * nation_by_number(const Nation_type_id nation)
Definition nation.c:474
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:443
bool is_nation_playable(const struct nation_type *nation)
Definition nation.c:199
const char * nation_plural_translation(const struct nation_type *pnation)
Definition nation.c:158
enum barbarian_type nation_barbarian_type(const struct nation_type *nation)
Definition nation.c:210
struct government * init_government_of_nation(const struct nation_type *pnation)
Definition nation.c:658
void notify_conn(struct conn_list *dest, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:238
int send_packet_edit_startpos_full(struct connection *pc, const struct packet_edit_startpos_full *packet)
int dsend_packet_edit_object_created(struct connection *pc, int tag, int id)
int dsend_packet_unit_remove(struct connection *pc, int unit_id16, int unit_id32)
int send_packet_edit_startpos(struct connection *pc, const struct packet_edit_startpos *packet)
struct player * player_by_number(const int player_id)
Definition player.c:840
int player_count(void)
Definition player.c:808
int player_slot_count(void)
Definition player.c:411
int player_number(const struct player *pplayer)
Definition player.c:828
const char * player_name(const struct player *pplayer)
Definition player.c:886
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1954
int player_index(const struct player *pplayer)
Definition player.c:820
bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
Definition player.c:852
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
#define ANON_USER_NAME
Definition player.h:48
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
void send_player_all_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:983
struct player * server_create_player(int player_id, const char *ai_tname, struct rgbcolor *prgbcolor, bool allow_ai_type_fallbacking)
Definition plrhand.c:1724
void player_limit_to_max_rates(struct player *pplayer)
Definition plrhand.c:1887
bool server_player_set_name_full(const struct connection *caller, struct player *pplayer, const struct nation_type *pnation, const char *name, char *error_buf, size_t error_buf_len)
Definition plrhand.c:1998
struct nation_type * pick_a_nation(const struct nation_list *choices, bool ignore_conflicts, bool needs_startpos, enum barbarian_type barb_type)
Definition plrhand.c:2283
void kill_player(struct player *pplayer)
Definition plrhand.c:125
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1000
void server_remove_player(struct player *pplayer)
Definition plrhand.c:1773
void government_change(struct player *pplayer, struct government *gov, bool revolution_finished)
Definition plrhand.c:336
void server_player_init(struct player *pplayer, bool initmap, bool needs_team)
Definition plrhand.c:1451
void assign_player_colors(void)
Definition plrhand.c:1564
bool nation_is_in_current_set(const struct nation_type *pnation)
Definition plrhand.c:2420
int revolution_length(struct government *gov, struct player *plr)
Definition plrhand.c:438
enum tech_state research_invention_set(struct research *presearch, Tech_type_id tech, enum tech_state value)
Definition research.c:634
struct research * research_get(const struct player *pplayer)
Definition research.c:126
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:616
void research_update(struct research *presearch)
Definition research.c:499
#define sanity_check_tile(x)
Definition sanitycheck.h:42
void save_game(const char *orig_filename, const char *save_reason, bool scenario)
Definition savemain.c:152
#define MAX_UINT8
Definition shared.h:83
#define CLIP(lower, current, upper)
Definition shared.h:57
size_t size
Definition specvec.h:72
void player_nation_defaults(struct player *pplayer, struct nation_type *pnation, bool set_name)
Definition srv_main.c:2510
bool game_was_started(void)
Definition srv_main.c:339
Definition city.h:309
int food_stock
Definition city.h:354
int history
Definition city.h:393
int id
Definition city.h:315
char * name
Definition city.h:310
int before_change_shields
Definition city.h:375
int shield_stock
Definition city.h:355
struct civ_game::@30::@34 server
struct packet_scenario_description scenario_desc
Definition game.h:88
struct packet_ruleset_control control
Definition game.h:83
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
struct packet_scenario_info scenario
Definition game.h:87
int max_players
Definition game.h:155
struct government * government_during_revolution
Definition game.h:94
enum cmdlevel access_level
Definition connection.h:182
struct conn_list * self
Definition connection.h:168
char capability[MAX_LEN_CAPSTR]
Definition connection.h:176
struct player * player
Definition nation.h:117
int built[B_LAST]
char name[MAX_LEN_CITYNAME]
char scenario_name[256]
char scenario_authors[MAX_LEN_PACKET/3]
Nation_type_id nation
char name[MAX_LEN_NAME]
Government_type_id government
bool inventions[A_LAST+1]
char label[MAX_LEN_NAME]
char description[MAX_LEN_CONTENT]
char authors[MAX_LEN_PACKET/3]
enum barbarian_type barbarian_type
Definition player.h:128
int infra_points
Definition player.h:74
struct player_ai ai_common
Definition player.h:288
bv_plr_flags flags
Definition player.h:292
bool got_first_city
Definition player.h:320
char username[MAX_LEN_NAME]
Definition player.h:252
bool is_connected
Definition player.h:296
int revolution_finishes
Definition player.h:273
struct government * government
Definition player.h:258
struct conn_list * connections
Definition player.h:298
bool is_alive
Definition player.h:268
struct player_economic economic
Definition player.h:284
struct player::@69::@71 server
bool unassigned_user
Definition player.h:253
Tech_type_id researching
Definition research.h:52
Tech_type_id tech_goal
Definition research.h:85
int techs_researched
Definition research.h:42
int bulbs_researched
Definition research.h:53
Definition map.c:41
Definition tile.h:49
bv_extras extras
Definition tile.h:54
struct unit_list * units
Definition tile.h:57
struct player * extras_owner
Definition tile.h:62
struct terrain * terrain
Definition tile.h:56
int vision_radius_sq
Definition unittype.h:503
Definition unit.h:138
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
bool moved
Definition unit.h:173
int hp
Definition unit.h:151
int fuel
Definition unit.h:153
bool stay
Definition unit.h:205
int homecity
Definition unit.h:146
bool done_moving
Definition unit.h:181
int veteran
Definition unit.h:152
struct civ_map map
#define sz_strlcpy(dest, src)
Definition support.h:167
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define A_FUTURE
Definition tech.h:46
#define advance_index_iterate_end
Definition tech.h:248
#define A_FIRST
Definition tech.h:44
#define A_UNSET
Definition tech.h:48
#define advance_index_iterate(_start, _index)
Definition tech.h:244
void init_tech(struct research *research, bool update)
Definition techtools.c:1070
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Definition techtools.c:273
void give_initial_techs(struct research *presearch, int num_random_techs)
Definition techtools.c:1162
struct terrain * terrain_by_number(const Terrain_type_id type)
Definition terrain.c:144
bool terrain_has_resource(const struct terrain *pterrain, const struct extra_type *presource)
Definition terrain.c:243
#define terrain_has_flag(terr, flag)
Definition terrain.h:269
bool tile_extra_apply(struct tile *ptile, struct extra_type *tgt)
Definition tile.c:552
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:473
bool tile_extra_rm_apply(struct tile *ptile, struct extra_type *tgt)
Definition tile.c:578
bool tile_set_label(struct tile *ptile, const char *label)
Definition tile.c:1080
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Definition tile.c:343
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:87
#define tile_hash_iterate(hash, ptile)
Definition tile.h:81
#define tile_terrain(_tile)
Definition tile.h:113
#define tile_hash_iterate_end
Definition tile.h:83
#define TILE_XY(ptile)
Definition tile.h:42
#define tile_has_extra(ptile, pextra)
Definition tile.h:150
#define unit_owner(_pu)
Definition unit.h:394
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:430
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2795
struct unit * create_unit(struct player *pplayer, struct tile *ptile, const struct unit_type *type, int veteran_level, int homecity_id, int moves_left)
Definition unittools.c:1616
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2248
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1979
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2645
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
#define utype_class(_t_)
Definition unittype.h:736
#define utype_fuel(ptype)
Definition unittype.h:825
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604