File: extras.h

package info (click to toggle)
freeciv 2.6.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 212,508 kB
  • sloc: ansic: 443,831; cpp: 29,541; sh: 7,982; makefile: 7,886; python: 1,933; xml: 945
file content (274 lines) | stat: -rw-r--r-- 10,990 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/***********************************************************************
 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
***********************************************************************/
#ifndef FC__EXTRAS_H
#define FC__EXTRAS_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* common */
#include "base.h"
#include "fc_types.h"
#include "road.h"
#include "terrain.h"

/* Used in the network protocol. */
#define SPECENUM_NAME extra_flag_id
/* Tile with this extra is considered native for units in tile. */
#define SPECENUM_VALUE0 EF_NATIVE_TILE
#define SPECENUM_VALUE0NAME N_("?extraflag:NativeTile")
/* Refuel native units */
#define SPECENUM_VALUE1 EF_REFUEL
#define SPECENUM_VALUE1NAME N_("?extraflag:Refuel")
#define SPECENUM_VALUE2 EF_TERR_CHANGE_REMOVES
#define SPECENUM_VALUE2NAME N_("?extraflag:TerrChangeRemoves")
/* Extra will be built in cities automatically */
#define SPECENUM_VALUE3 EF_AUTO_ON_CITY_CENTER
#define SPECENUM_VALUE3NAME N_("?extraflag:AutoOnCityCenter")
/* Extra is always present in cities */
#define SPECENUM_VALUE4 EF_ALWAYS_ON_CITY_CENTER
#define SPECENUM_VALUE4NAME N_("?extraflag:AlwaysOnCityCenter")
/* Road style gfx from ocean extra connects to nearby land */
#define SPECENUM_VALUE5 EF_CONNECT_LAND
#define SPECENUM_VALUE5NAME N_("?extraflag:ConnectLand")
/* Counts towards Global Warming */
#define SPECENUM_VALUE6 EF_GLOBAL_WARMING
#define SPECENUM_VALUE6NAME N_("?extraflag:GlobalWarming")
/* Counts towards Nuclear Winter */
#define SPECENUM_VALUE7 EF_NUCLEAR_WINTER
#define SPECENUM_VALUE7NAME N_("?extraflag:NuclearWinter")
/* Owner's flag will be shown on the tile */
#define SPECENUM_VALUE8 EF_SHOW_FLAG
#define SPECENUM_VALUE8NAME N_("?extraflag:ShowFlag")
/* Extra's defense bonus will be counted to
 * separate "Natural" defense layer. */
#define SPECENUM_VALUE9 EF_NATURAL_DEFENSE
#define SPECENUM_VALUE9NAME N_("?extraflag:NaturalDefense")
#define SPECENUM_COUNT EF_COUNT
#define SPECENUM_BITVECTOR bv_extra_flags
#include "specenum_gen.h"

#define EXTRA_NONE (-1)

struct extra_type
{
  int id;
  struct name_translation name;
  enum extra_category category;
  uint8_t causes;
  uint8_t rmcauses;

  char graphic_str[MAX_LEN_NAME];
  char graphic_alt[MAX_LEN_NAME];
  char activity_gfx[MAX_LEN_NAME];
  char act_gfx_alt[MAX_LEN_NAME];
  char act_gfx_alt2[MAX_LEN_NAME];
  char rmact_gfx[MAX_LEN_NAME];
  char rmact_gfx_alt[MAX_LEN_NAME];

  struct requirement_vector reqs;
  struct requirement_vector rmreqs;

  /* 'buildable' is unclean. Clean solution would be to rely solely on extra_cause:
   * if the extra cannot be built, it's not in the cause's list.
   * But we currently rely on actually-not-buildable extras to be on the lists,
   * for example for the editor to list non-buildable but editor-placeable
   * extras. */
  bool buildable;
  int build_time;
  int build_time_factor;
  int removal_time;
  int removal_time_factor;

  int defense_bonus;

  bv_unit_classes native_to;

  bv_extra_flags flags;
  bv_extras conflicts;
  bv_extras hidden_by;

  /* Same information as in hidden_by, but iterating through this list is much
   * faster than through all extra types to check which ones are hiding this one.
   * Only used client side. */
  struct extra_type_list *hiders;

  struct strvec *helptext;

  struct
  {
    int special_idx;
    struct base_type *base;
    struct road_type *road;
  } data;
};

/* get 'struct extra_type_list' and related functions: */
#define SPECLIST_TAG extra_type
#define SPECLIST_TYPE struct extra_type
#include "speclist.h"

#define extra_type_list_iterate(extralist, pextra) \
    TYPED_LIST_ITERATE(struct extra_type, extralist, pextra)
#define extra_type_list_iterate_end LIST_ITERATE_END

#define extra_type_list_iterate_rev(extralist, pextra) \
    TYPED_LIST_ITERATE_REV(struct extra_type, extralist, pextra)
#define extra_type_list_iterate_rev_end LIST_ITERATE_REV_END

void extras_init(void);
void extras_free(void);

int extra_count(void);
int extra_number(const struct extra_type *pextra);
struct extra_type *extra_by_number(int id);

/* For optimization purposes (being able to have it as macro instead of function
 * call) this is now same as extra_number(). extras.c does have semantically correct
 * implementation too. */
#define extra_index(_e_) (_e_)->id

struct extra_type *special_extra_get(int spe);

