Freeciv-3.3
Loading...
Searching...
No Matches
tilespec.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/***********************************************************************
15 Functions for handling the tilespec files which describe
16 the files and contents of tilesets.
17 original author: David Pfitzner <dwp@mso.anu.edu.au>
18***********************************************************************/
19
20#ifdef HAVE_CONFIG_H
21#include <fc_config.h>
22#endif
23
24#include <stdio.h>
25#include <stdlib.h> /* exit */
26#include <stdarg.h>
27#include <string.h>
28
29/* utility */
30#include "astring.h"
31#include "bitvector.h"
32#include "capability.h"
33#include "deprecations.h"
34#include "fcintl.h"
35#include "log.h"
36#include "mem.h"
37#include "rand.h"
38#include "registry.h"
39#include "shared.h"
40#include "string_vector.h"
41#include "support.h"
42
43/* common */
44#include "base.h"
45#include "effects.h"
46#include "game.h" /* game.control.num_city_styles */
47#include "government.h"
48#include "map.h"
49#include "modpack.h"
50#include "movement.h"
51#include "nation.h"
52#include "player.h"
53#include "road.h"
54#include "specialist.h"
55#include "unit.h"
56#include "unitlist.h"
57
58/* client/include */
59#include "dialogs_g.h"
60#include "graphics_g.h"
61#include "gui_main_g.h"
62#include "mapview_g.h" /* For update_map_canvas_visible */
63#include "menu_g.h"
64#include "themes_g.h"
65
66/* client */
67#include "citydlg_common.h" /* For generate_citydlg_dimensions() */
68#include "client_main.h"
69#include "climap.h" /* For client_tile_get_known() */
70#include "colors_common.h"
71#include "control.h" /* For fill_xxx */
72#include "editor.h"
73#include "goto.h"
74#include "helpdata.h"
75#include "options.h" /* For fill_xxx */
76#include "svgflag.h"
77#include "themes_common.h"
78
79#include "tilespec.h"
80
81#define TILESPEC_CAPSTR "+Freeciv-tilespec-3.2-Devel-2022-Jun-21 duplicates_ok"
82/*
83 * Tilespec capabilities acceptable to this program:
84 *
85 * +Freeciv-3.2-tilespec
86 * - basic format for Freeciv versions 3.2.x; required
87 *
88 * +Freeciv-tilespec-3.2-Devel-YYYY.MMM.DD
89 * - tilespec of the development version at the given date
90 *
91 * duplicates_ok
92 * - we can handle existence of duplicate tags (lattermost tag which
93 * appears is used; tilesets which have duplicates should specify
94 * "duplicates_ok")
95 */
96
97#define SPEC_CAPSTR "+Freeciv-spec-3.3-Devel-2023.Apr.05"
98/*
99 * Individual spec file capabilities acceptable to this program:
100 *
101 * +Freeciv-3.2-spec
102 * - basic format for Freeciv versions 3.2.x; required
103 */
104
105#define TILESPEC_SUFFIX ".tilespec"
106#define TILE_SECTION_PREFIX "tile_"
107
108/* This the way directional indices are now encoded: */
109#define MAX_INDEX_CARDINAL 64
110#define MAX_INDEX_HALF 16
111#define MAX_INDEX_VALID 256
112
113#define NUM_TILES_HP_BAR 11
114#define NUM_TILES_DIGITS 10
115#define NUM_TILES_SELECT 4
116#define MAX_NUM_UPKEEP_SPRITES 10
117
118#define SPECENUM_NAME extrastyle_id
119#define SPECENUM_VALUE0 ESTYLE_ROAD_ALL_SEPARATE
120#define SPECENUM_VALUE0NAME "RoadAllSeparate"
121#define SPECENUM_VALUE1 ESTYLE_ROAD_PARITY_COMBINED
122#define SPECENUM_VALUE1NAME "RoadParityCombined"
123#define SPECENUM_VALUE2 ESTYLE_ROAD_ALL_COMBINED
124#define SPECENUM_VALUE2NAME "RoadAllCombined"
125#define SPECENUM_VALUE3 ESTYLE_RIVER
126#define SPECENUM_VALUE3NAME "River"
127#define SPECENUM_VALUE4 ESTYLE_SINGLE1
128#define SPECENUM_VALUE4NAME "Single1"
129#define SPECENUM_VALUE5 ESTYLE_SINGLE2
130#define SPECENUM_VALUE5NAME "Single2"
131#define SPECENUM_VALUE6 ESTYLE_3LAYER
132#define SPECENUM_VALUE6NAME "3Layer"
133#define SPECENUM_VALUE7 ESTYLE_CARDINALS
134#define SPECENUM_VALUE7NAME "Cardinals"
135#define SPECENUM_COUNT ESTYLE_COUNT
136#include "specenum_gen.h"
137
138/* This could be moved to common/map.h if there's more use for it. */
142static const char direction4letters[4] = "udrl";
143/* This must correspond to enum edge_type. */
144static const char edge_name[EDGE_COUNT][3] = {"ns", "we", "ud", "lr"};
145
146static const int DIR4_TO_DIR8[4] =
148
155
157 CELL_WHOLE, /* Entire tile */
158 CELL_CORNER /* Corner of tile */
160
167
169 bool init;
170
171 char *name;
172
173 int num_layers; /* 1 thru MAX_NUM_LAYERS. */
174#define MAX_NUM_LAYERS 3
175
179
180#define MAX_NUM_MATCH_WITH 8
183 int match_indices; /* 0 = no match_type, 1 = no match_with */
184
186
189 struct sprite **cells;
190
191 /* List of those sprites in 'cells' that are allocated by some other
192 * means than load_sprite() and thus are not freed by unload_all_sprites(). */
195
197
198 int blending; /* layer, 0 = none */
200 struct sprite *blend[4]; /* indexed by a direction4 */
201};
202
204 struct sprite *sprite;
205};
206
214
220
222 /* Each citizen type has up to MAX_NUM_CITIZEN_SPRITES different
223 * sprites, as defined by the tileset. */
224 int count;
226};
227
232
237
239 struct sprite
241 *treaty_thumb[2], /* 0=disagree, 1=agree */
242 *arrow[ARROW_LAST], /* 0=right arrow, 1=plus, 2=minus */
243
245
247
248 /* The panel sprites for showing tax % allocations. */
250 *dither_tile; /* Only used for isometric view */
251
252 struct {
253 struct sprite
258
262
263 struct {
264 struct sprite *icon[U_LAST][ACTIVITY_LAST];
267
270
273
275 struct {
276 int hot_x, hot_y;
277 struct sprite *frame[NUM_CURSOR_FRAMES];
279 struct {
281 struct sprite *nuke;
283 struct {
286 struct sprite
288 *vet_lev[MAX_VET_LEVELS],
295 *go_to, /* goto is a C keyword :-) */
306 *battlegroup[MAX_NUM_BATTLEGROUPS],
311 struct {
312 struct sprite
316 struct {
317 struct sprite
320 *size_tens[NUM_TILES_DIGITS],
321 *size_hundreds[NUM_TILES_DIGITS],
322 *tile_foodnum[NUM_TILES_DIGITS],
323 *tile_shieldnum[NUM_TILES_DIGITS],
324 *tile_tradenum[NUM_TILES_DIGITS];
325 struct city_sprite
330 struct sprite_vector worked_tile_overlay;
331 struct sprite_vector unworked_tile_overlay;
335 struct {
336 struct {
338 struct sprite *turns[NUM_TILES_DIGITS];
339 struct sprite *turns_tens[NUM_TILES_DIGITS];
340 struct sprite *turns_hundreds[NUM_TILES_DIGITS];
344 struct {
348 struct {
349 struct sprite
352 *darkness[MAX_INDEX_CARDINAL]; /* First unused */
353 } tx; /* Terrain extra */
354 struct {
355 struct sprite
359 union {
360 struct sprite *single;
361 struct sprite *cardinals[MAX_INDEX_CARDINAL];
362 struct {
363 struct sprite
367 } bmf;
368 struct {
369 struct sprite
370 /* For extrastyles ESTYLE_ROAD_ALL_SEPARATE and ESTYLE_ROAD_PARITY_COMBINED */
372 *corner[8]; /* Indexed by direction; only non-cardinal dirs used. */
373 union {
374 /* For ESTYLE_ROAD_ALL_SEPARATE */
375 struct sprite *dir[8]; /* All entries used */
376 /* ESTYLE_ROAD_PARITY_COMBINED */
377 struct {
378 struct sprite
379 *even[MAX_INDEX_HALF], /* First unused */
380 *odd[MAX_INDEX_HALF]; /* First unused */
381 } combo;
382 /* ESTYLE_ALL_SEPARATE */
383 struct sprite *total[MAX_INDEX_VALID];
384 struct river_sprites rivers;
385 } ru;
387 } u;
389 struct {
390 struct sprite
393 *worked[EDGE_COUNT],
396 *selected[EDGE_COUNT],
397 *coastline[EDGE_COUNT],
398 *borders[EDGE_COUNT][2];
400 struct {
401 struct sprite_vector overlays;
403 struct {
404 struct sprite *color; /* Generic background color */
405 struct sprite *graphic; /* Generic background graphic */
407 struct {
408 struct sprite *grid_borders[EDGE_COUNT][2];
409 struct sprite *color;
410 struct sprite *background;
412
414};
415
416struct specfile {
417 struct sprite *big_sprite;
418 char *file_name;
419};
420
421#define SPECLIST_TAG specfile
422#define SPECLIST_TYPE struct specfile
423#include "speclist.h"
424
425#define specfile_list_iterate(list, pitem) \
426 TYPED_LIST_ITERATE(struct specfile, list, pitem)
427#define specfile_list_iterate_end LIST_ITERATE_END
428
429/*
430 * Information about an individual sprite. All fields except 'sprite' are
431 * filled at the time of the scan of the specfile. 'Sprite' is
432 * set/cleared on demand in load_sprite()/unload_sprite().
433 */
434struct small_sprite {
435 int ref_count;
436
437 /* The sprite is in this file. */
438 char *file;
439
440 /* Or, the sprite is in this file at the location. */
441 struct specfile *sf;
442 int x, y, width, height;
443
444 /* A little more (optional) data. */
445 int hot_x, hot_y;
446
447 struct sprite *sprite;
448};
449
450/* 'struct small_sprite_list' and related functions. */
451#define SPECLIST_TAG small_sprite
452#define SPECLIST_TYPE struct small_sprite
453#include "speclist.h"
454#define small_sprite_list_iterate(list, pitem) \
455 TYPED_LIST_ITERATE(struct small_sprite, list, pitem)
456#define small_sprite_list_iterate_end LIST_ITERATE_END
457
458/* 'struct sprite_hash' and related functions. */
459#define SPECHASH_TAG sprite
460#define SPECHASH_ASTR_KEY_TYPE
461#define SPECHASH_IDATA_TYPE struct small_sprite *
462#include "spechash.h"
463#define sprite_hash_iterate(hash, tag_name, sprite) \
464 TYPED_HASH_ITERATE(const char *, struct small_sprite *, \
465 hash, tag_name, sprite)
466#define sprite_hash_iterate_end HASH_ITERATE_END
467
468/* 'struct drawing_hash' and related functions. */
469static void drawing_data_destroy(struct drawing_data *draw);
470
471#define SPECHASH_TAG drawing
472#define SPECHASH_CSTR_KEY_TYPE
473#define SPECHASH_IDATA_TYPE struct drawing_data *
474#define SPECHASH_IDATA_FREE drawing_data_destroy
475#include "spechash.h"
476
477#define SPECHASH_TAG estyle
478#define SPECHASH_ASTR_KEY_TYPE
479#define SPECHASH_ENUM_DATA_TYPE extrastyle_id
480#include "spechash.h"
481
482struct tileset {
483 char name[512];
487
488 char *summary;
490 float scale;
491
493
495
499
504
507
509
511
514
520
533
534#define NUM_CORNER_DIRS 4
535#define TILES_PER_CORNER 4
539
544
547
548 /* This hash table maps tilespec tags to struct small_sprites. */
550
551 /* This hash table maps terrain graphic strings to drawing data. */
553
555
557
559
561
563
566};
567
570
572
573static bool tileset_update = FALSE;
574
575static struct tileset *tileset_read_toplevel(const char *tileset_name,
576 bool verbose, int topology_id,
577 float scale);
578
579static int fill_unit_type_sprite_array(const struct tileset *t,
580 struct drawn_sprite *sprs,
581 const struct unit_type *putype,
582 enum unit_activity activity,
583 enum direction8 facing);
584static int fill_unit_sprite_array(const struct tileset *t,
585 struct drawn_sprite *sprs,
586 const struct unit *punit,
587 int stack, bool backdrop);
588static bool load_river_sprites(struct tileset *t,
589 struct river_sprites *store, const char *tag_pfx);
590
591static void tileset_setup_base(struct tileset *t,
592 const struct extra_type *pextra,
593 const char *tag);
594static void tileset_setup_road(struct tileset *t,
595 struct extra_type *pextra,
596 const char *tag);
597
598static bool is_extra_drawing_enabled(struct extra_type *pextra);
599
600static int fill_basic_road_sprite_array(const struct tileset *t,
601 struct drawn_sprite *sprs,
602 const struct extra_type *pextra);
603static int fill_basic_base_sprite_array(const struct tileset *t,
604 struct drawn_sprite *sprs,
605 const struct extra_type *pextra);
606
607static void tileset_player_free(struct tileset *t, int plrid);
608
609static void tileset_setup_specialist_type(struct tileset *t,
610 struct citizen_set *set,
612 const char *tag_group,
613 const char *set_name,
614 bool required);
616static void tileset_setup_citizen_types(struct tileset *t,
617 struct citizen_set *set,
618 const char *tag_group,
619 const char *set_name,
620 bool required);
621
622/************************************************************************/
625void tileset_error(enum log_level level, const char *tset_name,
626 const char *format, ...)
627{
628 char buf[2048];
629 va_list args;
630
631 va_start(args, format);
632 fc_vsnprintf(buf, sizeof(buf), format, args);
633 va_end(args);
634
635 log_base(level, "%s", buf);
636
637 if (level <= LOG_NORMAL) {
639
640 if (level == LOG_FATAL) {
642 }
643 }
644}
645
646/************************************************************************/
649static struct drawing_data *drawing_data_new(void)
650{
651 struct drawing_data *draw = fc_calloc(1, sizeof(*draw));
652
653 draw->name = NULL;
654
655 return draw;
656}
657
658/************************************************************************/
662{
663 int i;
664
666
667 if (draw->name != NULL) {
668 free(draw->name);
669 }
670 for (i = 0; i < 4; i++) {
671 if (draw->blend[i]) {
672 free_sprite(draw->blend[i]);
673 }
674 }
675 for (i = 0; i < draw->num_layers; i++) {
676 int vec_size = sprite_vector_size(&draw->layer[i].allocated);
677 int j;
678
679 for (j = 0; j < vec_size; j++) {
680 free_sprite(draw->layer[i].allocated.p[j]);
681 }
682
683 sprite_vector_free(&draw->layer[i].base);
684 sprite_vector_free(&draw->layer[i].allocated);
685 free(draw->layer[i].cells);
686 }
687 free(draw);
688}
689
690/************************************************************************/
693struct tileset *get_tileset(void)
694{
695 if (unscaled_tileset != NULL) {
696 return unscaled_tileset;
697 } else {
698 return tileset;
699 }
700}
701
702/************************************************************************/
705const char *tileset_basename(const struct tileset *t)
706{
707 return t->name;
708}
709
710/************************************************************************/
713bool tileset_is_isometric(const struct tileset *t)
714{
715 return t->type == TS_ISOMETRIC;
716}
717
718/************************************************************************/
722int tileset_hex_width(const struct tileset *t)
723{
724 return t->hex_width;
725}
726
727/************************************************************************/
731int tileset_hex_height(const struct tileset *t)
732{
733 return t->hex_height;
734}
735
736/************************************************************************/
754int tileset_tile_width(const struct tileset *t)
755{
756 return t->normal_tile_width;
757}
758
759/************************************************************************/
766int tileset_tile_height(const struct tileset *t)
767{
768 return t->normal_tile_height;
769}
770
771/************************************************************************/
778{
779 return t->full_tile_width;
780}
781
782/************************************************************************/
791{
792 return t->full_tile_height;
793}
794
795/************************************************************************/
798int tileset_unit_width(const struct tileset *t)
799{
800 return t->unit_tile_width;
801}
802
803/************************************************************************/
806int tileset_unit_height(const struct tileset *t)
807{
808 return t->unit_tile_height;
809}
810
811/************************************************************************/
814static int calculate_max_upkeep_height(const struct tileset *t)
815{
816 int i;
817 int max = 0;
818
819 for (i = 0; i < MAX_NUM_UPKEEP_SPRITES; i++) {
820 if (t->sprites.upkeep.unhappy[i] != NULL) {
821 int width, height;
822
823 /* TODO: We want only height, getting the width might waste CPU
824 * depending on gui-specific implementation. */
826
827 max = MAX(max, height);
828 }
829 }
830
832 for (i = 0; i < MAX_NUM_UPKEEP_SPRITES; i++) {
833 if (t->sprites.upkeep.output[o][i] != NULL) {
834 int width, height;
835
836 /* TODO: We want only height, getting the width might waste CPU
837 * depending on gui-specific implementation. */
839
840 max = MAX(max, height);
841 }
842 }
844
845 return max;
846}
847
848/************************************************************************/
851static int tileset_upkeep_height(const struct tileset *t)
852{
853 /* Return cached value */
854 return t->max_upkeep_height;
855}
856
857/************************************************************************/
867
868/************************************************************************/
879
880/************************************************************************/
884{
885 return t->unit_upkeep_offset_y;
886}
887
888/************************************************************************/
893{
895}
896
897/************************************************************************/
903{
904 return t->small_sprite_width;
905}
906
907/************************************************************************/
912{
913 return t->citybar_offset_y;
914}
915
916/************************************************************************/
921{
922 return t->tilelabel_offset_y;
923}
924
925/************************************************************************/
928float tileset_scale(const struct tileset *t)
929{
930 return tileset->scale;
931}
932
933/************************************************************************/
939{
940 return t->small_sprite_height;
941}
942
943/************************************************************************/
948const char *tileset_main_intro_filename(const struct tileset *t)
949{
950 return t->main_intro_filename;
951}
952
953/************************************************************************/
957{
958 return t->sprites.city.worked_tile_overlay.size;
959}
960
961/************************************************************************/
965{
966 return FOG_AUTO == t->fogstyle;
967}
968
969/************************************************************************/
972static struct tileset *tileset_new(void)
973{
974 struct tileset *t = fc_calloc(1, sizeof(*t));
975
978
979 return t;
980}
981
982/************************************************************************/
986static const char *dir_get_tileset_name(enum direction8 dir)
987{
988 switch (dir) {
989 case DIR8_NORTH:
990 return "n";
991 case DIR8_NORTHEAST:
992 return "ne";
993 case DIR8_EAST:
994 return "e";
995 case DIR8_SOUTHEAST:
996 return "se";
997 case DIR8_SOUTH:
998 return "s";
999 case DIR8_SOUTHWEST:
1000 return "sw";
1001 case DIR8_WEST:
1002 return "w";
1003 case DIR8_NORTHWEST:
1004 return "nw";
1005 }
1006 log_error("Wrong direction8 variant: %d.", dir);
1007 return "";
1008}
1009
1010/************************************************************************/
1013static enum direction8 dir_by_tileset_name(const char *str)
1014{
1015 enum direction8 dir;
1016
1017 for (dir = direction8_begin();
1018 dir != direction8_end();
1019 dir = direction8_next(dir)) {
1020 if (strcmp(dir_get_tileset_name(dir), str) == 0) {
1021 return dir;
1022 }
1023 }
1024
1025 return direction8_invalid();
1026}
1027
1028/************************************************************************/
1031static bool is_valid_tileset_dir(const struct tileset *t,
1032 enum direction8 dir)
1033{
1034 if (t->hex_width > 0) {
1035 return dir != DIR8_NORTHEAST && dir != DIR8_SOUTHWEST;
1036 } else if (t->hex_height > 0) {
1037 return dir != DIR8_NORTHWEST && dir != DIR8_SOUTHEAST;
1038 } else {
1039 return TRUE;
1040 }
1041}
1042
1043/************************************************************************/
1049static bool is_cardinal_tileset_dir(const struct tileset *t,
1050 enum direction8 dir)
1051{
1052 if (t->hex_width > 0 || t->hex_height > 0) {
1053 return is_valid_tileset_dir(t, dir);
1054 } else {
1055 return (dir == DIR8_NORTH || dir == DIR8_EAST
1056 || dir == DIR8_SOUTH || dir == DIR8_WEST);
1057 }
1058}
1059
1060/************************************************************************/
1065{
1066 int idx;
1067
1068 if ((actual_topology & TF_HEX)
1069 && (actual_topology & TF_ISO)) {
1070 idx = TS_TOPO_ISOHEX;
1071 } else if (actual_topology & TF_ISO) {
1072 idx = TS_TOPO_SQUARE;
1073 } else if (actual_topology & TF_HEX) {
1074 idx = TS_TOPO_HEX;
1075 } else {
1076 idx = TS_TOPO_SQUARE;
1077 }
1078
1079 return idx;
1080}
1081
1082/************************************************************************/
1087{
1088 switch (idx) {
1089 case TS_TOPO_SQUARE:
1090 return TF_ISO;
1091 case TS_TOPO_HEX:
1092 return TF_HEX;
1093 case TS_TOPO_ISOHEX:
1094 return TF_HEX | TF_ISO;
1095 }
1096
1097 return 0;
1098}
1099
1101 struct strvec *list;
1102 int topo;
1103};
1104
1105/************************************************************************/
1108static void ts_list_cb(const char *modpack_name, const char *filename,
1109 void *data)
1110{
1111 struct ts_list_data *tsdata = (struct ts_list_data *)data;
1112 const char *target = modpack_tileset_target(modpack_name);
1113 struct tileset *t = tileset_read_toplevel(target,
1114 FALSE, tsdata->topo, 1.0f);
1115
1116 if (t != nullptr) {
1117 strvec_append(tsdata->list, target);
1118 tileset_free(t);
1119 }
1120}
1121
1122/************************************************************************/
1125const struct strvec *get_tileset_list(const struct option *poption)
1126{
1127 static struct strvec *tilesets[3] = { nullptr, nullptr, nullptr };
1128 int topo = option_get_cb_data(poption);
1129 int idx;
1130
1131 idx = ts_topology_index(topo);
1132
1133 fc_assert_ret_val(idx < ARRAY_SIZE(tilesets), nullptr);
1134
1135 if (tilesets[idx] == nullptr) {
1136 struct ts_list_data data;
1137
1138 /* Note: this means you must restart the client after installing a new
1139 tileset. */
1140 tilesets[idx] = strvec_new();
1141 data.list = tilesets[idx];
1142 data.topo = topo;
1144 }
1145
1146 return tilesets[idx];
1147}
1148
1149/************************************************************************/
1156static char *tilespec_fullname(const char *tileset_name)
1157{
1158 if (tileset_name) {
1160 const char *dname;
1161
1162 fc_snprintf(fname, sizeof(fname),
1163 "%s%s", tileset_name, TILESPEC_SUFFIX);
1164
1166
1167 if (dname) {
1168 return fc_strdup(dname);
1169 }
1170 }
1171
1172 return NULL;
1173}
1174
1175/************************************************************************/
1181 const char *which,
1182 const char *us_capstr,
1183 const char *filename,
1184 bool verbose)
1185{
1186 enum log_level level = verbose ? LOG_ERROR : LOG_DEBUG;
1187
1188 const char *file_capstr = secfile_lookup_str(file, "%s.options", which);
1189
1190 if (NULL == file_capstr) {
1191 log_base(level, "\"%s\": %s file doesn't have a capability string",
1192 filename, which);
1193 return FALSE;
1194 }
1196 log_base(level, "\"%s\": %s file appears incompatible:",
1197 filename, which);
1198 log_base(level, " datafile options: %s", file_capstr);
1199 log_base(level, " supported options: %s", us_capstr);
1200 return FALSE;
1201 }
1203 log_base(level, "\"%s\": %s file requires option(s) "
1204 "that client doesn't support:", filename, which);
1205 log_base(level, " datafile options: %s", file_capstr);
1206 log_base(level, " supported options: %s", us_capstr);
1207 return FALSE;
1208 }
1209
1210 return TRUE;
1211}
1212
1213/************************************************************************/
1218static void tileset_free_toplevel(struct tileset *t)
1219{
1220 int i, j;
1221
1222 if (t->main_intro_filename) {
1225 }
1226
1227 if (t->preferred_themes) {
1228 for (i = 0; i < t->num_preferred_themes; i++) {
1229 free(t->preferred_themes[i]);
1230 }
1233 }
1234 t->num_preferred_themes = 0;
1235
1236 if (t->tile_hash) {
1238 t->tile_hash = NULL; /* Helpful for sanity. */
1239 }
1240 if (t->estyle_hash) {
1242 t->estyle_hash = NULL;
1243 }
1244 for (i = 0; i < ESTYLE_COUNT; i++) {
1245 if (t->style_lists[i] != NULL) {
1247 t->style_lists[i] = NULL;
1248 }
1249 }
1250
1251 if (t->flagged_bases_list != NULL) {
1254 }
1255
1256 for (i = 0; i < MAX_NUM_LAYERS; i++) {
1257 struct tileset_layer *tslp = &t->layers[i];
1258
1259 if (tslp->match_types) {
1260 for (j = 0; j < tslp->match_count; j++) {
1261 free(tslp->match_types[j]);
1262 }
1263 free(tslp->match_types);
1264 tslp->match_types = NULL;
1265 }
1266 }
1267
1268 if (t->color_system) {
1270 t->color_system = NULL;
1271 }
1272
1273 if (t->summary != NULL) {
1274 free(t->summary);
1275 t->summary = NULL;
1276 }
1277 if (t->description != NULL) {
1278 free(t->description);
1279 t->description = NULL;
1280 }
1281 if (t->for_ruleset != NULL) {
1282 free(t->for_ruleset);
1283 t->for_ruleset = NULL;
1284 }
1285}
1286
1287/************************************************************************/
1290void tileset_free(struct tileset *t)
1291{
1292 int i;
1293
1296 for (i = 0; i < ARRAY_SIZE(t->sprites.player); i++) {
1298 }
1301 free(t);
1302}
1303
1304/************************************************************************/
1307static void ts_cb(const char *modpack_name, const char *filename, void *data)
1308{
1309 int topo_id = *((int *)data);
1310 struct tileset *t = tileset_read_toplevel(modpack_tileset_target(modpack_name),
1311 FALSE, topo_id, 1.0f);
1312
1313 if (t != nullptr) {
1314 if (tileset == nullptr) {
1315 tileset = t;
1316 } else if (t->priority > tileset->priority
1317 || (topo_id >= 0
1320 tileset = t;
1321 } else {
1322 tileset_free(t);
1323 }
1324 }
1325}
1326
1327/************************************************************************/
1335bool tilespec_try_read(const char *tileset_name, bool verbose, int topo_id,
1336 bool global_default)
1337{
1338 bool original;
1339
1340 if (tileset_name == nullptr
1342 topo_id, 1.0f))) {
1343 original = FALSE;
1345
1346 if (tileset == nullptr) {
1347 tileset_error(LOG_FATAL, nullptr, _("No usable default tileset found, aborting!"));
1348 }
1349
1350 log_verbose("Trying tileset \"%s\".", tileset->name);
1351 } else {
1352 original = TRUE;
1353 }
1355
1356 if (global_default) {
1358 }
1359
1360 return original;
1361}
1362
1363/************************************************************************/
1377 bool game_fully_initialized, float scale)
1378{
1379 int id;
1380 struct tile *center_tile;
1381 enum client_states state = client_state();
1383 char tileset_name[strlen(name) + 1], old_name[strlen(tileset->name) + 1];
1384 bool new_tileset_in_use;
1385 int ts_topo;
1386
1387 /* Make local copies since these values may be freed down below */
1389 sz_strlcpy(old_name, tileset->name);
1390
1391 log_normal(_("Loading tileset \"%s\"."), tileset_name);
1392
1393 /* Step 0: Record old data.
1394 *
1395 * We record the current mapcanvas center, etc.
1396 */
1398
1399 /* Step 1: Cleanup.
1400 *
1401 * Free old tileset or keep it in memory if we are loading the same
1402 * tileset with scaling and old one was not scaled.
1403 */
1404
1405 if (strcmp(tileset_name, old_name) == 0 && tileset->scale == 1.0f
1406 && scale != 1.0f) {
1407 if (unscaled_tileset) {
1409 }
1411 } else {
1413 }
1414
1415 /* Step 2: Read.
1416 *
1417 * We read in the new tileset. This should be pretty straightforward.
1418 */
1420 if (tileset != NULL) {
1422 } else {
1424
1425 if (!(tileset = tileset_read_toplevel(old_name, FALSE, -1, scale))) {
1426 log_fatal("Failed to re-read the currently loaded tileset.");
1428 }
1429 }
1433 }
1434
1438 } /* else we'll get round to it on PACKET_RULESET_GAME */
1439 players_iterate(pplayer) {
1440 tileset_player_init(tileset, pplayer);
1442 boot_help_texts(); /* "About Current Tileset" */
1443 }
1444
1445 /* Step 3: Setup
1446 *
1447 * This is a seriously sticky problem. On startup, we build a hash
1448 * from all the sprite data. Then, when we connect to a server, the
1449 * server sends us ruleset data a piece at a time and we use this data
1450 * to assemble the sprite structures. But if we change while connected
1451 * we have to reassemble all of these. This should just involve
1452 * calling tilespec_setup_*** on everything. But how do we tell what
1453 * "everything" is?
1454 *
1455 * The below code just does things straightforwardly, by setting up
1456 * each possible sprite again. Hopefully it catches everything, and
1457 * doesn't mess up too badly if we change tilesets while not connected
1458 * to a server.
1459 */
1460 if (!game.client.ruleset_ready) {
1461 /* The ruleset data is not sent until this point. */
1462 return new_tileset_in_use;
1463 }
1464
1466 == TOPO_INCOMP_HARD) {
1468 _("Map topology (%s) and tileset (%s) incompatible."),
1470 }
1471
1472 terrain_type_iterate(pterrain) {
1478 governments_iterate(gov) {
1481 extra_type_iterate(pextra) {
1484 nations_iterate(pnation) {
1487 improvement_iterate(pimprove) {
1496
1499 * sizeof(tileset->sprites.style_citizen_sets.sets[0]));
1500
1501 for (id = 0; id < game.control.num_city_styles; id++) {
1503 }
1504
1505 if (state < C_S_RUNNING) {
1506 /* Below redraws do not apply before this. */
1507 return new_tileset_in_use;
1508 }
1509
1510 /* Step 4: Draw.
1511 *
1512 * Do any necessary redraws.
1513 */
1516 can_slide = FALSE;
1518 /* update_map_canvas_visible forces a full redraw. Otherwise with fast
1519 * drawing we might not get one. Of course this is slower. */
1521 can_slide = TRUE;
1522
1523 return new_tileset_in_use;
1524}
1525
1526/************************************************************************/
1531{
1532 const char *tileset_name;
1533 enum client_states state = client_state();
1534
1535 if (state == C_S_RUNNING || state == C_S_OVER) {
1537
1538 /* Also iso map topology counts as 'square' tileset topology */
1539 if (opt != (wld.map.topology_id & (TF_ISO | TF_HEX))
1540 && (opt != 0 || ((wld.map.topology_id & TF_HEX) == TF_HEX))) {
1541 /* Changed option was not for current topology */
1542 return;
1543 }
1544 }
1545
1547
1548 fc_assert_ret(NULL != tileset_name && tileset_name[0] != '\0');
1551
1552 /* As it's going to be 'current' tileset, make it global default if
1553 * options saved. */
1555
1557 menus_init();
1558}
1559
1560/************************************************************************/
1567{
1569 tilespec_reread(tname, TRUE, 1.0f);
1571 menus_init();
1572}
1573
1574/************************************************************************/
1578static struct sprite *load_gfx_file(const char *gfx_filename, bool svgflag)
1579{
1580 const char **gfx_fileexts, *gfx_fileext;
1581 struct sprite *s;
1582
1583 if (svgflag) {
1585 } else {
1587 }
1588
1589 /* Try out all supported file extensions to find one that works. */
1590 while ((gfx_fileext = *gfx_fileexts++)) {
1591 const char *real_full_name;
1592 char full_name[strlen(gfx_filename) + strlen(".")
1593 + strlen(gfx_fileext) + 1];
1594
1597 log_debug("trying to load gfx file \"%s\".", real_full_name);
1599 svgflag && !strcmp("svg", gfx_fileext));
1600 if (s) {
1601 return s;
1602 }
1603 }
1604 }
1605
1606 log_error("Could not load gfx file \"%s\".", gfx_filename);
1607
1608 return NULL;
1609}
1610
1611/************************************************************************/
1614static void ensure_big_sprite(struct specfile *sf, const char *tset_name)
1615{
1616 struct section_file *file;
1617 const char *gfx_filename;
1618
1619 if (sf->big_sprite) {
1620 /* Looks like it's already loaded. */
1621 return;
1622 }
1623
1624 /* Otherwise load it. The big sprite will sometimes be freed and will have
1625 * to be reloaded, but most of the time it's just loaded once, the small
1626 * sprites are extracted, and then it's freed. */
1627 if (!(file = secfile_load(sf->file_name, TRUE))) {
1629 _("Could not open '%s':\n%s"), sf->file_name, secfile_error());
1630 }
1631
1632 if (!check_tilespec_capabilities(file, "spec",
1633 SPEC_CAPSTR, sf->file_name, TRUE)) {
1635 _("Specfile %s has incompatible capabilities"), sf->file_name);
1636 }
1637
1638 gfx_filename = secfile_lookup_str(file, "file.gfx");
1639
1641
1642 if (!sf->big_sprite) {
1644 _("Could not load gfx file for the spec file \"%s\"."),
1645 sf->file_name);
1646 }
1647 secfile_destroy(file);
1648}
1649
1650/************************************************************************/
1655static void scan_specfile(struct tileset *t, struct specfile *sf,
1656 bool duplicates_ok)
1657{
1658 struct section_file *file;
1659 struct section_list *sections;
1660 int i;
1661
1662 if (!(file = secfile_load(sf->file_name, TRUE))) {
1664 _("Could not open '%s':\n%s"), sf->file_name, secfile_error());
1665 }
1666 if (!check_tilespec_capabilities(file, "spec",
1667 SPEC_CAPSTR, sf->file_name, TRUE)) {
1669 _("Specfile %s has incompatible capabilities"), sf->file_name);
1670 }
1671
1672 /* Currently unused */
1673 secfile_entry_ignore(file, "info.artists");
1674
1675 /* Not used here */
1676 secfile_entry_ignore(file, "file.gfx");
1677
1678 if ((sections = secfile_sections_by_name_prefix(file, "grid_"))) {
1679 section_list_iterate(sections, psection) {
1680 int j, k;
1681 int x_top_left, y_top_left, dx, dy;
1682 int pixel_border_x;
1683 int pixel_border_y;
1684 const char *sec_name = section_name(psection);
1685
1686 pixel_border_x = secfile_lookup_int_default(file, 0, "%s.pixel_border",
1687 sec_name);
1688 pixel_border_y = secfile_lookup_int_default(file, pixel_border_x, "%s.pixel_border_y",
1689 sec_name);
1690 pixel_border_x = secfile_lookup_int_default(file, pixel_border_x, "%s.pixel_border_x",
1691 sec_name);
1692 if (!secfile_lookup_int(file, &x_top_left, "%s.x_top_left", sec_name)
1693 || !secfile_lookup_int(file, &y_top_left,
1694 "%s.y_top_left", sec_name)
1695 || !secfile_lookup_int(file, &dx, "%s.dx", sec_name)
1696 || !secfile_lookup_int(file, &dy, "%s.dy", sec_name)) {
1697 log_error("%s grid \"%s\" invalid: %s",
1699 continue;
1700 }
1701
1702 j = -1;
1703 while (NULL != secfile_entry_lookup(file, "%s.tiles%d.tag",
1704 sec_name, ++j)) {
1705 struct small_sprite *ss;
1706 int row, column;
1707 int xr, yb;
1708 const char **tags;
1709 size_t num_tags;
1710 int hot_x, hot_y;
1711
1712 if (!secfile_lookup_int(file, &row, "%s.tiles%d.row", sec_name, j)
1713 || !secfile_lookup_int(file, &column, "%s.tiles%d.column",
1714 sec_name, j)
1715 || !(tags = secfile_lookup_str_vec(file, &num_tags,
1716 "%s.tiles%d.tag",
1717 sec_name, j))) {
1718 log_error("%s small sprite \"%s.tiles%d\" invalid: %s",
1720 continue;
1721 }
1722 hot_x = secfile_lookup_int_default(file, 0, "%s.tiles%d.hot_x",
1723 sec_name, j);
1724 hot_y = secfile_lookup_int_default(file, 0, "%s.tiles%d.hot_y",
1725 sec_name, j);
1726
1727 /* There must be at least 1 because of the while(): */
1728 fc_assert_action(num_tags > 0, continue);
1729
1730 xr = x_top_left + (dx + pixel_border_x) * column;
1731 yb = y_top_left + (dy + pixel_border_y) * row;
1732
1733 ss = fc_malloc(sizeof(*ss));
1734 ss->ref_count = 0;
1735 ss->file = NULL;
1736 ss->x = xr;
1737 ss->y = yb;
1738 ss->width = dx;
1739 ss->height = dy;
1740 ss->sf = sf;
1741 ss->sprite = NULL;
1742 ss->hot_x = hot_x;
1743 ss->hot_y = hot_y;
1744
1746
1747 if (!duplicates_ok) {
1748 for (k = 0; k < num_tags; k++) {
1749 if (!sprite_hash_insert(t->sprite_hash, tags[k], ss)) {
1750 log_error("warning: %s already has a sprite for \"%s\".",
1751 tileset_name_get(t), tags[k]);
1752 }
1753 }
1754 } else {
1755 for (k = 0; k < num_tags; k++) {
1756 (void) sprite_hash_replace(t->sprite_hash, tags[k], ss);
1757 }
1758 }
1759
1760 free(tags);
1761 tags = NULL;
1762 }
1764 section_list_destroy(sections);
1765 }
1766
1767 /* Load "extra" sprites. Each sprite is one file. */
1768 i = -1;
1769 while (NULL != secfile_entry_lookup(file, "extra.sprites%d.tag", ++i)) {
1770 struct small_sprite *ss;
1771 const char **tags;
1772 const char *filename;
1773 size_t num_tags, k;
1774 int hot_x, hot_y;
1775
1776 if (!(tags = secfile_lookup_str_vec(file, &num_tags,
1777 "extra.sprites%d.tag", i))
1778 || !(filename = secfile_lookup_str(file,
1779 "extra.sprites%d.file", i))) {
1780 log_error("%s extra sprite \"extra.sprites%d\" invalid: %s",
1782 continue;
1783 }
1784 hot_x = secfile_lookup_int_default(file, 0, "extra.sprites%d.hot_x", i);
1785 hot_y = secfile_lookup_int_default(file, 0, "extra.sprites%d.hot_y", i);
1786
1787 ss = fc_malloc(sizeof(*ss));
1788 ss->ref_count = 0;
1789 ss->file = fc_strdup(filename);
1790 ss->sf = NULL;
1791 ss->sprite = NULL;
1792 ss->hot_x = hot_x;
1793 ss->hot_y = hot_y;
1794
1796
1797 if (!duplicates_ok) {
1798 for (k = 0; k < num_tags; k++) {
1799 if (!sprite_hash_insert(t->sprite_hash, tags[k], ss)) {
1800 log_error("warning: %s already have a sprite for \"%s\".",
1801 tileset_name_get(t), tags[k]);
1802 }
1803 }
1804 } else {
1805 for (k = 0; k < num_tags; k++) {
1806 (void) sprite_hash_replace(t->sprite_hash, tags[k], ss);
1807 }
1808 }
1809 free(tags);
1810 }
1811
1814}
1815
1816/************************************************************************/
1820static char *tilespec_gfx_filename(const char *gfx_filename,
1821 const char *tset_name)
1822{
1823 const char *gfx_current_fileext;
1824 const char **gfx_fileexts = gfx_fileextensions();
1825
1826 while ((gfx_current_fileext = *gfx_fileexts++)) {
1827 const char *real_full_name;
1828 char *full_name =
1831
1833
1835 free(full_name);
1836 if (real_full_name) {
1837 return fc_strdup(real_full_name);
1838 }
1839 }
1840
1842 _("Couldn't find a supported gfx file extension for \"%s\"."),
1843 gfx_filename);
1844
1845 return NULL;
1846}
1847
1848/************************************************************************/
1851static bool tileset_scan_single_list(struct tileset *t,
1852 const char *spec_filenames[],
1853 int num_spec_files, bool verbose,
1854 bool duplicates_ok)
1855{
1856 int i;
1857
1858 for (i = 0; i < num_spec_files; i++) {
1859 struct specfile *sf = fc_malloc(sizeof(*sf));
1860 const char *dname;
1861
1862 log_debug("spec file %s", spec_filenames[i]);
1863
1864 sf->big_sprite = NULL;
1866 if (!dname) {
1867 if (verbose) {
1868 log_error("Can't find spec file \"%s\".", spec_filenames[i]);
1869 }
1870
1871 return FALSE;
1872 }
1873 sf->file_name = fc_strdup(dname);
1875
1877 }
1878
1879 return TRUE;
1880}
1881
1882/************************************************************************/
1885static int check_sprite_type(const char *sprite_type, const char *tile_section)
1886{
1887 if (fc_strcasecmp(sprite_type, "corner") == 0) {
1888 return CELL_CORNER;
1889 }
1890 if (fc_strcasecmp(sprite_type, "single") == 0) {
1891 return CELL_WHOLE;
1892 }
1893 if (fc_strcasecmp(sprite_type, "whole") == 0) {
1894 return CELL_WHOLE;
1895 }
1896 log_error("[%s] unknown sprite_type \"%s\".", tile_section, sprite_type);
1897 return CELL_WHOLE;
1898}
1899
1900/************************************************************************/
1906static struct tileset *tileset_read_toplevel(const char *tileset_name,
1907 bool verbose, int topology_id,
1908 float scale)
1909{
1910 struct section_file *file;
1911 char *fname;
1912 const char *c;
1913 int i;
1914 size_t num_spec_files[SFILE_LAST];
1915 const char **spec_filenames[SFILE_LAST];
1916 size_t num_layers;
1917 const char **layer_order;
1918 size_t num_preferred_themes;
1919 struct section_list *sections = NULL;
1920 const char *file_capstr;
1921 bool duplicates_ok, is_hex;
1922 enum direction8 dir;
1923 struct tileset *t = NULL;
1924 const char *extraname;
1925 const char *tstr;
1926 int topo;
1927 bool svg;
1929 const char *type_name;
1930
1932
1933 if (fname == NULL) {
1934 if (verbose) {
1935 log_error("Can't find tileset \"%s\".", tileset_name);
1936 }
1937
1938 return NULL;
1939 }
1940 log_verbose("tilespec file is \"%s\".", fname);
1941
1942 if (!(file = secfile_load(fname, TRUE))) {
1943 log_error("Could not open '%s':\n%s", fname, secfile_error());
1944 free(fname);
1945 return NULL;
1946 }
1947
1948 if (!check_tilespec_capabilities(file, "tilespec",
1949 TILESPEC_CAPSTR, fname, verbose)) {
1950 secfile_destroy(file);
1951 free(fname);
1952 return NULL;
1953 }
1954
1955 t = tileset_new();
1956 t->scale = scale;
1957 file_capstr = secfile_lookup_str(file, "%s.options", "tilespec");
1959 && has_capabilities("+duplicates_ok", file_capstr));
1960
1961 tstr = secfile_lookup_str(file, "tilespec.name");
1962 /* Tileset name found */
1964 tstr = secfile_lookup_str_default(file, "", "tilespec.version");
1965 if (tstr[0] != '\0') {
1966 /* Tileset version found */
1967 sz_strlcpy(t->version, tstr);
1968 } else {
1969 /* No version information */
1970 t->version[0] = '\0';
1971 }
1972
1973 tstr = secfile_lookup_str_default(file, "", "tilespec.summary");
1974 if (tstr[0] != '\0') {
1975 int len;
1976
1977 /* Tileset summary found */
1978 len = strlen(tstr);
1979 t->summary = fc_malloc(len + 1);
1980 fc_strlcpy(t->summary, tstr, len + 1);
1981 } else {
1982 /* No summary */
1983 if (t->summary != NULL) {
1984 free(t->summary);
1985 t->summary = NULL;
1986 }
1987 }
1988
1989 tstr = secfile_lookup_str_default(file, "", "tilespec.description");
1990 if (tstr[0] != '\0') {
1991 int len;
1992
1993 /* Tileset description found */
1994 len = strlen(tstr);
1995 t->description = fc_malloc(len + 1);
1996 fc_strlcpy(t->description, tstr, len + 1);
1997 } else {
1998 /* No description */
1999 if (t->description != NULL) {
2000 free(t->description);
2001 t->description = NULL;
2002 }
2003 }
2004
2005 tstr = secfile_lookup_str_default(file, NULL, "tilespec.for_ruleset");
2006 if (tstr != NULL) {
2008 } else {
2009 t->for_ruleset = NULL;
2010 }
2011
2013 if (!secfile_lookup_int(file, &t->priority, "tilespec.priority")
2014 || !secfile_lookup_bool(file, &is_hex, "tilespec.is_hex")) {
2015 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2016 goto ON_ERROR;
2017 }
2018
2019 tstr = secfile_lookup_str(file, "tilespec.type");
2020 if (tstr == NULL) {
2021 log_error("Tileset \"%s\": no tileset type", t->name);
2022 goto ON_ERROR;
2023 }
2024
2026 if (!ts_type_is_valid(t->type)) {
2027 log_error("Tileset \"%s\": unknown tileset type \"%s\"", t->name, tstr);
2028 goto ON_ERROR;
2029 }
2030
2031 if (t->type == TS_ISOMETRIC) {
2032 topo = TF_ISO;
2033 } else {
2034 topo = 0;
2035 }
2036
2037 /* Read hex-tileset information. */
2038 t->hex_width = t->hex_height = 0;
2039 if (is_hex) {
2040 int hex_side;
2041
2042 if (!secfile_lookup_int(file, &hex_side, "tilespec.hex_side")) {
2043 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2044 goto ON_ERROR;
2045 }
2046 hex_side = hex_side * t->scale;
2047 if (t->type == TS_ISOMETRIC) {
2048 t->hex_width = hex_side;
2049 } else {
2050 t->hex_height = hex_side;
2051 }
2052
2053 topo |= TF_HEX;
2054
2055 /* Hex tilesets are drawn the same as isometric. */
2056 /* FIXME: There will be other legal values to be used with hex
2057 * tileset in the future, and this would just overwrite it. */
2058 t->type = TS_ISOMETRIC;
2059 }
2060
2061 if (topology_id >= 0) {
2062 if (((topology_id & TF_HEX) && topology_id != (topo & (TF_ISO | TF_HEX)))
2063 || (!(topology_id & TF_HEX) && (topo & TF_HEX))) {
2064 /* Not of requested topology */
2065 goto ON_ERROR;
2066 }
2067 }
2068
2069 t->ts_topo_idx = ts_topology_index(topo);
2070
2071 if (!is_view_supported(t->type)) {
2072 /* TRANS: "Overhead" or "Isometric" */
2073 log_normal(_("Client does not support %s tilesets."),
2074 _(ts_type_name(t->type)));
2075 log_normal(_("Using default tileset instead."));
2077 goto ON_ERROR;
2078 }
2079
2081
2082 /* Create arrays of valid and cardinal tileset dirs. These depend
2083 * entirely on the tileset, not the topology. They are also in clockwise
2084 * rotational ordering. */
2086 dir = DIR8_NORTH;
2087 do {
2088 if (is_valid_tileset_dir(t, dir)) {
2091 }
2092 if (is_cardinal_tileset_dir(t, dir)) {
2095 }
2096
2097 dir = dir_cw(dir);
2098 } while (dir != DIR8_NORTH);
2099
2100 fc_assert(t->num_valid_tileset_dirs % 2 == 0); /* Assumed elsewhere. */
2103
2105 "tilespec.normal_tile_width")
2107 "tilespec.normal_tile_height")) {
2108 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2109 goto ON_ERROR;
2110 }
2112 /* Adjust width to be multiple of 8 */
2113 if (scale != 1.0f) {
2114 i = t->normal_tile_width;
2115 while (i % 8 != 0) {
2116 i++;
2117 }
2118 t->scale = (t->scale * i) / t->normal_tile_width;
2119 t->normal_tile_width = i;
2120 }
2122 if (t->type == TS_ISOMETRIC) {
2124 if (tileset_hex_height(t) > 0) {
2126 } else {
2127 t->full_tile_height = 3 * t->normal_tile_height / 2;
2128 }
2129 } else {
2132 }
2134 = secfile_lookup_int_default(file, t->full_tile_width, "tilespec.unit_width");
2136 = secfile_lookup_int_default(file, t->full_tile_height, "tilespec.unit_height");
2138 "tilespec.small_tile_width")
2140 "tilespec.small_tile_height")) {
2141 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2142 goto ON_ERROR;
2143 }
2144 if (t->unit_tile_width != t->full_tile_width && t->scale != 1.0f) {
2146 }
2147 if (t->unit_tile_height != t->full_tile_height && t->scale != 1.0f) {
2149 }
2152 log_verbose("tile sizes %dx%d, %d%d unit, %d%d small",
2156
2157 tstr = secfile_lookup_str(file, "tilespec.fog_style");
2158 if (tstr == NULL) {
2159 log_error("Tileset \"%s\": no fog_style", t->name);
2160 goto ON_ERROR;
2161 }
2162
2164 if (!fog_style_is_valid(t->fogstyle)) {
2165 log_error("Tileset \"%s\": unknown fog_style \"%s\"", t->name, tstr);
2166 goto ON_ERROR;
2167 }
2168
2169 tstr = secfile_lookup_str(file, "tilespec.darkness_style");
2170 if (tstr == NULL) {
2171 log_error("Tileset \"%s\": no darkness_style", t->name);
2172 goto ON_ERROR;
2173 }
2174
2177 log_error("Tileset \"%s\": unknown darkness_style \"%s\"", t->name, tstr);
2178 goto ON_ERROR;
2179 }
2180
2182 && (t->type == TS_OVERHEAD || t->hex_width > 0 || t->hex_height > 0)) {
2183 log_error("Invalid darkness style set in tileset \"%s\".", t->name);
2184 goto ON_ERROR;
2185 }
2186
2188 "tilespec.unit_flag_offset_x")
2190 "tilespec.unit_flag_offset_y")
2192 "tilespec.city_flag_offset_x")
2194 "tilespec.city_flag_offset_y")
2195 || !secfile_lookup_int(file, &t->unit_offset_x,
2196 "tilespec.unit_offset_x")
2197 || !secfile_lookup_int(file, &t->unit_offset_y,
2198 "tilespec.unit_offset_y")
2200 "tilespec.activity_offset_x")
2202 "tilespec.activity_offset_y")
2203 || !secfile_lookup_int(file, &t->select_offset_x,
2204 "tilespec.select_offset_x")
2205 || !secfile_lookup_int(file, &t->select_offset_y,
2206 "tilespec.select_offset_y")
2208 "tilespec.stack_size_offset_x")
2210 "tilespec.stack_size_offset_y")
2211 || !secfile_lookup_int(file, &t->city_offset_x,
2212 "tilespec.city_offset_x")
2213 || !secfile_lookup_int(file, &t->city_offset_y,
2214 "tilespec.city_offset_y")
2216 "tilespec.city_size_offset_x")
2218 "tilespec.city_size_offset_y")
2220 "tilespec.citybar_offset_y")
2222 "tilespec.tilelabel_offset_y")
2224 "tilespec.occupied_offset_x")
2226 "tilespec.occupied_offset_y")) {
2227 log_error("Tileset \"%s\" invalid: %s", t->name, secfile_error());
2228 goto ON_ERROR;
2229 }
2230
2232 "tilespec.unit_upkeep_offset_y");
2234 "tilespec.unit_upkeep_small_offset_y");
2235 t->svg_height = secfile_lookup_int_default(file, 44, "tilespec.svg_height");
2236
2247 t->unit_offset_x = t->scale * t->unit_offset_x;
2248 t->unit_offset_y = t->scale * t->unit_offset_y;
2251 t->city_offset_x = t->scale * t->city_offset_x;
2252 t->city_offset_y = t->scale * t->city_offset_y;
2257 t->svg_height *= t->scale;
2258
2259 if (t->scale != 1.0f
2262 }
2263 if (t->scale != 1.0f
2266 }
2267
2269 "tilespec.unit_default_orientation");
2270 if (!c) {
2271 /* This is valid, but tileset must specify icon for every unit */
2273 } else {
2274 dir = dir_by_tileset_name(c);
2275
2276 if (!direction8_is_valid(dir)) {
2278 _("Unknown unit_default_orientation \"%s\""), c);
2279 goto ON_ERROR;
2280 } else {
2281 /* Default orientation is allowed to not be a valid one for the
2282 * tileset */
2283 t->unit_default_orientation = dir;
2284 }
2285 }
2286
2287 c = secfile_lookup_str(file, "tilespec.main_intro_file");
2289 log_debug("intro file %s", t->main_intro_filename);
2290
2291 /* Layer order */
2292 num_layers = 0;
2293 layer_order = secfile_lookup_str_vec(file, &num_layers,
2294 "tilespec.layer_order");
2295 if (layer_order != NULL) {
2296 for (i = 0; i < num_layers; i++) {
2297 int j;
2300
2301 /* Check for wrong layer names. */
2302 if (!mapview_layer_is_valid(layer)) {
2303 log_error("layer_order: Invalid layer \"%s\" in %s",
2305 goto ON_ERROR;
2306 }
2307 /* Check for duplicates. */
2308 for (j = 0; j < i; j++) {
2309 if (t->layer_order[j] == layer) {
2310 log_error("layer_order: Duplicate layer \"%s\" in %s",
2312 goto ON_ERROR;
2313 }
2314 }
2315 t->layer_order[i] = layer;
2316 }
2317
2318 /* Now check that all layers are present. Doing it now allows for a more
2319 * comprehensive error message. */
2320 for (i = 0; i < LAYER_COUNT; i++) {
2321 int j;
2322 bool found = FALSE;
2323
2324 for (j = 0; j < num_layers; j++) {
2325 if (i == t->layer_order[j]) {
2326 found = TRUE;
2327 break;
2328 }
2329 }
2330 if (!found) {
2331 log_error("layer_order: Missing layer \"%s\" in %s",
2333 goto ON_ERROR;
2334 }
2335 }
2336
2338 } else {
2339 /* There is no layer_order tag in the specfile -> use the default */
2340 for (i = 0; i < LAYER_COUNT; i++) {
2341 t->layer_order[i] = i;
2342 }
2343 }
2344
2345 /* Terrain layer info. */
2346 for (i = 0; i < MAX_NUM_LAYERS; i++) {
2347 struct tileset_layer *tslp = &t->layers[i];
2348 int j, k;
2349
2350 tslp->match_types =
2351 (char **) secfile_lookup_str_vec(file, &tslp->match_count,
2352 "layer%d.match_types", i);
2353 for (j = 0; j < tslp->match_count; j++) {
2354 tslp->match_types[j] = fc_strdup(tslp->match_types[j]);
2355
2356 for (k = 0; k < j; k++) {
2357 if (tslp->match_types[k][0] == tslp->match_types[j][0]) {
2359 _("[layer%d] match_types: \"%s\" initial "
2360 "('%c') is not unique."),
2361 i, tslp->match_types[j], tslp->match_types[j][0]);
2362 /* FIXME: Returns NULL. */
2363 }
2364 }
2365 }
2366 }
2367
2368 /* Tile drawing info. */
2370 if (NULL == sections || 0 == section_list_size(sections)) {
2372 _("No [%s] sections present."),
2374 goto ON_ERROR;
2375 }
2376
2377 fc_assert(t->tile_hash == NULL);
2379
2380 section_list_iterate(sections, psection) {
2381 const char *sec_name = section_name(psection);
2383 const char *sprite_type;
2384 int l;
2385 const char *terrain_name;
2386
2387 terrain_name = secfile_lookup_str(file, "%s.tag", sec_name);
2388
2389 if (terrain_name != NULL) {
2390 draw->name = fc_strdup(terrain_name);
2391 } else {
2392 tileset_error(LOG_ERROR, _("No terrain tag given in section [%s] in %s."),
2395 goto ON_ERROR;
2396 }
2397
2398 draw->blending = secfile_lookup_int_default(file, 0, "%s.blend_layer",
2399 sec_name);
2400 draw->blending = CLIP(0, draw->blending, MAX_NUM_LAYERS);
2401
2402 draw->is_reversed = secfile_lookup_bool_default(file, FALSE,
2403 "%s.is_reversed",
2404 sec_name);
2405 draw->num_layers = secfile_lookup_int_default(file, 0, "%s.num_layers",
2406 sec_name);
2407 draw->num_layers = CLIP(1, draw->num_layers, MAX_NUM_LAYERS);
2408
2409 for (l = 0; l < draw->num_layers; l++) {
2410 struct drawing_layer *dlp = &draw->layer[l];
2411 struct tileset_layer *tslp = &t->layers[l];
2412 const char *match_type;
2413 const char **match_with;
2414 size_t count;
2415
2416 dlp->is_tall
2417 = secfile_lookup_bool_default(file, FALSE, "%s.layer%d_is_tall",
2418 sec_name, l);
2419 dlp->offset_x
2420 = secfile_lookup_int_default(file, 0, "%s.layer%d_offset_x",
2421 sec_name, l);
2422 dlp->offset_y
2423 = secfile_lookup_int_default(file, 0, "%s.layer%d_offset_y",
2424 sec_name, l);
2425 dlp->offset_x = ceil(t->scale * dlp->offset_x);
2426 dlp->offset_y = ceil(t->scale * dlp->offset_y);
2427
2429 "%s.layer%d_match_type",
2430 sec_name, l);
2431 if (match_type) {
2432 int j;
2433
2434 /* Determine our match_type. */
2435 for (j = 0; j < tslp->match_count; j++) {
2436 if (fc_strcasecmp(tslp->match_types[j], match_type) == 0) {
2437 break;
2438 }
2439 }
2440 if (j >= tslp->match_count) {
2441 log_error("[%s] invalid match_type \"%s\" in %s.",
2443 } else {
2444 dlp->match_index[dlp->match_indices++] = j;
2445 }
2446 }
2447
2448 match_with = secfile_lookup_str_vec(file, &count,
2449 "%s.layer%d_match_with",
2450 sec_name, l);
2451 if (match_with) {
2452 int j, k;
2453
2454 if (count > MAX_NUM_MATCH_WITH) {
2455 log_error("[%s] match_with has too many types (%d, max %d) in %s",
2456 sec_name, (int) count, MAX_NUM_MATCH_WITH,
2457 tileset_name_get(t));
2458 count = MAX_NUM_MATCH_WITH;
2459 }
2460
2461 if (1 < dlp->match_indices) {
2462 log_error("[%s] previous match_with ignored in %s.",
2464 dlp->match_indices = 1;
2465 } else if (1 > dlp->match_indices) {
2466 log_error("[%s] missing match_type, using \"%s\" in %s.",
2467 sec_name, tslp->match_types[0], tileset_name_get(t));
2468 dlp->match_index[0] = 0;
2469 dlp->match_indices = 1;
2470 }
2471
2472 for (k = 0; k < count; k++) {
2473 for (j = 0; j < tslp->match_count; j++) {
2474 if (fc_strcasecmp(tslp->match_types[j], match_with[k]) == 0) {
2475 break;
2476 }
2477 }
2478 if (j >= tslp->match_count) {
2479 log_error("[%s] layer%d_match_with: invalid \"%s\".",
2480 sec_name, l, match_with[k]);
2481 } else if (1 < count) {
2482 int m;
2483
2484 for (m = 0; m < dlp->match_indices; m++) {
2485 if (dlp->match_index[m] == j) {
2486 log_error("[%s] layer%d_match_with: duplicate \"%s\" in %s.",
2488 break;
2489 }
2490 }
2491 if (m >= dlp->match_indices) {
2492 dlp->match_index[dlp->match_indices++] = j;
2493 }
2494 } else {
2495 dlp->match_index[dlp->match_indices++] = j;
2496 }
2497 }
2499 match_with = NULL;
2500 }
2501
2502 /* Check match_indices */
2503 switch (dlp->match_indices) {
2504 case 0:
2505 case 1:
2506 dlp->match_style = MATCH_NONE;
2507 break;
2508 case 2:
2509 if (dlp->match_index[0] == dlp->match_index[1] ) {
2510 dlp->match_style = MATCH_SAME;
2511 } else {
2512 dlp->match_style = MATCH_PAIR;
2513 }
2514 break;
2515 default:
2516 dlp->match_style = MATCH_FULL;
2517 break;
2518 };
2519
2521 = secfile_lookup_str_default(file, "whole", "%s.layer%d_sprite_type",
2522 sec_name, l);
2523 dlp->sprite_type = check_sprite_type(sprite_type, sec_name);
2524
2525 switch (dlp->sprite_type) {
2526 case CELL_WHOLE:
2527 /* OK, no problem */
2528 break;
2529 case CELL_CORNER:
2530 if (dlp->is_tall
2531 || dlp->offset_x > 0
2532 || dlp->offset_y > 0) {
2533 log_error("[%s] layer %d: you cannot have tall terrain or\n"
2534 "a sprite offset with a cell-based drawing method in %s.",
2536 dlp->is_tall = FALSE;
2537 dlp->offset_x = dlp->offset_y = 0;
2538 }
2539 break;
2540 };
2541 }
2542
2543 if (!drawing_hash_insert(t->tile_hash, draw->name, draw)) {
2544 log_error("warning: multiple tile sections containing terrain tag \"%s\" in %s.",
2545 draw->name, tileset_name_get(t));
2546 goto ON_ERROR;
2547 }
2549 section_list_destroy(sections);
2550 sections = NULL;
2551
2553
2554 for (i = 0; i < ESTYLE_COUNT; i++) {
2556 }
2558
2559 for (i = 0; (extraname = secfile_lookup_str_default(file, NULL,
2560 "extras.styles%d.name",
2561 i)); i++) {
2562 const char *style_name;
2563 enum extrastyle_id style;
2564
2565 style_name = secfile_lookup_str_default(file, "Single1",
2566 "extras.styles%d.style", i);
2568 if (!extrastyle_id_is_valid(style)) {
2569 log_error("Unknown extra style \"%s\" for extra \"%s\" in %s.",
2571 goto ON_ERROR;
2572 }
2573
2574 if (!estyle_hash_insert(t->estyle_hash, extraname, style)) {
2575 log_error("warning: duplicate extrastyle entry [%s] in %s.",
2577 goto ON_ERROR;
2578 }
2579 }
2580
2582
2585 "tilespec.files");
2586
2587 if (svg) {
2589 type_name = "svg";
2590
2591 /* Avoid "unused entry" warning about the other list */
2592 secfile_entry_ignore_by_path(file, "tilespec.files_pixel");
2593 } else {
2595 type_name = "pixel";
2596
2597 /* Avoid "unused entry" warning about the other list */
2598 secfile_entry_ignore_by_path(file, "tilespec.files_svg");
2599 }
2600
2603 "tilespec.files_%s", type_name);
2606 log_error("No tile graphics files specified in \"%s\" for %s mode.",
2607 type_name, fname);
2608 goto ON_ERROR;
2609 }
2610
2611 fc_assert(t->sprite_hash == NULL);
2613
2616 verbose, duplicates_ok)) {
2617 goto ON_ERROR;
2618 }
2619
2622 verbose, duplicates_ok)) {
2623 goto ON_ERROR;
2624 }
2625
2628
2630
2632 = (char **) secfile_lookup_str_vec(file, &num_preferred_themes,
2633 "tilespec.preferred_themes");
2634 t->num_preferred_themes = num_preferred_themes;
2635 for (i = 0; i < t->num_preferred_themes; i++) {
2637 }
2638
2640 secfile_destroy(file);
2641 log_verbose("Finished reading \"%s\".", fname);
2642 free(fname);
2643
2644 return t;
2645
2646ON_ERROR:
2647 secfile_destroy(file);
2648 free(fname);
2649 tileset_free(t);
2650
2651 if (NULL != sections) {
2652 section_list_destroy(sections);
2653 }
2654
2655 return NULL;
2656}
2657
2658/************************************************************************/
2661static const char *citizen_rule_name(enum citizen_category citizen)
2662{
2663 /* These strings are used in reading the tileset. Do not
2664 * translate. */
2665 switch (citizen) {
2666 case CITIZEN_HAPPY:
2667 return "happy";
2668 case CITIZEN_CONTENT:
2669 return "content";
2670 case CITIZEN_UNHAPPY:
2671 return "unhappy";
2672 case CITIZEN_ANGRY:
2673 return "angry";
2674 default:
2675 break;
2676 }
2677 log_error("Unknown citizen type: %d.", (int) citizen);
2678 return NULL;
2679}
2680
2681/************************************************************************/
2686static const char *cardinal_index_str(const struct tileset *t, int idx)
2687{
2688 static char c[64];
2689 int i;
2690
2691 c[0] = '\0';
2692 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
2693 int value = (idx >> i) & 1;
2694
2695 cat_snprintf(c, sizeof(c), "%s%d",
2697 }
2698
2699 return c;
2700}
2701
2702/************************************************************************/
2706static char *valid_index_str(const struct tileset *t, int idx)
2707{
2708 static char c[64];
2709 int i;
2710
2711 c[0] = '\0';
2712 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
2713 int value = (idx >> i) & 1;
2714
2715 cat_snprintf(c, sizeof(c), "%s%d",
2717 }
2718
2719 return c;
2720}
2721
2722/************************************************************************/
2729static struct sprite *load_sprite(struct tileset *t, const char *tag_name,
2730 bool scale, bool smooth, bool svgflag)
2731{
2732 struct small_sprite *ss;
2733 float sprite_scale = 1.0f;
2734
2735 log_debug("load_sprite(tag='%s')", tag_name);
2736 /* Lookup information about where the sprite is found. */
2738 return NULL;
2739 }
2740
2741 fc_assert(ss->ref_count >= 0);
2742
2743 if (!ss->sprite) {
2744 /* If the sprite hasn't been loaded already, then load it. */
2745 fc_assert(ss->ref_count == 0);
2746
2747 if (ss->file) {
2748 int w, h;
2749 struct sprite *s;
2750
2751 if (scale) {
2752 s = load_gfx_file(ss->file, svgflag);
2753
2754 if (s != NULL) {
2755 get_sprite_dimensions(s, &w, &h);
2756 ss->sprite = crop_sprite(s, 0, 0, w,
2757 h, NULL, -1, -1, t->scale, smooth);
2758 free_sprite(s);
2759 }
2760 } else {
2761 ss->sprite = load_gfx_file(ss->file, svgflag);
2762 }
2763
2764 if (!ss->sprite) {
2766 _("Couldn't load gfx file \"%s\" for sprite '%s'."),
2767 ss->file, tag_name);
2768 }
2769 } else {
2770 int sf_w, sf_h;
2771
2773 get_sprite_dimensions(ss->sf->big_sprite, &sf_w, &sf_h);
2774 if (ss->x < 0 || ss->x + ss->width > sf_w
2775 || ss->y < 0 || ss->y + ss->height > sf_h) {
2777 _("Sprite '%s' in file \"%s\" isn't within the image!"),
2778 tag_name, ss->sf->file_name);
2779 return NULL;
2780 }
2781 if (scale) {
2782 sprite_scale = t->scale;
2783 }
2784 ss->sprite = crop_sprite(ss->sf->big_sprite, ss->x, ss->y, ss->width,
2785 ss->height, NULL, -1, -1, sprite_scale,
2786 smooth);
2787 }
2788 }
2789
2790 /* Track the reference count so we know when to free the sprite. */
2791 ss->ref_count++;
2792
2793 return ss->sprite;
2794}
2795
2796/************************************************************************/
2799static struct sprite *create_plr_sprite(struct color *pcolor)
2800{
2801 struct sprite *sprite;
2802
2804
2805 if (tileset->scale == 1.0f) {
2806 sprite = create_sprite(128, 64, pcolor);
2807 } else {
2810 }
2811
2812 return sprite;
2813}
2814
2815/************************************************************************/
2819static void unload_sprite(struct tileset *t, const char *tag_name)
2820{
2821 struct small_sprite *ss;
2822
2825 fc_assert_ret(ss->ref_count >= 1);
2826 fc_assert_ret(ss->sprite);
2827
2828 ss->ref_count--;
2829
2830 if (ss->ref_count == 0) {
2831 /* Nobody's using the sprite anymore, so we should free it. We know
2832 * where to find it if we need it again. */
2833 log_debug("freeing sprite '%s'.", tag_name);
2834 free_sprite(ss->sprite);
2835 ss->sprite = NULL;
2836 }
2837}
2838
2839/************************************************************************/
2843static bool sprite_exists(const struct tileset *t, const char *tag_name)
2844{
2845 /* Lookup information about where the sprite is found. */
2847}
2848
2849/* Not very safe, but convenient: */
2850#define SET_SPRITE(field, tag) \
2851 do { \
2852 t->sprites.field = load_sprite(t, tag, TRUE, TRUE, FALSE); \
2853 if (t->sprites.field == NULL) { \
2854 tileset_error(LOG_FATAL, tileset_name_get(t), \
2855 _("Sprite for tag '%s' missing."), tag); \
2856 } \
2857 } while (FALSE)
2858
2859
2860#define SET_SPRITE_NOTSMOOTH(field, tag) \
2861 do { \
2862 t->sprites.field = load_sprite(t, tag, TRUE, FALSE, FALSE); \
2863 if (t->sprites.field == NULL) { \
2864 tileset_error(LOG_FATAL, tileset_name_get(t), \
2865 _("Sprite for tag '%s' missing."), tag); \
2866 } \
2867 } while (FALSE)
2868
2869#define SET_SPRITE_UNSCALED(field, tag) \
2870 do { \
2871 t->sprites.field = load_sprite(t, tag, FALSE, FALSE, FALSE); \
2872 if (t->sprites.field == NULL) { \
2873 tileset_error(LOG_FATAL, tileset_name_get(t), \
2874 _("Sprite for tag '%s' missing."), tag); \
2875 } \
2876 } while (FALSE)
2877
2878/* Sets sprites.field to tag or (if tag isn't available) to alt */
2879#define SET_SPRITE_ALT(field, tag, alt) \
2880 do { \
2881 t->sprites.field = load_sprite(t, tag, TRUE, TRUE, FALSE); \
2882 if (!t->sprites.field) { \
2883 t->sprites.field = load_sprite(t, alt, TRUE, TRUE, FALSE); \
2884 } \
2885 if (t->sprites.field == NULL) { \
2886 tileset_error(LOG_FATAL, tileset_name_get(t), \
2887 _("Sprite for tags '%s' and alternate '%s' are " \
2888 "both missing."), tag, alt); \
2889 } \
2890 } while (FALSE)
2891
2892/* Sets sprites.field to tag or (if tag isn't available) to deprecated alt */
2893#define SET_SPRITE_DEPR_ALT(field, tag, alt, ver) \
2894 do { \
2895 t->sprites.field = load_sprite(t, tag, TRUE, TRUE, FALSE); \
2896 if (!t->sprites.field) { \
2897 t->sprites.field = load_sprite(t, alt, TRUE, TRUE, FALSE); \
2898 if (t->sprites.field != NULL) { \
2899 log_deprecation(_("%s: Using tag \"%s\" deprecated by \"%s\" in %s"), \
2900 tileset_name_get(t), alt, tag, ver); \
2901 } \
2902 } \
2903 if (t->sprites.field == NULL) { \
2904 tileset_error(LOG_FATAL, tileset_name_get(t), \
2905 _("Sprite for tags '%s' and alternate '%s' are " \
2906 "both missing."), tag, alt); \
2907 } \
2908 } while (FALSE)
2909
2910/* Sets sprites.field to tag, or NULL if not available */
2911#define SET_SPRITE_OPT(field, tag) \
2912 t->sprites.field = load_sprite(t, tag, TRUE, TRUE, FALSE)
2913
2914#define SET_SPRITE_ALT_OPT(field, tag, alt) \
2915 do { \
2916 t->sprites.field = tiles_lookup_sprite_tag_alt(t, LOG_VERBOSE, tag, alt, \
2917 NULL, "sprite", #field, \
2918 TRUE); \
2919 } while (FALSE)
2920
2921/************************************************************************/
2930
2931/************************************************************************/
2935 struct citizen_set *set,
2937 const char *tag_group,
2938 const char *set_name,
2939 bool required)
2940{
2941 /* Load the specialist sprite graphics. */
2942 char buffer[512];
2943 int j;
2944 struct specialist *spe = specialist_by_number(id);
2945 const char *tag = spe->graphic_str;
2946 const char *graphic_alt = spe->graphic_alt;
2947
2948 for (j = 0; j < MAX_NUM_CITIZEN_SPRITES; j++) {
2949 /* Try tag name + index number */
2950 if (tag_group != NULL) {
2951 fc_snprintf(buffer, sizeof(buffer), "%s.%s_%d", tag_group, tag, j);
2952 } else {
2953 fc_snprintf(buffer, sizeof(buffer), "%s_%d", tag, j);
2954 }
2955 set->specialist[id].sprite[j] = load_sprite(t, buffer,
2956 FALSE, FALSE, FALSE);
2957
2958 /* Break if no more index specific sprites are defined */
2959 if (!set->specialist[id].sprite[j]) {
2960 break;
2961 }
2962 }
2963
2964 if (j == 0) {
2965 /* Try non-indexed */
2966 set->specialist[id].sprite[j] = load_sprite(t, tag,
2967 FALSE, FALSE, FALSE);
2968
2969 if (set->specialist[id].sprite[j]) {
2970 j = 1;
2971 }
2972 }
2973
2974 if (j == 0) {
2975 /* Try the alt tag */
2976 for (j = 0; j < MAX_NUM_CITIZEN_SPRITES; j++) {
2977 /* Try alt tag name + index number */
2978 if (tag_group != NULL) {
2979 fc_snprintf(buffer, sizeof(buffer), "%s.%s_%d", tag_group, graphic_alt, j);
2980 } else {
2981 fc_snprintf(buffer, sizeof(buffer), "%s_%d", graphic_alt, j);
2982 }
2983 set->specialist[id].sprite[j] = load_sprite(t, buffer,
2984 FALSE, FALSE, FALSE);
2985
2986 /* Break if no more index specific sprites are defined */
2987 if (!set->specialist[id].sprite[j]) {
2988 break;
2989 }
2990 }
2991 }
2992
2993 if (j == 0) {
2994 /* Try alt tag non-indexed */
2996 FALSE, FALSE, FALSE);
2997
2998 if (set->specialist[id].sprite[j]) {
2999 j = 1;
3000 }
3001 }
3002
3003 set->specialist[id].count = j;
3004
3005 /* Still nothing? Give up. */
3006 if (j == 0 && required) {
3007 /* TRANS: First %s is a graphics tag of the specialist, second one
3008 * is a citizen set name; 'citizen_graphic' from styles.ruleset */
3010 _("No graphics for specialist \"%s\" in %s."),
3011 tag, set_name);
3012 }
3013}
3014
3015/************************************************************************/
3019{
3021 "default set", TRUE);
3022}
3023
3024/************************************************************************/
3028 struct citizen_set *set,
3029 const char *tag_group,
3030 const char *set_name,
3031 bool required)
3032{
3033 int i, j;
3034 char buffer[512];
3035
3036 /* Load the citizen sprite graphics, no specialist. */
3037 for (i = 0; i < CITIZEN_LAST; i++) {
3038 const char *name = citizen_rule_name(i);
3039
3040 for (j = 0; j < MAX_NUM_CITIZEN_SPRITES; j++) {
3041 if (tag_group != NULL) {
3042 fc_snprintf(buffer, sizeof(buffer), "citizen.%s.%s_%d", tag_group, name, j);
3043 } else {
3044 fc_snprintf(buffer, sizeof(buffer), "citizen.%s_%d", name, j);
3045 }
3046 set->citizen[i].sprite[j] = load_sprite(t, buffer, FALSE, FALSE, FALSE);
3047 if (!set->citizen[i].sprite[j]) {
3048 break;
3049 }
3050 }
3051 set->citizen[i].count = j;
3052 if (j == 0 && required) {
3053 /* TRANS: First %s is type of the citizen ("happy" ... "angry"), second one
3054 * is a citizen set name; 'citizen_graphic' from styles.ruleset */
3056 _("No graphics for citizen \"%s\" in %s."),
3057 name, set_name);
3058 }
3059 }
3060}
3061
3062/************************************************************************/
3068static struct sprite *get_city_sprite(const struct city_sprite *city_sprite,
3069 const struct city *pcity)
3070{
3071 /* Get style and match the best tile based on city size */
3072 int style = style_of_city(pcity);
3073 int num_thresholds;
3075 int img_index;
3076
3078
3081
3082 if (num_thresholds == 0) {
3083 return NULL;
3084 }
3085
3086 /* Get the sprite with the index defined by the effects. */
3087 img_index = pcity->client.city_image;
3088 if (img_index == -100) {
3089 /* Server doesn't know right value as this is from old savegame.
3090 * Guess here based on *client* side information as was done in
3091 * versions where information was not saved to savegame - this should
3092 * give us right answer of what city looked like by the time it was
3093 * put under FoW. */
3095 }
3097
3098 return thresholds[img_index].sprite;
3099}
3100
3101/************************************************************************/
3104static int load_city_thresholds_sprites(struct tileset *t, const char *tag,
3105 char *graphic, char *graphic_alt,
3107{
3108 char buffer[128];
3109 char *gfx_in_use = graphic;
3110 int num_thresholds = 0;
3111 struct sprite *sprite;
3112 int size;
3113
3114 *thresholds = NULL;
3115
3116 for (size = 0; size < MAX_CITY_SIZE; size++) {
3117 fc_snprintf(buffer, sizeof(buffer), "%s_%s_%d",
3118 gfx_in_use, tag, size);
3119 if ((sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE))) {
3122 (*thresholds)[num_thresholds - 1].sprite = sprite;
3123 } else if (size == 0) {
3124 if (gfx_in_use == graphic) {
3125 /* Try again with graphic_alt. */
3126 size--;
3127 gfx_in_use = graphic_alt;
3128 } else {
3129 /* Don't load any others if the 0 element isn't there. */
3130 break;
3131 }
3132 }
3133 }
3134
3135 return num_thresholds;
3136}
3137
3138/************************************************************************/
3145static struct city_sprite *load_city_sprite(struct tileset *t,
3146 const char *tag)
3147{
3148 struct city_sprite *city_sprite = fc_malloc(sizeof(*city_sprite));
3149 int style;
3150
3151 /* Store number of styles we have allocated memory for.
3152 * game.control.num_city_styles might change if client disconnects from
3153 * server and connects new one. */
3156 * sizeof(*city_sprite->styles));
3157
3158 for (style = 0; style < city_sprite->num_styles; style++) {
3160 load_city_thresholds_sprites(t, tag, city_styles[style].graphic,
3161 city_styles[style].graphic_alt,
3163 }
3164
3165 return city_sprite;
3166}
3167
3168/************************************************************************/
3174{
3175 int style;
3176
3177 if (!city_sprite) {
3178 return;
3179 }
3180 for (style = 0; style < city_sprite->num_styles; style++) {
3181 if (city_sprite->styles[style].land_thresholds) {
3183 }
3184 }
3187}
3188
3189/************************************************************************/
3194{
3195 char buffer[512], buffer2[512];
3196 const int W = t->normal_tile_width, H = t->normal_tile_height;
3197 int i, j, f;
3198
3200
3201 SET_SPRITE_UNSCALED(treaty_thumb[0], "treaty.disagree_thumb_down");
3202 SET_SPRITE_UNSCALED(treaty_thumb[1], "treaty.agree_thumb_up");
3203
3204 for (j = 0; j < INDICATOR_COUNT; j++) {
3205 const char *names[] = {"science_bulb", "warming_sun", "cooling_flake"};
3206
3207 for (i = 0; i < NUM_TILES_PROGRESS; i++) {
3208 fc_snprintf(buffer, sizeof(buffer), "s.%s_%d", names[j], i);
3209 SET_SPRITE_UNSCALED(indicator[j][i], buffer);
3210 }
3211 }
3212
3213 SET_SPRITE(arrow[ARROW_RIGHT], "s.right_arrow");
3214 SET_SPRITE(arrow[ARROW_PLUS], "s.plus");
3215 SET_SPRITE(arrow[ARROW_MINUS], "s.minus");
3216 if (t->type == TS_ISOMETRIC) {
3217 SET_SPRITE(dither_tile, "t.dither_tile");
3218 }
3219
3221 SET_SPRITE_NOTSMOOTH(mask.tile, "mask.tile");
3222 } else {
3223 SET_SPRITE(mask.tile, "mask.tile");
3224 }
3225 SET_SPRITE(mask.worked_tile, "mask.worked_tile");
3226 SET_SPRITE(mask.unworked_tile, "mask.unworked_tile");
3227
3228 SET_SPRITE_UNSCALED(tax_luxury, "s.tax_luxury");
3229 SET_SPRITE_UNSCALED(tax_science, "s.tax_science");
3230 SET_SPRITE_UNSCALED(tax_gold, "s.tax_gold");
3231
3233
3234 for (i = 0; i < SPACESHIP_COUNT; i++) {
3235 const char *names[SPACESHIP_COUNT]
3236 = {"solar_panels", "life_support", "habitation",
3237 "structural", "fuel", "propulsion", "exhaust"};
3238
3239 fc_snprintf(buffer, sizeof(buffer), "spaceship.%s", names[i]);
3240 SET_SPRITE(spaceship[i], buffer);
3241 }
3242
3243 for (i = 0; i < CURSOR_LAST; i++) {
3244 const char *names[CURSOR_LAST] =
3245 {"goto", "patrol", "paradrop", "teleport", "nuke", "select",
3246 "invalid", "attack", "edit_paint", "edit_add", "wait"};
3247
3248 for (f = 0; f < NUM_CURSOR_FRAMES; f++) {
3249 struct small_sprite *ss;
3250
3251 fc_assert(ARRAY_SIZE(names) == CURSOR_LAST);
3252 fc_snprintf(buffer, sizeof(buffer), "cursor.%s%d", names[i], f);
3253 SET_SPRITE(cursor[i].frame[f], buffer);
3254
3255 if (sprite_hash_lookup(t->sprite_hash, buffer, &ss)) {
3256 t->sprites.cursor[i].hot_x = ss->hot_x;
3257 t->sprites.cursor[i].hot_y = ss->hot_y;
3258 }
3259 }
3260 }
3261
3262 for (i = 0; i < ICON_COUNT; i++) {
3263 const char *names[ICON_COUNT] = {"freeciv", "citydlg"};
3264
3265 fc_snprintf(buffer, sizeof(buffer), "icon.%s", names[i]);
3266 SET_SPRITE(icon[i], buffer);
3267 }
3268
3269 for (i = 0; i < E_COUNT; i++) {
3270 const char *tag = get_event_tag(i);
3271
3272 SET_SPRITE(events[i], tag);
3273 }
3274
3275 SET_SPRITE(explode.nuke, "explode.nuke");
3276
3278 for (i = 0; ; i++) {
3279 struct sprite *sprite;
3280
3281 fc_snprintf(buffer, sizeof(buffer), "explode.unit_%d", i);
3282 sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3283 if (!sprite) {
3284 break;
3285 }
3287 }
3288
3289 SET_SPRITE(unit.auto_attack, "unit.auto_attack");
3290 /* TODO: Drop backward compatibility with "unit.auto_settler" tag. */
3291 SET_SPRITE_DEPR_ALT(unit.auto_worker, "unit.auto_worker", "unit.auto_settler", "3.3");
3292 SET_SPRITE(unit.auto_explore, "unit.auto_explore");
3293 SET_SPRITE(unit.fortified, "unit.fortified");
3294 SET_SPRITE(unit.fortifying, "unit.fortifying");
3295 SET_SPRITE(unit.go_to, "unit.goto");
3296 SET_SPRITE(unit.cultivate, "unit.cultivate");
3297 SET_SPRITE(unit.plant, "unit.plant");
3298 SET_SPRITE(unit.pillage, "unit.pillage");
3299 SET_SPRITE(unit.sentry, "unit.sentry");
3300 SET_SPRITE(unit.convert, "unit.convert");
3301 t->sprites.unit.stack = fc_malloc(sizeof(struct sprite *));
3302 t->sprites.unit.num_stack_sprites = 1;
3303 SET_SPRITE(unit.stack[0], "unit.stack");
3304 t->sprites.unit.no_more_stack_sprites = FALSE;
3305 SET_SPRITE(unit.loaded, "unit.loaded");
3306 SET_SPRITE(unit.transform, "unit.transform");
3307 SET_SPRITE(unit.connect, "unit.connect");
3308 SET_SPRITE(unit.patrol, "unit.patrol");
3309 for (i = 0; i < MAX_NUM_BATTLEGROUPS; i++) {
3310 fc_snprintf(buffer, sizeof(buffer), "unit.battlegroup_%d", i);
3311 fc_snprintf(buffer2, sizeof(buffer2), "city.size_%d", i + 1);
3314 }
3315 SET_SPRITE(unit.lowfuel, "unit.lowfuel");
3316 SET_SPRITE(unit.tired, "unit.tired");
3317
3318 SET_SPRITE_OPT(unit.action_decision_want, "unit.action_decision_want");
3319
3320 for (i = 0; i < NUM_TILES_HP_BAR; i++) {
3321 fc_snprintf(buffer, sizeof(buffer), "unit.hp_%d", i*10);
3322 SET_SPRITE(unit.hp_bar[i], buffer);
3323 }
3324
3325 for (i = 0; i < MAX_VET_LEVELS; i++) {
3326 /* Veteran level sprites are optional. For instance "green" units
3327 * usually have no special graphic. */
3328 fc_snprintf(buffer, sizeof(buffer), "unit.vet_%d", i);
3329 t->sprites.unit.vet_lev[i] = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3330 }
3331
3332 t->sprites.unit.select[0] = NULL;
3333 if (sprite_exists(t, "unit.select0")) {
3334 for (i = 0; i < NUM_TILES_SELECT; i++) {
3335 fc_snprintf(buffer, sizeof(buffer), "unit.select%d", i);
3336 SET_SPRITE(unit.select[i], buffer);
3337 }
3338 }
3339
3340 SET_SPRITE(citybar.shields, "citybar.shields");
3341 SET_SPRITE(citybar.food, "citybar.food");
3342 SET_SPRITE(citybar.trade, "citybar.trade");
3343 SET_SPRITE(citybar.occupied, "citybar.occupied");
3344 SET_SPRITE(citybar.background, "citybar.background");
3346 for (i = 0; ; i++) {
3347 struct sprite *sprite;
3348
3349 fc_snprintf(buffer, sizeof(buffer), "citybar.occupancy_%d", i);
3350 sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3351 if (!sprite) {
3352 break;
3353 }
3355 }
3356 if (t->sprites.citybar.occupancy.size < 2) {
3358 _("Missing necessary citybar.occupancy_N sprites."));
3359 }
3360
3361#define SET_EDITOR_SPRITE(x) SET_SPRITE(editor.x, "editor." #x)
3362 SET_EDITOR_SPRITE(erase);
3363 SET_EDITOR_SPRITE(brush);
3364 SET_EDITOR_SPRITE(copy);
3365 SET_EDITOR_SPRITE(paste);
3366 SET_EDITOR_SPRITE(copypaste);
3369 SET_EDITOR_SPRITE(terrain_resource);
3370 SET_EDITOR_SPRITE(terrain_special);
3374 SET_EDITOR_SPRITE(territory);
3375 SET_EDITOR_SPRITE(properties);
3377 SET_EDITOR_SPRITE(military_base);
3378#undef SET_EDITOR_SPRITE
3379
3380 SET_SPRITE(city.disorder, "city.disorder");
3381
3382 /* Fallbacks for goto path turn numbers:
3383 * path.step_%d, path.exhausted_mp_%d
3384 * --> path.turns_%d
3385 * --> city.size_%d */
3386#define SET_GOTO_TURN_SPRITE(state, state_name, factor, factor_name) \
3387 fc_snprintf(buffer, sizeof(buffer), "path." state_name "_%d" #factor, i); \
3388 SET_SPRITE_OPT(path.s[state].turns ## factor_name [i], buffer); \
3389 if (t->sprites.path.s[state].turns ## factor_name [i] == NULL) { \
3390 t->sprites.path.s[state].turns ## factor_name [i] = \
3391 t->sprites.path.s[GTS_MP_LEFT].turns ## factor_name [i]; \
3392 }
3393
3394 for (i = 0; i < NUM_TILES_DIGITS; i++) {
3395 fc_snprintf(buffer, sizeof(buffer), "city.size_%d", i);
3396 SET_SPRITE(city.size[i], buffer);
3397 fc_snprintf(buffer2, sizeof(buffer2), "path.turns_%d", i);
3398 SET_SPRITE_ALT(path.s[GTS_MP_LEFT].turns[i], buffer2, buffer);
3400 SET_GOTO_TURN_SPRITE(GTS_EXHAUSTED_MP, "exhausted_mp",,);
3401
3402 fc_snprintf(buffer, sizeof(buffer), "city.size_%d0", i);
3403 SET_SPRITE(city.size_tens[i], buffer);
3404 fc_snprintf(buffer2, sizeof(buffer2), "path.turns_%d0", i);
3405 SET_SPRITE_ALT(path.s[GTS_MP_LEFT].turns_tens[i], buffer2, buffer);
3407 SET_GOTO_TURN_SPRITE(GTS_EXHAUSTED_MP, "exhausted_mp", 0, _tens);
3408
3409 fc_snprintf(buffer, sizeof(buffer), "city.size_%d00", i);
3410 SET_SPRITE_OPT(city.size_hundreds[i], buffer);
3411 fc_snprintf(buffer2, sizeof(buffer2), "path.turns_%d00", i);
3412 SET_SPRITE_ALT_OPT(path.s[GTS_MP_LEFT].turns_hundreds[i], buffer2,
3413 buffer);
3415 SET_GOTO_TURN_SPRITE(GTS_EXHAUSTED_MP, "exhausted_mp", 00, _hundreds);
3416
3417 fc_snprintf(buffer, sizeof(buffer), "city.t_food_%d", i);
3418 SET_SPRITE(city.tile_foodnum[i], buffer);
3419 fc_snprintf(buffer, sizeof(buffer), "city.t_shields_%d", i);
3420 SET_SPRITE(city.tile_shieldnum[i], buffer);
3421 fc_snprintf(buffer, sizeof(buffer), "city.t_trade_%d", i);
3422 SET_SPRITE(city.tile_tradenum[i], buffer);
3423 }
3424#undef SET_GOTO_TURN_SPRITE
3425
3426 /* Must have at least one upkeep sprite per output type (and unhappy) */
3427 /* The rest are optional; we copy the previous sprite for unspecified ones */
3428 fc_strlcpy(buffer, "upkeep.unhappy", sizeof(buffer));
3429 SET_SPRITE(upkeep.unhappy[0], buffer);
3430 for (i = 1; i < MAX_NUM_UPKEEP_SPRITES; i++) {
3431 fc_snprintf(buffer2, sizeof(buffer2), "upkeep.unhappy%d", i+1);
3432 if (sprite_exists(t, buffer2)) {
3433 SET_SPRITE(upkeep.unhappy[i], buffer2);
3434 fc_strlcpy(buffer, buffer2, sizeof(buffer));
3435 } else {
3436 SET_SPRITE(upkeep.unhappy[i], buffer);
3437 }
3438 }
3440 fc_snprintf(buffer, sizeof(buffer),
3441 "upkeep.%s", get_output_identifier(o));
3442 SET_SPRITE_OPT(upkeep.output[o][0], buffer);
3443 for (i = 1; i < MAX_NUM_UPKEEP_SPRITES; i++) {
3444 fc_snprintf(buffer2, sizeof(buffer2),
3445 "upkeep.%s%d", get_output_identifier(o), i+1);
3446 if (sprite_exists(t, buffer2)) {
3447 SET_SPRITE(upkeep.output[o][i], buffer2);
3448 fc_strlcpy(buffer, buffer2, sizeof(buffer));
3449 } else {
3450 /* Optional, as maybe the upkeep 1 sprite didn't exist either */
3451 SET_SPRITE_OPT(upkeep.output[o][i], buffer);
3452 }
3453 }
3455
3457
3458 SET_SPRITE(user.attention, "user.attention");
3459 SET_SPRITE(user.infratile, "user.infratile");
3460
3461 SET_SPRITE_OPT(path.s[GTS_MP_LEFT].specific, "path.normal");
3462 SET_SPRITE_OPT(path.s[GTS_EXHAUSTED_MP].specific, "path.exhausted_mp");
3463 SET_SPRITE_OPT(path.s[GTS_TURN_STEP].specific, "path.step");
3464 SET_SPRITE(path.waypoint, "path.waypoint");
3465
3466 SET_SPRITE_NOTSMOOTH(tx.fog, "tx.fog");
3467
3469 for (i = 0; ; i++) {
3470 struct sprite *sprite;
3471
3472 fc_snprintf(buffer, sizeof(buffer), "colors.overlay_%d", i);
3473 sprite = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3474 if (!sprite) {
3475 break;
3476 }
3478 }
3479 if (i == 0) {
3481 _("Missing overlay-color sprite colors.overlay_0."));
3482 }
3483
3484 /* Chop up and build the overlay graphics. */
3489 for (i = 0; i < sprite_vector_size(&t->sprites.colors.overlays); i++) {
3490 struct sprite *color, *color_mask;
3491 struct sprite *worked, *unworked;
3492
3494 color_mask = crop_sprite(color, 0, 0, W, H, t->sprites.mask.tile, 0, 0,
3495 1.0f, FALSE);
3496 worked = crop_sprite(color_mask, 0, 0, W, H,
3497 t->sprites.mask.worked_tile, 0, 0, 1.0f, FALSE);
3498 unworked = crop_sprite(color_mask, 0, 0, W, H,
3499 t->sprites.mask.unworked_tile, 0, 0, 1.0f, FALSE);
3501 t->sprites.city.worked_tile_overlay.p[i] = worked;
3503 }
3504
3505
3506 {
3507 SET_SPRITE(grid.unavailable, "grid.unavailable");
3508 SET_SPRITE_OPT(grid.nonnative, "grid.nonnative");
3509
3510 for (i = 0; i < EDGE_COUNT; i++) {
3511 int be;
3512
3513 if (i == EDGE_UD && t->hex_width == 0) {
3514 continue;
3515 } else if (i == EDGE_LR && t->hex_height == 0) {
3516 continue;
3517 }
3518
3519 fc_snprintf(buffer, sizeof(buffer), "grid.main.%s", edge_name[i]);
3520 SET_SPRITE(grid.main[i], buffer);
3521
3522 fc_snprintf(buffer, sizeof(buffer), "grid.city.%s", edge_name[i]);
3523 SET_SPRITE(grid.city[i], buffer);
3524
3525 fc_snprintf(buffer, sizeof(buffer), "grid.worked.%s", edge_name[i]);
3526 SET_SPRITE(grid.worked[i], buffer);
3527
3528 fc_snprintf(buffer, sizeof(buffer), "grid.selected.%s", edge_name[i]);
3529 SET_SPRITE(grid.selected[i], buffer);
3530
3531 fc_snprintf(buffer, sizeof(buffer), "grid.coastline.%s", edge_name[i]);
3532 SET_SPRITE(grid.coastline[i], buffer);
3533
3534 for (be = 0; be < 2; be++) {
3535 fc_snprintf(buffer, sizeof(buffer), "grid.borders.%c",
3536 edge_name[i][be]);
3537 SET_SPRITE(grid.borders[i][be], buffer);
3538 }
3539 }
3540 }
3541
3542 switch (t->darkness_style) {
3543 case DARKNESS_NONE:
3544 /* Nothing. */
3545 break;
3546 case DARKNESS_ISORECT:
3547 {
3548 /* Isometric: take a single tx.darkness tile and split it into 4. */
3549 struct sprite *darkness = load_sprite(t, "tx.darkness",
3550 TRUE, FALSE, FALSE);
3551 const int ntw = t->normal_tile_width, nth = t->normal_tile_height;
3552 int offsets[4][2] = {{ntw / 2, 0}, {0, nth / 2}, {ntw / 2, nth / 2}, {0, 0}};
3553
3554 if (!darkness) {
3556 _("Sprite tx.darkness missing."));
3557 }
3558 for (i = 0; i < 4; i++) {
3559 t->sprites.tx.darkness[i] = crop_sprite(darkness, offsets[i][0],
3560 offsets[i][1], ntw / 2,
3561 nth / 2, NULL, 0, 0, 1.0f,
3562 FALSE);
3563 }
3564 }
3565 break;
3567 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
3568 enum direction8 dir = t->cardinal_tileset_dirs[i];
3569
3570 fc_snprintf(buffer, sizeof(buffer), "tx.darkness_%s",
3572 SET_SPRITE_NOTSMOOTH(tx.darkness[i], buffer);
3573 }
3574 break;
3575 case DARKNESS_CARD_FULL:
3576 for (i = 1; i < t->num_index_cardinal; i++) {
3577 fc_snprintf(buffer, sizeof(buffer), "tx.darkness_%s",
3578 cardinal_index_str(t, i));
3579 SET_SPRITE_NOTSMOOTH(tx.darkness[i], buffer);
3580 }
3581 break;
3582 case DARKNESS_CORNER:
3584 81 * sizeof(*t->sprites.tx.fullfog));
3585 for (i = 0; i < 81; i++) {
3586 /* Unknown, fog, known. */
3587 char ids[] = {'u', 'f', 'k'};
3588 char buf[512] = "t.fog";
3589 int values[4], vi, k = i;
3590
3591 for (vi = 0; vi < 4; vi++) {
3592 values[vi] = k % 3;
3593 k /= 3;
3594
3595 cat_snprintf(buf, sizeof(buf), "_%c", ids[values[vi]]);
3596 }
3597 fc_assert(k == 0);
3598
3600 }
3601 break;
3602 };
3603
3604 /* No other place to initialize these variables */
3607}
3608
3609/************************************************************************/
3612static bool load_river_sprites(struct tileset *t,
3613 struct river_sprites *store, const char *tag_pfx)
3614{
3615 int i;
3616 char buffer[512];
3617
3618 for (i = 0; i < t->num_index_cardinal; i++) {
3619 fc_snprintf(buffer, sizeof(buffer), "%s_s_%s",
3621 store->spec[i] = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3622 if (store->spec[i] == NULL) {
3623 return FALSE;
3624 }
3625 }
3626
3627 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
3628 fc_snprintf(buffer, sizeof(buffer), "%s_outlet_%s",
3630 store->outlet[i] = load_sprite(t, buffer, TRUE, TRUE, FALSE);
3631 if (store->outlet[i] == NULL) {
3632 log_error("Missing \"%s\" for \"%s\".", buffer, tag_pfx);
3633 return FALSE;
3634 }
3635 }
3636
3637 return TRUE;
3638}
3639
3640/************************************************************************/
3647{
3649 if (sf->big_sprite) {
3650 free_sprite(sf->big_sprite);
3651 sf->big_sprite = NULL;
3652 }
3654}
3655
3656/************************************************************************/
3667
3668/************************************************************************/
3674 enum log_level level,
3675 const char *tag, const char *alt,
3676 const char *alt2,
3677 const char *what, const char *name,
3678 bool scale)
3679{
3680 struct sprite *sp;
3681
3682 /* (Should get sprite_hash before connection) */
3684 "attempt to lookup for %s \"%s\" before "
3685 "sprite_hash setup", what, name);
3686
3687 sp = load_sprite(t, tag, scale, TRUE, FALSE);
3688 if (sp) return sp;
3689
3690 sp = load_sprite(t, alt, scale, TRUE, FALSE);
3691 if (sp) {
3692 log_verbose("Using alternate graphic \"%s\" "
3693 "(instead of \"%s\") for %s \"%s\".",
3694 alt, tag, what, name);
3695 return sp;
3696 }
3697
3698 if (alt2 != NULL) {
3699 sp = load_sprite(t, alt2, scale, TRUE, FALSE);
3700 if (sp) {
3701 log_verbose("Using second alternate graphic \"%s\" "
3702 "(instead of \"%s\" or \"%s\") for %s \"%s\".",
3703 alt2, tag, alt, what, name);
3704 return sp;
3705 }
3706 }
3707
3709 _("Don't have graphics tags \"%s\" or \"%s\" for %s \"%s\"."),
3710 tag, alt, what, name);
3711
3712 return NULL;
3713}
3714
3715/************************************************************************/
3720 int uidx,
3721 const char *base_str,
3722 enum direction8 dir,
3723 enum unit_activity activity,
3724 bool has_icon)
3725{
3726 enum direction8 loaddir = dir;
3727 char buf[2048];
3728 const char *act_name = unit_activity_name(activity);
3729
3730 if (act_name == NULL) {
3731 /* gcc-9 thinks this is possible. */
3732 return FALSE;
3733 }
3734
3735 /*
3736 * There may be more orientations available in this tileset than are
3737 * needed, if an oriented unit set has been reused between tilesets.
3738 *
3739 * Don't bother loading unused ones, unless they might be used by
3740 * unit_default_orientation (logic here mirrors get_unittype_sprite()).
3741 */
3742 if (!(dir == t->unit_default_orientation && !has_icon)
3743 && !is_valid_tileset_dir(t, dir)) {
3744 /* Instead we copy a nearby valid dir's sprite, so we're not caught
3745 * out in case this tileset is used with an incompatible topology,
3746 * although it'll be ugly. */
3747 do {
3749 /* This loop _should_ terminate... */
3751 } while (!is_valid_tileset_dir(t, loaddir));
3752 }
3753
3754 fc_snprintf(buf, sizeof(buf), "%s_%s_%s", base_str,
3756
3757 /* We don't use _alt graphics here, as that could lead to loading
3758 * real icon gfx, but alternative orientation gfx. Tileset author
3759 * probably meant icon gfx to be used as fallback for all orientations */
3760 t->sprites.units.facing[uidx][dir][activity] = load_sprite(t, buf,
3761 TRUE, TRUE, FALSE);
3762
3763 if (activity == ACTIVITY_IDLE
3764 && t->sprites.units.facing[uidx][dir][activity] == NULL) {
3765 /* Backward compatibility: Set Idle sprite from tag with no activity defined. */
3766 fc_snprintf(buf, sizeof(buf), "%s_%s", base_str,
3768
3769 t->sprites.units.facing[uidx][dir][activity] = load_sprite(t, buf,
3770 TRUE, TRUE, FALSE);
3771 }
3772
3773 if (t->sprites.units.facing[uidx][dir][activity] != NULL) {
3774 return TRUE;
3775 }
3776
3777 return FALSE;
3778}
3779
3780/************************************************************************/
3784 int uidx,
3785 const char *tag)
3786{
3788
3789 activity_type_iterate(activity) {
3790 char buffer[2048];
3791
3792 fc_snprintf(buffer, sizeof(buffer), "%s_%s",
3793 tag, unit_activity_name(activity));
3794 t->sprites.units.icon[uidx][activity] = load_sprite(t, buffer,
3795 TRUE, TRUE, FALSE);
3796
3797 if (activity == ACTIVITY_IDLE
3798 && t->sprites.units.icon[uidx][activity] == NULL) {
3799 /* Backward compatibility: Set Idle sprite from tag with no activity defined. */
3800 t->sprites.units.icon[uidx][activity] = load_sprite(t, tag,
3801 TRUE, TRUE, FALSE);
3802 }
3804
3806
3807#define LOAD_FACING_SPRITE(dir) \
3808 if (!tileset_setup_unit_direction(t, uidx, tag, dir, activity, has_icon)) { \
3809 facing_sprites[activity] = FALSE; \
3810 }
3811
3812 activity_type_iterate(activity) {
3813 facing_sprites[activity] = TRUE;
3814
3823
3825
3827 /* Neither icon gfx or orientation sprites */
3828 return FALSE;
3829 }
3830
3831 return TRUE;
3832
3833#undef LOAD_FACING_SPRITE
3834}
3835
3836/************************************************************************/
3841{
3842 int uidx = utype_index(ut);
3843
3844 if (!tileset_setup_unit_type_from_tag(t, uidx, ut->graphic_str)
3845 && !tileset_setup_unit_type_from_tag(t, uidx, ut->graphic_alt)
3846 && !tileset_setup_unit_type_from_tag(t, uidx, ut->graphic_alt2)) {
3848 _("Missing %s unit sprite for tags \"%s\" and alternatives "
3849 "\"%s\" and \"%s\"."),
3850 utype_rule_name(ut), ut->graphic_str,
3851 ut->graphic_alt, ut->graphic_alt2);
3852 }
3853
3854 if (!t->sprites.units.icon[uidx][ACTIVITY_IDLE]) {
3857 _("Unit type %s has no unoriented sprite and "
3858 "tileset has no unit_default_orientation."),
3860 } else {
3861 /* We're guaranteed to have an oriented sprite corresponding to
3862 * unit_default_orientation, because tileset_setup_unit_type_from_tag()
3863 * checked for this. */
3865 != NULL);
3866 }
3867 }
3868}
3869
3870/************************************************************************/
3875 struct impr_type *pimprove)
3876{
3877 t->sprites.building[improvement_index(pimprove)]
3879 pimprove->graphic_alt, pimprove->graphic_alt2,
3880 "improvement",
3881 improvement_rule_name(pimprove), FALSE);
3882
3883 /* Should maybe do something if NULL, eg generic default? */
3884}
3885
3886/************************************************************************/
3891 struct advance *padvance)
3892{
3893 if (valid_advance(padvance)) {
3896 padvance->graphic_alt, NULL, "technology",
3898
3899 /* Should maybe do something if NULL, eg generic default? */
3900 } else {
3902 }
3903}
3904
3905/************************************************************************/
3910 struct extra_type *pextra)
3911{
3912 const int id = extra_index(pextra);
3913 enum extrastyle_id extrastyle;
3914
3915 if (!fc_strcasecmp(pextra->graphic_str, "none")) {
3916 /* Extra without graphics */
3918 } else {
3919 const char *tag;
3920
3921 tag = pextra->graphic_str;
3922 if (!estyle_hash_lookup(t->estyle_hash, tag, &extrastyle)) {
3923 tag = pextra->graphic_alt;
3924 if (!estyle_hash_lookup(t->estyle_hash, tag, &extrastyle)) {
3926 _("No extra style for \"%s\" or \"%s\"."),
3927 pextra->graphic_str,
3928 pextra->graphic_alt);
3929 } else {
3930 log_verbose("Using alternate graphic \"%s\" "
3931 "(instead of \"%s\") for extra \"%s\".",
3932 pextra->graphic_alt, pextra->graphic_str,
3933 extra_rule_name(pextra));
3934 }
3935 }
3936
3937 t->sprites.extras[id].extrastyle = extrastyle;
3938
3939 extra_type_list_append(t->style_lists[extrastyle], pextra);
3940
3941 if (extra_has_flag(pextra, EF_SHOW_FLAG)) {
3943 }
3944
3945 switch (extrastyle) {
3946 case ESTYLE_3LAYER:
3947 tileset_setup_base(t, pextra, tag);
3948 break;
3949
3953 case ESTYLE_RIVER:
3954 tileset_setup_road(t, pextra, tag);
3955 break;
3956
3957 case ESTYLE_SINGLE1:
3958 case ESTYLE_SINGLE2:
3959 SET_SPRITE(extras[id].u.single, tag);
3960 break;
3961
3962 case ESTYLE_CARDINALS:
3963 {
3964 int i;
3965 char buffer[512];
3966
3967 /* We use direction-specific irrigation and farmland graphics, if they
3968 * are available. If not, we just fall back to the basic irrigation
3969 * graphics. */
3970 for (i = 0; i < t->num_index_cardinal; i++) {
3971 fc_snprintf(buffer, sizeof(buffer), "%s_%s",
3972 tag, cardinal_index_str(t, i));
3973 t->sprites.extras[id].u.cardinals[i] = load_sprite(t, buffer,
3974 TRUE, TRUE, FALSE);
3975 if (!t->sprites.extras[id].u.cardinals[i]) {
3976 t->sprites.extras[id].u.cardinals[i] = load_sprite(t, tag,
3977 TRUE, TRUE, FALSE);
3978 }
3979 if (!t->sprites.extras[id].u.cardinals[i]) {
3981 _("No cardinal-style graphics \"%s*\" for "
3982 "extra \"%s\""),
3983 tag, extra_rule_name(pextra));
3984 }
3985 }
3986 }
3987 break;
3988 case ESTYLE_COUNT:
3989 break;
3990 }
3991 }
3992
3993 if (!fc_strcasecmp(pextra->activity_gfx, "none")) {
3995 } else {
3997 TRUE, TRUE, FALSE);
3998 if (t->sprites.extras[id].activity == NULL) {
4000 TRUE, TRUE, FALSE);
4001 }
4002 if (t->sprites.extras[id].activity == NULL) {
4004 TRUE, TRUE, FALSE);
4005 }
4006 if (t->sprites.extras[id].activity == NULL) {
4008 _("Missing %s building activity sprite for tags \"%s\" and alternatives \"%s\" and \"%s\"."),
4009 extra_rule_name(pextra), pextra->activity_gfx,
4010 pextra->act_gfx_alt, pextra->act_gfx_alt2);
4011 }
4012 }
4013
4014 if (!fc_strcasecmp(pextra->rmact_gfx, "none")) {
4015 t->sprites.extras[id].rmact = NULL;
4016 } else {
4017 t->sprites.extras[id].rmact = load_sprite(t, pextra->rmact_gfx,
4018 TRUE, TRUE, FALSE);
4019 if (t->sprites.extras[id].rmact == NULL) {
4021 TRUE, TRUE, FALSE);
4022 if (t->sprites.extras[id].rmact == NULL) {
4024 TRUE, TRUE, FALSE);
4025 if (t->sprites.extras[id].rmact == NULL) {
4027 _("Missing %s removal activity sprite for tags \"%s\" "
4028 "and alternatives \"%s\" and \"%s\"."),
4029 extra_rule_name(pextra), pextra->rmact_gfx,
4030 pextra->rmact_gfx_alt, pextra->rmact_gfx_alt2);
4031 }
4032 }
4033 }
4034 }
4035}
4036
4037/************************************************************************/
4041static void tileset_setup_road(struct tileset *t,
4042 struct extra_type *pextra,
4043 const char *tag)
4044{
4045 char full_tag_name[MAX_LEN_NAME + strlen("_isolated")];
4046 const int id = extra_index(pextra);
4047 int i;
4048 enum extrastyle_id extrastyle = t->sprites.extras[id].extrastyle;
4049
4050 /* Isolated road graphics are used by ESTYLE_ROAD_ALL_SEPARATE and
4051 ESTYLE_ROAD_PARITY_COMBINED. */
4052 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE
4053 || extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
4055 "%s_isolated", tag);
4056
4057 SET_SPRITE(extras[id].u.road.isolated, full_tag_name);
4058 }
4059
4060 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE) {
4061 /* ESTYLE_ROAD_ALL_SEPARATE has just 8 additional sprites for each
4062 * road type: one going off in each direction. */
4063 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4064 enum direction8 dir = t->valid_tileset_dirs[i];
4065 const char *dir_name = dir_get_tileset_name(dir);
4066
4068 "%s_%s", tag, dir_name);
4069
4070 SET_SPRITE(extras[id].u.road.ru.dir[i], full_tag_name);
4071 }
4072 } else if (extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
4073 int num_index = 1 << (t->num_valid_tileset_dirs / 2), j;
4074
4075 /* ESTYLE_ROAD_PARITY_COMBINED has 32 additional sprites for each road
4076 * type: 16 each for cardinal and diagonal directions. Each set
4077 * of 16 provides a NSEW-indexed sprite to provide connectors for
4078 * all rails in the cardinal/diagonal directions. The 0 entry is
4079 * unused (the "isolated" sprite is used instead). */
4080
4081 for (i = 1; i < num_index; i++) {
4082 char c[64] = "", d[64] = "";
4083
4084 for (j = 0; j < t->num_valid_tileset_dirs / 2; j++) {
4085 int value = (i >> j) & 1;
4086
4087 cat_snprintf(c, sizeof(c), "%s%d",
4089 value);
4090 cat_snprintf(d, sizeof(d), "%s%d",
4092 value);
4093 }
4094
4096 "%s_c_%s", tag, c);
4097
4098 SET_SPRITE(extras[id].u.road.ru.combo.even[i], full_tag_name);
4099
4101 "%s_d_%s", tag, d);
4102
4103 SET_SPRITE(extras[id].u.road.ru.combo.odd[i], full_tag_name);
4104 }
4105 } else if (extrastyle == ESTYLE_ROAD_ALL_COMBINED) {
4106 /* ESTYLE_ROAD_ALL_COMBINED includes 256 sprites, one for every possibility.
4107 * Just go around clockwise, with all combinations. */
4108 for (i = 0; i < t->num_index_valid; i++) {
4109 char *idx_str = valid_index_str(t, i);
4110
4112 "%s_%s", tag, idx_str);
4113
4114 SET_SPRITE(extras[id].u.road.ru.total[i], full_tag_name);
4115 }
4116 } else if (extrastyle == ESTYLE_RIVER) {
4117 if (!load_river_sprites(t, &t->sprites.extras[id].u.road.ru.rivers, tag)) {
4119 _("No river-style graphics \"%s*\" for extra \"%s\""),
4120 tag, extra_rule_name(pextra));
4121 }
4122 } else {
4124 }
4125
4126 /* Corner road graphics are used by ESTYLE_ROAD_ALL_SEPARATE and
4127 * ESTYLE_ROAD_PARITY_COMBINED. */
4128 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE
4129 || extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
4130 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4131 enum direction8 dir = t->valid_tileset_dirs[i];
4132
4133 if (!is_cardinal_tileset_dir(t, dir)) {
4134 const char *dtn = dir_get_tileset_name(dir);
4135
4137 "%s_c_%s", pextra->graphic_str, dtn);
4138
4139 SET_SPRITE_OPT(extras[id].u.road.corner[dir], full_tag_name);
4140 }
4141 }
4142 }
4143}
4144
4145/************************************************************************/
4149static void tileset_setup_base(struct tileset *t,
4150 const struct extra_type *pextra,
4151 const char *tag)
4152{
4153 char full_tag_name[MAX_LEN_NAME + strlen("_fg")];
4154 const int id = extra_index(pextra);
4155
4156 fc_assert_ret(id >= 0 && id < extra_count());
4157
4159 strcat(full_tag_name, "_bg");
4161 TRUE, TRUE, FALSE);
4162
4164 strcat(full_tag_name, "_mg");
4166 TRUE, TRUE, FALSE);
4167
4169 strcat(full_tag_name, "_fg");
4171 TRUE, TRUE, FALSE);
4172
4173 if (t->sprites.extras[id].u.bmf.background == NULL
4174 && t->sprites.extras[id].u.bmf.middleground == NULL
4175 && t->sprites.extras[id].u.bmf.foreground == NULL) {
4176 /* There was an extra style definition but no matching graphics */
4178 _("No graphics with tag \"%s_bg/mg/fg\" for extra \"%s\""),
4179 tag, extra_rule_name(pextra));
4180 }
4181}
4182
4183/************************************************************************/
4188 const struct terrain *pterrain)
4189{
4190 struct drawing_data *draw;
4191 struct sprite *sprite;
4192 char buffer[MAX_LEN_NAME + 20];
4193 int i, l;
4194
4195 if (!drawing_hash_lookup(t->tile_hash, pterrain->graphic_str, &draw)
4196 && !drawing_hash_lookup(t->tile_hash, pterrain->graphic_alt, &draw)
4197 && !drawing_hash_lookup(t->tile_hash, pterrain->graphic_alt2, &draw)) {
4199 _("Terrain \"%s\": no graphic tile \"%s\", \"%s\", or \"%s\"."),
4200 terrain_rule_name(pterrain), pterrain->graphic_str,
4201 pterrain->graphic_alt, pterrain->graphic_alt2);
4202 }
4203
4204 if (draw->init) {
4205 t->sprites.drawing[terrain_index(pterrain)] = draw;
4206 return;
4207 }
4208
4209 /* Set up each layer of the drawing. */
4210 for (l = 0; l < draw->num_layers; l++) {
4211 struct drawing_layer *dlp = &draw->layer[l];
4212 struct tileset_layer *tslp = &t->layers[l];
4213 sprite_vector_init(&dlp->base);
4214 sprite_vector_init(&dlp->allocated);
4215
4216 switch (dlp->sprite_type) {
4217 case CELL_WHOLE:
4218 switch (dlp->match_style) {
4219 case MATCH_NONE:
4220 /* Load whole sprites for this tile. */
4221 for (i = 0; ; i++) {
4222 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s%d",
4223 l, draw->name, i + 1);
4224 sprite = load_sprite(t, buffer, TRUE, FALSE, FALSE);
4225 if (!sprite) {
4226 break;
4227 }
4228 sprite_vector_reserve(&dlp->base, i + 1);
4229 dlp->base.p[i] = sprite;
4230 }
4231 /* Check for base sprite, allowing missing sprites above base */
4232 if (0 == i && 0 == l) {
4233 /* TRANS: 'base' means 'base of terrain gfx', not 'military base' */
4235 _("Missing base sprite for tag \"%s\"."), buffer);
4236 }
4237 break;
4238 case MATCH_SAME:
4239 /* Load 16 cardinally-matched sprites. */
4240 for (i = 0; i < t->num_index_cardinal; i++) {
4241 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_%s",
4242 l, draw->name, cardinal_index_str(t, i));
4243 dlp->match[i]
4244 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4245 NULL, "matched terrain",
4246 terrain_rule_name(pterrain), TRUE);
4247 }
4248 break;
4249 case MATCH_PAIR:
4250 case MATCH_FULL:
4251 fc_assert(FALSE); /* Not yet defined */
4252 break;
4253 };
4254 break;
4255 case CELL_CORNER:
4256 {
4257 const int count = dlp->match_indices;
4258 int number = NUM_CORNER_DIRS;
4259
4260 switch (dlp->match_style) {
4261 case MATCH_NONE:
4262 /* Do nothing */
4263 break;
4264 case MATCH_PAIR:
4265 case MATCH_SAME:
4266 /* N directions (NSEW) * 3 dimensions of matching */
4267 fc_assert(count == 2);
4268 number = NUM_CORNER_DIRS * 2 * 2 * 2;
4269 break;
4270 case MATCH_FULL:
4271 default:
4272 /* N directions (NSEW) * 3 dimensions of matching */
4273 /* could use exp() or expi() here? */
4274 number = NUM_CORNER_DIRS * count * count * count;
4275 break;
4276 };
4277
4278 dlp->cells
4279 = fc_calloc(number, sizeof(*dlp->cells));
4280
4281 for (i = 0; i < number; i++) {
4282 enum direction4 dir = i % NUM_CORNER_DIRS;
4283 int value = i / NUM_CORNER_DIRS;
4284
4285 switch (dlp->match_style) {
4286 case MATCH_NONE:
4287 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_cell_%c",
4288 l, draw->name, direction4letters[dir]);
4289 dlp->cells[i]
4290 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4291 NULL, "cell terrain",
4292 terrain_rule_name(pterrain), TRUE);
4293 break;
4294 case MATCH_SAME:
4295 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_cell_%c%d%d%d",
4296 l, draw->name, direction4letters[dir],
4297 (value) & 1, (value >> 1) & 1, (value >> 2) & 1);
4298 dlp->cells[i]
4299 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4300 NULL, "same cell terrain",
4301 terrain_rule_name(pterrain), TRUE);
4302 break;
4303 case MATCH_PAIR:
4304 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s_cell_%c_%c_%c_%c",
4305 l, draw->name, direction4letters[dir],
4306 tslp->match_types[dlp->match_index[(value) & 1]][0],
4307 tslp->match_types[dlp->match_index[(value >> 1) & 1]][0],
4308 tslp->match_types[dlp->match_index[(value >> 2) & 1]][0]);
4309 dlp->cells[i]
4310 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4311 NULL, "cell pair terrain",
4312 terrain_rule_name(pterrain), TRUE);
4313 break;
4314 case MATCH_FULL:
4315 {
4316 int this = dlp->match_index[0];
4317 int n, s, e, w;
4318 int v1, v2, v3;
4319
4320 v1 = dlp->match_index[value % count];
4321 value /= count;
4322 v2 = dlp->match_index[value % count];
4323 value /= count;
4324 v3 = dlp->match_index[value % count];
4325
4326 fc_assert(v1 < count && v2 < count && v3 < count);
4327
4328 /* Assume merged cells. This should be a separate option. */
4329 switch (dir) {
4330 case DIR4_NORTH:
4331 s = this;
4332 w = v1;
4333 n = v2;
4334 e = v3;
4335 break;
4336 case DIR4_EAST:
4337 w = this;
4338 n = v1;
4339 e = v2;
4340 s = v3;
4341 break;
4342 case DIR4_SOUTH:
4343 n = this;
4344 e = v1;
4345 s = v2;
4346 w = v3;
4347 break;
4348 case DIR4_WEST:
4349 default: /* Avoid warnings */
4350 e = this;
4351 s = v1;
4352 w = v2;
4353 n = v3;
4354 break;
4355 };
4356
4357 /* Use first character of match_types,
4358 * already checked for uniqueness. */
4359 fc_snprintf(buffer, sizeof(buffer),
4360 "t.l%d.cellgroup_%c_%c_%c_%c", l,
4361 tslp->match_types[n][0], tslp->match_types[e][0],
4362 tslp->match_types[s][0], tslp->match_types[w][0]);
4363 sprite = load_sprite(t, buffer, TRUE, FALSE, FALSE);
4364
4365 if (sprite) {
4366 /* Crop the sprite to separate this cell. */
4367 int vec_size = sprite_vector_size(&dlp->allocated);
4368
4369 const int W = t->normal_tile_width;
4370 const int H = t->normal_tile_height;
4371 int x[4] = {W / 4, W / 4, 0, W / 2};
4372 int y[4] = {H / 2, 0, H / 4, H / 4};
4373 int xo[4] = {0, 0, -W / 2, W / 2};
4374 int yo[4] = {H / 2, -H / 2, 0, 0};
4375
4376 sprite = crop_sprite(sprite, x[dir], y[dir], W / 2, H / 2,
4377 t->sprites.mask.tile, xo[dir], yo[dir], 1.0f,
4378 FALSE);
4379 /* We allocated new sprite with crop_sprite. Store its
4380 * address so we can free it. */
4381 sprite_vector_reserve(&dlp->allocated, vec_size + 1);
4382 dlp->allocated.p[vec_size] = sprite;
4383 } else {
4384 log_error("Terrain graphics sprite for tag \"%s\" missing.", buffer);
4385 }
4386
4387 dlp->cells[i] = sprite;
4388 }
4389 break;
4390 };
4391 }
4392 }
4393 break;
4394 };
4395 }
4396
4397 /* Try an optional special name */
4398 fc_snprintf(buffer, sizeof(buffer), "t.blend.%s", draw->name);
4399 draw->blender
4401 NULL, "blend terrain",
4402 terrain_rule_name(pterrain), TRUE);
4403
4404 if (draw->blending > 0) {
4405 const int bl = draw->blending - 1;
4406
4407 if (NULL == draw->blender) {
4408 int li = 0;
4409
4410 /* Try an already loaded base */
4411 while (NULL == draw->blender
4412 && li < draw->blending
4413 && 0 < draw->layer[li].base.size) {
4414 draw->blender = draw->layer[li++].base.p[0];
4415 }
4416 }
4417
4418 if (NULL == draw->blender) {
4419 /* Try an unloaded base name */
4420 fc_snprintf(buffer, sizeof(buffer), "t.l%d.%s1", bl, draw->name);
4421 draw->blender
4422 = tiles_lookup_sprite_tag_alt(t, LOG_FATAL, buffer, "",
4423 NULL, "base (blend) terrain",
4424 terrain_rule_name(pterrain), TRUE);
4425 }
4426 }
4427
4428 if (NULL != draw->blender) {
4429 /* Set up blending sprites. This only works in iso-view! */
4430 const int W = t->normal_tile_width;
4431 const int H = t->normal_tile_height;
4432 const int offsets[4][2] = {
4433 {W / 2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}
4434 };
4435 enum direction4 dir = 0;
4436
4437 for (; dir < 4; dir++) {
4438 draw->blend[dir] = crop_sprite(draw->blender, offsets[dir][0],
4439 offsets[dir][1], W / 2, H / 2,
4440 t->sprites.dither_tile, 0, 0, 1.0f,
4441 FALSE);
4442 }
4443 }
4444
4445 draw->init = TRUE;
4446 t->sprites.drawing[terrain_index(pterrain)] = draw;
4447}
4448
4449/************************************************************************/
4454 struct government *gov)
4455{
4458 gov->graphic_alt, NULL, "government",
4460
4461 /* Should probably do something if NULL, eg generic default? */
4462}
4463
4464/************************************************************************/
4469 struct nation_type *nation)
4470{
4471 char *tags[] = {nation->flag_graphic_str,
4472 nation->flag_graphic_alt,
4473 "unknown", NULL};
4474 int i;
4475 struct sprite *flag = NULL, *shield = NULL;
4476 char buf[1024];
4478
4479 for (i = 0; tags[i] && !flag; i++) {
4480 fc_snprintf(buf, sizeof(buf), "f.%s", tags[i]);
4481 flag = load_sprite(t, buf, TRUE, TRUE, svgflag);
4482 }
4483 for (i = 0; tags[i] && !shield; i++) {
4484 fc_snprintf(buf, sizeof(buf), "f.shield.%s", tags[i]);
4485 shield = load_sprite(t, buf, TRUE, TRUE, svgflag);
4486 }
4487 if (!flag || !shield) {
4488 /* Should never get here because of the f.unknown fallback. */
4490 _("Nation %s: no national flag."), nation_rule_name(nation));
4491 }
4492
4494 t->sprites.nation_flag.p[nation_index(nation)] = flag;
4495
4497 t->sprites.nation_shield.p[nation_index(nation)] = shield;
4498}
4499
4500/************************************************************************/
4503struct sprite *get_city_flag_sprite(const struct tileset *t,
4504 const struct city *pcity)
4505{
4506 return get_nation_flag_sprite(t, nation_of_city(pcity));
4507}
4508
4509/************************************************************************/
4512static struct sprite *get_unit_nation_flag_sprite(const struct tileset *t,
4513 const struct unit *punit)
4514{
4515 struct nation_type *pnation = nation_of_unit(punit);
4516
4518 return t->sprites.nation_shield.p[nation_index(pnation)];
4519 } else {
4520 return t->sprites.nation_flag.p[nation_index(pnation)];
4521 }
4522}
4523
4524#define FULL_TILE_X_OFFSET ((t->normal_tile_width - t->full_tile_width) / 2)
4525#define FULL_TILE_Y_OFFSET (t->normal_tile_height - t->full_tile_height)
4526
4527#define ADD_SPRITE(s, draw_fog, x_offset, y_offset) \
4528 (fc_assert(s != NULL), \
4529 sprs->sprite = s, \
4530 sprs->foggable = (draw_fog && t->fogstyle == FOG_AUTO), \
4531 sprs->offset_x = x_offset, \
4532 sprs->offset_y = y_offset, \
4533 sprs++)
4534#define ADD_SPRITE_SIMPLE(s) ADD_SPRITE(s, TRUE, 0, 0)
4535#define ADD_SPRITE_FULL(s) \
4536 ADD_SPRITE(s, TRUE, FULL_TILE_X_OFFSET, FULL_TILE_Y_OFFSET)
4537
4538/************************************************************************/
4545static void build_tile_data(const struct tile *ptile,
4546 struct terrain *pterrain,
4547 struct terrain **tterrain_near,
4549{
4550 enum direction8 dir;
4551
4552 /* Loop over all adjacent tiles. We should have an iterator for this. */
4553 for (dir = 0; dir < 8; dir++) {
4554 struct tile *tile1 = mapstep(&(wld.map), ptile, dir);
4555
4558
4559 if (NULL != terrain1) {
4560 tterrain_near[dir] = terrain1;
4562 continue;
4563 }
4564 log_error("build_tile_data() tile (%d,%d) has no terrain!",
4565 TILE_XY(tile1));
4566 }
4567 /* At the edges of the (known) map, pretend the same terrain continued
4568 * past the edge of the map. */
4569 tterrain_near[dir] = pterrain;
4571 }
4572}
4573
4574/************************************************************************/
4577static int fill_unit_type_sprite_array(const struct tileset *t,
4578 struct drawn_sprite *sprs,
4579 const struct unit_type *putype,
4580 enum unit_activity activity,
4581 enum direction8 facing)
4582{
4583 struct drawn_sprite *save_sprs = sprs;
4584 struct sprite *uspr = get_unittype_sprite(t, putype, activity, facing);
4585
4589
4590 return sprs - save_sprs;
4591}
4592
4593/************************************************************************/
4596static int fill_unit_sprite_array(const struct tileset *t,
4597 struct drawn_sprite *sprs,
4598 const struct unit *punit,
4599 int stack, bool backdrop)
4600{
4601 struct drawn_sprite *save_sprs = sprs;
4602 int ihp;
4603 const struct unit_type *ptype = unit_type_get(punit);
4604
4605 if (backdrop) {
4611 }
4612 } else {
4613 /* Taken care of in the LAYER_BACKGROUND. */
4614 }
4615 }
4616
4617 /* Add the sprite for the unit type. */
4620
4621 if (t->sprites.unit.loaded && unit_transported(punit)) {
4622 ADD_SPRITE_FULL(t->sprites.unit.loaded);
4623 }
4624
4625 if (punit->activity != ACTIVITY_IDLE) {
4626 struct sprite *s = NULL;
4627
4628 switch (punit->activity) {
4629 case ACTIVITY_MINE:
4630 if (punit->activity_target == NULL) {
4631 s = t->sprites.unit.plant;
4632 } else {
4634 }
4635 break;
4636 case ACTIVITY_PLANT:
4637 s = t->sprites.unit.plant;
4638 break;
4639 case ACTIVITY_IRRIGATE:
4640 if (punit->activity_target == NULL) {
4641 s = t->sprites.unit.cultivate;
4642 } else {
4644 }
4645 break;
4646 case ACTIVITY_CULTIVATE:
4647 s = t->sprites.unit.cultivate;
4648 break;
4649 case ACTIVITY_CLEAN:
4651 break;
4652 case ACTIVITY_PILLAGE:
4654 if (s == NULL) {
4655 s = t->sprites.unit.pillage;
4656 }
4657 break;
4658 case ACTIVITY_EXPLORE:
4659 /* Drawn below as the server side agent. */
4660 break;
4661 case ACTIVITY_FORTIFIED:
4662 s = t->sprites.unit.fortified;
4663 break;
4665 s = t->sprites.unit.fortifying;
4666 break;
4667 case ACTIVITY_SENTRY:
4668 s = t->sprites.unit.sentry;
4669 break;
4670 case ACTIVITY_GOTO:
4671 s = t->sprites.unit.go_to;
4672 break;
4673 case ACTIVITY_TRANSFORM:
4674 s = t->sprites.unit.transform;
4675 break;
4676 case ACTIVITY_BASE:
4677 case ACTIVITY_GEN_ROAD:
4679 break;
4680 case ACTIVITY_CONVERT:
4681 s = t->sprites.unit.convert;
4682 break;
4683 default:
4684 break;
4685 }
4686
4687 if (s != NULL) {
4690 }
4691 }
4692
4693 {
4694 struct sprite *s = NULL;
4695 int offset_x = 0;
4696 int offset_y = 0;
4697
4698 switch (punit->ssa_controller) {
4699 case SSA_NONE:
4700 break;
4701 case SSA_AUTOWORKER:
4702 s = t->sprites.unit.auto_worker;
4703 break;
4704 case SSA_AUTOEXPLORE:
4705 s = t->sprites.unit.auto_explore;
4706 /* Specified as an activity in the tileset. */
4709 break;
4710 default:
4711 s = t->sprites.unit.auto_attack;
4712 break;
4713 }
4714
4715 if (s != NULL) {
4716 ADD_SPRITE(s, TRUE,
4719 }
4720 }
4721
4722 if (unit_has_orders(punit)) {
4723 if (punit->orders.repeat) {
4724 ADD_SPRITE_FULL(t->sprites.unit.patrol);
4725 } else if (punit->activity != ACTIVITY_IDLE) {
4726 ADD_SPRITE_SIMPLE(t->sprites.unit.connect);
4727 } else {
4728 ADD_SPRITE(t->sprites.unit.go_to, TRUE,
4731 }
4732 }
4733
4734 if (t->sprites.unit.action_decision_want != NULL
4736 ADD_SPRITE(t->sprites.unit.action_decision_want, TRUE,
4739 }
4740
4742 ADD_SPRITE_FULL(t->sprites.unit.battlegroup[punit->battlegroup]);
4743 }
4744
4745 if (t->sprites.unit.lowfuel
4746 && utype_fuel(ptype)
4747 && punit->fuel == 1
4748 && punit->moves_left <= 2 * SINGLE_MOVE) {
4749 /* Show a low-fuel graphic if the plane has 2 or fewer moves left. */
4750 ADD_SPRITE_FULL(t->sprites.unit.lowfuel);
4751 }
4752 if (t->sprites.unit.tired
4754 && ptype->move_rate > 0) {
4755 /* Show a "tired" graphic if the unit has fewer than one move
4756 * remaining, except for units for which it's full movement. */
4757 ADD_SPRITE_FULL(t->sprites.unit.tired);
4758 }
4759
4760 if (stack == 1 && punit->client.occupied) {
4761 ADD_SPRITE_FULL(t->sprites.unit.stack[0]);
4762 } else if (stack > 1) {
4764 && t->sprites.unit.num_stack_sprites >= stack) {
4765 ADD_SPRITE(t->sprites.unit.stack[stack - 1], FALSE,
4767 } else {
4768 ADD_SPRITE_FULL(t->sprites.unit.stack[0]);
4769 }
4770 }
4771
4772 if (t->sprites.unit.vet_lev[punit->veteran]) {
4774 }
4775
4776 ihp = ((NUM_TILES_HP_BAR-1)*punit->hp) / ptype->hp;
4777 ihp = CLIP(0, ihp, NUM_TILES_HP_BAR-1);
4778 ADD_SPRITE_FULL(t->sprites.unit.hp_bar[ihp]);
4779
4780 return sprs - save_sprs;
4781}
4782
4783/************************************************************************/
4786static int fill_road_corner_sprites(const struct tileset *t,
4787 const struct extra_type *pextra,
4788 struct drawn_sprite *sprs,
4789 bool road, bool *road_near,
4790 bool hider, bool *hider_near)
4791{
4792 struct drawn_sprite *saved_sprs = sprs;
4793 int i;
4794 int extra_idx = extra_index(pextra);
4795
4796 if (is_cardinal_only_road(pextra)) {
4797 return 0;
4798 }
4799
4800 /* Roads going diagonally adjacent to this tile need to be
4801 * partly drawn on this tile. */
4802
4803 /* Draw the corner sprite if:
4804 * - There is a diagonal road (not rail!) between two adjacent tiles.
4805 * - There is no diagonal road (not rail!) that intersects this road.
4806 * The logic is simple: roads are drawn underneath railrods, but are
4807 * not always covered by them (even in the corners!). But if a railroad
4808 * connects two tiles, only the railroad (no road) is drawn between
4809 * those tiles.
4810 */
4811 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4812 enum direction8 dir = t->valid_tileset_dirs[i];
4813
4814 if (!is_cardinal_tileset_dir(t, dir)) {
4815 /* Draw corner sprites for this non-cardinal direction. */
4816 int cw = (i + 1) % t->num_valid_tileset_dirs;
4817 int ccw
4819 enum direction8 cwdir = t->valid_tileset_dirs[cw];
4821
4822 if (t->sprites.extras[extra_idx].u.road.corner[dir]
4824 && !(hider_near[cwdir] && hider_near[ccwdir]))
4825 && !(road && road_near[dir] && !(hider && hider_near[dir]))) {
4827 }
4828 }
4829 }
4830
4831 return sprs - saved_sprs;
4832}
4833
4834/************************************************************************/
4837static int fill_road_sprite_array(const struct tileset *t,
4838 const struct extra_type *pextra,
4839 struct drawn_sprite *sprs,
4842 struct terrain *tterrain_near[8],
4843 const struct city *pcity)
4844{
4845 struct drawn_sprite *saved_sprs = sprs;
4846 bool road, road_near[8], hider, hider_near[8];
4847 bool land_near[8], hland_near[8];
4848 bool draw_road[8], draw_single_road;
4849 enum direction8 dir;
4850 int extra_idx = -1;
4851 bool cl = FALSE;
4852 enum extrastyle_id extrastyle;
4853 const struct road_type *proad = extra_road_get(pextra);
4854
4855 extra_idx = extra_index(pextra);
4856
4857 extrastyle = t->sprites.extras[extra_idx].extrastyle;
4858
4859 if (extra_has_flag(pextra, EF_CONNECT_LAND)) {
4860 cl = TRUE;
4861 } else {
4862 int i;
4863
4864 for (i = 0; i < 8; i++) {
4865 land_near[i] = FALSE;
4866 }
4867 }
4868
4869 /* Fill some data arrays. rail_near and road_near store whether road/rail
4870 * is present in the given direction. draw_rail and draw_road store
4871 * whether road/rail is to be drawn in that direction. draw_single_road
4872 * and draw_single_rail store whether we need an isolated road/rail to be
4873 * drawn. */
4875
4876 hider = FALSE;
4879 hider = TRUE;
4880 break;
4881 }
4883
4884 if (road && (!pcity || !gui_options.draw_cities) && !hider) {
4886 } else {
4888 }
4889
4890 for (dir = 0; dir < 8; dir++) {
4891 bool roads_exist;
4892
4893 /* Check if there is adjacent road/rail. */
4894 if (!is_cardinal_only_road(pextra)
4895 || is_cardinal_tileset_dir(t, dir)) {
4896 road_near[dir] = FALSE;
4897 extra_type_list_iterate(proad->integrators, iextra) {
4899 road_near[dir] = TRUE;
4900 break;
4901 }
4903 if (cl) {
4904 land_near[dir] = (tterrain_near[dir] != T_UNKNOWN
4906 }
4907 } else {
4908 road_near[dir] = FALSE;
4909 land_near[dir] = FALSE;
4910 }
4911
4912 /* Draw rail/road if there is a connection from this tile to the
4913 * adjacent tile. But don't draw road if there is also a rail
4914 * connection. */
4915 roads_exist = road && (road_near[dir] || land_near[dir]);
4916 draw_road[dir] = roads_exist;
4917 hider_near[dir] = FALSE;
4918 hland_near[dir] = tterrain_near[dir] != T_UNKNOWN
4921 bool hider_dir = FALSE;
4922 bool land_dir = FALSE;
4923
4925 || is_cardinal_tileset_dir(t, dir)) {
4927 hider_near[dir] = TRUE;
4928 hider_dir = TRUE;
4929 }
4930 if (hland_near[dir]
4933 land_dir = TRUE;
4934 }
4935 if (hider_dir || land_dir) {
4937 draw_road[dir] = FALSE;
4938 }
4939 }
4940 }
4942
4943 /* Don't draw an isolated road/rail if there's any connection.
4944 * draw_single_road would be true in the first place only if start tile has road,
4945 * so it will have road connection with any adjacent road tile. We check from real
4946 * existence of road (road_near[dir]) and not from whether road gets drawn (draw_road[dir])
4947 * as latter can be FALSE when road is simply hidden by another one, and we don't want to
4948 * draw single road in that case either. */
4949 if (draw_single_road && road_near[dir]) {
4951 }
4952 }
4953
4954 /* Draw road corners */
4955 sprs
4957
4958 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE) {
4959 /* With ESTYLE_ROAD_ALL_SEPARATE, we simply draw one road for every connection.
4960 * This means we only need a few sprites, but a lot of drawing is
4961 * necessary and it generally doesn't look very good. */
4962 int i;
4963
4964 /* First draw roads under rails. */
4965 if (road) {
4966 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
4967 if (draw_road[t->valid_tileset_dirs[i]]) {
4969 }
4970 }
4971 }
4972 } else if (extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
4973 /* With ESTYLE_ROAD_PARITY_COMBINED, we draw one sprite for cardinal
4974 * road connections, one sprite for diagonal road connections.
4975 * This means we need about 4x more sprites than in style 0, but up to
4976 * 4x less drawing is needed. The drawing quality may also be
4977 * improved. */
4978
4979 /* First draw roads under rails. */
4980 if (road) {
4981 int road_even_tileno = 0, road_odd_tileno = 0, i;
4982
4983 for (i = 0; i < t->num_valid_tileset_dirs / 2; i++) {
4984 enum direction8 even = t->valid_tileset_dirs[2 * i];
4985 enum direction8 odd = t->valid_tileset_dirs[2 * i + 1];
4986
4987 if (draw_road[even]) {
4988 road_even_tileno |= 1 << i;
4989 }
4990 if (draw_road[odd]) {
4991 road_odd_tileno |= 1 << i;
4992 }
4993 }
4994
4995 /* Draw the cardinal/even roads first. */
4996 if (road_even_tileno != 0) {
4998 }
4999 if (road_odd_tileno != 0) {
5001 }
5002 }
5003 } else if (extrastyle == ESTYLE_ROAD_ALL_COMBINED) {
5004 /* RSTYLE_ALL_COMBINED is a very simple method that lets us simply retrieve
5005 * entire finished tiles, with a bitwise index of the presence of
5006 * roads in each direction. */
5007
5008 /* Draw roads first */
5009 if (road) {
5010 int road_tileno = 0, i;
5011
5012 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
5014
5015 if (draw_road[vdir]) {
5016 road_tileno |= 1 << i;
5017 }
5018 }
5019
5020 if (road_tileno != 0 || draw_single_road) {
5022 }
5023 }
5024 } else {
5026 }
5027
5028 /* Draw isolated rail/road separately (ESTYLE_ROAD_ALL_SEPARATE and
5029 ESTYLE_ROAD_PARITY_COMBINED only). */
5030 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE
5031 || extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
5032 if (draw_single_road) {
5034 }
5035 }
5036
5037 return sprs - saved_sprs;
5038}
5039
5040/************************************************************************/
5049static int get_irrigation_index(const struct tileset *t,
5050 struct extra_type *pextra,
5052{
5053 int tileno = 0, i;
5054
5055 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5056 enum direction8 dir = t->cardinal_tileset_dirs[i];
5057
5058 if (BV_ISSET(textras_near[dir], extra_index(pextra))) {
5059 tileno |= 1 << i;
5060 }
5061 }
5062
5063 return tileno;
5064}
5065
5066/************************************************************************/
5069static int fill_irrigation_sprite_array(const struct tileset *t,
5070 struct drawn_sprite *sprs,
5073 const struct city *pcity)
5074{
5075 struct drawn_sprite *saved_sprs = sprs;
5076
5077 /* We don't draw the irrigation if there's a city (it just gets overdrawn
5078 * anyway, and ends up looking bad). */
5079 if (!(pcity && gui_options.draw_cities)) {
5081 if (is_extra_drawing_enabled(pextra)) {
5082 int eidx = extra_index(pextra);
5083
5084 if (BV_ISSET(textras, eidx)) {
5085 bool hidden = FALSE;
5086
5087 extra_type_list_iterate(pextra->hiders, phider) {
5089 hidden = TRUE;
5090 break;
5091 }
5093
5094 if (!hidden) {
5095 int idx = get_irrigation_index(t, pextra, textras_near);
5096
5098 }
5099 }
5100 }
5102 }
5103
5104 return sprs - saved_sprs;
5105}
5106
5107/************************************************************************/
5111static int fill_city_overlays_sprite_array(const struct tileset *t,
5112 struct drawn_sprite *sprs,
5113 const struct tile *ptile,
5114 const struct city *citymode)
5115{
5116 const struct city *pcity;
5117 const struct city *pwork;
5118 struct unit *psettler;
5119 struct drawn_sprite *saved_sprs = sprs;
5120 int city_x, city_y;
5121 const int NUM_CITY_COLORS = t->sprites.city.worked_tile_overlay.size;
5122
5123 if (NULL == ptile || TILE_UNKNOWN == client_tile_get_known(ptile)) {
5124 return 0;
5125 }
5126 pwork = tile_worked(ptile);
5127
5128 if (citymode) {
5129 pcity = citymode;
5130 } else {
5132 }
5133
5134 /* Below code does not work if pcity is invisible.
5135 * Make sure it is not. */
5136 fc_assert_ret_val(pcity == NULL || pcity->tile != NULL, 0);
5137 if (pcity && !pcity->tile) {
5138 pcity = NULL;
5139 }
5140
5141 if (pcity && city_base_to_city_map(&city_x, &city_y, pcity, ptile)) {
5142 /* FIXME: check elsewhere for valid tile (instead of above) */
5143
5144 if (!citymode && pcity->client.colored) {
5145 /* Add citymap overlay for a city. */
5146 int idx = pcity->client.color_index % NUM_CITY_COLORS;
5147
5148 if (NULL != pwork && pwork == pcity) {
5150 } else if (city_can_work_tile(pcity, ptile)) {
5152 }
5153 } else if (NULL != pwork && pwork == pcity
5155
5156 /* Add on the tile output sprites.
5157 * NOTE: To show correct output on end of turn
5158 * base_city_celebrating() must be used instead of city_celebrating()
5159 * mirroring the behavior of the server that does so in
5160 * city_tile_cache_update(). */
5161 bool celebrating = base_city_celebrating(pcity);
5162 int food = city_tile_output(pcity, ptile, celebrating, O_FOOD);
5163 int shields = city_tile_output(pcity, ptile, celebrating, O_SHIELD);
5164 int trade = city_tile_output(pcity, ptile, celebrating, O_TRADE);
5165
5166 const int ox = t->type == TS_ISOMETRIC ? t->normal_tile_width / 3 : 0;
5167 const int oy = t->type == TS_ISOMETRIC ? -t->normal_tile_height / 3 : 0;
5168
5169 food = CLIP(0, food / game.info.granularity, NUM_TILES_DIGITS - 1);
5170 shields = CLIP(0, shields / game.info.granularity, NUM_TILES_DIGITS - 1);
5171 trade = CLIP(0, trade / game.info.granularity, NUM_TILES_DIGITS - 1);
5172
5174 ADD_SPRITE(t->sprites.city.tile_shieldnum[shields], TRUE, ox, oy);
5176 }
5177 } else if (psettler && psettler->client.colored) {
5178 /* Add citymap overlay for a unit. */
5179 int idx = psettler->client.color_index % NUM_CITY_COLORS;
5180
5182 }
5183
5184 return sprs - saved_sprs;
5185}
5186
5187/************************************************************************/
5191static int fill_terrain_sprite_blending(const struct tileset *t,
5192 struct drawn_sprite *sprs,
5193 const struct tile *ptile,
5194 const struct terrain *pterrain,
5195 struct terrain **tterrain_near)
5196{
5197 struct drawn_sprite *saved_sprs = sprs;
5198 const int W = t->normal_tile_width, H = t->normal_tile_height;
5199 const int offsets[4][2] = {
5200 {W/2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}
5201 };
5202 enum direction4 dir = 0;
5203
5204 /*
5205 * We want to mark unknown tiles so that an unreal tile will be
5206 * given the same marking as our current tile - that way we won't
5207 * get the "unknown" dither along the edge of the map.
5208 */
5209 for (; dir < 4; dir++) {
5210 struct tile *tile1 = mapstep(&(wld.map), ptile, DIR4_TO_DIR8[dir]);
5211 struct terrain *other;
5212
5213 if (!tile1
5215 || pterrain == (other = tterrain_near[DIR4_TO_DIR8[dir]])
5216 || (0 == t->sprites.drawing[terrain_index(other)]->blending
5217 && NULL == t->sprites.drawing[terrain_index(other)]->blender)) {
5218 continue;
5219 }
5220
5222 offsets[dir][0], offsets[dir][1]);
5223 }
5224
5225 return sprs - saved_sprs;
5226}
5227
5228/************************************************************************/
5231static int fill_fog_sprite_array(const struct tileset *t,
5232 struct drawn_sprite *sprs,
5233 const struct tile *ptile,
5234 const struct tile_edge *pedge,
5235 const struct tile_corner *pcorner)
5236{
5237 struct drawn_sprite *saved_sprs = sprs;
5238
5240 && NULL != ptile
5242 /* With FOG_AUTO, fog is done this way. */
5244 }
5245
5248 int i, tileno = 0;
5249
5250 for (i = 3; i >= 0; i--) {
5251 const int unknown = 0, fogged = 1, known = 2;
5252 int value = -1;
5253
5254 if (!pcorner->tile[i]) {
5255 value = fogged;
5256 } else {
5257 switch (client_tile_get_known(pcorner->tile[i])) {
5258 case TILE_KNOWN_SEEN:
5259 value = known;
5260 break;
5261 case TILE_KNOWN_UNSEEN:
5262 value = fogged;
5263 break;
5264 case TILE_UNKNOWN:
5265 value = unknown;
5266 break;
5267 }
5268 }
5269 fc_assert(value >= 0 && value < 3);
5270
5271 tileno = tileno * 3 + value;
5272 }
5273
5274 if (t->sprites.tx.fullfog[tileno]) {
5276 }
5277 }
5278
5279 return sprs - saved_sprs;
5280}
5281
5282/************************************************************************/
5286 struct drawn_sprite *sprs,
5287 int l, /* layer_num */
5288 const struct tile *ptile,
5289 const struct terrain *pterrain,
5290 struct terrain **tterrain_near,
5291 struct drawing_data *draw)
5292{
5293 struct drawn_sprite *saved_sprs = sprs;
5294 struct drawing_layer *dlp = &draw->layer[l];
5295 int this = dlp->match_index[0];
5296 int that = dlp->match_index[1];
5297 int ox = dlp->offset_x;
5298 int oy = dlp->offset_y;
5299 int i;
5300
5301#define MATCH(dir) \
5302 (t->sprites.drawing[terrain_index(tterrain_near[(dir)])]->num_layers > l \
5303 ? t->sprites.drawing[terrain_index(tterrain_near[(dir)])]->layer[l].match_index[0] \
5304 : -1)
5305
5306 switch (dlp->sprite_type) {
5307 case CELL_WHOLE:
5308 {
5309 switch (dlp->match_style) {
5310 case MATCH_NONE:
5311 {
5312 int count = sprite_vector_size(&dlp->base);
5313
5314 if (count > 0) {
5315 /* Pseudo-random reproducable algorithm to pick a sprite. Use modulo
5316 * to limit the number to a handleable size [0..32000). */
5317 count = fc_randomly(tile_index(ptile) % 32000, count);
5318
5319 if (dlp->is_tall) {
5322 }
5323 ADD_SPRITE(dlp->base.p[count], TRUE, ox, oy);
5324 }
5325 break;
5326 }
5327 case MATCH_SAME:
5328 {
5329 int tileno = 0;
5330
5331 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5332 enum direction8 dir = t->cardinal_tileset_dirs[i];
5333
5334 if (MATCH(dir) == this) {
5335 tileno |= 1 << i;
5336 }
5337 }
5338
5339 if (dlp->is_tall) {
5342 }
5343 ADD_SPRITE(dlp->match[tileno], TRUE, ox, oy);
5344 break;
5345 }
5346 case MATCH_PAIR:
5347 case MATCH_FULL:
5348 fc_assert(FALSE); /* Not yet defined */
5349 break;
5350 };
5351 break;
5352 }
5353 case CELL_CORNER:
5354 {
5355 /* Divide the tile up into four rectangular cells. Each of these
5356 * cells covers one corner, and each is adjacent to 3 different
5357 * tiles. For each cell we pick a sprite based upon the adjacent
5358 * terrains at each of those tiles. Thus, we have 8 different sprites
5359 * for each of the 4 cells (32 sprites total).
5360 *
5361 * These arrays correspond to the direction4 ordering. */
5362 const int W = t->normal_tile_width;
5363 const int H = t->normal_tile_height;
5364 const int iso_offsets[4][2] = {
5365 {W / 4, 0}, {W / 4, H / 2}, {W / 2, H / 4}, {0, H / 4}
5366 };
5367 const int noniso_offsets[4][2] = {
5368 {0, 0}, {W / 2, H / 2}, {W / 2, 0}, {0, H / 2}
5369 };
5370
5371 /* Put corner cells */
5372 for (i = 0; i < NUM_CORNER_DIRS; i++) {
5373 const int count = dlp->match_indices;
5374 int array_index = 0;
5375 enum direction8 dir = dir_ccw(DIR4_TO_DIR8[i]);
5376 int x = (t->type == TS_ISOMETRIC ? iso_offsets[i][0] : noniso_offsets[i][0]);
5377 int y = (t->type == TS_ISOMETRIC ? iso_offsets[i][1] : noniso_offsets[i][1]);
5378 int m[3] = {MATCH(dir_ccw(dir)), MATCH(dir), MATCH(dir_cw(dir))};
5379 struct sprite *s;
5380
5381 /* Synthesize 4 dimensional array? */
5382 switch (dlp->match_style) {
5383 case MATCH_NONE:
5384 /* We have no need for matching, just plug the piece in place. */
5385 break;
5386 case MATCH_SAME:
5387 array_index = array_index * 2 + (m[2] != this);
5388 array_index = array_index * 2 + (m[1] != this);
5389 array_index = array_index * 2 + (m[0] != this);
5390 break;
5391 case MATCH_PAIR:
5392 array_index = array_index * 2 + (m[2] == that);
5393 array_index = array_index * 2 + (m[1] == that);
5394 array_index = array_index * 2 + (m[0] == that);
5395 break;
5396 case MATCH_FULL:
5397 default:
5398 if (count > 0) {
5399 int n[3];
5400 int j;
5401
5402 for (j = 0; j < 3; j++) {
5403 int k;
5404
5405 for (k = 0; k < count; k++) {
5406 n[j] = k; /* Default to last entry */
5407 if (m[j] == dlp->match_index[k]) {
5408 break;
5409 }
5410 }
5411 }
5412 array_index = array_index * count + n[2];
5413 array_index = array_index * count + n[1];
5414 array_index = array_index * count + n[0];
5415 }
5416 break;
5417 };
5418
5420
5421 s = dlp->cells[array_index];
5422 if (s) {
5423 ADD_SPRITE(s, TRUE, x, y);
5424 }
5425 }
5426 break;
5427 }
5428 };
5429#undef MATCH
5430
5431 return sprs - saved_sprs;
5432}
5433
5434/************************************************************************/
5439 struct drawn_sprite *sprs,
5440 const struct tile *ptile,
5441 struct terrain **tterrain_near)
5442{
5443 struct drawn_sprite *saved_sprs = sprs;
5444 int i, tileno;
5445 struct tile *adjc_tile;
5446
5447#define UNKNOWN(dir) \
5448 ((adjc_tile = mapstep(&(wld.map), ptile, (dir))) \
5449 && client_tile_get_known(adjc_tile) == TILE_UNKNOWN)
5450
5451 switch (t->darkness_style) {
5452 case DARKNESS_NONE:
5453 break;
5454 case DARKNESS_ISORECT:
5455 for (i = 0; i < 4; i++) {
5456 const int W = t->normal_tile_width, H = t->normal_tile_height;
5457 int offsets[4][2] = {{W / 2, 0}, {0, H / 2}, {W / 2, H / 2}, {0, 0}};
5458
5459 if (UNKNOWN(DIR4_TO_DIR8[i])) {
5461 offsets[i][0], offsets[i][1]);
5462 }
5463 }
5464 break;
5466 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5467 if (UNKNOWN(t->cardinal_tileset_dirs[i])) {
5469 }
5470 }
5471 break;
5472 case DARKNESS_CARD_FULL:
5473 /* We're looking to find the INDEX_NSEW for the directions that
5474 * are unknown. We want to mark unknown tiles so that an unreal
5475 * tile will be given the same marking as our current tile - that
5476 * way we won't get the "unknown" dither along the edge of the
5477 * map. */
5478 tileno = 0;
5479 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
5480 if (UNKNOWN(t->cardinal_tileset_dirs[i])) {
5481 tileno |= 1 << i;
5482 }
5483 }
5484
5485 if (tileno != 0) {
5487 }
5488 break;
5489 case DARKNESS_CORNER:
5490 /* Handled separately. */
5491 break;
5492 };
5493#undef UNKNOWN
5494
5495 return sprs - saved_sprs;
5496}
5497
5498/************************************************************************/
5503 struct drawn_sprite *sprs,
5504 int layer_num,
5505 const struct tile *ptile,
5506 const struct terrain *pterrain,
5507 struct terrain **tterrain_near)
5508{
5509 struct sprite *sprite;
5510 struct drawn_sprite *saved_sprs = sprs;
5511 struct drawing_data *draw = t->sprites.drawing[terrain_index(pterrain)];
5512 const int l = (draw->is_reversed
5513 ? (draw->num_layers - layer_num - 1) : layer_num);
5514
5516
5517 /* Skip the normal drawing process. */
5518 /* FIXME: this should avoid calling load_sprite since it's slow and
5519 * increases the refcount without limit. */
5520 if (ptile->spec_sprite && (sprite = load_sprite(t, ptile->spec_sprite,
5521 TRUE, FALSE, FALSE))) {
5522 if (l == 0) {
5524 return 1;
5525 } else {
5526 return 0;
5527 }
5528 }
5529
5531 sprs += fill_terrain_sprite_array(t, sprs, l, ptile, pterrain, tterrain_near, draw);
5532
5533 if ((l + 1) == draw->blending) {
5534 sprs += fill_terrain_sprite_blending(t, sprs, ptile, pterrain, tterrain_near);
5535 }
5536 }
5537
5538 return sprs - saved_sprs;
5539}
5540
5541/************************************************************************/
5548{
5549 /* Display an outline for city-builder type units if they are selected,
5550 * and on a tile where a city can be built.
5551 * But suppress the outline if the unit has orders (likely it is in
5552 * transit to somewhere else and this will just slow down redraws). */
5559}
5560
5561/************************************************************************/
5564static int fill_grid_sprite_array(const struct tileset *t,
5565 struct drawn_sprite *sprs,
5566 const struct tile *ptile,
5567 const struct tile_edge *pedge,
5568 const struct tile_corner *pcorner,
5569 const struct unit *punit,
5570 const struct city *pcity,
5571 const struct city *citymode)
5572{
5573 struct drawn_sprite *saved_sprs = sprs;
5574
5575 if (pedge) {
5576 bool known[NUM_EDGE_TILES], city[NUM_EDGE_TILES];
5577 bool unit[NUM_EDGE_TILES], worked[NUM_EDGE_TILES];
5578 int i;
5579 struct unit_list *pfocus_units = get_units_in_focus();
5580
5581 for (i = 0; i < NUM_EDGE_TILES; i++) {
5582 int dummy_x, dummy_y;
5583 const struct tile *tile = pedge->tile[i];
5584 struct player *powner = tile ? tile_owner(tile) : NULL;
5585
5587 unit[i] = FALSE;
5588 if (tile && !citymode) {
5591 struct tile *utile = unit_tile(pfocus_unit);
5592 int radius = game.info.init_city_radius_sq
5594 NULL,
5595 &(const struct req_context) {
5596 .player = unit_owner(pfocus_unit),
5597 .tile = utile,
5598 },
5599 NULL,
5601 );
5602
5603 if (city_tile_to_city_map(&dummy_x, &dummy_y, radius,
5604 utile, tile)) {
5605 unit[i] = TRUE;
5606 break;
5607 }
5608 }
5610 }
5611 worked[i] = FALSE;
5612
5613 city[i] = (tile
5614 && (NULL == powner || NULL == client.conn.playing
5615 || powner == client.conn.playing)
5617 if (city[i]) {
5618 if (citymode) {
5619 /* In citymode, we only draw worked tiles for this city - other
5620 * tiles may be marked as unavailable. */
5621 worked[i] = (tile_worked(tile) == citymode);
5622 } else {
5623 worked[i] = (NULL != tile_worked(tile));
5624 }
5625 }
5626 }
5627
5628 if (mapdeco_is_highlight_set(pedge->tile[0])
5629 || mapdeco_is_highlight_set(pedge->tile[1])) {
5632 && pedge->tile[0] && pedge->tile[1]
5633 && known[0] && known[1]
5634 && (is_ocean_tile(pedge->tile[0])
5635 ^ is_ocean_tile(pedge->tile[1]))) {
5637 } else {
5639 if (worked[0] || worked[1]) {
5641 } else if (city[0] || city[1]) {
5643 } else if (known[0] || known[1]) {
5645 }
5646 }
5648 if (XOR(city[0], city[1])) {
5650 }
5651 if (XOR(unit[0], unit[1])) {
5653 }
5654 }
5655 }
5656
5659 && known[0]
5660 && known[1]) {
5661 struct player *owner0 = tile_owner(pedge->tile[0]);
5662 struct player *owner1 = tile_owner(pedge->tile[1]);
5663
5664 if (owner0 != owner1) {
5665 if (owner0) {
5666 int plrid = player_index(owner0);
5668 [pedge->type][0]);
5669 }
5670 if (owner1) {
5671 int plrid = player_index(owner1);
5673 [pedge->type][1]);
5674 }
5675 }
5676 }
5677 } else if (NULL != ptile && TILE_UNKNOWN != client_tile_get_known(ptile)) {
5678 int cx, cy;
5679
5680 if (citymode
5681 /* Test to ensure valid coordinates? */
5682 && city_base_to_city_map(&cx, &cy, citymode, ptile)
5683 && !client_city_can_work_tile(citymode, ptile)) {
5685 }
5686
5688 bool native = TRUE;
5689 struct unit_list *pfocus_units = get_units_in_focus();
5690
5692 if (!is_native_tile(unit_type_get(pfocus), ptile)) {
5693 native = FALSE;
5694 break;
5695 }
5697
5698 if (!native) {
5699 if (t->sprites.grid.nonnative != NULL) {
5701 } else {
5703 }
5704 }
5705 }
5706 }
5707
5708 return sprs - saved_sprs;
5709}
5710
5711/************************************************************************/
5714static int fill_goto_sprite_array(const struct tileset *t,
5715 struct drawn_sprite *sprs,
5716 const struct tile *ptile,
5717 const struct tile_edge *pedge,
5718 const struct tile_corner *pcorner)
5719{
5720 struct drawn_sprite *saved_sprs = sprs;
5721 struct sprite *sprite;
5722 bool warn = FALSE;
5723 enum goto_tile_state state;
5724 int length;
5725 bool waypoint;
5726
5727 if (goto_tile_state(ptile, &state, &length, &waypoint)) {
5728 if (length >= 0) {
5729 fc_assert(state >= 0);
5730 fc_assert(state < ARRAY_SIZE(t->sprites.path.s));
5731
5732 sprite = t->sprites.path.s[state].specific;
5733 if (sprite != NULL) {
5734 ADD_SPRITE(sprite, FALSE, 0, 0);
5735 }
5736
5737 sprite = t->sprites.path.s[state].turns[length % 10];
5739 if (length >= 10) {
5740 sprite = t->sprites.path.s[state].turns_tens[(length / 10) % 10];
5742 if (length >= 100) {
5743 sprite = t->sprites.path.s[state].turns_hundreds[(length / 100)
5744 % 10];
5745
5746 if (sprite != NULL) {
5748 if (length >= 1000) {
5749 warn = TRUE;
5750 }
5751 } else {
5752 warn = TRUE;
5753 }
5754 }
5755 }
5756 }
5757
5758 if (waypoint) {
5760 }
5761
5762 if (warn) {
5763 /* Warn only once by tileset. */
5764 static char last_reported[256] = "";
5765
5766 if (0 != strcmp(last_reported, t->name)) {
5767 log_normal(_("Tileset \"%s\" doesn't support long goto paths, "
5768 "such as %d. Path not displayed as expected."),
5769 t->name, length);
5771 }
5772 }
5773 }
5774
5775 return sprs - saved_sprs;
5776}
5777
5778/************************************************************************/
5782static bool is_extra_drawing_enabled(struct extra_type *pextra)
5783{
5784 bool no_disable = TRUE; /* Draw if matches no cause */
5785
5786 if (is_extra_caused_by(pextra, EC_IRRIGATION)) {
5788 return TRUE;
5789 }
5790 no_disable = FALSE;
5791 }
5792 if (is_extra_caused_by(pextra, EC_POLLUTION)
5793 || is_extra_caused_by(pextra, EC_FALLOUT)) {
5795 return TRUE;
5796 }
5797 no_disable = FALSE;
5798 }
5799 if (is_extra_caused_by(pextra, EC_MINE)) {
5800 if (gui_options.draw_mines) {
5801 return TRUE;
5802 }
5803 no_disable = FALSE;
5804 }
5805 if (is_extra_caused_by(pextra, EC_RESOURCE)) {
5807 return TRUE;
5808 }
5809 no_disable = FALSE;
5810 }
5811 if (is_extra_removed_by(pextra, ERM_ENTER)) {
5812 if (gui_options.draw_huts) {
5813 return TRUE;
5814 }
5815 no_disable = FALSE;
5816 }
5817 if (is_extra_caused_by(pextra, EC_BASE)) {
5819 return TRUE;
5820 }
5821 no_disable = FALSE;
5822 }
5823 if (is_extra_caused_by(pextra, EC_ROAD)) {
5824 if (gui_options.draw_paths) {
5825 return TRUE;
5826 }
5827 no_disable = FALSE;
5828 }
5829
5830 return no_disable;
5831}
5832
5833/************************************************************************/
5850 struct drawn_sprite *sprs, enum mapview_layer layer,
5851 const struct tile *ptile,
5852 const struct tile_edge *pedge,
5853 const struct tile_corner *pcorner,
5854 const struct unit *punit, const struct city *pcity,
5855 const struct city *citymode,
5856 const struct unit_type *putype)
5857{
5858 int tileno, dir;
5861 struct terrain *tterrain_near[8];
5862 struct terrain *pterrain = nullptr;
5863 struct drawn_sprite *save_sprs = sprs;
5864 struct player *owner = nullptr;
5865 /* Unit drawing is disabled when the view options are turned off,
5866 * but only where we're drawing on the mapview. */
5867 bool do_draw_unit = (punit != nullptr && (gui_options.draw_units
5868 || ptile == nullptr
5870 && unit_is_in_focus(punit))));
5871 bool flagless = (do_draw_unit
5874 && ((do_draw_unit && !flagless)
5875 || (pcity != nullptr && gui_options.draw_cities)
5876 || (ptile != nullptr && !gui_options.draw_terrain)));
5877
5878 if (citymode) {
5879 int count = 0, i, cx, cy;
5880 const struct tile *const *tiles = nullptr;
5881 bool valid = FALSE;
5882
5883 if (ptile) {
5884 tiles = &ptile;
5885 count = 1;
5886 } else if (pcorner) {
5887 tiles = pcorner->tile;
5888 count = NUM_CORNER_TILES;
5889 } else if (pedge) {
5890 tiles = pedge->tile;
5891 count = NUM_EDGE_TILES;
5892 }
5893
5894 for (i = 0; i < count; i++) {
5895 if (tiles[i] && city_base_to_city_map(&cx, &cy, citymode, tiles[i])) {
5896 valid = TRUE;
5897 break;
5898 }
5899 }
5900 if (!valid) {
5901 return 0;
5902 }
5903 }
5904
5905 if (ptile && client_tile_get_known(ptile) != TILE_UNKNOWN) {
5906 textras = *tile_extras(ptile);
5907 pterrain = tile_terrain(ptile);
5908
5909 if (NULL != pterrain) {
5910 if (layer == LAYER_TERRAIN1
5911 || layer == LAYER_TERRAIN2
5912 || layer == LAYER_TERRAIN3
5913 || layer == LAYER_WATER
5914 || layer == LAYER_ROADS) {
5915 build_tile_data(ptile, pterrain, tterrain_near, textras_near);
5916 }
5917 } else {
5918 log_error("fill_sprite_array() tile (%d,%d) has no terrain!",
5919 TILE_XY(ptile));
5920 }
5921 } else {
5923 }
5924
5925 switch (layer) {
5926 case LAYER_BACKGROUND:
5927 /* Set up background color. */
5929 if (do_draw_unit && !flagless) {
5931 } else if (pcity != nullptr && gui_options.draw_cities) {
5932 owner = city_owner(pcity);
5933 }
5934 }
5935 if (owner != nullptr) {
5937 } else if (ptile != nullptr && !gui_options.draw_terrain) {
5939 }
5940 break;
5941
5942 case LAYER_TERRAIN1:
5943 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5944 sprs += fill_terrain_sprite_layer(t, sprs, 0, ptile, pterrain, tterrain_near);
5945 }
5946 break;
5947
5948 case LAYER_DARKNESS:
5949 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5951 }
5952 break;
5953
5954 case LAYER_TERRAIN2:
5955 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5956 sprs += fill_terrain_sprite_layer(t, sprs, 1, ptile, pterrain, tterrain_near);
5957 }
5958 break;
5959
5960 case LAYER_TERRAIN3:
5961 if (NULL != pterrain && gui_options.draw_terrain && !solid_bg) {
5963 sprs += fill_terrain_sprite_layer(t, sprs, 2, ptile, pterrain, tterrain_near);
5964 }
5965 break;
5966
5967 case LAYER_WATER:
5968 if (NULL != pterrain) {
5970 && terrain_type_terrain_class(pterrain) == TC_OCEAN) {
5971 for (dir = 0; dir < t->num_cardinal_tileset_dirs; dir++) {
5972 int didx = t->cardinal_tileset_dirs[dir];
5973
5976 int idx = extra_index(priver);
5977
5978 if (BV_ISSET(textras_near[didx], idx)) {
5980 }
5981 }
5983 }
5984 }
5985
5987 pcity);
5988
5992 int idx = extra_index(priver);
5993
5994 if (BV_ISSET(textras, idx)) {
5995 int i;
5996
5997 /* Draw rivers on top of irrigation. */
5998 tileno = 0;
5999 for (i = 0; i < t->num_cardinal_tileset_dirs; i++) {
6001
6003 tileno |= 1 << i;
6004 } else {
6006
6007 if (proad != NULL) {
6008 extra_type_list_iterate(proad->integrators, iextra) {
6010 tileno |= 1 << i;
6011 }
6013 }
6014 }
6015 }
6016
6018 }
6019 }
6021 }
6022 }
6023 break;
6024
6025 case LAYER_ROADS:
6026 if (NULL != pterrain) {
6028 if (is_extra_drawing_enabled(pextra)) {
6029 sprs += fill_road_sprite_array(t, pextra, sprs,
6031 tterrain_near, pcity);
6032 }
6035 if (is_extra_drawing_enabled(pextra)) {
6036 sprs += fill_road_sprite_array(t, pextra, sprs,
6038 tterrain_near, pcity);
6039 }
6042 if (is_extra_drawing_enabled(pextra)) {
6043 sprs += fill_road_sprite_array(t, pextra, sprs,
6045 tterrain_near, pcity);
6046 }
6048 }
6049 break;
6050
6051 case LAYER_SPECIAL1:
6052 if (NULL != pterrain) {
6053 if (ptile) {
6055 if (tile_has_extra(ptile, pextra)
6056 && is_extra_drawing_enabled(pextra)
6057 && t->sprites.extras[extra_index(pextra)].u.bmf.background) {
6058 bool hidden = FALSE;
6059
6060 extra_type_list_iterate(pextra->hiders, phider) {
6062 hidden = TRUE;
6063 break;
6064 }
6066
6067 if (!hidden) {
6069 }
6070 }
6072 }
6073
6075 if (BV_ISSET(textras, extra_index(pextra))
6076 && is_extra_drawing_enabled(pextra)) {
6077 bool hidden = FALSE;
6078
6079 extra_type_list_iterate(pextra->hiders, phider) {
6081 hidden = TRUE;
6082 break;
6083 }
6085
6086 if (!hidden) {
6088 }
6089 }
6091 }
6092 break;
6093
6094 case LAYER_GRID1:
6095 if (t->type == TS_ISOMETRIC) {
6097 punit, pcity, citymode);
6098 }
6099 break;
6100
6101 case LAYER_CITY1:
6102 /* City. Some city sprites are drawn later. */
6103 if (pcity && gui_options.draw_cities) {
6108 }
6109 /* For iso-view the city.wall graphics include the full city, whereas
6110 * for non-iso view they are an overlay on top of the base city
6111 * graphic. */
6112 if (t->type == TS_OVERHEAD || pcity->client.walls <= 0) {
6116 }
6117 if (t->type == TS_ISOMETRIC && pcity->client.walls > 0) {
6118 struct city_sprite *cspr = t->sprites.city.wall[pcity->client.walls - 1];
6119 struct sprite *spr = NULL;
6120
6121 if (cspr != NULL) {
6122 spr = get_city_sprite(cspr, pcity);
6123 }
6124 if (spr == NULL) {
6126 if (cspr != NULL) {
6127 spr = get_city_sprite(cspr, pcity);
6128 }
6129 }
6130
6131 if (spr != NULL) {
6135 }
6136 }
6141 }
6142 if (t->type == TS_OVERHEAD && pcity->client.walls > 0) {
6143 struct city_sprite *cspr = t->sprites.city.wall[pcity->client.walls - 1];
6144 struct sprite *spr = NULL;
6145
6146 if (cspr != NULL) {
6147 spr = get_city_sprite(cspr, pcity);
6148 }
6149 if (spr == NULL) {
6151 if (cspr != NULL) {
6152 spr = get_city_sprite(cspr, pcity);
6153 }
6154 }
6155
6156 if (spr != NULL) {
6158 }
6159 }
6160 if (pcity->client.unhappy) {
6162 }
6163 }
6164 break;
6165
6166 case LAYER_SPECIAL2:
6167 if (NULL != pterrain) {
6168 if (ptile) {
6170 if (tile_has_extra(ptile, pextra)
6171 && is_extra_drawing_enabled(pextra)
6172 && t->sprites.extras[extra_index(pextra)].u.bmf.middleground) {
6173 bool hidden = FALSE;
6174
6175 extra_type_list_iterate(pextra->hiders, phider) {
6177 hidden = TRUE;
6178 break;
6179 }
6181
6182 if (!hidden) {
6184 }
6185 }
6187 }
6188
6190 if (BV_ISSET(textras, extra_index(pextra))
6191 && is_extra_drawing_enabled(pextra)) {
6192 bool hidden = FALSE;
6193
6194 extra_type_list_iterate(pextra->hiders, phider) {
6196 hidden = TRUE;
6197 break;
6198 }
6200
6201 if (!hidden) {
6203 }
6204 }
6206 }
6207 break;
6208
6209 case LAYER_UNIT:
6210 case LAYER_FOCUS_UNIT:
6211 if (do_draw_unit && XOR(layer == LAYER_UNIT, unit_is_in_focus(punit))) {
6212 int stack_count = ptile ? unit_list_size(ptile->units) : 0;
6213 bool backdrop = !pcity;
6214
6215 if (ptile && unit_is_in_focus(punit)
6216 && t->sprites.unit.select[0]) {
6217 /* Special case for drawing the selection rectangle. The blinking
6218 * unit is handled separately, inside get_drawable_unit(). */
6221 }
6222
6223 /* Load more stack number sprites if needed. no_more_stack_sprites guard
6224 * that we don't retry over and over again for every stack,
6225 * when it's not working. */
6226 if (t->sprites.unit.num_stack_sprites < stack_count
6227 && !t->sprites.unit.no_more_stack_sprites) {
6228 t->sprites.unit.stack = fc_realloc(t->sprites.unit.stack,
6229 stack_count * sizeof(struct sprite *));
6230
6231 while (t->sprites.unit.num_stack_sprites < stack_count
6232 && !t->sprites.unit.no_more_stack_sprites) {
6233 struct sprite *spr = load_gfxnumber(t->sprites.unit.num_stack_sprites + 1);
6234
6235 if (spr != NULL) {
6236 t->sprites.unit.stack[t->sprites.unit.num_stack_sprites++] = spr;
6237 } else {
6238 t->sprites.unit.no_more_stack_sprites = TRUE;
6239 t->sprites.unit.stack = fc_realloc(t->sprites.unit.stack,
6240 t->sprites.unit.num_stack_sprites * sizeof(struct sprite *));
6241 }
6242 }
6243 }
6244
6246 } else if (putype != NULL && layer == LAYER_UNIT) {
6247 /* Only the sprite for the unit type. */
6248 /* FIXME: Shouldn't this still get activity and orientation of
6249 * the actual unit? */
6252 }
6253 break;
6254
6255 case LAYER_SPECIAL3:
6256 if (NULL != pterrain) {
6257 if (ptile) {
6258 bool show_flag = FALSE;
6259 struct player *eowner = extra_owner(ptile);
6260
6262 if (is_extra_drawing_enabled(pextra)
6263 && tile_has_extra(ptile, pextra)
6264 && t->sprites.extras[extra_index(pextra)].u.bmf.foreground) {
6265 bool hidden = FALSE;
6266
6267 extra_type_list_iterate(pextra->hiders, phider) {
6269 hidden = TRUE;
6270 break;
6271 }
6273
6274 if (!hidden) {
6275 if (t->sprites.extras[extra_index(pextra)].u.bmf.foreground) {
6277 }
6278 }
6279 }
6281
6282 /* Show base flag. Not part of previous iteration as
6283 * "extras of ESTYLE_3_LAYER" != "bases" */
6284 if (eowner != NULL) {
6286 if (tile_has_extra(ptile, pextra)) {
6287 bool hidden = FALSE;
6288
6289 extra_type_list_iterate(pextra->hiders, phider) {
6291 hidden = TRUE;
6292 break;
6293 }
6295
6296 if (!hidden) {
6297 show_flag = TRUE;
6298 }
6299 }
6301
6302 if (show_flag) {
6306 }
6307 }
6308 }
6309 }
6310 break;
6311
6312 case LAYER_FOG:
6314 break;
6315
6316 case LAYER_CITY2:
6317 /* City size. Drawing this under fog makes it hard to read. */
6319 bool warn = FALSE;
6320 unsigned int size = city_size_get(pcity);
6321
6325 if (10 <= size) {
6327 % 10], FALSE,
6330 if (100 <= size) {
6331 struct sprite *sprite =
6332 t->sprites.city.size_hundreds[(size / 100) % 10];
6333
6334 if (NULL != sprite) {
6338 } else {
6339 warn = TRUE;
6340 }
6341 if (1000 <= size) {
6342 warn = TRUE;
6343 }
6344 }
6345 }
6346
6347 if (warn) {
6348 /* Warn only once by tileset. */
6349 static char last_reported[256] = "";
6350
6351 if (0 != strcmp(last_reported, t->name)) {
6352 log_normal(_("Tileset \"%s\" doesn't support big cities size, "
6353 "such as %d. Size not displayed as expected."),
6354 t->name, size);
6356 }
6357 }
6358 }
6359 break;
6360
6361 case LAYER_GRID2:
6362 if (t->type == TS_OVERHEAD) {
6364 punit, pcity, citymode);
6365 }
6366 break;
6367
6368 case LAYER_OVERLAYS:
6370 if (mapdeco_is_crosshair_set(ptile)) {
6372 }
6373 break;
6374
6375 case LAYER_CITYBAR:
6376 case LAYER_TILELABEL:
6377 /* Nothing. This is just a placeholder. */
6378 break;
6379
6380 case LAYER_GOTO:
6381 if (ptile && goto_is_active()) {
6383 }
6384 break;
6385
6386 case LAYER_WORKERTASK:
6387 if (citymode != NULL && ptile != NULL) {
6389 if (ptask->ptile == ptile) {
6390 switch (ptask->act) {
6391 case ACTIVITY_MINE:
6392 if (ptask->tgt == NULL) {
6393 ADD_SPRITE(t->sprites.unit.plant,
6396 } else {
6400 }
6401 break;
6402 case ACTIVITY_PLANT:
6403 ADD_SPRITE(t->sprites.unit.plant,
6406 break;
6407 case ACTIVITY_IRRIGATE:
6408 if (ptask->tgt == NULL) {
6409 ADD_SPRITE(t->sprites.unit.cultivate,
6412 } else {
6416 }
6417 break;
6418 case ACTIVITY_CULTIVATE:
6419 ADD_SPRITE(t->sprites.unit.cultivate,
6422 break;
6423 case ACTIVITY_GEN_ROAD:
6424 if (ptask->tgt != NULL) {
6428 }
6429 break;
6430 case ACTIVITY_TRANSFORM:
6431 ADD_SPRITE(t->sprites.unit.transform,
6434 break;
6435 case ACTIVITY_CLEAN:
6436 if (ptask->tgt != NULL) {
6440 }
6441 break;
6442 default:
6443 break;
6444 }
6445 }
6447 }
6448 break;
6449
6450 case LAYER_EDITOR:
6451 if (ptile && editor_is_active()) {
6452 if (editor_tile_is_selected(ptile)) {
6455 }
6456
6457 if (NULL != map_startpos_get(ptile)) {
6458 /* FIXME: Use a more representative sprite. */
6460 }
6461 }
6462 break;
6463
6464 case LAYER_INFRAWORK:
6465 if (ptile != NULL) {
6466 if (ptile->placing != NULL) {
6467 const int id = extra_index(ptile->placing);
6468
6469 if (t->sprites.extras[id].activity != NULL) {
6473 }
6474 }
6475 if (client_infratile() == ptile) {
6477 }
6478 }
6479 break;
6480
6481 case LAYER_COUNT:
6483 break;
6484 }
6485
6486 return sprs - save_sprs;
6487}
6488
6489/************************************************************************/
6493void tileset_setup_city_tiles(struct tileset *t, int style)
6494{
6495 const char *style_name = city_style_rule_name(style);
6496
6497 if (style == game.control.num_city_styles - 1) {
6498 int i;
6499
6500 /* Free old sprites */
6502
6503 for (i = 0; i < NUM_WALL_TYPES; i++) {
6505 t->sprites.city.wall[i] = NULL;
6506 }
6509
6511
6512 t->sprites.city.tile = load_city_sprite(t, "city");
6513
6514 for (i = 0; i < NUM_WALL_TYPES; i++) {
6515 char buffer[256];
6516
6517 fc_snprintf(buffer, sizeof(buffer), "bldg_%d", i);
6518 t->sprites.city.wall[i] = load_city_sprite(t, buffer);
6519 }
6520 t->sprites.city.single_wall = load_city_sprite(t, "wall");
6521
6522 t->sprites.city.occupied = load_city_sprite(t, "occupied");
6523 }
6524
6526 &t->sprites.style_citizen_sets.sets[style],
6527 city_styles[style].citizens_graphic,
6528 style_name, FALSE);
6531 &t->sprites.style_citizen_sets.sets[style],
6532 sp,
6533 city_styles[style].citizens_graphic,
6534 style_name, FALSE);
6536
6537 if (style == game.control.num_city_styles - 1) {
6538 for (style = 0; style < game.control.num_city_styles; style++) {
6539 if (t->sprites.city.tile->styles[style].land_num_thresholds == 0) {
6541 _("City style \"%s\": no city graphics."),
6542 city_style_rule_name(style));
6543 }
6544 if (t->sprites.city.occupied->styles[style].land_num_thresholds == 0) {
6546 _("City style \"%s\": no occupied graphics."),
6547 city_style_rule_name(style));
6548 }
6549 }
6550 }
6551}
6552
6553/************************************************************************/
6559{
6560 if (t->sprites.unit.select[0]) {
6561 return 0.1;
6562 } else {
6563 return 0.5;
6564 }
6565}
6566
6567/************************************************************************/
6572{
6573 focus_unit_state = 0;
6574}
6575
6576/************************************************************************/
6580{
6581 if (!t->sprites.unit.select[0]) {
6583 }
6584}
6585
6586/************************************************************************/
6591{
6593 if (t->sprites.unit.select[0]) {
6595 } else {
6596 focus_unit_state %= 2;
6597 }
6598}
6599
6600/************************************************************************/
6603struct unit *get_drawable_unit(const struct tileset *t,
6604 struct tile *ptile,
6605 const struct city *citymode)
6606{
6607 struct unit *punit = find_visible_unit(ptile);
6608
6609 if (punit == NULL) {
6610 return NULL;
6611 }
6612
6614 return NULL;
6615 }
6616
6618 || t->sprites.unit.select[0] || focus_unit_state == 0) {
6619 return punit;
6620 } else {
6621 return NULL;
6622 }
6623}
6624
6625/************************************************************************/
6629static void unload_all_sprites(struct tileset *t)
6630{
6631 if (t->sprite_hash) {
6633 while (ss->ref_count > 0) {
6635 }
6637 }
6638}
6639
6640/************************************************************************/
6644{
6645 int i;
6646
6647 log_debug("tileset_free_tiles()");
6648
6650
6652 t->sprites.city.tile = NULL;
6653
6654 for (i = 0; i < NUM_WALL_TYPES; i++) {
6656 t->sprites.city.wall[i] = NULL;
6657 }
6660
6663
6664 if (t->sprite_hash) {
6666 t->sprite_hash = NULL;
6667 }
6668
6669 if (t->sprites.style_citizen_sets.sets != NULL) {
6672 }
6673
6676 if (ss->file) {
6677 free(ss->file);
6678 }
6679 fc_assert(ss->sprite == NULL);
6680 free(ss);
6682
6685 free(sf->file_name);
6686 if (sf->big_sprite) {
6687 free_sprite(sf->big_sprite);
6688 sf->big_sprite = NULL;
6689 }
6690 free(sf);
6692
6697
6702
6703 if (t->sprites.tx.fullfog) {
6704 free(t->sprites.tx.fullfog);
6705 t->sprites.tx.fullfog = NULL;
6706 }
6707
6713
6714 /* Index 0 is 'occupied' or 'default' stack sprite */
6715 for (i = 1; i < t->sprites.unit.num_stack_sprites - 1; i++) {
6716 free_sprite(t->sprites.unit.stack[i]);
6717 }
6718 t->sprites.unit.num_stack_sprites = 0;
6719 if (t->sprites.unit.stack != NULL) {
6720 free(t->sprites.unit.stack);
6721 t->sprites.unit.stack = NULL;
6722 }
6723
6725}
6726
6727/************************************************************************/
6730struct sprite *get_spaceship_sprite(const struct tileset *t,
6731 enum spaceship_part part)
6732{
6733 return t->sprites.spaceship[part];
6734}
6735
6736/************************************************************************/
6739static inline const struct citizen_graphic *
6742{
6743 fc_assert_ret_val(set != NULL, NULL);
6744
6745 if (type < CITIZEN_SPECIALIST) {
6747 return &set->citizen[type];
6748 } else {
6750 return &set->specialist[type - CITIZEN_SPECIALIST];
6751 }
6752}
6753
6754/************************************************************************/
6761struct sprite *get_citizen_sprite(const struct tileset *t,
6763 int citizen_index,
6764 const struct city *pcity)
6765{
6766 const struct citizen_graphic *graphic = NULL;
6768
6769 if (pcity != NULL) {
6770 int style = style_of_city(pcity);
6771
6773
6775 type);
6776
6778 }
6779
6780 if (graphic == NULL || graphic->count == 0) {
6781 /* Fall back to default sprites */
6783 }
6784
6785 if (graphic->count == 0) {
6786 return NULL;
6787 }
6788
6789 return graphic->sprite[gfx_index % graphic->count];
6790}
6791
6792/************************************************************************/
6795struct sprite *get_nation_flag_sprite(const struct tileset *t,
6796 const struct nation_type *pnation)
6797{
6798 return t->sprites.nation_flag.p[nation_index(pnation)];
6799}
6800
6801/************************************************************************/
6805 const struct nation_type *pnation)
6806{
6807 return t->sprites.nation_shield.p[nation_index(pnation)];
6808}
6809
6810/************************************************************************/
6813struct sprite *get_tech_sprite(const struct tileset *t, Tech_type_id tech)
6814{
6815 fc_assert_ret_val(0 <= tech && tech < advance_count(), NULL);
6816 return t->sprites.tech[tech];
6817}
6818
6819/************************************************************************/
6822struct sprite *get_building_sprite(const struct tileset *t,
6823 const struct impr_type *pimprove)
6824{
6825 fc_assert_ret_val(NULL != pimprove, NULL);
6826 return t->sprites.building[improvement_index(pimprove)];
6827}
6828
6829/************************************************************************/
6832struct sprite *get_government_sprite(const struct tileset *t,
6833 const struct government *gov)
6834{
6835 fc_assert_ret_val(NULL != gov, NULL);
6836 return t->sprites.government[government_index(gov)];
6837}
6838
6839/************************************************************************/
6844struct sprite *get_unittype_sprite(const struct tileset *t,
6845 const struct unit_type *punittype,
6846 enum unit_activity activity,
6847 enum direction8 facing)
6848{
6849 int uidx = utype_index(punittype);
6850 bool icon = !direction8_is_valid(facing);
6851
6852 if (activity >= ACTIVITY_LAST) {
6853 activity = ACTIVITY_IDLE;
6854 }
6855
6857
6858 if (!direction8_is_valid(facing) || !is_valid_dir(facing)) {
6859 facing = t->unit_default_orientation;
6860 /* May not have been specified, but it only matters if we don't
6861 * turn out to have an icon sprite */
6862 }
6863
6864 if (t->sprites.units.icon[uidx][activity] != NULL
6865 && (icon || t->sprites.units.facing[uidx][facing][activity] == NULL)) {
6866 /* Has icon sprite, and we prefer to (or must) use it */
6867 return t->sprites.units.icon[uidx][activity];
6868 } else if (t->sprites.units.icon[uidx][ACTIVITY_IDLE] != NULL
6869 && (icon
6870 || t->sprites.units.facing[uidx][facing][ACTIVITY_IDLE] == NULL)) {
6871 /* Has icon sprite, and we prefer to (or must) use it */
6872 return t->sprites.units.icon[uidx][ACTIVITY_IDLE];
6873 } else {
6874 /* We should have a valid orientation by now. Failure to have either
6875 * an icon sprite or default orientation should have been caught at
6876 * tileset load. */
6878
6879 if (t->sprites.units.facing[uidx][facing][activity] == NULL) {
6880 return t->sprites.units.facing[uidx][facing][ACTIVITY_IDLE];
6881 }
6882
6883 return t->sprites.units.facing[uidx][facing][activity];
6884 }
6885}
6886
6887/************************************************************************/
6890struct sprite *get_sample_city_sprite(const struct tileset *t,
6891 int style_idx)
6892{
6893 int num_thresholds =
6894 t->sprites.city.tile->styles[style_idx].land_num_thresholds;
6895
6896 if (num_thresholds == 0) {
6897 return NULL;
6898 } else {
6899 return (t->sprites.city.tile->styles[style_idx]
6900 .land_thresholds[num_thresholds - 1].sprite);
6901 }
6902}
6903
6904/************************************************************************/
6907struct sprite *get_arrow_sprite(const struct tileset *t,
6908 enum arrow_type arrow)
6909{
6910 fc_assert_ret_val(arrow >= 0 && arrow < ARROW_LAST, NULL);
6911
6912 return t->sprites.arrow[arrow];
6913}
6914
6915/************************************************************************/
6919{
6920 switch (otype) {
6921 case O_SCIENCE:
6922 return t->sprites.tax_science;
6923 case O_GOLD:
6924 return t->sprites.tax_gold;
6925 case O_LUXURY:
6926 return t->sprites.tax_luxury;
6927 case O_TRADE:
6928 case O_FOOD:
6929 case O_SHIELD:
6930 case O_LAST:
6931 break;
6932 }
6933 return NULL;
6934}
6935
6936/************************************************************************/
6939struct sprite *get_event_sprite(const struct tileset *t, enum event_type event)
6940{
6941 return t->sprites.events[event];
6942}
6943
6944/************************************************************************/
6948struct sprite *get_treaty_thumb_sprite(const struct tileset *t, bool on_off)
6949{
6950 return t->sprites.treaty_thumb[on_off ? 1 : 0];
6951}
6952
6953/************************************************************************/
6958 tileset *t)
6959{
6960 return &t->sprites.explode.unit;
6961}
6962
6963/************************************************************************/
6969{
6970 return t->sprites.explode.nuke;
6971}
6972
6973/************************************************************************/
6976const struct citybar_sprites *get_citybar_sprites(const struct tileset *t)
6977{
6979 return &t->sprites.citybar;
6980 } else {
6981 return NULL;
6982 }
6983}
6984
6985/************************************************************************/
6988const struct editor_sprites *get_editor_sprites(const struct tileset *t)
6989{
6990 return &t->sprites.editor;
6991}
6992
6993/************************************************************************/
6999struct sprite *get_cursor_sprite(const struct tileset *t,
7000 enum cursor_type cursor,
7001 int *hot_x, int *hot_y, int frame)
7002{
7003 *hot_x = t->sprites.cursor[cursor].hot_x;
7004 *hot_y = t->sprites.cursor[cursor].hot_y;
7005
7006 return t->sprites.cursor[cursor].frame[frame];
7007}
7008
7009/************************************************************************/
7018struct sprite *get_icon_sprite(const struct tileset *t, enum icon_type icon)
7019{
7020 return t->sprites.icon[icon];
7021}
7022
7023/************************************************************************/
7030{
7031 return t->sprites.user.attention;
7032}
7033
7034/************************************************************************/
7038struct sprite *get_indicator_sprite(const struct tileset *t,
7039 enum indicator_type indicator,
7040 int idx)
7041{
7042 idx = CLIP(0, idx, NUM_TILES_PROGRESS - 1);
7043
7044 fc_assert_ret_val(indicator >= 0 && indicator < INDICATOR_COUNT, NULL);
7045
7046 return t->sprites.indicator[indicator][idx];
7047}
7048
7049/************************************************************************/
7056 const struct unit *punit,
7057 int happy_cost)
7058{
7059 const int unhappy = CLIP(0, happy_cost, MAX_NUM_UPKEEP_SPRITES+1);
7060
7061 if (unhappy > 0) {
7062 return t->sprites.upkeep.unhappy[unhappy - 1];
7063 } else {
7064 return NULL;
7065 }
7066}
7067
7068/************************************************************************/
7074struct sprite *get_unit_upkeep_sprite(const struct tileset *t,
7076 const struct unit *punit,
7077 const int *upkeep_cost)
7078{
7079 const int upkeep = CLIP(0, upkeep_cost[otype], MAX_NUM_UPKEEP_SPRITES + 1);
7080
7081 if (upkeep > 0) {
7082 return t->sprites.upkeep.output[otype][upkeep - 1];
7083 } else {
7084 return NULL;
7085 }
7086}
7087
7088/************************************************************************/
7092struct sprite *get_basic_fog_sprite(const struct tileset *t)
7093{
7094 return t->sprites.tx.fog;
7095}
7096
7097/************************************************************************/
7100struct color_system *get_color_system(const struct tileset *t)
7101{
7102 return t->color_system;
7103}
7104
7105/************************************************************************/
7109{
7110 char *default_theme_name = NULL;
7111 size_t default_theme_name_sz = 0;
7112 int i;
7113
7114 switch (get_gui_type()) {
7115 case GUI_GTK3_22:
7118 break;
7119 case GUI_GTK4:
7122 break;
7123 case GUI_GTK5:
7126 break;
7127 case GUI_SDL2:
7130 break;
7131 case GUI_SDL3:
7134 break;
7135 case GUI_STUB:
7136 case GUI_QT:
7137 case GUI_SDL:
7138 case GUI_WEB:
7139 case GUI_GTK2:
7140 case GUI_GTK3:
7141 break;
7142 }
7143
7145 /* Theme is not supported by this client. */
7146 return;
7147 }
7148
7149 for (i = 0; i < t->num_preferred_themes; i++) {
7152 log_debug("trying theme \"%s\".", t->preferred_themes[i]);
7153 if (load_theme(t->preferred_themes[i])) {
7156 return;
7157 }
7158 }
7159 }
7160 }
7161 log_verbose("The tileset doesn't specify preferred themes or none of its "
7162 "preferred themes can be used. Using system default.");
7164}
7165
7166/************************************************************************/
7169void tileset_init(struct tileset *t)
7170{
7171 int wi;
7172
7173 /* We currently have no city sprites loaded. */
7174 t->sprites.city.tile = NULL;
7175
7176 for (wi = 0; wi < NUM_WALL_TYPES; wi++) {
7177 t->sprites.city.wall[wi] = NULL;
7178 }
7180
7182
7183 t->sprites.background.color = NULL;
7184 t->sprites.background.graphic = NULL;
7185
7186 player_slots_iterate(pslot) {
7187 int edge, j, id = player_slot_index(pslot);
7188
7189 for (edge = 0; edge < EDGE_COUNT; edge++) {
7190 for (j = 0; j < 2; j++) {
7192 }
7193 }
7194
7195 t->sprites.player[id].color = NULL;
7198
7199 t->max_upkeep_height = 0;
7200}
7201
7202/************************************************************************/
7211 struct drawn_sprite *sprs,
7212 int layer,
7213 struct terrain *pterrain)
7214{
7215 struct drawn_sprite *save_sprs = sprs;
7216 struct drawing_data *draw = t->sprites.drawing[terrain_index(pterrain)];
7217
7218 struct terrain *tterrain_near[8];
7220
7221 struct tile dummy_tile; /* :( */
7222
7223 int i;
7224
7225
7226 memset(&dummy_tile, 0, sizeof(struct tile));
7227
7228 for (i = 0; i < 8; i++) {
7229 tterrain_near[i] = pterrain;
7231 }
7232
7233 i = draw->is_reversed ? draw->num_layers - layer - 1 : layer;
7235 pterrain, tterrain_near, draw);
7236
7237 return sprs - save_sprs;
7238}
7239
7240/************************************************************************/
7244 struct drawn_sprite *sprs,
7245 const struct extra_type *pextra)
7246{
7247 int idx = extra_index(pextra);
7248 struct drawn_sprite *saved_sprs = sprs;
7249
7250 switch (t->sprites.extras[idx].extrastyle) {
7251 case ESTYLE_SINGLE1:
7252 case ESTYLE_SINGLE2:
7254 break;
7255 case ESTYLE_CARDINALS:
7257 break;
7261 case ESTYLE_RIVER:
7262 return fill_basic_road_sprite_array(t, sprs, pextra);
7263 case ESTYLE_3LAYER:
7264 return fill_basic_base_sprite_array(t, sprs, pextra);
7265 case ESTYLE_COUNT:
7267 break;
7268 }
7269
7270 return sprs - saved_sprs;
7271}
7272
7273/************************************************************************/
7279 struct drawn_sprite *sprs,
7280 const struct extra_type *pextra)
7281{
7282 struct drawn_sprite *saved_sprs = sprs;
7283 int idx;
7284 int i;
7285 enum extrastyle_id extrastyle;
7286
7287 if (!t || !sprs || !pextra) {
7288 return 0;
7289 }
7290
7291 idx = extra_index(pextra);
7292
7293 if (!(0 <= idx && idx < game.control.num_extra_types)) {
7294 return 0;
7295 }
7296
7297 extrastyle = t->sprites.extras[idx].extrastyle;
7298
7299 if (extrastyle == ESTYLE_RIVER) {
7301 } else {
7302 for (i = 0; i < t->num_valid_tileset_dirs; i++) {
7303 if (!t->valid_tileset_dirs[i]) {
7304 continue;
7305 }
7306 if (extrastyle == ESTYLE_ROAD_ALL_SEPARATE) {
7308 } else if (extrastyle == ESTYLE_ROAD_PARITY_COMBINED) {
7309 if ((i % 2) == 0) {
7310 ADD_SPRITE_SIMPLE(t->sprites.extras[idx].u.road.ru.combo.even[1 << (i / 2)]);
7311 }
7312 } else if (extrastyle == ESTYLE_ROAD_ALL_COMBINED) {
7313 ADD_SPRITE_SIMPLE(t->sprites.extras[idx].u.road.ru.total[1 << i]);
7314 }
7315 }
7316 }
7317
7318 return sprs - saved_sprs;
7319}
7320
7321/************************************************************************/
7327 struct drawn_sprite *sprs,
7328 const struct extra_type *pextra)
7329{
7330 struct drawn_sprite *saved_sprs = sprs;
7331 int idx;
7332
7333 if (!t || !sprs || !pextra) {
7334 return 0;
7335 }
7336
7337 idx = extra_index(pextra);
7338
7339 if (!(0 <= idx && idx < game.control.num_extra_types)) {
7340 return 0;
7341 }
7342
7343#define ADD_SPRITE_IF_NOT_NULL(x) do {\
7344 if ((x) != NULL) {\
7345 ADD_SPRITE_FULL(x);\
7346 }\
7347} while (FALSE)
7348
7349 /* Corresponds to LAYER_SPECIAL{1,2,3} order. */
7353
7354#undef ADD_SPRITE_IF_NOT_NULL
7355
7356 return sprs - saved_sprs;
7357}
7358
7359/************************************************************************/
7362enum mapview_layer tileset_get_layer(const struct tileset *t, int n)
7363{
7365 return t->layer_order[n];
7366}
7367
7368/************************************************************************/
7372 enum layer_category cat)
7373{
7374 switch (layer) {
7375 case LAYER_BACKGROUND:
7376 case LAYER_TERRAIN1:
7377 case LAYER_DARKNESS:
7378 case LAYER_TERRAIN2:
7379 case LAYER_TERRAIN3:
7380 case LAYER_WATER:
7381 case LAYER_ROADS:
7382 case LAYER_SPECIAL1:
7383 case LAYER_SPECIAL2:
7384 case LAYER_SPECIAL3:
7386 case LAYER_CITY1:
7387 case LAYER_CITY2:
7388 return cat == LAYER_CATEGORY_CITY;
7389 case LAYER_UNIT:
7390 case LAYER_FOCUS_UNIT:
7391 return cat == LAYER_CATEGORY_UNIT;
7392 case LAYER_GRID1:
7393 case LAYER_FOG:
7394 case LAYER_GRID2:
7395 case LAYER_OVERLAYS:
7396 case LAYER_TILELABEL:
7397 case LAYER_CITYBAR:
7398 case LAYER_GOTO:
7399 case LAYER_WORKERTASK:
7400 case LAYER_EDITOR:
7401 case LAYER_INFRAWORK:
7402 return FALSE;
7403 case LAYER_COUNT:
7404 break; /* and fail below */
7405 }
7406
7407 fc_assert_msg(FALSE, "Unknown layer category: %d", cat);
7408 return FALSE;
7409}
7410
7411/************************************************************************/
7414void tileset_player_init(struct tileset *t, struct player *pplayer)
7415{
7416 int plrid, i, j;
7417 struct sprite *color;
7418
7419 fc_assert_ret(pplayer != NULL);
7420
7421 plrid = player_index(pplayer);
7422 fc_assert_ret(plrid >= 0);
7424
7425 /* Free all data before recreating it. */
7427
7428 if (player_has_color(pplayer)) {
7430 = create_plr_sprite(get_player_color(t, pplayer));
7431 } else {
7432 /* XXX: if player hasn't been assigned a color, perhaps there's no
7433 * point proceeding with an arbitrary color; this should only happen
7434 * in pregame. Probably blank sprites would be better. */
7435
7436 fc_assert_ret(t->sprites.background.color != NULL);
7437
7438 color = t->sprites.background.color;
7439 }
7440
7442 = crop_sprite(color, 0, 0,
7444 t->sprites.mask.tile, 0, 0, t->scale, FALSE);
7445
7446 for (i = 0; i < EDGE_COUNT; i++) {
7447 for (j = 0; j < 2; j++) {
7448 struct sprite *s;
7449
7450 if (color && t->sprites.grid.borders[i][j]) {
7451 s = crop_sprite(color, 0, 0,
7453 t->sprites.grid.borders[i][j], 0, 0, 1.0f, FALSE);
7454 } else {
7455 s = t->sprites.grid.borders[i][j];
7456 }
7457 t->sprites.player[plrid].grid_borders[i][j] = s;
7458 }
7459 }
7460}
7461
7462/************************************************************************/
7465static void tileset_player_free(struct tileset *t, int plrid)
7466{
7467 int i, j;
7468
7469 fc_assert_ret(plrid >= 0);
7471
7472 if (t->sprites.player[plrid].color) {
7475 }
7476 if (t->sprites.player[plrid].background) {
7479 }
7480
7481 for (i = 0; i < EDGE_COUNT; i++) {
7482 for (j = 0; j < 2; j++) {
7483 if (t->sprites.player[plrid].grid_borders[i][j]) {
7486 }
7487 }
7488 }
7489}
7490
7491/************************************************************************/
7495{
7496 /* Free all data before recreating it. */
7498
7499 /* Generate background color */
7500 t->sprites.background.color
7502
7503 /* Chop up and build the background graphics. */
7504 t->sprites.background.graphic
7505 = crop_sprite(t->sprites.background.color, 0, 0,
7507 t->sprites.mask.tile, 0, 0, t->scale, FALSE);
7508}
7509
7510/************************************************************************/
7514{
7515 if (t->sprites.background.color) {
7516 free_sprite(t->sprites.background.color);
7517 t->sprites.background.color = NULL;
7518 }
7519
7520 if (t->sprites.background.graphic) {
7521 free_sprite(t->sprites.background.graphic);
7522 t->sprites.background.graphic = NULL;
7523 }
7524}
7525
7526/************************************************************************/
7530{
7531 int i;
7532
7533 for (i = 0; i < ESTYLE_COUNT; i++) {
7534 if (t->style_lists[i] != NULL) {
7537 }
7538 }
7539
7540 if (t->flagged_bases_list != NULL) {
7543 }
7544
7545 if (t->sprites.style_citizen_sets.sets != NULL) {
7547 }
7548
7551 * sizeof(t->sprites.style_citizen_sets.sets[0]));
7552}
7553
7554/************************************************************************/
7558{
7559 return !tileset_update;
7560}
7561
7562/************************************************************************/
7565const char *tileset_name_get(struct tileset *t)
7566{
7567 return t->given_name;
7568}
7569
7570/************************************************************************/
7573const char *tileset_version(struct tileset *t)
7574{
7575 return t->version;
7576}
7577
7578/************************************************************************/
7581const char *tileset_summary(struct tileset *t)
7582{
7583 return t->summary;
7584}
7585
7586/************************************************************************/
7589const char *tileset_description(struct tileset *t)
7590{
7591 return t->description;
7592}
7593
7594/************************************************************************/
7598{
7599 return t->for_ruleset;
7600}
7601
7602/************************************************************************/
7606{
7607 return t->ts_topo_idx;
7608}
7609
7610/************************************************************************/
7614{
7615 return t->svg_height;
7616}
7617
7618/************************************************************************/
7621struct sprite *load_popup_sprite(const char *tag)
7622{
7623 return load_sprite(tileset, tag, TRUE, TRUE, FALSE);
7624}
7625
7626/************************************************************************/
7629void unload_popup_sprite(const char *tag)
7630{
7631 unload_sprite(tileset, tag);
7632}
#define str
Definition astring.c:76
#define n
Definition astring.c:77
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
struct canvas int int int int struct sprite *sprite struct canvas struct color * pcolor
Definition canvas_g.h:56
struct canvas int int struct sprite int int offset_y
Definition canvas_g.h:44
struct canvas int int struct sprite int offset_x
Definition canvas_g.h:44
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
bool has_capabilities(const char *us, const char *them)
Definition capability.c:88
bool base_city_celebrating(const struct city *pcity)
Definition city.c:1633
const char * city_style_rule_name(const int style)
Definition city.c:1761
const char * get_output_identifier(Output_type_id output)
Definition city.c:619
bool city_can_be_built_here(const struct civ_map *nmap, const struct tile *ptile, const struct unit *punit, bool hut_test)
Definition city.c:1483
bool city_base_to_city_map(int *city_map_x, int *city_map_y, const struct city *const pcity, const struct tile *map_tile)
Definition city.c:281
bool city_tile_to_city_map(int *city_map_x, int *city_map_y, const int city_radius_sq, const struct tile *city_center, const struct tile *map_tile)
Definition city.c:264
static const struct city struct citystyle * city_styles
Definition city.c:84
int city_tile_output(const struct city *pcity, const struct tile *ptile, bool is_celebrating, Output_type_id otype)
Definition city.c:1279
bool city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition city.c:1452
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
citizen_category
Definition city.h:267
@ CITIZEN_LAST
Definition city.h:272
@ CITIZEN_SPECIALIST
Definition city.h:273
@ CITIZEN_ANGRY
Definition city.h:271
@ CITIZEN_HAPPY
Definition city.h:268
@ CITIZEN_CONTENT
Definition city.h:269
@ CITIZEN_UNHAPPY
Definition city.h:270
#define output_type_iterate(output)
Definition city.h:836
#define city_owner(_pcity_)
Definition city.h:563
#define MAX_CITY_SIZE
Definition city.h:106
#define output_type_iterate_end
Definition city.h:842
void generate_citydlg_dimensions(void)
struct civclient client
enum client_states client_state(void)
#define client_player()
client_states
Definition client_main.h:43
@ C_S_RUNNING
Definition client_main.h:47
@ C_S_OVER
Definition client_main.h:48
enum known_type client_tile_get_known(const struct tile *ptile)
Definition climap.c:36
bool client_city_can_work_tile(const struct city *pcity, const struct tile *ptile)
Definition climap.c:133
void color_system_free(struct color_system *colors)
struct color * get_player_color(const struct tileset *t, const struct player *pplayer)
struct color_system * color_system_read(struct section_file *file)
struct color * ensure_color(struct rgbcolor *rgb)
bool player_has_color(const struct player *pplayer)
char * incite_cost
Definition comments.c:74
bool unit_is_in_focus(const struct unit *punit)
Definition control.c:383
bool should_ask_server_for_actions(const struct unit *punit)
Definition control.c:334
struct unit_list * get_units_in_focus(void)
Definition control.c:177
struct unit * find_visible_unit(struct tile *ptile)
Definition control.c:804
static void road(QVariant data1, QVariant data2)
Definition dialogs.cpp:2917
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 const struct action *paction show_tileset_error
Definition dialogs_g.h:85
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 const struct action *paction bool const char * tset_name
Definition dialogs_g.h:86
int int id
Definition editgui_g.h:28
bool editor_is_active(void)
Definition editor.c:346
bool editor_tile_is_selected(const struct tile *ptile)
Definition editor.c:1117
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
int get_target_bonus_effects(struct effect_list *plist, const struct req_context *context, const struct req_context *other_context, enum effect_type effect_type)
Definition effects.c:744
enum event_type event
Definition events.c:81
const char * get_event_tag(enum event_type event)
Definition events.c:276
static struct @24 events[]
char * tag_name
Definition events.c:77
struct player * extra_owner(const struct tile *ptile)
Definition extras.c:1128
bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag)
Definition extras.c:875
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
const char * extra_rule_name(const struct extra_type *pextra)
Definition extras.c:203
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Definition extras.c:353
int extra_count(void)
Definition extras.c:153
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
#define extra_type_iterate_end
Definition extras.h:321
#define is_extra_caused_by(e, c)
Definition extras.h:203
#define extra_index(_e_)
Definition extras.h:183
#define extra_type_list_iterate_end
Definition extras.h:167
#define extra_road_get(_e_)
Definition extras.h:191
#define MAX_VET_LEVELS
Definition fc_types.h:49
#define DIR8_MAGIC_MAX
Definition fc_types.h:473
#define MAX_NUM_ITEMS
Definition fc_types.h:40
int Tech_type_id
Definition fc_types.h:381
#define SP_MAX
Definition fc_types.h:412
int Specialist_type_id
Definition fc_types.h:379
#define MAX_NUM_PLAYER_SLOTS
Definition fc_types.h:32
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define MAX_LEN_NAME
Definition fc_types.h:66
@ O_SHIELD
Definition fc_types.h:101
@ O_FOOD
Definition fc_types.h:101
@ O_TRADE
Definition fc_types.h:101
@ O_SCIENCE
Definition fc_types.h:101
@ O_LUXURY
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
@ O_LAST
Definition fc_types.h:101
@ BORDERS_DISABLED
Definition fc_types.h:1017
enum output_type_id Output_type_id
Definition fc_types.h:382
#define _(String)
Definition fcintl.h:67
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
bool goto_is_active(void)
Definition goto.c:1063
goto_tile_state
Definition goto.h:25
@ GTS_EXHAUSTED_MP
Definition goto.h:28
@ GTS_MP_LEFT
Definition goto.h:27
@ GTS_TURN_STEP
Definition goto.h:26
@ GTS_COUNT
Definition goto.h:30
Government_type_id government_index(const struct government *pgovern)
Definition government.c:82
const char * government_rule_name(const struct government *pgovern)
Definition government.c:133
#define governments_iterate(NAME_pgov)
Definition government.h:122
#define G_LAST
Definition government.h:48
#define governments_iterate_end
Definition government.h:125
struct city * owner
Definition citydlg.c:226
bool is_view_supported(enum ts_type type)
Definition graphics.c:53
void tileset_type_set(enum ts_type type)
Definition graphics.c:73
enum gui_type get_gui_type(void)
Definition gui_main.c:2100
void tileset_changed(void)
Definition mapview.c:782
GType type
Definition repodlgs.c:1313
void free_sprite(struct sprite *s)
Definition sprite.c:278
struct sprite * create_sprite(int width, int height, struct color *pcolor)
Definition sprite.c:84
struct sprite * sprite_scale(struct sprite *src, int new_w, int new_h)
Definition sprite.c:291
struct sprite * load_gfxnumber(int num)
Definition sprite.c:526
struct sprite * load_gfxfile(const char *filename, bool svgflag)
Definition sprite.c:170
const char ** gfx_fileextensions(void)
Definition sprite.c:117
bool popup_theme_suggestion_dialog(const char *theme_name)
Definition theme_dlg.c:46
static bool load_theme
Definition theme_dlg.c:30
void gui_clear_theme(void)
Definition themes.c:72
void boot_help_texts(void)
Definition helpdata.c:710
const char * improvement_rule_name(const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define B_LAST
Definition improvement.h:42
const char * name
Definition inputfile.c:127
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_fatal(message,...)
Definition log.h:100
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_base(level, message,...)
Definition log.h:94
log_level
Definition log.h:28
@ LOG_ERROR
Definition log.h:30
@ LOG_DEBUG
Definition log.h:34
@ LOG_NORMAL
Definition log.h:32
@ LOG_FATAL
Definition log.h:29
@ LOG_VERBOSE
Definition log.h:33
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1912
enum direction8 dir_ccw(enum direction8 dir)
Definition map.c:1218
bool is_valid_dir(enum direction8 dir)
Definition map.c:1275
enum direction8 dir_cw(enum direction8 dir)
Definition map.c:1189
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:375
static int img_index(const int x, const int y, const struct img *pimg)
Definition mapimg.c:1999
struct city * find_city_or_settler_near_tile(const struct tile *ptile, struct unit **punit)
void update_map_canvas_visible(void)
enum topo_comp_lvl tileset_map_topo_compatible(int topology_id, struct tileset *tset, int *tset_topo)
struct tile * get_center_tile_mapcanvas(void)
bool mapdeco_is_highlight_set(const struct tile *ptile)
#define NUM_CITY_COLORS
void center_tile_mapcanvas(const struct tile *ptile)
const struct tile * center_tile
struct tile * client_infratile(void)
const char * describe_topology(int topo)
bool can_slide
bool mapdeco_is_crosshair_set(const struct tile *ptile)
@ TOPO_INCOMP_HARD
#define H(x, y, z)
Definition md5.c:92
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_strdup(str)
Definition mem.h:43
#define fc_realloc(ptr, sz)
Definition mem.h:36
#define fc_malloc(sz)
Definition mem.h:34
void menus_init(void)
const char * modpack_tileset_target(const char *name)
Definition modpack.c:329
void modpack_tileset_cache_iterate(mrc_cb cb, void *data)
Definition modpack.c:360
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:330
#define SINGLE_MOVE
Definition movement.h:26
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
Nation_type_id nation_count(void)
Definition nation.c:507
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:463
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
struct nation_type * nation_of_city(const struct city *pcity)
Definition nation.c:454
Nation_type_id nation_index(const struct nation_type *pnation)
Definition nation.c:498
#define nations_iterate_end
Definition nation.h:336
#define nations_iterate(NAME_pnation)
Definition nation.h:333
void option_set_default_ts(struct tileset *t)
Definition options.c:6804
const char * option_str_get(const struct option *poption)
Definition options.c:928
int option_get_cb_data(const struct option *poption)
Definition options.c:822
struct client_options gui_options
Definition options.c:71
int len
Definition packhand.c:127
bool player_in_city_map(const struct player *pplayer, const struct tile *ptile)
Definition player.c:1249
int player_slot_index(const struct player_slot *pslot)
Definition player.c:426
int player_index(const struct player *pplayer)
Definition player.c:829
#define players_iterate_end
Definition player.h:539
#define players_iterate(_pplayer)
Definition player.h:534
#define player_slots_iterate(_pslot)
Definition player.h:525
#define player_slots_iterate_end
Definition player.h:529
#define fc_randomly(_seed, _size)
Definition rand.h:73
struct section_file * secfile_load(const char *filename, bool allow_duplicates)
Definition registry.c:51
const char * secfile_error(void)
const char * section_name(const struct section *psection)
void secfile_destroy(struct section_file *secfile)
void secfile_check_unused(const struct section_file *secfile)
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
struct section_list * secfile_sections_by_name_prefix(const struct section_file *secfile, const char *prefix)
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
#define section_list_iterate(seclist, psection)
#define secfile_entry_ignore(_sfile_, _fmt_,...)
#define section_list_iterate_end
#define secfile_entry_ignore_by_path(_sfile_, _path_)
bool is_cardinal_only_road(const struct extra_type *pextra)
Definition road.c:489
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
const char * fileinfoname(const struct strvec *dirs, const char *filename)
Definition shared.c:1094
const struct strvec * get_data_dirs(void)
Definition shared.c:886
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MAX(x, y)
Definition shared.h:54
#define XOR(p, q)
Definition shared.h:71
struct specialist * specialist_by_number(const Specialist_type_id id)
Definition specialist.c:100
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
size_t size
Definition specvec.h:72
struct sprite int int int int struct sprite * mask
Definition sprite_g.h:32
struct sprite int int y
Definition sprite_g.h:31
struct sprite int int int int struct sprite int int float scale
Definition sprite_g.h:33
struct sprite int x
Definition sprite_g.h:31
crop_sprite
Definition sprite_g.h:30
struct sprite int int int int struct sprite int int float bool smooth get_sprite_dimensions
Definition sprite_g.h:36
int main(int argc, char *argv[])
static bool wall(char *str, bool check)
Definition stdinhand.c:1929
void strvec_append(struct strvec *psv, const char *string)
struct strvec * strvec_new(void)
struct sprite * sprite[MAX_NUM_CITIZEN_SPRITES]
Definition tilespec.c:225
struct citizen_graphic citizen[CITIZEN_LAST]
Definition tilespec.c:229
struct citizen_graphic specialist[SP_MAX]
Definition tilespec.c:230
struct city_style_threshold * land_thresholds
Definition tilespec.c:210
int land_num_thresholds
Definition tilespec.c:209
int num_styles
Definition tilespec.c:212
struct city_sprite::@253 * styles
struct sprite * sprite
Definition tilespec.c:204
Definition city.h:320
int color_index
Definition city.h:470
bool occupied
Definition city.h:460
int walls
Definition city.h:461
citizens size
Definition city.h:332
unsigned char first_citizen_index
Definition city.h:483
struct tile * tile
Definition city.h:322
int city_image
Definition city.h:464
bool colored
Definition city.h:469
bool unhappy
Definition city.h:463
struct city::@17::@20 client
struct sprite_vector occupancy
Definition tilespec.h:338
struct rgbcolor * plr_bg_color
Definition game.h:103
struct packet_ruleset_control control
Definition game.h:83
struct packet_game_info info
Definition game.h:89
bool ruleset_ready
Definition game.h:117
struct civ_game::@31::@34 client
int topology_id
Definition map_types.h:72
struct connection conn
Definition client_main.h:96
bool draw_native
Definition options.h:216
bool draw_specials
Definition options.h:208
bool draw_city_output
Definition options.h:195
char gui_sdl3_default_theme_name[512]
Definition options.h:430
bool draw_mines
Definition options.h:206
bool draw_borders
Definition options.h:215
bool draw_fortress_airbase
Definition options.h:207
bool draw_unit_stack_size
Definition options.h:219
bool draw_irrigation
Definition options.h:205
bool draw_terrain
Definition options.h:202
bool draw_units
Definition options.h:212
int default_topology
Definition options.h:123
bool draw_fog_of_war
Definition options.h:214
bool draw_unit_shields
Definition options.h:218
char gui_sdl2_default_theme_name[512]
Definition options.h:417
bool draw_cities
Definition options.h:211
bool draw_map_grid
Definition options.h:196
bool draw_focus_unit
Definition options.h:213
bool draw_paths
Definition options.h:204
bool draw_city_outlines
Definition options.h:194
bool draw_coastline
Definition options.h:203
bool draw_full_citybar
Definition options.h:217
bool draw_pollution
Definition options.h:210
char gui_gtk5_default_theme_name[512]
Definition options.h:374
char gui_gtk4_default_theme_name[512]
Definition options.h:338
char gui_gtk3_22_default_theme_name[512]
Definition options.h:302
bool solid_color_behind_units
Definition options.h:150
Definition colors.h:21
bool established
Definition connection.h:140
struct player * playing
Definition connection.h:151
int match_index[1+MAX_NUM_MATCH_WITH]
Definition tilespec.c:182
enum match_style match_style
Definition tilespec.c:181
enum sprite_type sprite_type
Definition tilespec.c:185
struct sprite_vector allocated
Definition tilespec.c:193
struct sprite * match[MAX_INDEX_CARDINAL]
Definition tilespec.c:188
struct sprite_vector base
Definition tilespec.c:187
struct sprite ** cells
Definition tilespec.c:189
bool is_reversed
Definition tilespec.c:196
struct sprite * blend[4]
Definition tilespec.c:200
struct drawing_data::drawing_layer layer[MAX_NUM_LAYERS]
struct sprite * blender
Definition tilespec.c:199
char * name
Definition tilespec.c:171
char rmact_gfx[MAX_LEN_NAME]
Definition extras.h:102
char act_gfx_alt[MAX_LEN_NAME]
Definition extras.h:100
struct extra_type_list * hiders
Definition extras.h:144
char rmact_gfx_alt[MAX_LEN_NAME]
Definition extras.h:103
struct road_type * road
Definition extras.h:155
char rmact_gfx_alt2[MAX_LEN_NAME]
Definition extras.h:104
char graphic_alt[MAX_LEN_NAME]
Definition extras.h:98
char activity_gfx[MAX_LEN_NAME]
Definition extras.h:99
char act_gfx_alt2[MAX_LEN_NAME]
Definition extras.h:101
char graphic_str[MAX_LEN_NAME]
Definition extras.h:97
char graphic_alt[MAX_LEN_NAME]
Definition government.h:57
char graphic_str[MAX_LEN_NAME]
Definition government.h:56
char graphic_str[MAX_LEN_NAME]
Definition improvement.h:55
char graphic_alt2[MAX_LEN_NAME]
Definition improvement.h:57
char graphic_alt[MAX_LEN_NAME]
Definition improvement.h:56
struct sprite * graphic
Definition tilespec.c:405
struct sprite * tax_gold
Definition tilespec.c:249
struct sprite * government[G_LAST]
Definition tilespec.c:261
struct sprite_vector nation_shield
Definition tilespec.c:269
struct citizen_set default_citizens
Definition tilespec.c:271
struct sprite * loaded
Definition tilespec.c:301
struct sprite * even[MAX_INDEX_HALF]
Definition tilespec.c:378
struct sprite * output[O_LAST][MAX_NUM_UPKEEP_SPRITES]
Definition tilespec.c:314
struct sprite ** stack
Definition tilespec.c:300
struct sprite * infratile
Definition tilespec.c:346
struct sprite * background
Definition tilespec.c:363
struct sprite * frame[NUM_CURSOR_FRAMES]
Definition tilespec.c:277
struct sprite * patrol
Definition tilespec.c:304
struct sprite * spaceship[SPACESHIP_COUNT]
Definition tilespec.c:274
struct named_sprites::@260 city
struct sprite * rmact
Definition tilespec.c:357
struct sprite * selected[EDGE_COUNT]
Definition tilespec.c:396
struct named_sprites::@261 path
int num_stack_sprites
Definition tilespec.c:284
struct sprite * transform
Definition tilespec.c:302
struct sprite * tile_shieldnum[NUM_TILES_DIGITS]
Definition tilespec.c:323
struct sprite ** fullfog
Definition tilespec.c:351
struct sprite_vector unworked_tile_overlay
Definition tilespec.c:331
enum extrastyle_id extrastyle
Definition tilespec.c:358
struct sprite * tile_foodnum[NUM_TILES_DIGITS]
Definition tilespec.c:322
struct sprite * turns[NUM_TILES_DIGITS]
Definition tilespec.c:338
struct sprite_vector nation_flag
Definition tilespec.c:268
struct sprite * nonnative
Definition tilespec.c:395
struct sprite * plant
Definition tilespec.c:297
bool no_more_stack_sprites
Definition tilespec.c:285
struct city_sprite * single_wall
Definition tilespec.c:327
struct named_sprites::@255 units
struct sprite * indicator[INDICATOR_COUNT][NUM_TILES_PROGRESS]
Definition tilespec.c:239
struct sprite * borders[EDGE_COUNT][2]
Definition tilespec.c:398
struct sprite * size_tens[NUM_TILES_DIGITS]
Definition tilespec.c:320
struct city_sprite * tile
Definition tilespec.c:325
struct sprite * disorder
Definition tilespec.c:317
struct sprite * tile_tradenum[NUM_TILES_DIGITS]
Definition tilespec.c:324
struct sprite * unworked_tile
Definition tilespec.c:256
struct sprite * waypoint
Definition tilespec.c:342
struct sprite * pillage
Definition tilespec.c:298
struct named_sprites::@254 mask
struct sprite * fortified
Definition tilespec.c:293
struct sprite * dither_tile
Definition tilespec.c:250
struct sprite * coastline[EDGE_COUNT]
Definition tilespec.c:397
union named_sprites::@264::@270 u
struct sprite * tired
Definition tilespec.c:309
struct style_citizen_set style_citizen_sets
Definition tilespec.c:272
struct sprite * isolated
Definition tilespec.c:369
struct sprite * treaty_thumb[2]
Definition tilespec.c:241
struct named_sprites::@257 explode
struct sprite * sentry
Definition tilespec.c:299
struct sprite * tax_luxury
Definition tilespec.c:249
struct sprite_vector unit
Definition tilespec.c:280
struct sprite * building[B_LAST]
Definition tilespec.c:260
struct sprite * turns_hundreds[NUM_TILES_DIGITS]
Definition tilespec.c:340
struct sprite * total[MAX_INDEX_VALID]
Definition tilespec.c:383
struct sprite * action_decision_want
Definition tilespec.c:307
struct named_sprites::@264::@270::@271 bmf
struct named_sprites::@268 player[MAX_NUM_PLAYER_SLOTS]
struct named_sprites::@259 upkeep
struct sprite * unhappy[MAX_NUM_UPKEEP_SPRITES]
Definition tilespec.c:312
struct sprite_vector worked_tile_overlay
Definition tilespec.c:330
struct sprite * corner[8]
Definition tilespec.c:372
struct sprite * darkness[MAX_INDEX_CARDINAL]
Definition tilespec.c:352
struct named_sprites::@266 colors
struct named_sprites::@261::@269 s[GTS_COUNT]
struct sprite * tax_science
Definition tilespec.c:249
struct sprite * icon[ICON_COUNT]
Definition tilespec.c:244
struct named_sprites::@264::@270::@272 road
struct sprite * specific
Definition tilespec.c:337
struct named_sprites::@264 extras[MAX_EXTRA_TYPES]
struct sprite * odd[MAX_INDEX_HALF]
Definition tilespec.c:380
struct sprite * color
Definition tilespec.c:404
struct named_sprites::@256 cursor[CURSOR_LAST]
struct sprite * unavailable
Definition tilespec.c:394
struct sprite * worked_tile
Definition tilespec.c:255
struct river_sprites rivers
Definition tilespec.c:384
struct drawing_data * drawing[MAX_NUM_ITEMS]
Definition tilespec.c:413
struct sprite * go_to
Definition tilespec.c:295
struct sprite * middleground
Definition tilespec.c:365
struct sprite * foreground
Definition tilespec.c:366
struct citybar_sprites citybar
Definition tilespec.c:333
struct sprite * auto_explore
Definition tilespec.c:292
struct sprite * turns_tens[NUM_TILES_DIGITS]
Definition tilespec.c:339
struct sprite * tech[A_LAST]
Definition tilespec.c:259
struct sprite * nuke
Definition tilespec.c:281
struct named_sprites::@263 tx
struct sprite * convert
Definition tilespec.c:305
struct sprite * worked[EDGE_COUNT]
Definition tilespec.c:393
struct sprite_vector overlays
Definition tilespec.c:401
struct editor_sprites editor
Definition tilespec.c:334
struct sprite * size_hundreds[NUM_TILES_DIGITS]
Definition tilespec.c:321
struct sprite * activity
Definition tilespec.c:355
struct named_sprites::@262 user
struct sprite * size[NUM_TILES_DIGITS]
Definition tilespec.c:319
struct sprite * cardinals[MAX_INDEX_CARDINAL]
Definition tilespec.c:361
union named_sprites::@264::@270::@272::@273 ru
struct sprite * fortifying
Definition tilespec.c:294
struct sprite * main[EDGE_COUNT]
Definition tilespec.c:390
struct sprite * events[E_COUNT]
Definition tilespec.c:246
struct sprite * auto_attack
Definition tilespec.c:290
struct city_sprite * wall[NUM_WALL_TYPES]
Definition tilespec.c:328
struct sprite * connect
Definition tilespec.c:303
struct sprite * fog
Definition tilespec.c:349
struct named_sprites::@264::@270::@272::@273::@274 combo
struct named_sprites::@265 grid
struct sprite * arrow[ARROW_LAST]
Definition tilespec.c:242
struct sprite * dir[8]
Definition tilespec.c:375
struct sprite * single
Definition tilespec.c:360
struct sprite * grid_borders[EDGE_COUNT][2]
Definition tilespec.c:408
struct sprite * facing[U_LAST][DIR8_MAGIC_MAX][ACTIVITY_LAST]
Definition tilespec.c:265
struct sprite * attention
Definition tilespec.c:345
struct city_sprite * occupied
Definition tilespec.c:329
struct sprite * tile
Definition tilespec.c:253
struct sprite * cultivate
Definition tilespec.c:296
struct sprite * auto_worker
Definition tilespec.c:291
struct sprite * lowfuel
Definition tilespec.c:308
char flag_graphic_str[MAX_LEN_NAME]
Definition nation.h:103
char flag_graphic_alt[MAX_LEN_NAME]
Definition nation.h:104
enum borders_mode borders
Definition goto.c:52
struct sprite * spec[MAX_INDEX_CARDINAL]
Definition tilespec.c:216
struct sprite * outlet[MAX_INDEX_CARDINAL]
Definition tilespec.c:218
struct sprite * sprite
Definition themespec.c:109
char * file
Definition themespec.c:100
struct specfile * sf
Definition themespec.c:103
char * file_name
Definition themespec.c:80
struct sprite * big_sprite
Definition themespec.c:79
char graphic_alt[MAX_LEN_NAME]
Definition specialist.h:36
Definition map.c:40
struct citizen_set * sets
Definition tilespec.c:234
char graphic_alt2[MAX_LEN_NAME]
Definition terrain.h:82
char graphic_alt[MAX_LEN_NAME]
Definition terrain.h:81
char graphic_str[MAX_LEN_NAME]
Definition terrain.h:80
Definition tile.h:50
char * spec_sprite
Definition tile.h:67
struct unit_list * units
Definition tile.h:58
struct extra_type * placing
Definition tile.h:61
struct city * worked
Definition tile.h:59
char given_name[MAX_LEN_NAME]
Definition tilespec.c:484
int num_cardinal_tileset_dirs
Definition tilespec.c:536
int occupied_offset_x
Definition tilespec.c:529
int stack_size_offset_y
Definition tilespec.c:528
struct named_sprites sprites
Definition tilespec.c:556
int ts_topo_idx
Definition tilespec.c:498
int hex_height
Definition tilespec.c:497
enum fog_style fogstyle
Definition tilespec.c:512
int normal_tile_height
Definition tilespec.c:500
int unit_tile_width
Definition tilespec.c:502
int city_offset_y
Definition tilespec.c:518
char * main_intro_filename
Definition tilespec.c:508
enum ts_type type
Definition tilespec.c:496
int city_size_offset_x
Definition tilespec.c:519
int num_preferred_themes
Definition tilespec.c:564
char version[MAX_LEN_NAME]
Definition tilespec.c:485
int full_tile_height
Definition tilespec.c:501
int small_sprite_width
Definition tilespec.c:503
char ** preferred_themes
Definition tilespec.c:565
struct extra_type_list * flagged_bases_list
Definition tilespec.c:562
enum darkness_style darkness_style
Definition tilespec.c:513
int activity_offset_x
Definition tilespec.c:523
int citybar_offset_y
Definition tilespec.c:521
int normal_tile_width
Definition tilespec.c:500
float scale
Definition tilespec.c:490
int svg_height
Definition tilespec.c:506
int unit_tile_height
Definition tilespec.c:502
int hex_width
Definition tilespec.c:497
int select_offset_y
Definition tilespec.c:526
int city_flag_offset_x
Definition tilespec.c:516
int unit_flag_offset_x
Definition tilespec.c:515
int occupied_offset_y
Definition tilespec.c:530
char * description
Definition tilespec.c:489
int max_upkeep_height
Definition tilespec.c:505
int unit_flag_offset_y
Definition tilespec.c:515
int unit_upkeep_offset_y
Definition tilespec.c:531
struct estyle_hash * estyle_hash
Definition tilespec.c:554
char * for_ruleset
Definition tilespec.c:492
int activity_offset_y
Definition tilespec.c:524
int num_index_valid
Definition tilespec.c:537
int select_offset_x
Definition tilespec.c:525
int num_index_cardinal
Definition tilespec.c:537
int full_tile_width
Definition tilespec.c:501
struct small_sprite_list * small_sprites
Definition tilespec.c:546
struct extra_type_list * style_lists[ESTYLE_COUNT]
Definition tilespec.c:560
enum direction8 unit_default_orientation
Definition tilespec.c:510
struct tileset::tileset_layer layers[MAX_NUM_LAYERS]
int small_sprite_height
Definition tilespec.c:503
int city_size_offset_y
Definition tilespec.c:519
struct sprite_hash * sprite_hash
Definition tilespec.c:549
int unit_upkeep_small_offset_y
Definition tilespec.c:532
int unit_offset_x
Definition tilespec.c:517
int unit_offset_y
Definition tilespec.c:517
enum mapview_layer layer_order[LAYER_COUNT]
Definition tilespec.c:494
int city_offset_x
Definition tilespec.c:518
int priority
Definition tilespec.c:486
enum direction8 cardinal_tileset_dirs[8]
Definition tilespec.c:538
enum direction8 valid_tileset_dirs[8]
Definition tilespec.c:538
struct color_system * color_system
Definition tilespec.c:558
char * summary
Definition tilespec.c:488
char name[512]
Definition tilespec.c:483
int city_flag_offset_y
Definition tilespec.c:516
struct drawing_hash * tile_hash
Definition tilespec.c:552
int num_valid_tileset_dirs
Definition tilespec.c:536
int stack_size_offset_x
Definition tilespec.c:527
struct specfile_list * specfiles
Definition tilespec.c:545
int tilelabel_offset_y
Definition tilespec.c:522
struct strvec * list
Definition tilespec.c:1101
Definition unit.h:140
struct unit::@80 orders
bool occupied
Definition unit.h:222
enum action_decision action_decision_want
Definition unit.h:205
int battlegroup
Definition unit.h:194
enum unit_activity activity
Definition unit.h:159
int moves_left
Definition unit.h:152
struct unit::@81::@83 client
int hp
Definition unit.h:153
int fuel
Definition unit.h:155
enum direction8 facing
Definition unit.h:144
struct extra_type * activity_target
Definition unit.h:167
bool repeat
Definition unit.h:199
int veteran
Definition unit.h:154
enum server_side_agent ssa_controller
Definition unit.h:175
struct civ_map map
int style_of_city(const struct city *pcity)
Definition style.c:202
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:777
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:986
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
Definition support.c:886
#define sz_strlcpy(dest, src)
Definition support.h:189
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char ** ordered_gfx_fextensions(void)
Definition svgflag.c:53
#define is_svg_flag_enabled()
Definition svgflag.h:30
struct advance * valid_advance(struct advance *padvance)
Definition tech.c:152
const char * advance_rule_name(const struct advance *padvance)
Definition tech.c:309
Tech_type_id advance_index(const struct advance *padvance)
Definition tech.c:89
static Tech_type_id advance_count(void)
Definition tech.h:170
#define advance_iterate(_p)
Definition tech.h:276
#define advance_iterate_end
Definition tech.h:277
#define A_LAST
Definition tech.h:45
Terrain_type_id terrain_index(const struct terrain *pterrain)
Definition terrain.c:138
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
enum terrain_class terrain_type_terrain_class(const struct terrain *pterrain)
Definition terrain.c:582
#define terrain_type_iterate(_p)
Definition terrain.h:266
#define T_UNKNOWN
Definition terrain.h:62
#define is_ocean_tile(ptile)
Definition terrain.h:196
#define terrain_type_iterate_end
Definition terrain.h:272
#define tile_index(_pt_)
Definition tile.h:89
#define tile_worked(_tile)
Definition tile.h:115
@ TILE_KNOWN_UNSEEN
Definition tile.h:37
@ TILE_UNKNOWN
Definition tile.h:36
@ TILE_KNOWN_SEEN
Definition tile.h:38
#define tile_terrain(_tile)
Definition tile.h:111
#define TILE_XY(ptile)
Definition tile.h:43
static const bv_extras * tile_extras(const struct tile *ptile)
Definition tile.h:121
#define tile_has_extra(ptile, pextra)
Definition tile.h:148
#define tile_owner(_tile)
Definition tile.h:97
static int fill_unit_type_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct unit_type *putype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:4577
struct sprite * get_government_sprite(const struct tileset *t, const struct government *gov)
Definition tilespec.c:6832
void tileset_load_tiles(struct tileset *t)
Definition tilespec.c:3662
struct sprite * get_nuke_explode_sprite(const struct tileset *t)
Definition tilespec.c:6968
#define sprite_hash_iterate(hash, tag_name, sprite)
Definition tilespec.c:463
int tileset_hex_width(const struct tileset *t)
Definition tilespec.c:722
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:6822
#define SET_SPRITE_DEPR_ALT(field, tag, alt, ver)
Definition tilespec.c:2893
int tileset_unit_width(const struct tileset *t)
Definition tilespec.c:798
static int fill_goto_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner)
Definition tilespec.c:5714
#define NUM_TILES_SELECT
Definition tilespec.c:115
struct unit * get_drawable_unit(const struct tileset *t, struct tile *ptile, const struct city *citymode)
Definition tilespec.c:6603
static int check_sprite_type(const char *sprite_type, const char *tile_section)
Definition tilespec.c:1885
struct sprite * get_attention_crosshair_sprite(const struct tileset *t)
Definition tilespec.c:7029
int tileset_unit_height(const struct tileset *t)
Definition tilespec.c:806
static struct tileset * tileset_new(void)
Definition tilespec.c:972
#define MAX_INDEX_VALID
Definition tilespec.c:111
void tileset_setup_unit_type(struct tileset *t, struct unit_type *ut)
Definition tilespec.c:3840
static bool check_tilespec_capabilities(struct section_file *file, const char *which, const char *us_capstr, const char *filename, bool verbose)
Definition tilespec.c:1180
int tileset_small_sprite_width(const struct tileset *t)
Definition tilespec.c:902
static struct sprite * load_gfx_file(const char *gfx_filename, bool svgflag)
Definition tilespec.c:1578
#define specfile_list_iterate_end
Definition tilespec.c:427
static struct sprite * create_plr_sprite(struct color *pcolor)
Definition tilespec.c:2799
int tileset_svg_flag_height(struct tileset *t)
Definition tilespec.c:7613
#define SPEC_CAPSTR
Definition tilespec.c:97
static struct sprite * get_unit_nation_flag_sprite(const struct tileset *t, const struct unit *punit)
Definition tilespec.c:4512
direction4
Definition tilespec.c:139
@ DIR4_EAST
Definition tilespec.c:140
@ DIR4_NORTH
Definition tilespec.c:140
@ DIR4_SOUTH
Definition tilespec.c:140
@ DIR4_WEST
Definition tilespec.c:140
struct tileset * get_tileset(void)
Definition tilespec.c:693
#define MAX_NUM_MATCH_WITH
Definition tilespec.c:180
static struct sprite * get_city_sprite(const struct city_sprite *city_sprite, const struct city *pcity)
Definition tilespec.c:3068
void tileset_setup_government(struct tileset *t, struct government *gov)
Definition tilespec.c:4453
#define sprite_hash_iterate_end
Definition tilespec.c:466
struct sprite * get_city_flag_sprite(const struct tileset *t, const struct city *pcity)
Definition tilespec.c:4503
void tileset_setup_specialist_type_default_set(struct tileset *t, Specialist_type_id id)
Definition tilespec.c:2924
static bool is_valid_tileset_dir(const struct tileset *t, enum direction8 dir)
Definition tilespec.c:1031
struct sprite * get_basic_fog_sprite(const struct tileset *t)
Definition tilespec.c:7092
static enum direction8 dir_by_tileset_name(const char *str)
Definition tilespec.c:1013
#define ADD_SPRITE_SIMPLE(s)
Definition tilespec.c:4534
static int fill_basic_road_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
Definition tilespec.c:7278
static int fill_unit_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct unit *punit, int stack, bool backdrop)
Definition tilespec.c:4596
int tileset_full_tile_height(const struct tileset *t)
Definition tilespec.c:790
bool tilespec_try_read(const char *tileset_name, bool verbose, int topo_id, bool global_default)
Definition tilespec.c:1335
static bool tileset_setup_unit_type_from_tag(struct tileset *t, int uidx, const char *tag)
Definition tilespec.c:3783
struct tileset * unscaled_tileset
Definition tilespec.c:569
static int fill_irrigation_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, bv_extras textras, bv_extras *textras_near, const struct city *pcity)
Definition tilespec.c:5069
int fill_basic_extra_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
Definition tilespec.c:7243
#define specfile_list_iterate(list, pitem)
Definition tilespec.c:425
struct sprite * get_unit_upkeep_sprite(const struct tileset *t, Output_type_id otype, const struct unit *punit, const int *upkeep_cost)
Definition tilespec.c:7074
const char * tileset_main_intro_filename(const struct tileset *t)
Definition tilespec.c:948
void tileset_setup_tile_type(struct tileset *t, const struct terrain *pterrain)
Definition tilespec.c:4187
static const char direction4letters[4]
Definition tilespec.c:142
void tileset_player_init(struct tileset *t, struct player *pplayer)
Definition tilespec.c:7414
const struct strvec * get_tileset_list(const struct option *poption)
Definition tilespec.c:1125
int tileset_unit_layout_offset_y(const struct tileset *t)
Definition tilespec.c:883
int tileset_citybar_offset_y(const struct tileset *t)
Definition tilespec.c:911
#define MAX_NUM_UPKEEP_SPRITES
Definition tilespec.c:116
struct sprite * get_treaty_thumb_sprite(const struct tileset *t, bool on_off)
Definition tilespec.c:6948
bool unit_drawn_with_city_outline(const struct unit *punit, bool check_focus)
Definition tilespec.c:5547
#define MAX_INDEX_HALF
Definition tilespec.c:110
double get_focus_unit_toggle_timeout(const struct tileset *t)
Definition tilespec.c:6558
#define SET_SPRITE_ALT_OPT(field, tag, alt)
Definition tilespec.c:2914
static int calculate_max_upkeep_height(const struct tileset *t)
Definition tilespec.c:814
static int fill_fog_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner)
Definition tilespec.c:5231
#define TILE_SECTION_PREFIX
Definition tilespec.c:106
static struct city_sprite * load_city_sprite(struct tileset *t, const char *tag)
Definition tilespec.c:3145
static char * valid_index_str(const struct tileset *t, int idx)
Definition tilespec.c:2706
void tileset_free_tiles(struct tileset *t)
Definition tilespec.c:6643
void tileset_setup_impr_type(struct tileset *t, struct impr_type *pimprove)
Definition tilespec.c:3874
static struct tileset * tileset_read_toplevel(const char *tileset_name, bool verbose, int topology_id, float scale)
Definition tilespec.c:1906
static bool sprite_exists(const struct tileset *t, const char *tag_name)
Definition tilespec.c:2843
const struct sprite_vector * get_unit_explode_animation(const struct tileset *t)
Definition tilespec.c:6957
#define TILESPEC_CAPSTR
Definition tilespec.c:81
static int load_city_thresholds_sprites(struct tileset *t, const char *tag, char *graphic, char *graphic_alt, struct city_style_threshold **thresholds)
Definition tilespec.c:3104
struct sprite * load_popup_sprite(const char *tag)
Definition tilespec.c:7621
static void unload_all_sprites(struct tileset *t)
Definition tilespec.c:6629
static const char * dir_get_tileset_name(enum direction8 dir)
Definition tilespec.c:986
#define SET_SPRITE_UNSCALED(field, tag)
Definition tilespec.c:2869
void tileset_background_init(struct tileset *t)
Definition tilespec.c:7494
void tileset_setup_tech_type(struct tileset *t, struct advance *padvance)
Definition tilespec.c:3890
static const int DIR4_TO_DIR8[4]
Definition tilespec.c:146
static int fill_terrain_sprite_layer(struct tileset *t, struct drawn_sprite *sprs, int layer_num, const struct tile *ptile, const struct terrain *pterrain, struct terrain **tterrain_near)
Definition tilespec.c:5502
static void unload_sprite(struct tileset *t, const char *tag_name)
Definition tilespec.c:2819
static void drawing_data_destroy(struct drawing_data *draw)
Definition tilespec.c:661
static int fill_terrain_sprite_darkness(struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, struct terrain **tterrain_near)
Definition tilespec.c:5438
#define small_sprite_list_iterate_end
Definition tilespec.c:456
static struct drawing_data * drawing_data_new(void)
Definition tilespec.c:649
static void build_tile_data(const struct tile *ptile, struct terrain *pterrain, struct terrain **tterrain_near, bv_extras *textras_near)
Definition tilespec.c:4545
static void tileset_player_free(struct tileset *t, int plrid)
Definition tilespec.c:7465
float tileset_scale(const struct tileset *t)
Definition tilespec.c:928
#define UNKNOWN(dir)
int tileset_unit_with_small_upkeep_height(const struct tileset *t)
Definition tilespec.c:872
bool tileset_layer_in_category(enum mapview_layer layer, enum layer_category cat)
Definition tilespec.c:7371
static int fill_grid_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner, const struct unit *punit, const struct city *pcity, const struct city *citymode)
Definition tilespec.c:5564
match_style
Definition tilespec.c:149
@ MATCH_SAME
Definition tilespec.c:151
@ MATCH_FULL
Definition tilespec.c:153
@ MATCH_PAIR
Definition tilespec.c:152
@ MATCH_NONE
Definition tilespec.c:150
#define small_sprite_list_iterate(list, pitem)
Definition tilespec.c:454
static void ts_cb(const char *modpack_name, const char *filename, void *data)
Definition tilespec.c:1307
int tileset_num_city_colors(const struct tileset *t)
Definition tilespec.c:956
int index_ts_topology(int idx)
Definition tilespec.c:1086
#define NUM_TILES_HP_BAR
Definition tilespec.c:113
#define TILESPEC_SUFFIX
Definition tilespec.c:105
bool tileset_is_isometric(const struct tileset *t)
Definition tilespec.c:713
bool tileset_use_hard_coded_fog(const struct tileset *t)
Definition tilespec.c:964
void tileset_use_preferred_theme(const struct tileset *t)
Definition tilespec.c:7108
#define FULL_TILE_X_OFFSET
Definition tilespec.c:4524
sprite_type
Definition tilespec.c:156
@ CELL_CORNER
Definition tilespec.c:158
@ CELL_WHOLE
Definition tilespec.c:157
void tileset_setup_city_tiles(struct tileset *t, int style)
Definition tilespec.c:6493
struct sprite * get_nation_shield_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6804
const char * tileset_description(struct tileset *t)
Definition tilespec.c:7589
#define SET_GOTO_TURN_SPRITE(state, state_name, factor, factor_name)
void tileset_background_free(struct tileset *t)
Definition tilespec.c:7513
#define MAX_NUM_LAYERS
Definition tilespec.c:174
int tileset_unit_layout_small_offset_y(const struct tileset *t)
Definition tilespec.c:892
struct sprite * get_event_sprite(const struct tileset *t, enum event_type event)
Definition tilespec.c:6939
void toggle_focus_unit_state(struct tileset *t)
Definition tilespec.c:6590
void tilespec_reread_frozen_refresh(const char *tname)
Definition tilespec.c:1566
int tileset_small_sprite_height(const struct tileset *t)
Definition tilespec.c:938
void tileset_free(struct tileset *t)
Definition tilespec.c:1290
static const char * cardinal_index_str(const struct tileset *t, int idx)
Definition tilespec.c:2686
#define NUM_TILES_DIGITS
Definition tilespec.c:114
void focus_unit_in_combat(struct tileset *t)
Definition tilespec.c:6579
static int tileset_upkeep_height(const struct tileset *t)
Definition tilespec.c:851
const char * tileset_summary(struct tileset *t)
Definition tilespec.c:7581
struct sprite * get_icon_sprite(const struct tileset *t, enum icon_type icon)
Definition tilespec.c:7018
static void ensure_big_sprite(struct specfile *sf, const char *tset_name)
Definition tilespec.c:1614
static bool tileset_update
Definition tilespec.c:573
#define FULL_TILE_Y_OFFSET
Definition tilespec.c:4525
struct sprite * get_indicator_sprite(const struct tileset *t, enum indicator_type indicator, int idx)
Definition tilespec.c:7038
struct sprite * get_sample_city_sprite(const struct tileset *t, int style_idx)
Definition tilespec.c:6890
#define ADD_SPRITE_FULL(s)
Definition tilespec.c:4535
void tileset_setup_extra(struct tileset *t, struct extra_type *pextra)
Definition tilespec.c:3909
int focus_unit_state
Definition tilespec.c:571
void tileset_init(struct tileset *t)
Definition tilespec.c:7169
static int fill_city_overlays_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct city *citymode)
Definition tilespec.c:5111
static char * tilespec_gfx_filename(const char *gfx_filename, const char *tset_name)
Definition tilespec.c:1820
const char * tileset_basename(const struct tileset *t)
Definition tilespec.c:705
int fill_basic_terrain_layer_sprite_array(struct tileset *t, struct drawn_sprite *sprs, int layer, struct terrain *pterrain)
Definition tilespec.c:7210
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:766
#define LOAD_FACING_SPRITE(dir)
#define SET_SPRITE_NOTSMOOTH(field, tag)
Definition tilespec.c:2860
static int fill_road_corner_sprites(const struct tileset *t, const struct extra_type *pextra, struct drawn_sprite *sprs, bool road, bool *road_near, bool hider, bool *hider_near)
Definition tilespec.c:4786
static bool is_extra_drawing_enabled(struct extra_type *pextra)
Definition tilespec.c:5782
struct sprite * get_spaceship_sprite(const struct tileset *t, enum spaceship_part part)
Definition tilespec.c:6730
int tileset_unit_with_upkeep_height(const struct tileset *t)
Definition tilespec.c:860
static void tileset_free_toplevel(struct tileset *t)
Definition tilespec.c:1218
static struct sprite * load_sprite(struct tileset *t, const char *tag_name, bool scale, bool smooth, bool svgflag)
Definition tilespec.c:2729
struct sprite * get_cursor_sprite(const struct tileset *t, enum cursor_type cursor, int *hot_x, int *hot_y, int frame)
Definition tilespec.c:6999
static const char edge_name[EDGE_COUNT][3]
Definition tilespec.c:144
struct color_system * get_color_system(const struct tileset *t)
Definition tilespec.c:7100
int tileset_hex_height(const struct tileset *t)
Definition tilespec.c:731
void reset_focus_unit_state(struct tileset *t)
Definition tilespec.c:6571
static const char * citizen_rule_name(enum citizen_category citizen)
Definition tilespec.c:2661
static void tileset_setup_citizen_types_default_set(struct tileset *t)
Definition tilespec.c:3018
bool tileset_is_fully_loaded(void)
Definition tilespec.c:7557
static int fill_terrain_sprite_blending(const struct tileset *t, struct drawn_sprite *sprs, const struct tile *ptile, const struct terrain *pterrain, struct terrain **tterrain_near)
Definition tilespec.c:5191
const struct citybar_sprites * get_citybar_sprites(const struct tileset *t)
Definition tilespec.c:6976
static bool is_cardinal_tileset_dir(const struct tileset *t, enum direction8 dir)
Definition tilespec.c:1049
void unload_popup_sprite(const char *tag)
Definition tilespec.c:7629
#define SET_SPRITE(field, tag)
Definition tilespec.c:2850
static void tileset_lookup_sprite_tags(struct tileset *t)
Definition tilespec.c:3193
struct sprite * get_arrow_sprite(const struct tileset *t, enum arrow_type arrow)
Definition tilespec.c:6907
struct sprite * get_unit_unhappy_sprite(const struct tileset *t, const struct unit *punit, int happy_cost)
Definition tilespec.c:7055
#define NUM_CORNER_DIRS
Definition tilespec.c:534
static int fill_basic_base_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
Definition tilespec.c:7326
static void tileset_setup_base(struct tileset *t, const struct extra_type *pextra, const char *tag)
Definition tilespec.c:4149
static int fill_road_sprite_array(const struct tileset *t, const struct extra_type *pextra, struct drawn_sprite *sprs, bv_extras textras, bv_extras *textras_near, struct terrain *tterrain_near[8], const struct city *pcity)
Definition tilespec.c:4837
void finish_loading_sprites(struct tileset *t)
Definition tilespec.c:3646
static bool tileset_scan_single_list(struct tileset *t, const char *spec_filenames[], int num_spec_files, bool verbose, bool duplicates_ok)
Definition tilespec.c:1851
struct sprite * tiles_lookup_sprite_tag_alt(struct tileset *t, enum log_level level, const char *tag, const char *alt, const char *alt2, const char *what, const char *name, bool scale)
Definition tilespec.c:3673
#define SET_EDITOR_SPRITE(x)
#define SET_SPRITE_ALT(field, tag, alt)
Definition tilespec.c:2879
#define SET_SPRITE_OPT(field, tag)
Definition tilespec.c:2911
void tilespec_reread_callback(struct option *poption)
Definition tilespec.c:1530
static void tileset_setup_specialist_type(struct tileset *t, struct citizen_set *set, Specialist_type_id id, const char *tag_group, const char *set_name, bool required)
Definition tilespec.c:2934
static bool load_river_sprites(struct tileset *t, struct river_sprites *store, const char *tag_pfx)
Definition tilespec.c:3612
const char * tileset_name_get(struct tileset *t)
Definition tilespec.c:7565
static char * tilespec_fullname(const char *tileset_name)
Definition tilespec.c:1156
static const struct citizen_graphic * get_citizen_graphic(const struct citizen_set *set, enum citizen_category type)
Definition tilespec.c:6740
int fill_sprite_array(struct tileset *t, struct drawn_sprite *sprs, enum mapview_layer layer, const struct tile *ptile, const struct tile_edge *pedge, const struct tile_corner *pcorner, const struct unit *punit, const struct city *pcity, const struct city *citymode, const struct unit_type *putype)
Definition tilespec.c:5849
#define ADD_SPRITE(s, draw_fog, x_offset, y_offset)
Definition tilespec.c:4527
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:777
struct sprite * get_tax_sprite(const struct tileset *t, Output_type_id otype)
Definition tilespec.c:6918
static bool tileset_setup_unit_direction(struct tileset *t, int uidx, const char *base_str, enum direction8 dir, enum unit_activity activity, bool has_icon)
Definition tilespec.c:3719
struct sprite * get_citizen_sprite(const struct tileset *t, enum citizen_category type, int citizen_index, const struct city *pcity)
Definition tilespec.c:6761
static int fill_terrain_sprite_array(struct tileset *t, struct drawn_sprite *sprs, int l, const struct tile *ptile, const struct terrain *pterrain, struct terrain **tterrain_near, struct drawing_data *draw)
Definition tilespec.c:5285
const char * tileset_version(struct tileset *t)
Definition tilespec.c:7573
static void free_city_sprite(struct city_sprite *city_sprite)
Definition tilespec.c:3173
static int ts_topology_index(int actual_topology)
Definition tilespec.c:1064
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:6844
char * tileset_what_ruleset(struct tileset *t)
Definition tilespec.c:7597
static void ts_list_cb(const char *modpack_name, const char *filename, void *data)
Definition tilespec.c:1108
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6795
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:754
int tileset_tilelabel_offset_y(const struct tileset *t)
Definition tilespec.c:920
static void tileset_setup_citizen_types(struct tileset *t, struct citizen_set *set, const char *tag_group, const char *set_name, bool required)
Definition tilespec.c:3027
static void tileset_setup_road(struct tileset *t, struct extra_type *pextra, const char *tag)
Definition tilespec.c:4041
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6813
#define MATCH(dir)
static int get_irrigation_index(const struct tileset *t, struct extra_type *pextra, bv_extras *textras_near)
Definition tilespec.c:5049
#define MAX_INDEX_CARDINAL
Definition tilespec.c:109
void tileset_error(enum log_level level, const char *tset_name, const char *format,...)
Definition tilespec.c:625
const struct editor_sprites * get_editor_sprites(const struct tileset *t)
Definition tilespec.c:6988
int tileset_topo_index(struct tileset *t)
Definition tilespec.c:7605
bool tilespec_reread(const char *new_tileset_name, bool game_fully_initialized, float scale)
Definition tilespec.c:1376
spec_file_types
Definition tilespec.c:161
@ SFILE_COMMON
Definition tilespec.c:162
@ SFILE_PIXEL
Definition tilespec.c:164
@ SFILE_LAST
Definition tilespec.c:165
@ SFILE_SVG
Definition tilespec.c:163
void tileset_setup_nation_flag(struct tileset *t, struct nation_type *nation)
Definition tilespec.c:4468
void tileset_ruleset_reset(struct tileset *t)
Definition tilespec.c:7529
#define ADD_SPRITE_IF_NOT_NULL(x)
static void scan_specfile(struct tileset *t, struct specfile *sf, bool duplicates_ok)
Definition tilespec.c:1655
enum mapview_layer tileset_get_layer(const struct tileset *t, int n)
Definition tilespec.c:7362
#define NUM_EDGE_TILES
Definition tilespec.h:101
#define NUM_CURSOR_FRAMES
Definition tilespec.h:305
indicator_type
Definition tilespec.h:307
@ INDICATOR_COUNT
Definition tilespec.h:311
arrow_type
Definition tilespec.h:201
@ ARROW_LAST
Definition tilespec.h:205
@ ARROW_MINUS
Definition tilespec.h:204
@ ARROW_RIGHT
Definition tilespec.h:202
@ ARROW_PLUS
Definition tilespec.h:203
#define TS_TOPO_ISOHEX
Definition tilespec.h:457
#define TERRAIN_LAYER_COUNT
Definition tilespec.h:175
#define sprite_vector_iterate_end
Definition tilespec.h:46
#define NUM_CORNER_TILES
Definition tilespec.h:108
#define NUM_TILES_PROGRESS
Definition tilespec.h:197
#define MAX_NUM_CITIZEN_SPRITES
Definition tilespec.h:199
#define TS_TOPO_HEX
Definition tilespec.h:456
#define TS_TOPO_SQUARE
Definition tilespec.h:455
layer_category
Definition tilespec.h:191
@ LAYER_CATEGORY_TILE
Definition tilespec.h:193
@ LAYER_CATEGORY_CITY
Definition tilespec.h:192
@ LAYER_CATEGORY_UNIT
Definition tilespec.h:194
icon_type
Definition tilespec.h:314
@ ICON_COUNT
Definition tilespec.h:317
@ EDGE_UD
Definition tilespec.h:95
@ EDGE_LR
Definition tilespec.h:96
@ EDGE_COUNT
Definition tilespec.h:97
spaceship_part
Definition tilespec.h:320
@ SPACESHIP_COUNT
Definition tilespec.h:328
#define NUM_WALL_TYPES
Definition tilespec.h:361
#define sprite_vector_iterate(sprite_vec, psprite)
Definition tilespec.h:44
cursor_type
Definition tilespec.h:289
@ CURSOR_LAST
Definition tilespec.h:301
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2699
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2483
bool is_flagless_to_player(const struct unit *punit, const struct player *pplayer)
Definition unit.c:366
bool unit_has_orders(const struct unit *punit)
Definition unit.c:205
#define unit_tile(_pu)
Definition unit.h:397
#define BATTLEGROUP_NONE
Definition unit.h:193
#define unit_owner(_pu)
Definition unit.h:396
#define activity_type_iterate(_act_)
Definition unit.h:287
#define activity_type_iterate_end
Definition unit.h:292
#define MAX_NUM_BATTLEGROUPS
Definition unit.h:192
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1578
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
#define utype_fuel(ptype)
Definition unittype.h:843
#define unit_type_iterate(_p)
Definition unittype.h:859
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:866
#define worker_task_list_iterate(tasklist, ptask)
Definition workertask.h:33
#define worker_task_list_iterate_end
Definition workertask.h:35