~ubuntu-branches/debian/squeeze/freeciv/squeeze

« back to all changes in this revision

Viewing changes to common/requirements.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20100223220902-kiyrmr9i4152cka5
Tags: 2.2.0-1
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#include <config.h>
15
15
#endif
16
16
 
17
 
#include <assert.h>
18
 
 
 
17
/* utility */
19
18
#include "fcintl.h"
20
19
#include "game.h"
21
20
#include "log.h"
22
21
#include "support.h"
23
22
 
 
23
/* common */
24
24
#include "government.h"
25
25
#include "improvement.h"
26
26
#include "map.h"
 
27
#include "specialist.h"
 
28
 
27
29
#include "requirements.h"
28
30
 
29
 
/* Names of source types.  These must correspond to enum req_source_type in
30
 
 * requirements.h.  Do not change these unless you know what you're doing! */
31
 
static const char *req_source_type_names[] = {
 
31
/* Names of source types.  These must correspond to enum universals_n in
 
32
 * fc_types.h.  Do not change these unless you know what you're doing! */
 
33
static const char *universal_names[] = {
32
34
  "None",
33
35
  "Tech",
34
36
  "Gov",
39
41
  "UnitType",
40
42
  "UnitFlag",
41
43
  "UnitClass",
 
44
  "UnitClassFlag",
42
45
  "OutputType",
43
46
  "Specialist",
44
 
  "MinSize"
 
47
  "MinSize",
 
48
  "AI",
 
49
  "TerrainClass",
 
50
  "Base",
 
51
  "MinYear",
 
52
  "TerrainAlter",
 
53
  "CityTile"
45
54
};
46
55
 
47
56
/* Names of requirement ranges. These must correspond to enum req_range in
65
74
{
66
75
  enum req_range range;
67
76
 
68
 
  assert(ARRAY_SIZE(req_range_names) == REQ_RANGE_LAST);
 
77
  RETURN_VAL_IF_FAIL(ARRAY_SIZE(req_range_names) == REQ_RANGE_LAST,
 
78
                     REQ_RANGE_LAST);
69
79
 
70
80
  for (range = 0; range < REQ_RANGE_LAST; range++) {
71
81
    if (0 == mystrcasecmp(req_range_names[range], str)) {
77
87
}
78
88
 
79
89
/**************************************************************************
80
 
  Parse a requirement type and value string into a requirement source
81
 
  structure.  Passing in a NULL type is considered REQ_NONE (not an error).
 
90
  Parse requirement type (kind) and value strings into a universal
 
91
  structure.  Passing in a NULL type is considered VUT_NONE (not an error).
82
92
 
83
93
  Pass this some values like "Building", "Factory".
 
94
  FIXME: ensure that every caller checks error return!
84
95
**************************************************************************/
85
 
struct req_source req_source_from_str(const char *type, const char *value)
 
96
struct universal universal_by_rule_name(const char *kind,
 
97
                                        const char *value)
86
98
{
87
 
  struct req_source source;
88
 
 
89
 
  assert(ARRAY_SIZE(req_source_type_names) == REQ_LAST);
90
 
  if (type) {
91
 
    for (source.type = 0;
92
 
         source.type < ARRAY_SIZE(req_source_type_names);
93
 
         source.type++) {
94
 
      if (0 == mystrcasecmp(req_source_type_names[source.type], type)) {
95
 
        break;
 
99
  struct universal source = { .kind = VUT_LAST };
 
100
 
 
101
  RETURN_VAL_IF_FAIL(ARRAY_SIZE(universal_names) == VUT_LAST, source);
 
102
 
 
103
  if (kind) {
 
104
    for (source.kind = 0;
 
105
         source.kind < ARRAY_SIZE(universal_names);
 
106
         source.kind++) {
 
107
      if (0 == mystrcasecmp(universal_names[source.kind], kind)) {
 
108
        break;
96
109
      }
97
110
    }
98
111
  } else {
99
 
    source.type = REQ_NONE;
 
112
    source.kind = VUT_NONE;
100
113
  }
101
114
 
102
115
  /* Finally scan the value string based on the type of the source. */
103
 
  switch (source.type) {
104
 
  case REQ_NONE:
 
116
  switch (source.kind) {
 
117
  case VUT_NONE:
105
118
    return source;
106
 
  case REQ_TECH:
107
 
    source.value.tech = find_advance_by_rule_name(value);
108
 
    if (source.value.tech != A_LAST) {
109
 
      return source;
110
 
    }
111
 
    break;
112
 
  case REQ_GOV:
113
 
    source.value.gov = find_government_by_rule_name(value);
114
 
    if (source.value.gov != NULL) {
115
 
      return source;
116
 
    }
117
 
    break;
118
 
  case REQ_BUILDING:
 
119
  case VUT_ADVANCE:
 
120
    source.value.advance = find_advance_by_rule_name(value);
 
121
    if (source.value.advance != NULL) {
 
122
      return source;
 
123
    }
 
124
    break;
 
125
  case VUT_GOVERNMENT:
 
126
    source.value.govern = find_government_by_rule_name(value);
 
127
    if (source.value.govern != NULL) {
 
128
      return source;
 
129
    }
 
130
    break;
 
131
  case VUT_IMPROVEMENT:
119
132
    source.value.building = find_improvement_by_rule_name(value);
120
 
    if (source.value.building != B_LAST) {
 
133
    if (source.value.building != NULL) {
121
134
      return source;
122
135
    }
123
136
    break;
124
 
  case REQ_SPECIAL:
 
137
  case VUT_SPECIAL:
125
138
    source.value.special = find_special_by_rule_name(value);
126
139
    if (source.value.special != S_LAST) {
127
140
      return source;
128
141
    }
129
142
    break;
130
 
  case REQ_TERRAIN:
 
143
  case VUT_TERRAIN:
131
144
    source.value.terrain = find_terrain_by_rule_name(value);
132
145
    if (source.value.terrain != T_UNKNOWN) {
133
146
      return source;
134
147
    }
135
148
    break;
136
 
  case REQ_NATION:
 
149
  case VUT_NATION:
137
150
    source.value.nation = find_nation_by_rule_name(value);
138
151
    if (source.value.nation != NO_NATION_SELECTED) {
139
152
      return source;
140
153
    }
141
154
    break;
142
 
  case REQ_UNITTYPE:
143
 
    source.value.unittype = find_unit_type_by_rule_name(value);
144
 
    if (source.value.unittype) {
 
155
  case VUT_UTYPE:
 
156
    source.value.utype = find_unit_type_by_rule_name(value);
 
157
    if (source.value.utype) {
145
158
      return source;
146
159
    }
147
160
    break;
148
 
  case REQ_UNITFLAG:
 
161
  case VUT_UTFLAG:
149
162
    source.value.unitflag = find_unit_flag_by_rule_name(value);
150
163
    if (source.value.unitflag != F_LAST) {
151
164
      return source;
152
165
    }
153
166
    break;
154
 
  case REQ_UNITCLASS:
155
 
    source.value.unitclass = find_unit_class_by_rule_name(value);
156
 
    if (source.value.unitclass) {
157
 
      return source;
158
 
    }
159
 
    break;
160
 
  case REQ_OUTPUTTYPE:
 
167
  case VUT_UCLASS:
 
168
    source.value.uclass = find_unit_class_by_rule_name(value);
 
169
    if (source.value.uclass) {
 
170
      return source;
 
171
    }
 
172
    break;
 
173
  case VUT_UCFLAG:
 
174
    source.value.unitclassflag = find_unit_class_flag_by_rule_name(value);
 
175
    if (source.value.unitclassflag != UCF_LAST) {
 
176
      return source;
 
177
    }
 
178
    break;
 
179
  case VUT_OTYPE:
161
180
    source.value.outputtype = find_output_type_by_identifier(value);
162
181
    if (source.value.outputtype != O_LAST) {
163
182
      return source;
164
183
    }
165
184
    break;
166
 
  case REQ_SPECIALIST:
167
 
    source.value.specialist = find_specialist_by_name(value);
168
 
    if (source.value.specialist != SP_MAX) {
 
185
  case VUT_SPECIALIST:
 
186
    source.value.specialist = find_specialist_by_rule_name(value);
 
187
    if (source.value.specialist) {
169
188
      return source;
170
189
    }
171
 
  case REQ_MINSIZE:
 
190
  case VUT_MINSIZE:
172
191
    source.value.minsize = atoi(value);
173
192
    if (source.value.minsize > 0) {
174
193
      return source;
175
194
    }
176
195
    break;
177
 
  case REQ_LAST:
 
196
  case VUT_AI_LEVEL:
 
197
    source.value.ai_level = find_ai_level_by_name(value);
 
198
    if (source.value.ai_level != AI_LEVEL_LAST) {
 
199
      return source;
 
200
    }
 
201
    break;
 
202
  case VUT_TERRAINCLASS:
 
203
    source.value.terrainclass = find_terrain_class_by_rule_name(value);
 
204
    if (source.value.terrainclass != TC_LAST) {
 
205
      return source;
 
206
    }
 
207
    break;
 
208
  case VUT_BASE:
 
209
    source.value.base = find_base_type_by_rule_name(value);
 
210
    if (source.value.base != NULL) {
 
211
      return source;
 
212
    }
 
213
    break;
 
214
  case VUT_MINYEAR:
 
215
    source.value.minyear = atoi(value);
 
216
    if (source.value.minyear >= GAME_START_YEAR) {
 
217
      return source;
 
218
    }
 
219
    break;
 
220
  case VUT_TERRAINALTER:
 
221
    source.value.terrainalter = find_terrain_alteration_by_rule_name(value);
 
222
    if (source.value.terrainalter != TA_LAST) {
 
223
      return source;
 
224
    }
 
225
    break;
 
226
  case VUT_CITYTILE:
 
227
    source.value.citytile = find_citytile_by_rule_name(value);
 
228
    if (source.value.citytile != CITYT_LAST) {
 
229
      return source;
 
230
    }
 
231
    break;
 
232
  case VUT_LAST:
178
233
    break;
179
234
  }
180
235
 
181
236
  /* If we reach here there's been an error. */
182
 
  source.type = REQ_LAST;
 
237
  source.kind = VUT_LAST;
183
238
  return source;
184
239
}
185
240
 
186
241
/**************************************************************************
187
 
  Parse some integer values into a req source.  This is for serialization
188
 
  of req sources and is the opposite of req_source_get_values().
 
242
  Combine values into a universal structure.  This is for serialization
 
243
  and is the opposite of universal_extraction().
 
244
  FIXME: ensure that every caller checks error return!
189
245
**************************************************************************/
190
 
struct req_source req_source_from_values(int type, int value)
 
246
struct universal universal_by_number(const enum universals_n kind,
 
247
                                     const int value)
191
248
{
192
 
  struct req_source source;
193
 
 
194
 
  source.type = type;
195
 
 
196
 
  switch (source.type) {
197
 
  case REQ_NONE:
198
 
    return source;
199
 
  case REQ_TECH:
200
 
    source.value.tech = value;
201
 
    return source;
202
 
  case REQ_GOV:
203
 
    source.value.gov = government_by_number(value);
204
 
    return source;
205
 
  case REQ_BUILDING:
206
 
    source.value.building = value;
207
 
    return source;
208
 
  case REQ_SPECIAL:
 
249
  struct universal source;
 
250
 
 
251
  source.kind = kind;
 
252
 
 
253
  switch (source.kind) {
 
254
  case VUT_NONE:
 
255
    return source;
 
256
  case VUT_ADVANCE:
 
257
    source.value.advance = advance_by_number(value);
 
258
    if (source.value.advance != NULL) {
 
259
      return source;
 
260
    }
 
261
    break;
 
262
  case VUT_GOVERNMENT:
 
263
    source.value.govern = government_by_number(value);
 
264
    if (source.value.govern != NULL) {
 
265
      return source;
 
266
    }
 
267
    break;
 
268
  case VUT_IMPROVEMENT:
 
269
    source.value.building = improvement_by_number(value);
 
270
    if (source.value.building != NULL) {
 
271
      return source;
 
272
    }
 
273
    break;
 
274
  case VUT_SPECIAL:
209
275
    source.value.special = value;
210
276
    return source;
211
 
  case REQ_TERRAIN:
 
277
  case VUT_TERRAIN:
212
278
    source.value.terrain = terrain_by_number(value);
213
 
    return source;
214
 
  case REQ_NATION:
 
279
    if (source.value.terrain != NULL) {
 
280
      return source;
 
281
    }
 
282
    break;
 
283
  case VUT_NATION:
215
284
    source.value.nation = nation_by_number(value);
216
 
    return source;
217
 
  case REQ_UNITTYPE:
218
 
    source.value.unittype = utype_by_number(value);
219
 
    return source;
220
 
  case REQ_UNITFLAG:
 
285
    if (source.value.nation != NULL) {
 
286
      return source;
 
287
    }
 
288
    break;
 
289
  case VUT_UTYPE:
 
290
    source.value.utype = utype_by_number(value);
 
291
    if (source.value.utype != NULL) {
 
292
      return source;
 
293
    }
 
294
    break;
 
295
  case VUT_UTFLAG:
221
296
    source.value.unitflag = value;
222
297
    return source;
223
 
  case REQ_UNITCLASS:
224
 
    source.value.unitclass = uclass_by_number(value);
 
298
  case VUT_UCLASS:
 
299
    source.value.uclass = uclass_by_number(value);
 
300
    if (source.value.uclass != NULL) {
 
301
      return source;
 
302
    }
 
303
    break;
 
304
  case VUT_UCFLAG:
 
305
    source.value.unitclassflag = value;
225
306
    return source;
226
 
  case REQ_OUTPUTTYPE:
 
307
  case VUT_OTYPE:
227
308
    source.value.outputtype = value;
228
309
    return source;
229
 
  case REQ_SPECIALIST:
230
 
    source.value.specialist = value;
 
310
  case VUT_SPECIALIST:
 
311
    source.value.specialist = specialist_by_number(value);
231
312
    return source;
232
 
  case REQ_MINSIZE:
 
313
  case VUT_MINSIZE:
233
314
    source.value.minsize = value;
234
315
    return source;
235
 
  case REQ_LAST:
 
316
  case VUT_AI_LEVEL:
 
317
    source.value.ai_level = value;
 
318
    return source;
 
319
  case VUT_TERRAINCLASS:
 
320
    source.value.terrainclass = value;
 
321
    return source;
 
322
  case VUT_BASE:
 
323
    source.value.base = base_by_number(value);
 
324
    return source;
 
325
  case VUT_MINYEAR:
 
326
    source.value.minyear = value;
 
327
    return source;
 
328
  case VUT_TERRAINALTER:
 
329
    source.value.terrainalter = value;
 
330
    return source;
 
331
  case VUT_CITYTILE:
 
332
    source.value.citytile = value;
 
333
    return source;
 
334
  case VUT_LAST:
236
335
    return source;
237
336
  }
238
337
 
239
 
  source.type = REQ_LAST;
240
 
  assert(0);
 
338
  /* If we reach here there's been an error. */
 
339
  source.kind = VUT_LAST;
241
340
  return source;
242
341
}
243
342
 
244
343
/**************************************************************************
245
 
  Look at a req source and return some integer values describing it.  This
246
 
  is for serialization of req sources and is the opposite of
247
 
  req_source_from_values().
 
344
  Extract universal structure into its components for serialization;
 
345
  the opposite of universal_by_number().
248
346
**************************************************************************/
249
 
void req_source_get_values(const struct req_source *source,
250
 
                           int *type, int *value)
 
347
void universal_extraction(const struct universal *source,
 
348
                          int *kind, int *value)
251
349
{
252
 
  *type = source->type;
 
350
  *kind = source->kind;
 
351
  *value = universal_number(source);
 
352
}
253
353
 
254
 
  switch (source->type) {
255
 
  case REQ_NONE:
256
 
    *value = 0;
257
 
    return;
258
 
  case REQ_TECH:
259
 
    *value = source->value.tech;
260
 
    return;
261
 
  case REQ_GOV:
262
 
    *value = source->value.gov->index;
263
 
    return;
264
 
  case REQ_BUILDING:
265
 
    *value = source->value.building;
266
 
    return;
267
 
  case REQ_SPECIAL:
268
 
    *value = source->value.special;
269
 
    return;
270
 
  case REQ_TERRAIN:
271
 
    *value = source->value.terrain->index;
272
 
    return;
273
 
  case REQ_NATION:
274
 
    *value = nation_number(source->value.nation);
275
 
    return;
276
 
  case REQ_UNITTYPE:
277
 
    *value = source->value.unittype->index;
278
 
    return;
279
 
  case REQ_UNITFLAG:
280
 
    *value = source->value.unitflag;
281
 
    return;
282
 
  case REQ_UNITCLASS:
283
 
    *value = source->value.unitclass->id;
284
 
    return;
285
 
  case REQ_OUTPUTTYPE:
286
 
    *value = source->value.outputtype;
287
 
    return;
288
 
  case REQ_SPECIALIST:
289
 
    *value = source->value.specialist;
290
 
    return;
291
 
  case REQ_MINSIZE:
292
 
    *value = source->value.minsize;
293
 
    return;
294
 
  case REQ_LAST:
 
354
/**************************************************************************
 
355
  Return the universal number of the constituent.
 
356
**************************************************************************/
 
357
int universal_number(const struct universal *source)
 
358
{
 
359
  switch (source->kind) {
 
360
  case VUT_NONE:
 
361
    return 0;
 
362
  case VUT_ADVANCE:
 
363
    return advance_number(source->value.advance);
 
364
  case VUT_GOVERNMENT:
 
365
    return government_number(source->value.govern);
 
366
  case VUT_IMPROVEMENT:
 
367
    return improvement_number(source->value.building);
 
368
  case VUT_SPECIAL:
 
369
    return source->value.special;
 
370
  case VUT_TERRAIN:
 
371
    return terrain_number(source->value.terrain);
 
372
  case VUT_NATION:
 
373
    return nation_number(source->value.nation);
 
374
  case VUT_UTYPE:
 
375
    return utype_number(source->value.utype);
 
376
  case VUT_UTFLAG:
 
377
    return source->value.unitflag;
 
378
  case VUT_UCLASS:
 
379
    return uclass_number(source->value.uclass);
 
380
  case VUT_UCFLAG:
 
381
    return source->value.unitclassflag;
 
382
  case VUT_OTYPE:
 
383
    return source->value.outputtype;
 
384
  case VUT_SPECIALIST:
 
385
    return specialist_number(source->value.specialist);
 
386
  case VUT_MINSIZE:
 
387
    return source->value.minsize;
 
388
  case VUT_AI_LEVEL:
 
389
    return source->value.ai_level;
 
390
  case VUT_TERRAINCLASS:
 
391
    return source->value.terrainclass;
 
392
  case VUT_BASE:
 
393
    return base_number(source->value.base);
 
394
  case VUT_MINYEAR:
 
395
    return source->value.minyear;
 
396
  case VUT_TERRAINALTER:
 
397
    return source->value.terrainalter;
 
398
  case VUT_CITYTILE:
 
399
    return source->value.citytile;
 
400
  case VUT_LAST:
295
401
    break;
296
402
  }
297
403
 
298
 
  assert(0);
299
 
  *value = 0;
 
404
  /* If we reach here there's been an error. */
 
405
  freelog(LOG_ERROR, "universal_number(): invalid source kind %d.",
 
406
          source->kind);
 
407
  return 0;
300
408
}
301
409
 
302
410
/****************************************************************************
303
411
  Parse a requirement type and value string into a requrement structure.
304
 
  Returns REQ_LAST on error.  Passing in a NULL type is considered REQ_NONE
 
412
  Returns VUT_LAST on error.  Passing in a NULL type is considered VUT_NONE
305
413
  (not an error).
306
414
 
307
415
  Pass this some values like "Building", "Factory".
313
421
  struct requirement req;
314
422
  bool invalid = TRUE;
315
423
 
316
 
  req.source = req_source_from_str(type, value);
 
424
  req.source = universal_by_rule_name(type, value);
317
425
 
318
426
  /* Scan the range string to find the range.  If no range is given a
319
427
   * default fallback is used rather than giving an error. */
320
428
  req.range = req_range_from_str(range);
321
429
  if (req.range == REQ_RANGE_LAST) {
322
 
    switch (req.source.type) {
323
 
    case REQ_NONE:
324
 
    case REQ_LAST:
 
430
    switch (req.source.kind) {
 
431
    case VUT_NONE:
 
432
    case VUT_LAST:
325
433
      break;
326
 
    case REQ_BUILDING:
327
 
    case REQ_SPECIAL:
328
 
    case REQ_TERRAIN:
329
 
    case REQ_UNITTYPE:
330
 
    case REQ_UNITFLAG:
331
 
    case REQ_UNITCLASS:
332
 
    case REQ_OUTPUTTYPE:
333
 
    case REQ_SPECIALIST:
 
434
    case VUT_IMPROVEMENT:
 
435
    case VUT_SPECIAL:
 
436
    case VUT_TERRAIN:
 
437
    case VUT_UTYPE:
 
438
    case VUT_UTFLAG:
 
439
    case VUT_UCLASS:
 
440
    case VUT_UCFLAG:
 
441
    case VUT_OTYPE:
 
442
    case VUT_SPECIALIST:
 
443
    case VUT_TERRAINCLASS:
 
444
    case VUT_BASE:
 
445
    case VUT_TERRAINALTER:
 
446
    case VUT_CITYTILE:
334
447
      req.range = REQ_RANGE_LOCAL;
335
448
      break;
336
 
    case REQ_MINSIZE:
 
449
    case VUT_MINSIZE:
337
450
      req.range = REQ_RANGE_CITY;
338
451
      break;
339
 
    case REQ_GOV:
340
 
    case REQ_TECH:
341
 
    case REQ_NATION:
 
452
    case VUT_GOVERNMENT:
 
453
    case VUT_ADVANCE:
 
454
    case VUT_NATION:
 
455
    case VUT_AI_LEVEL:
342
456
      req.range = REQ_RANGE_PLAYER;
343
457
      break;
 
458
    case VUT_MINYEAR:
 
459
      req.range = REQ_RANGE_WORLD;
 
460
      break;
344
461
    }
345
462
  }
346
463
 
349
466
 
350
467
  /* These checks match what combinations are supported inside
351
468
   * is_req_active(). */
352
 
  switch (req.source.type) {
353
 
  case REQ_SPECIAL:
354
 
  case REQ_TERRAIN:
 
469
  switch (req.source.kind) {
 
470
  case VUT_SPECIAL:
 
471
  case VUT_TERRAIN:
 
472
  case VUT_TERRAINCLASS:
 
473
  case VUT_BASE:
355
474
    invalid = (req.range != REQ_RANGE_LOCAL
356
475
               && req.range != REQ_RANGE_ADJACENT);
357
476
    break;
358
 
  case REQ_TECH:
 
477
  case VUT_ADVANCE:
359
478
    invalid = (req.range < REQ_RANGE_PLAYER);
360
479
    break;
361
 
  case REQ_GOV:
 
480
  case VUT_GOVERNMENT:
 
481
  case VUT_AI_LEVEL:
362
482
    invalid = (req.range != REQ_RANGE_PLAYER);
363
483
    break;
364
 
  case REQ_BUILDING:
 
484
  case VUT_IMPROVEMENT:
365
485
    invalid = ((req.range == REQ_RANGE_WORLD
366
486
                && !is_great_wonder(req.source.value.building))
367
487
               || (req.range > REQ_RANGE_CITY
368
488
                   && !is_wonder(req.source.value.building)));
369
489
    break;
370
 
  case REQ_MINSIZE:
 
490
  case VUT_MINSIZE:
371
491
    invalid = (req.range != REQ_RANGE_CITY);
372
492
    break;
373
 
  case REQ_NATION:
 
493
  case VUT_NATION:
374
494
    invalid = (req.range != REQ_RANGE_PLAYER
375
495
               && req.range != REQ_RANGE_WORLD);
376
496
    break;
377
 
  case REQ_UNITTYPE:
378
 
  case REQ_UNITFLAG:
379
 
  case REQ_UNITCLASS:
380
 
  case REQ_OUTPUTTYPE:
381
 
  case REQ_SPECIALIST:
 
497
  case VUT_UTYPE:
 
498
  case VUT_UTFLAG:
 
499
  case VUT_UCLASS:
 
500
  case VUT_UCFLAG:
 
501
  case VUT_OTYPE:
 
502
  case VUT_SPECIALIST:
 
503
  case VUT_TERRAINALTER: /* XXX could in principle support ADJACENT */
 
504
  case VUT_CITYTILE:
382
505
    invalid = (req.range != REQ_RANGE_LOCAL);
383
506
    break;
384
 
  case REQ_NONE:
 
507
  case VUT_MINYEAR:
 
508
    invalid = (req.range != REQ_RANGE_WORLD);
 
509
    break;
 
510
  case VUT_NONE:
385
511
    invalid = FALSE;
386
512
    break;
387
 
  case REQ_LAST:
 
513
  case VUT_LAST:
388
514
    break;
389
515
  }
390
516
  if (invalid) {
392
518
            type, range,
393
519
            survives ? "survives" : "",
394
520
            negated ? "negated" : "", value);
395
 
    req.source.type = REQ_LAST;
 
521
    req.source.kind = VUT_LAST;
396
522
  }
397
523
 
398
524
  return req;
408
534
{
409
535
  struct requirement req;
410
536
 
411
 
  req.source = req_source_from_values(type, value);
 
537
  req.source = universal_by_number(type, value);
412
538
  req.range = range;
413
539
  req.survives = survives;
414
540
  req.negated = negated;
424
550
                    bool *survives, bool *negated,
425
551
                    int *value)
426
552
{
427
 
  req_source_get_values(&req->source, type, value);
 
553
  universal_extraction(&req->source, type, value);
428
554
  *range = req->range;
429
555
  *survives = req->survives;
430
556
  *negated = req->negated;
436
562
bool are_requirements_equal(const struct requirement *req1,
437
563
                            const struct requirement *req2)
438
564
{
439
 
  return (are_req_sources_equal(&req1->source, &req2->source)
 
565
  return (are_universals_equal(&req1->source, &req2->source)
440
566
          && req1->range == req2->range
441
567
          && req1->survives == req2->survives
442
568
          && req1->negated == req2->negated);
446
572
  Returns the number of total world buildings (this includes buildings
447
573
  that have been destroyed).
448
574
****************************************************************************/
449
 
static int num_world_buildings_total(Impr_type_id building)
 
575
static int num_world_buildings_total(const struct impr_type *building)
450
576
{
451
577
  if (is_great_wonder(building)) {
452
 
    return (great_wonder_was_built(building) ? 1 : 0);
 
578
    return (great_wonder_is_built(building)
 
579
            || great_wonder_is_destroyed(building) ? 1 : 0);
453
580
  } else {
454
581
    freelog(LOG_ERROR,
455
582
            /* TRANS: Obscure ruleset error. */
461
588
/****************************************************************************
462
589
  Returns the number of buildings of a certain type in the world.
463
590
****************************************************************************/
464
 
static int num_world_buildings(Impr_type_id id)
 
591
static int num_world_buildings(const struct impr_type *building)
465
592
{
466
 
  if (is_great_wonder(id)) {
467
 
    return (find_city_from_great_wonder(id) ? 1 : 0);
 
593
  if (is_great_wonder(building)) {
 
594
    return (great_wonder_is_built(building) ? 1 : 0);
468
595
  } else {
469
596
    freelog(LOG_ERROR,
470
597
            /* TRANS: Obscure ruleset error. */
473
600
  }
474
601
}
475
602
 
476
 
/**************************************************************************
477
 
  Returns the player city with the given wonder.
478
 
**************************************************************************/
479
 
static struct city *player_find_city_from_wonder(const struct player *plr,
480
 
                                                 Impr_type_id id)
481
 
{
482
 
  int city_id;
483
 
  struct city *pcity;
484
 
 
485
 
  if (is_great_wonder(id)) {
486
 
    city_id = game.info.great_wonders[id];
487
 
  } else if (is_small_wonder(id)) {
488
 
    city_id = plr->small_wonders[id];
489
 
  } else {
490
 
    return NULL;
491
 
  }
492
 
 
493
 
  pcity = game_find_city_by_number(city_id);
494
 
  if (pcity && (city_owner(pcity) == plr)) {
495
 
    return pcity;
496
 
  } else {
497
 
    return NULL;
498
 
  }
499
 
}
500
 
 
501
603
/****************************************************************************
502
604
  Returns the number of buildings of a certain type owned by plr.
503
605
****************************************************************************/
504
606
static int num_player_buildings(const struct player *pplayer,
505
 
                                Impr_type_id building)
 
607
                                const struct impr_type *building)
506
608
{
507
609
  if (is_wonder(building)) {
508
 
    return (player_find_city_from_wonder(pplayer, building) ? 1 : 0);
 
610
    return (wonder_is_built(pplayer, building) ? 1 : 0);
509
611
  } else {
510
612
    freelog(LOG_ERROR,
511
613
            /* TRANS: Obscure ruleset error. */
518
620
  Returns the number of buildings of a certain type on a continent.
519
621
****************************************************************************/
520
622
static int num_continent_buildings(const struct player *pplayer,
521
 
                                   int continent, Impr_type_id building)
 
623
                                   int continent,
 
624
                                   const struct impr_type *building)
522
625
{
523
626
  if (is_wonder(building)) {
524
627
    const struct city *pcity;
525
628
 
526
 
    pcity = player_find_city_from_wonder(pplayer, building);
527
 
    if (pcity && tile_get_continent(pcity->tile) == continent) {
 
629
    pcity = find_city_from_wonder(pplayer, building);
 
630
    if (pcity && tile_continent(pcity->tile) == continent) {
528
631
      return 1;
529
632
    }
530
633
  } else {
538
641
/****************************************************************************
539
642
  Returns the number of buildings of a certain type in a city.
540
643
****************************************************************************/
541
 
static int num_city_buildings(const struct city *pcity, Impr_type_id id)
 
644
static int num_city_buildings(const struct city *pcity,
 
645
                              const struct impr_type *building)
542
646
{
543
 
  return (city_got_building(pcity, id) ? 1 : 0);
 
647
  return (city_has_building(pcity, building) ? 1 : 0);
544
648
}
545
649
 
546
650
/****************************************************************************
563
667
****************************************************************************/
564
668
static int count_buildings_in_range(const struct player *target_player,
565
669
                                    const struct city *target_city,
566
 
                                    const struct impr_type * target_building,
567
 
                                    enum req_range range, bool survives,
568
 
                                    Impr_type_id source)
 
670
                                    const struct impr_type *target_building,
 
671
                                    enum req_range range,
 
672
                                    bool survives,
 
673
                                    const struct impr_type *source)
569
674
{
570
675
  if (improvement_obsolete(target_player, source)) {
571
676
    return 0;
591
696
    return target_player ? num_player_buildings(target_player, source) : 0;
592
697
  case REQ_RANGE_CONTINENT:
593
698
    if (target_player && target_city) {
594
 
      int continent = tile_get_continent(target_city->tile);
 
699
      int continent = tile_continent(target_city->tile);
595
700
 
596
701
      return num_continent_buildings(target_player, continent, source);
597
702
    } else {
602
707
  case REQ_RANGE_CITY:
603
708
    return target_city ? num_city_buildings(target_city, source) : 0;
604
709
  case REQ_RANGE_LOCAL:
605
 
    if (target_building && target_building->index == source) {
 
710
    if (target_building && target_building == source) {
606
711
      return num_city_buildings(target_city, source);
607
712
    } else {
608
713
      /* TODO: other local targets */
613
718
  case REQ_RANGE_LAST:
614
719
    break;
615
720
  }
616
 
  assert(0);
 
721
 
 
722
  freelog(LOG_ERROR, "count_buildings_in_range(): invalid range %d.", range);
617
723
  return 0;
618
724
}
619
725
 
621
727
  Is there a source tech within range of the target?
622
728
****************************************************************************/
623
729
static bool is_tech_in_range(const struct player *target_player,
624
 
                             enum req_range range,
625
 
                             Tech_type_id tech)
 
730
                             enum req_range range,
 
731
                             Tech_type_id tech,
 
732
                             enum req_problem_type prob_type)
626
733
{
627
734
  switch (range) {
628
735
  case REQ_RANGE_PLAYER:
629
 
    return (target_player
630
 
            && get_invention(target_player, tech) == TECH_KNOWN);
 
736
    /* If target_player is NULL and prob_type RPT_POSSIBLE, then it will
 
737
     * consider the advance is in range. */
 
738
    if (NULL != target_player) {
 
739
      return TECH_KNOWN == player_invention_state(target_player, tech);
 
740
    } else {
 
741
      return RPT_POSSIBLE == prob_type;
 
742
    }
631
743
  case REQ_RANGE_WORLD:
632
744
    return game.info.global_advances[tech];
633
745
  case REQ_RANGE_LOCAL:
638
750
    break;
639
751
  }
640
752
 
641
 
  assert(0);
 
753
  freelog(LOG_ERROR, "is_tech_in_range(): invalid range %d.", range);
642
754
  return FALSE;
643
755
}
644
756
 
663
775
    break;
664
776
  }
665
777
 
666
 
  assert(0);
 
778
  freelog(LOG_ERROR, "is_special_in_range(): invalid range %d.", range);
667
779
  return FALSE;
668
780
}
669
781
 
681
793
  switch (range) {
682
794
  case REQ_RANGE_LOCAL:
683
795
    /* The requirement is filled if the tile has the terrain. */
684
 
    return pterrain && target_tile->terrain == pterrain;
 
796
    return pterrain && tile_terrain(target_tile) == pterrain;
685
797
  case REQ_RANGE_ADJACENT:
686
798
    return pterrain && is_terrain_near_tile(target_tile, pterrain, TRUE);
687
799
  case REQ_RANGE_CITY:
692
804
    break;
693
805
  }
694
806
 
695
 
  assert(0);
 
807
  freelog(LOG_ERROR, "is_terrain_in_range(): invalid range %d.", range);
 
808
  return FALSE;
 
809
}
 
810
 
 
811
/****************************************************************************
 
812
  Is there a source terrain class within range of the target?
 
813
****************************************************************************/
 
814
static bool is_terrain_class_in_range(const struct tile *target_tile,
 
815
                                      enum req_range range, bool survives,
 
816
                                      enum terrain_class class)
 
817
{
 
818
  if (!target_tile) {
 
819
    return FALSE;
 
820
  }
 
821
 
 
822
  switch (range) {
 
823
  case REQ_RANGE_LOCAL:
 
824
    /* The requirement is filled if the tile has the terrain of correct class. */
 
825
    return terrain_belongs_to_class(tile_terrain(target_tile), class);
 
826
  case REQ_RANGE_ADJACENT:
 
827
    return is_terrain_class_near_tile(target_tile, class);
 
828
  case REQ_RANGE_CITY:
 
829
  case REQ_RANGE_CONTINENT:
 
830
  case REQ_RANGE_PLAYER:
 
831
  case REQ_RANGE_WORLD:
 
832
  case REQ_RANGE_LAST:
 
833
    break;
 
834
  }
 
835
 
 
836
  freelog(LOG_ERROR, "is_terrain_class_in_range(): invalid range %d.",
 
837
          range);
 
838
  return FALSE;
 
839
}
 
840
 
 
841
/****************************************************************************
 
842
  Is there a source base type within range of the target?
 
843
****************************************************************************/
 
844
static bool is_base_type_in_range(const struct tile *target_tile,
 
845
                                  enum req_range range, bool survives,
 
846
                                  struct base_type *pbase)
 
847
{
 
848
  if (!target_tile) {
 
849
    return FALSE;
 
850
  }
 
851
 
 
852
  switch (range) {
 
853
  case REQ_RANGE_LOCAL:
 
854
    /* The requirement is filled if the tile has base of requested type. */
 
855
    return tile_has_base(target_tile, pbase);
 
856
  case REQ_RANGE_ADJACENT:
 
857
    return is_base_near_tile(target_tile, pbase);
 
858
  case REQ_RANGE_CITY:
 
859
  case REQ_RANGE_CONTINENT:
 
860
  case REQ_RANGE_PLAYER:
 
861
  case REQ_RANGE_WORLD:
 
862
  case REQ_RANGE_LAST:
 
863
    break;
 
864
  }
 
865
 
 
866
  freelog(LOG_ERROR, "is_base_type_in_range(): invalid range %d.", range);
 
867
  return FALSE;
 
868
}
 
869
 
 
870
/****************************************************************************
 
871
  Is there a terrain which can support the specified infrastructure
 
872
  within range of the target?
 
873
****************************************************************************/
 
874
static bool is_terrain_alter_possible_in_range(const struct tile *target_tile,
 
875
                                           enum req_range range, bool survives,
 
876
                                           enum terrain_alteration alteration)
 
877
{
 
878
  if (!target_tile) {
 
879
    return FALSE;
 
880
  }
 
881
 
 
882
  switch (range) {
 
883
  case REQ_RANGE_LOCAL:
 
884
    return terrain_can_support_alteration(tile_terrain(target_tile),
 
885
                                          alteration);
 
886
  case REQ_RANGE_ADJACENT: /* XXX Could in principle support ADJACENT. */
 
887
  case REQ_RANGE_CITY:
 
888
  case REQ_RANGE_CONTINENT:
 
889
  case REQ_RANGE_PLAYER:
 
890
  case REQ_RANGE_WORLD:
 
891
  case REQ_RANGE_LAST:
 
892
    break;
 
893
  }
 
894
 
 
895
  freelog(LOG_ERROR,
 
896
          "is_terrain_alter_possible_in_range(): invalid range %d.", range);
696
897
  return FALSE;
697
898
}
698
899
 
722
923
    break;
723
924
  }
724
925
 
725
 
  assert(0);
 
926
  freelog(LOG_ERROR, "is_nation_in_range(): invalid range %d.", range);
726
927
  return FALSE;
727
928
}
728
929
 
777
978
   * walls) without actually knowing the target unit. */
778
979
  return (range == REQ_RANGE_LOCAL
779
980
          && (!target_unittype
780
 
              || target_unittype->uclass == pclass));
 
981
              || utype_class(target_unittype) == pclass));
 
982
}
 
983
 
 
984
/****************************************************************************
 
985
  Is there a unit with the given flag within range of the target?
 
986
****************************************************************************/
 
987
static bool is_unitclassflag_in_range(const struct unit_type *target_unittype,
 
988
                                      enum req_range range, bool survives,
 
989
                                      enum unit_class_flag_id ucflag)
 
990
{
 
991
  /* If no target_unittype is given, we allow the req to be met.  This is
 
992
   * to allow querying of certain effect types (like the presence of city
 
993
   * walls) without actually knowing the target unit. */
 
994
  return (range == REQ_RANGE_LOCAL
 
995
          && (!target_unittype
 
996
              || uclass_has_flag(utype_class(target_unittype), ucflag)));
781
997
}
782
998
 
783
999
/****************************************************************************
804
1020
  bool eval = FALSE;
805
1021
 
806
1022
  /* Note the target may actually not exist.  In particular, effects that
807
 
   * have a REQ_SPECIAL or REQ_TERRAIN may often be passed to this function
 
1023
   * have a VUT_SPECIAL or VUT_TERRAIN may often be passed to this function
808
1024
   * with a city as their target.  In this case the requirement is simply
809
1025
   * not met. */
810
 
  switch (req->source.type) {
811
 
  case REQ_NONE:
 
1026
  switch (req->source.kind) {
 
1027
  case VUT_NONE:
812
1028
    eval = TRUE;
813
1029
    break;
814
 
  case REQ_TECH:
 
1030
  case VUT_ADVANCE:
815
1031
    /* The requirement is filled if the player owns the tech. */
816
1032
    eval = is_tech_in_range(target_player, req->range,
817
 
                            req->source.value.tech);
 
1033
                            advance_number(req->source.value.advance),
 
1034
                            prob_type);
818
1035
    break;
819
 
  case REQ_GOV:
 
1036
  case VUT_GOVERNMENT:
820
1037
    /* The requirement is filled if the player is using the government. */
821
 
    eval = (government_of_player(target_player) == req->source.value.gov);
 
1038
    eval = (government_of_player(target_player) == req->source.value.govern);
822
1039
    break;
823
 
  case REQ_BUILDING:
 
1040
  case VUT_IMPROVEMENT:
824
1041
    /* The requirement is filled if there's at least one of the building
825
1042
     * in the city.  (This is a slightly nonstandard use of
826
1043
     * count_sources_in_range.) */
829
1046
                                     req->range, req->survives,
830
1047
                                     req->source.value.building) > 0);
831
1048
    break;
832
 
  case REQ_SPECIAL:
 
1049
  case VUT_SPECIAL:
833
1050
    eval = is_special_in_range(target_tile,
834
1051
                               req->range, req->survives,
835
1052
                               req->source.value.special);
836
1053
    break;
837
 
  case REQ_TERRAIN:
 
1054
  case VUT_TERRAIN:
838
1055
    eval = is_terrain_in_range(target_tile,
839
1056
                               req->range, req->survives,
840
1057
                               req->source.value.terrain);
841
1058
    break;
842
 
  case REQ_NATION:
 
1059
  case VUT_NATION:
843
1060
    eval = is_nation_in_range(target_player, req->range, req->survives,
844
1061
                              req->source.value.nation);
845
1062
    break;
846
 
  case REQ_UNITTYPE:
 
1063
  case VUT_UTYPE:
847
1064
    eval = is_unittype_in_range(target_unittype,
848
1065
                                req->range, req->survives,
849
 
                                req->source.value.unittype);
 
1066
                                req->source.value.utype);
850
1067
    break;
851
 
  case REQ_UNITFLAG:
 
1068
  case VUT_UTFLAG:
852
1069
    eval = is_unitflag_in_range(target_unittype,
853
1070
                                req->range, req->survives,
854
1071
                                req->source.value.unitflag,
855
1072
                                prob_type);
856
1073
    break;
857
 
  case REQ_UNITCLASS:
 
1074
  case VUT_UCLASS:
858
1075
    eval = is_unitclass_in_range(target_unittype,
859
1076
                                 req->range, req->survives,
860
 
                                 req->source.value.unitclass);
861
 
    break;
862
 
  case REQ_OUTPUTTYPE:
 
1077
                                 req->source.value.uclass);
 
1078
    break;
 
1079
  case VUT_UCFLAG:
 
1080
    eval = is_unitclassflag_in_range(target_unittype,
 
1081
                                     req->range, req->survives,
 
1082
                                     req->source.value.unitclassflag);
 
1083
    break;
 
1084
  case VUT_OTYPE:
863
1085
    eval = (target_output
864
1086
            && target_output->index == req->source.value.outputtype);
865
1087
    break;
866
 
  case REQ_SPECIALIST:
 
1088
  case VUT_SPECIALIST:
867
1089
    eval = (target_specialist
868
 
            && target_specialist->index == req->source.value.specialist);
 
1090
            && target_specialist == req->source.value.specialist);
869
1091
    break;
870
 
  case REQ_MINSIZE:
 
1092
  case VUT_MINSIZE:
871
1093
    eval = target_city && target_city->size >= req->source.value.minsize;
872
1094
    break;
873
 
  case REQ_LAST:
874
 
    assert(0);
 
1095
  case VUT_AI_LEVEL:
 
1096
    eval = target_player
 
1097
      && target_player->ai_data.control
 
1098
      && target_player->ai_data.skill_level == req->source.value.ai_level;
 
1099
    break;
 
1100
  case VUT_TERRAINCLASS:
 
1101
    eval = is_terrain_class_in_range(target_tile,
 
1102
                                     req->range, req->survives,
 
1103
                                     req->source.value.terrainclass);
 
1104
    break;
 
1105
  case VUT_BASE:
 
1106
    eval = is_base_type_in_range(target_tile,
 
1107
                                 req->range, req->survives,
 
1108
                                 req->source.value.base);
 
1109
    break;
 
1110
  case VUT_MINYEAR:
 
1111
    eval = game.info.year >= req->source.value.minyear;
 
1112
    break;
 
1113
  case VUT_TERRAINALTER:
 
1114
    eval = is_terrain_alter_possible_in_range(target_tile,
 
1115
                                              req->range, req->survives,
 
1116
                                              req->source.value.terrainalter);
 
1117
    break;
 
1118
  case VUT_CITYTILE:
 
1119
    if (target_tile) {
 
1120
      if (req->source.value.citytile == CITYT_CENTER) {
 
1121
        if (target_city) {
 
1122
          eval = is_city_center(target_city, target_tile);
 
1123
        } else {
 
1124
          eval = tile_city(target_tile) != NULL;
 
1125
        }
 
1126
      } else {
 
1127
        /* Not implemented */
 
1128
        freelog(LOG_ERROR, "is_req_active(): citytile %d not supported.",
 
1129
                req->source.value.citytile);
 
1130
        return FALSE;
 
1131
      }
 
1132
    } else {
 
1133
      eval = FALSE;
 
1134
    }
 
1135
    break;
 
1136
  case VUT_LAST:
 
1137
    freelog(LOG_ERROR, "is_req_active(): invalid source kind %d.",
 
1138
            req->source.kind);
875
1139
    return FALSE;
876
1140
  }
877
1141
 
928
1192
*****************************************************************************/
929
1193
bool is_req_unchanging(const struct requirement *req)
930
1194
{
931
 
  switch (req->source.type) {
932
 
  case REQ_NATION:
933
 
  case REQ_NONE:
934
 
  case REQ_OUTPUTTYPE:
935
 
  case REQ_SPECIALIST: /* Only so long as it's at local range only */
 
1195
  switch (req->source.kind) {
 
1196
  case VUT_NATION:
 
1197
  case VUT_NONE:
 
1198
  case VUT_OTYPE:
 
1199
  case VUT_SPECIALIST:  /* Only so long as it's at local range only */
 
1200
  case VUT_AI_LEVEL:
 
1201
  case VUT_CITYTILE:
936
1202
    return TRUE;
937
 
  case REQ_TECH:
938
 
  case REQ_GOV:
939
 
  case REQ_BUILDING:
940
 
  case REQ_MINSIZE:
941
 
  case REQ_UNITTYPE: /* Not sure about this one */
942
 
  case REQ_UNITFLAG: /* Not sure about this one */
943
 
  case REQ_UNITCLASS: /* Not sure about this one */
 
1203
  case VUT_ADVANCE:
 
1204
  case VUT_GOVERNMENT:
 
1205
  case VUT_IMPROVEMENT:
 
1206
  case VUT_MINSIZE:
 
1207
  case VUT_UTYPE:       /* Not sure about this one */
 
1208
  case VUT_UTFLAG:      /* Not sure about this one */
 
1209
  case VUT_UCLASS:      /* Not sure about this one */
 
1210
  case VUT_UCFLAG:      /* Not sure about this one */
944
1211
    return FALSE;
945
 
  case REQ_SPECIAL:
946
 
  case REQ_TERRAIN:
947
 
    /* Terrains and specials aren't really unchanging; in fact they're
 
1212
  case VUT_SPECIAL:
 
1213
  case VUT_TERRAIN:
 
1214
  case VUT_TERRAINCLASS:
 
1215
  case VUT_TERRAINALTER:
 
1216
  case VUT_BASE:
 
1217
    /* Terrains, specials and bases aren't really unchanging; in fact they're
948
1218
     * practically guaranteed to change.  We return TRUE here for historical
949
1219
     * reasons and so that the AI doesn't get confused (since the AI
950
1220
     * doesn't know how to meet special and terrain requirements). */
951
1221
    return TRUE;
952
 
  case REQ_LAST:
 
1222
  case VUT_MINYEAR:
 
1223
    /* Once year is reached, it does not change again */
 
1224
    return req->source.value.minyear > game.info.year;
 
1225
  case VUT_LAST:
953
1226
    break;
954
1227
  }
955
 
  assert(0);
 
1228
  freelog(LOG_ERROR, "is_req_unchanging(): invalid source kind %d.",
 
1229
          req->source.kind);
956
1230
  return TRUE;
957
1231
}
958
1232
 
960
1234
  Return TRUE iff the two sources are equivalent.  Note this isn't the
961
1235
  same as an == or memcmp check.
962
1236
*****************************************************************************/
963
 
bool are_req_sources_equal(const struct req_source *psource1,
964
 
                           const struct req_source *psource2)
 
1237
bool are_universals_equal(const struct universal *psource1,
 
1238
                          const struct universal *psource2)
965
1239
{
966
 
  if (psource1->type != psource2->type) {
 
1240
  if (psource1->kind != psource2->kind) {
967
1241
    return FALSE;
968
1242
  }
969
 
  switch (psource1->type) {
970
 
  case REQ_NONE:
 
1243
  switch (psource1->kind) {
 
1244
  case VUT_NONE:
971
1245
    return TRUE;
972
 
  case REQ_TECH:
973
 
    return psource1->value.tech == psource2->value.tech;
974
 
  case REQ_GOV:
975
 
    return psource1->value.gov == psource2->value.gov;
976
 
  case REQ_BUILDING:
 
1246
  case VUT_ADVANCE:
 
1247
    return psource1->value.advance == psource2->value.advance;
 
1248
  case VUT_GOVERNMENT:
 
1249
    return psource1->value.govern == psource2->value.govern;
 
1250
  case VUT_IMPROVEMENT:
977
1251
    return psource1->value.building == psource2->value.building;
978
 
  case REQ_SPECIAL:
 
1252
  case VUT_SPECIAL:
979
1253
    return psource1->value.special == psource2->value.special;
980
 
  case REQ_TERRAIN:
 
1254
  case VUT_TERRAIN:
981
1255
    return psource1->value.terrain == psource2->value.terrain;
982
 
  case REQ_NATION:
 
1256
  case VUT_NATION:
983
1257
    return psource1->value.nation == psource2->value.nation;
984
 
  case REQ_UNITTYPE:
985
 
    return psource1->value.unittype == psource2->value.unittype;
986
 
  case REQ_UNITFLAG:
 
1258
  case VUT_UTYPE:
 
1259
    return psource1->value.utype == psource2->value.utype;
 
1260
  case VUT_UTFLAG:
987
1261
    return psource1->value.unitflag == psource2->value.unitflag;
988
 
  case REQ_UNITCLASS:
989
 
    return psource1->value.unitclass == psource2->value.unitclass;
990
 
  case REQ_OUTPUTTYPE:
 
1262
  case VUT_UCLASS:
 
1263
    return psource1->value.uclass == psource2->value.uclass;
 
1264
  case VUT_UCFLAG:
 
1265
    return psource1->value.unitclassflag == psource2->value.unitclassflag;
 
1266
  case VUT_OTYPE:
991
1267
    return psource1->value.outputtype == psource2->value.outputtype;
992
 
  case REQ_SPECIALIST:
 
1268
  case VUT_SPECIALIST:
993
1269
    return psource1->value.specialist == psource2->value.specialist;
994
 
  case REQ_MINSIZE:
 
1270
  case VUT_MINSIZE:
995
1271
    return psource1->value.minsize == psource2->value.minsize;
996
 
  case REQ_LAST:
 
1272
  case VUT_AI_LEVEL:
 
1273
    return psource1->value.ai_level == psource2->value.ai_level;
 
1274
  case VUT_TERRAINCLASS:
 
1275
    return psource1->value.terrainclass == psource2->value.terrainclass;
 
1276
  case VUT_BASE:
 
1277
    return psource1->value.base == psource2->value.base;
 
1278
  case VUT_MINYEAR:
 
1279
    return psource1->value.minyear == psource2->value.minyear;
 
1280
  case VUT_TERRAINALTER:
 
1281
    return psource1->value.terrainalter == psource2->value.terrainalter;
 
1282
  case VUT_CITYTILE:
 
1283
    return psource1->value.citytile == psource2->value.citytile;
 
1284
  case VUT_LAST:
997
1285
    break;
998
1286
  }
999
 
  assert(0);
 
1287
  freelog(LOG_ERROR, "are_universals_equal(): invalid source kind %d.",
 
1288
          psource1->kind);
1000
1289
  return FALSE;
1001
1290
}
1002
1291
 
1003
1292
/****************************************************************************
 
1293
  Return the (untranslated) rule name of the kind of universal.
 
1294
  You don't have to free the return pointer.
 
1295
*****************************************************************************/
 
1296
const char *universal_kind_name(const enum universals_n kind)
 
1297
{
 
1298
  RETURN_VAL_IF_FAIL(kind >= 0 && kind < ARRAY_SIZE(universal_names), NULL);
 
1299
  return universal_names[kind];
 
1300
}
 
1301
 
 
1302
/****************************************************************************
 
1303
  Return the (untranslated) rule name of the universal.
 
1304
  You don't have to free the return pointer.
 
1305
*****************************************************************************/
 
1306
const char *universal_rule_name(const struct universal *psource)
 
1307
{
 
1308
  switch (psource->kind) {
 
1309
  case VUT_NONE:
 
1310
  case VUT_CITYTILE:
 
1311
  case VUT_MINYEAR:
 
1312
    /* TRANS: missing value */
 
1313
    return N_("(none)");
 
1314
  case VUT_ADVANCE:
 
1315
    return advance_rule_name(psource->value.advance);
 
1316
  case VUT_GOVERNMENT:
 
1317
    return government_rule_name(psource->value.govern);
 
1318
  case VUT_IMPROVEMENT:
 
1319
    return improvement_rule_name(psource->value.building);
 
1320
  case VUT_SPECIAL:
 
1321
    return special_rule_name(psource->value.special);
 
1322
  case VUT_TERRAIN:
 
1323
    return terrain_rule_name(psource->value.terrain);
 
1324
  case VUT_NATION:
 
1325
    return nation_rule_name(psource->value.nation);
 
1326
  case VUT_UTYPE:
 
1327
    return utype_rule_name(psource->value.utype);
 
1328
  case VUT_UTFLAG:
 
1329
    return unit_flag_rule_name(psource->value.unitflag);
 
1330
  case VUT_UCLASS:
 
1331
    return uclass_rule_name(psource->value.uclass);
 
1332
  case VUT_UCFLAG:
 
1333
    return unit_class_flag_rule_name(psource->value.unitclassflag);
 
1334
  case VUT_OTYPE:
 
1335
    return get_output_name(psource->value.outputtype);
 
1336
  case VUT_SPECIALIST:
 
1337
    return specialist_rule_name(psource->value.specialist);
 
1338
  case VUT_MINSIZE:
 
1339
    return N_("Size %d");
 
1340
  case VUT_AI_LEVEL:
 
1341
    return ai_level_name(psource->value.ai_level);
 
1342
  case VUT_TERRAINCLASS:
 
1343
    return terrain_class_rule_name(psource->value.terrainclass);
 
1344
  case VUT_BASE:
 
1345
    return base_rule_name(psource->value.base);
 
1346
  case VUT_TERRAINALTER:
 
1347
    return terrain_alteration_rule_name(psource->value.terrainalter);
 
1348
  case VUT_LAST:
 
1349
    break;
 
1350
  }
 
1351
 
 
1352
  freelog(LOG_ERROR, "universal_rule_name: invalid source kind %d.",
 
1353
          psource->kind);
 
1354
  return NULL;
 
1355
}
 
1356
 
 
1357
/****************************************************************************
1004
1358
  Make user-friendly text for the source.  The text is put into a user
1005
1359
  buffer which is also returned.
1006
1360
*****************************************************************************/
1007
 
char *get_req_source_text(const struct req_source *psource,
1008
 
                          char *buf, size_t bufsz)
 
1361
const char *universal_name_translation(const struct universal *psource,
 
1362
                                       char *buf, size_t bufsz)
1009
1363
{
1010
1364
  buf[0] = '\0'; /* to be safe. */
1011
 
  switch (psource->type) {
1012
 
  case REQ_NONE:
 
1365
  switch (psource->kind) {
 
1366
  case VUT_NONE:
1013
1367
    /* TRANS: missing value */
1014
1368
    mystrlcat(buf, _("(none)"), bufsz);
1015
 
    break;
1016
 
  case REQ_TECH:
1017
 
    mystrlcat(buf, advance_name_translation(psource->value.tech), bufsz);
1018
 
    break;
1019
 
  case REQ_GOV:
1020
 
    mystrlcat(buf, government_name_translation(psource->value.gov), bufsz);
1021
 
    break;
1022
 
  case REQ_BUILDING:
 
1369
    return buf;
 
1370
  case VUT_ADVANCE:
 
1371
    mystrlcat(buf, advance_name_translation(psource->value.advance), bufsz);
 
1372
    return buf;
 
1373
  case VUT_GOVERNMENT:
 
1374
    mystrlcat(buf, government_name_translation(psource->value.govern), bufsz);
 
1375
    return buf;
 
1376
  case VUT_IMPROVEMENT:
1023
1377
    mystrlcat(buf, improvement_name_translation(psource->value.building), bufsz);
1024
 
    break;
1025
 
  case REQ_SPECIAL:
 
1378
    return buf;
 
1379
  case VUT_SPECIAL:
1026
1380
    mystrlcat(buf, special_name_translation(psource->value.special), bufsz);
1027
 
    break;
1028
 
  case REQ_TERRAIN:
 
1381
    return buf;
 
1382
  case VUT_TERRAIN:
1029
1383
    mystrlcat(buf, terrain_name_translation(psource->value.terrain), bufsz);
1030
 
    break;
1031
 
  case REQ_NATION:
 
1384
    return buf;
 
1385
  case VUT_NATION:
1032
1386
    mystrlcat(buf, nation_adjective_translation(psource->value.nation), bufsz);
1033
 
    break;
1034
 
  case REQ_UNITTYPE:
1035
 
    mystrlcat(buf, utype_name_translation(psource->value.unittype), bufsz);
1036
 
    break;
1037
 
  case REQ_UNITFLAG:
1038
 
    cat_snprintf(buf, bufsz, _("%s units"),
 
1387
    return buf;
 
1388
  case VUT_UTYPE:
 
1389
    mystrlcat(buf, utype_name_translation(psource->value.utype), bufsz);
 
1390
    return buf;
 
1391
  case VUT_UTFLAG:
 
1392
    cat_snprintf(buf, bufsz, _("\"%s\" units"),
 
1393
                 /* flag names are never translated */
1039
1394
                 unit_flag_rule_name(psource->value.unitflag));
1040
 
    break;
1041
 
  case REQ_UNITCLASS:
 
1395
    return buf;
 
1396
  case VUT_UCLASS:
1042
1397
    cat_snprintf(buf, bufsz, _("%s units"),
1043
 
                 uclass_name_translation(psource->value.unitclass));
1044
 
    break;
1045
 
  case REQ_OUTPUTTYPE:
1046
 
    mystrlcat(buf, get_output_name(psource->value.outputtype), bufsz);
1047
 
    break;
1048
 
  case REQ_SPECIALIST:
1049
 
    mystrlcat(buf, get_specialist(psource->value.specialist)->name, bufsz);
1050
 
    break;
1051
 
  case REQ_MINSIZE:
 
1398
                 uclass_name_translation(psource->value.uclass));
 
1399
    return buf;
 
1400
  case VUT_UCFLAG:
 
1401
    cat_snprintf(buf, bufsz, _("\"%s\" units"),
 
1402
                 /* flag names are never translated */
 
1403
                 unit_class_flag_rule_name(psource->value.unitclassflag));
 
1404
    return buf;
 
1405
  case VUT_OTYPE:
 
1406
    mystrlcat(buf, get_output_name(psource->value.outputtype), bufsz); /* FIXME */
 
1407
    return buf;
 
1408
  case VUT_SPECIALIST:
 
1409
    mystrlcat(buf, specialist_name_translation(psource->value.specialist), bufsz);
 
1410
    return buf;
 
1411
  case VUT_MINSIZE:
1052
1412
    cat_snprintf(buf, bufsz, _("Size %d"),
1053
1413
                 psource->value.minsize);
1054
 
    break;
1055
 
  case REQ_LAST:
1056
 
    assert(0);
 
1414
    return buf;
 
1415
  case VUT_AI_LEVEL:
 
1416
    /* TRANS: "Hard AI" */
 
1417
    cat_snprintf(buf, bufsz, _("%s AI"),
 
1418
                 ai_level_name(psource->value.ai_level)); /* FIXME */
 
1419
    return buf;
 
1420
  case VUT_TERRAINCLASS:
 
1421
    /* TRANS: "Land terrain" */
 
1422
    cat_snprintf(buf, bufsz, _("%s terrain"),
 
1423
                 terrain_class_name_translation(psource->value.terrainclass));
 
1424
    return buf;
 
1425
  case VUT_BASE:
 
1426
    /* TRANS: "Fortress base" */
 
1427
    cat_snprintf(buf, bufsz, _("%s base"),
 
1428
                 base_name_translation(psource->value.base));
 
1429
    return buf;
 
1430
  case VUT_MINYEAR:
 
1431
    cat_snprintf(buf, bufsz, _("After %s"),
 
1432
                 textyear(psource->value.minyear));
 
1433
    return buf;
 
1434
  case VUT_TERRAINALTER:
 
1435
    /* TRANS: "Irrigation possible" */
 
1436
    cat_snprintf(buf, bufsz, _("%s possible"),
 
1437
                 terrain_alteration_name_translation(psource->value.terrainalter));
 
1438
    return buf;
 
1439
  case VUT_CITYTILE:
 
1440
    mystrlcat(buf, _("City center tile"), bufsz);
 
1441
    return buf;
 
1442
  case VUT_LAST:
1057
1443
    break;
1058
1444
  }
1059
1445
 
 
1446
  freelog(LOG_ERROR, "universal_rule_name: invalid source kind %d.",
 
1447
          psource->kind);
 
1448
 
1060
1449
  return buf;
1061
1450
}
1062
1451
 
1063
 
 
1064
1452
/****************************************************************************
1065
 
  Return untranslated name of the requirement source name.
 
1453
  Return untranslated name of the universal source name.
1066
1454
*****************************************************************************/
1067
 
const char *get_req_source_type_name_orig(const struct req_source *psource)
1068
 
{
1069
 
  return req_source_type_names[psource->type];
 
1455
const char *universal_type_rule_name(const struct universal *psource)
 
1456
{
 
1457
  return universal_kind_name(psource->kind);
 
1458
}
 
1459
 
 
1460
/**************************************************************************
 
1461
  Return the number of shields it takes to build this universal.
 
1462
**************************************************************************/
 
1463
int universal_build_shield_cost(const struct universal *target)
 
1464
{
 
1465
  switch (target->kind) {
 
1466
  case VUT_IMPROVEMENT:
 
1467
    return impr_build_shield_cost(target->value.building);
 
1468
  case VUT_UTYPE:
 
1469
    return utype_build_shield_cost(target->value.utype);
 
1470
  default:
 
1471
    break;
 
1472
  }
 
1473
  return FC_INFINITY;
1070
1474
}