const char *extra_name_translation(const struct extra_type *pextra);
const char *extra_rule_name(const struct extra_type *pextra);
struct extra_type *extra_type_by_rule_name(const char *name);
struct extra_type *extra_type_by_translated_name(const char *name);

#define extra_base_get(_e_) (_e_)->data.base
#define extra_road_get(_e_) (_e_)->data.road

void extra_to_caused_by_list(struct extra_type *pextra, enum extra_cause cause);
struct extra_type_list *extra_type_list_by_cause(enum extra_cause cause);
struct extra_type *rand_extra_for_tile(struct tile *ptile, enum extra_cause cause);

#define is_extra_caused_by(e, c) (e->causes & (1 << c))
bool is_extra_caused_by_worker_action(const struct extra_type *pextra);
bool is_extra_caused_by_action(const struct extra_type *pextra,
                               enum unit_activity act);

void extra_to_removed_by_list(struct extra_type *pextra, enum extra_rmcause rmcause);
struct extra_type_list *extra_type_list_by_rmcause(enum extra_rmcause rmcause);

bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause);
bool is_extra_removed_by_worker_action(const struct extra_type *pextra);
bool is_extra_removed_by_action(const struct extra_type *pextra,
                                enum unit_activity act);

bool is_extra_card_near(const struct tile *ptile, const struct extra_type *pextra);
bool is_extra_near_tile(const struct tile *ptile, const struct extra_type *pextra);

bool extra_can_be_built(const struct extra_type *pextra, const struct tile *ptile);
bool can_build_extra(const struct extra_type *pextra,
                     const struct unit *punit,
                     const struct tile *ptile);
bool player_can_build_extra(const struct extra_type *pextra,
                            const struct player *pplayer,
                            const struct tile *ptile);

bool can_remove_extra(struct extra_type *pextra,
                      const struct unit *punit,
                      const struct tile *ptile);
bool player_can_remove_extra(const struct extra_type *pextra,
                             const struct player *pplayer,
                             const struct tile *ptile);

bool is_native_extra_to_uclass(const struct extra_type *pextra,
                               const struct unit_class *pclass);
bool is_native_extra_to_utype(const struct extra_type *pextra,
                              const struct unit_type *punittype);
bool is_native_tile_to_extra(const struct extra_type *pextra,
                             const struct tile *ptile);

bool extra_has_flag(const struct extra_type *pextra, enum extra_flag_id flag);
bool is_extra_flag_card_near(const struct tile *ptile,
                             enum extra_flag_id flag);
bool is_extra_flag_near_tile(const struct tile *ptile,
                             enum extra_flag_id flag);

bool extra_causes_env_upset(struct extra_type *pextra,
                            enum environment_upset_type upset);

bool can_extras_coexist(const struct extra_type *pextra1,
                        const struct extra_type *pextra2);

struct extra_type *next_extra_for_tile(const struct tile *ptile, enum extra_cause cause,
                                       const struct player *pplayer,
                                       const struct unit *punit);
struct extra_type *prev_extra_in_tile(const struct tile *ptile, enum extra_rmcause rmcause,
                                      const struct player *pplayer,
                                      const struct unit *punit);

enum extra_cause activity_to_extra_cause(enum unit_activity act);
enum extra_rmcause activity_to_extra_rmcause(enum unit_activity act);

struct player *extra_owner(const struct tile *ptile);

#define extra_type_iterate(_p)                                \
{                                                             \
  int _i_##_p;                                                \
  for (_i_##_p = 0; _i_##_p < game.control.num_extra_types; _i_##_p++) {  \
    struct extra_type *_p = extra_by_number(_i_##_p);

#define extra_type_iterate_end                    \
  }                                               \
}

#define extra_type_by_cause_iterate(_cause, _extra)                 \
{                                                                   \
  struct extra_type_list *_etl_##_extra = extra_type_list_by_cause(_cause); \
  if (_etl_##_extra != NULL) {                                              \
    extra_type_list_iterate(_etl_##_extra, _extra) {

#define extra_type_by_cause_iterate_end                    \
    } extra_type_list_iterate_end                          \
  }                                                        \
}

#define extra_type_by_cause_iterate_rev(_cause, _extra)                 \
{                                                                      \
 struct extra_type_list *_etl_ = extra_type_list_by_cause(_cause);     \
  extra_type_list_iterate_rev(_etl_, _extra) {

#define extra_type_by_cause_iterate_rev_end                \
  } extra_type_list_iterate_rev_end                        \
}

#define extra_type_by_rmcause_iterate(_rmcause, _extra)                   \
{                                                                         \
  struct extra_type_list *_etl_ = extra_type_list_by_rmcause(_rmcause);   \
  extra_type_list_iterate_rev(_etl_, _extra) {

#define extra_type_by_rmcause_iterate_end                \
  } extra_type_list_iterate_rev_end                      \
}

#define extra_deps_iterate(_reqs, _dep)                 \
{                                                       \
  requirement_vector_iterate(_reqs, preq) {             \
    if (preq->source.kind == VUT_EXTRA                  \
        && preq->present) {                             \
      struct extra_type *_dep;                          \
      _dep = preq->source.value.extra;

#define extra_deps_iterate_end                          \
    }                                                   \
  } requirement_vector_iterate_end;                     \
}

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif  /* FC__EXTRAS_H */