OpenTTD Source  1.11.0-beta1
newgrf.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD 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, version 2.
4  * OpenTTD 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.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 
12 #include <stdarg.h>
13 
14 #include "debug.h"
15 #include "fileio_func.h"
16 #include "engine_func.h"
17 #include "engine_base.h"
18 #include "bridge.h"
19 #include "town.h"
20 #include "newgrf_engine.h"
21 #include "newgrf_text.h"
22 #include "fontcache.h"
23 #include "currency.h"
24 #include "landscape.h"
25 #include "newgrf_cargo.h"
26 #include "newgrf_house.h"
27 #include "newgrf_sound.h"
28 #include "newgrf_station.h"
29 #include "industrytype.h"
30 #include "newgrf_canal.h"
31 #include "newgrf_townname.h"
32 #include "newgrf_industries.h"
33 #include "newgrf_airporttiles.h"
34 #include "newgrf_airport.h"
35 #include "newgrf_object.h"
36 #include "rev.h"
37 #include "fios.h"
38 #include "strings_func.h"
39 #include "date_func.h"
40 #include "string_func.h"
41 #include "network/network.h"
42 #include <map>
43 #include "smallmap_gui.h"
44 #include "genworld.h"
45 #include "error.h"
46 #include "vehicle_func.h"
47 #include "language.h"
48 #include "vehicle_base.h"
49 #include "road.h"
50 
51 #include "table/strings.h"
52 #include "table/build_industry.h"
53 
54 #include "safeguards.h"
55 
56 /* TTDPatch extended GRF format codec
57  * (c) Petr Baudis 2004 (GPL'd)
58  * Changes by Florian octo Forster are (c) by the OpenTTD development team.
59  *
60  * Contains portions of documentation by TTDPatch team.
61  * Thanks especially to Josef Drexler for the documentation as well as a lot
62  * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
63  * served as subject to the initial testing of this codec. */
64 
66 static std::vector<GRFFile *> _grf_files;
67 
68 const std::vector<GRFFile *> &GetAllGRFFiles()
69 {
70  return _grf_files;
71 }
72 
75 
77 static uint32 _ttdpatch_flags[8];
78 
81 
82 static const uint MAX_SPRITEGROUP = UINT8_MAX;
83 
86 private:
88  struct SpriteSet {
90  uint num_sprites;
91  };
92 
94  std::map<uint, SpriteSet> spritesets[GSF_END];
95 
96 public:
97  /* Global state */
98  GrfLoadingStage stage;
100 
101  /* Local state in the file */
102  uint file_index;
105  uint32 nfo_line;
107 
108  /* Kind of return values when processing certain actions */
110 
111  /* Currently referenceable spritegroups */
112  SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
113 
116  {
117  this->nfo_line = 0;
118  this->skip_sprites = 0;
119 
120  for (uint i = 0; i < GSF_END; i++) {
121  this->spritesets[i].clear();
122  }
123 
124  memset(this->spritegroups, 0, sizeof(this->spritegroups));
125  }
126 
135  void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
136  {
137  assert(feature < GSF_END);
138  for (uint i = 0; i < numsets; i++) {
139  SpriteSet &set = this->spritesets[feature][first_set + i];
140  set.sprite = first_sprite + i * numents;
141  set.num_sprites = numents;
142  }
143  }
144 
151  bool HasValidSpriteSets(byte feature) const
152  {
153  assert(feature < GSF_END);
154  return !this->spritesets[feature].empty();
155  }
156 
164  bool IsValidSpriteSet(byte feature, uint set) const
165  {
166  assert(feature < GSF_END);
167  return this->spritesets[feature].find(set) != this->spritesets[feature].end();
168  }
169 
176  SpriteID GetSprite(byte feature, uint set) const
177  {
178  assert(IsValidSpriteSet(feature, set));
179  return this->spritesets[feature].find(set)->second.sprite;
180  }
181 
188  uint GetNumEnts(byte feature, uint set) const
189  {
190  assert(IsValidSpriteSet(feature, set));
191  return this->spritesets[feature].find(set)->second.num_sprites;
192  }
193 };
194 
195 static GrfProcessingState _cur;
196 
197 
204 template <VehicleType T>
205 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
206 {
207  return image_index == 0xFD || IsValidImageIndex<T>(image_index);
208 }
209 
211 
213 class ByteReader {
214 protected:
215  byte *data;
216  byte *end;
217 
218 public:
219  ByteReader(byte *data, byte *end) : data(data), end(end) { }
220 
221  inline byte ReadByte()
222  {
223  if (data < end) return *(data)++;
224  throw OTTDByteReaderSignal();
225  }
226 
227  uint16 ReadWord()
228  {
229  uint16 val = ReadByte();
230  return val | (ReadByte() << 8);
231  }
232 
233  uint16 ReadExtendedByte()
234  {
235  uint16 val = ReadByte();
236  return val == 0xFF ? ReadWord() : val;
237  }
238 
239  uint32 ReadDWord()
240  {
241  uint32 val = ReadWord();
242  return val | (ReadWord() << 16);
243  }
244 
245  uint32 ReadVarSize(byte size)
246  {
247  switch (size) {
248  case 1: return ReadByte();
249  case 2: return ReadWord();
250  case 4: return ReadDWord();
251  default:
252  NOT_REACHED();
253  return 0;
254  }
255  }
256 
257  const char *ReadString()
258  {
259  char *string = reinterpret_cast<char *>(data);
260  size_t string_length = ttd_strnlen(string, Remaining());
261 
262  if (string_length == Remaining()) {
263  /* String was not NUL terminated, so make sure it is now. */
264  string[string_length - 1] = '\0';
265  grfmsg(7, "String was not terminated with a zero byte.");
266  } else {
267  /* Increase the string length to include the NUL byte. */
268  string_length++;
269  }
270  Skip(string_length);
271 
272  return string;
273  }
274 
275  inline size_t Remaining() const
276  {
277  return end - data;
278  }
279 
280  inline bool HasData(size_t count = 1) const
281  {
282  return data + count <= end;
283  }
284 
285  inline byte *Data()
286  {
287  return data;
288  }
289 
290  inline void Skip(size_t len)
291  {
292  data += len;
293  /* It is valid to move the buffer to exactly the end of the data,
294  * as there may not be any more data read. */
295  if (data > end) throw OTTDByteReaderSignal();
296  }
297 };
298 
299 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
300 
301 static const uint NUM_STATIONS_PER_GRF = 255;
302 
307  UNSET = 0,
310  };
311 
312  uint16 cargo_allowed;
313  uint16 cargo_disallowed;
314  RailTypeLabel railtypelabel;
315  uint8 roadtramtype;
318  bool prop27_set;
319  uint8 rv_max_speed;
320  CargoTypes ctt_include_mask;
321  CargoTypes ctt_exclude_mask;
322 
327  void UpdateRefittability(bool non_empty)
328  {
329  if (non_empty) {
330  this->refittability = NONEMPTY;
331  } else if (this->refittability == UNSET) {
332  this->refittability = EMPTY;
333  }
334  }
335 };
336 
338 
343 static uint32 _grm_engines[256];
344 
346 static uint32 _grm_cargoes[NUM_CARGO * 2];
347 
348 struct GRFLocation {
349  uint32 grfid;
350  uint32 nfoline;
351 
352  GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
353 
354  bool operator<(const GRFLocation &other) const
355  {
356  return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
357  }
358 
359  bool operator == (const GRFLocation &other) const
360  {
361  return this->grfid == other.grfid && this->nfoline == other.nfoline;
362  }
363 };
364 
365 static std::map<GRFLocation, SpriteID> _grm_sprites;
366 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
367 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
368 
379 void CDECL grfmsg(int severity, const char *str, ...)
380 {
381  char buf[1024];
382  va_list va;
383 
384  va_start(va, str);
385  vseprintf(buf, lastof(buf), str, va);
386  va_end(va);
387 
388  DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
389 }
390 
396 static GRFFile *GetFileByGRFID(uint32 grfid)
397 {
398  for (GRFFile * const file : _grf_files) {
399  if (file->grfid == grfid) return file;
400  }
401  return nullptr;
402 }
403 
409 static GRFFile *GetFileByFilename(const char *filename)
410 {
411  for (GRFFile * const file : _grf_files) {
412  if (strcmp(file->filename, filename) == 0) return file;
413  }
414  return nullptr;
415 }
416 
419 {
420  /* Clear the GOTO labels used for GRF processing */
421  for (GRFLabel *l = gf->label; l != nullptr;) {
422  GRFLabel *l2 = l->next;
423  free(l);
424  l = l2;
425  }
426  gf->label = nullptr;
427 }
428 
435 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = nullptr)
436 {
437  GRFFile *file;
438  if (config != nullptr) {
439  file = GetFileByGRFID(config->ident.grfid);
440  } else {
441  config = _cur.grfconfig;
442  file = _cur.grffile;
443  }
444 
445  config->status = GCS_DISABLED;
446  if (file != nullptr) ClearTemporaryNewGRFData(file);
447  if (config == _cur.grfconfig) _cur.skip_sprites = -1;
448 
449  if (message != STR_NULL) {
450  delete config->error;
451  config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
452  if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
453  }
454 
455  return config->error;
456 }
457 
462  uint32 grfid;
465 };
466 typedef std::vector<StringIDMapping> StringIDMappingVector;
467 static StringIDMappingVector _string_to_grf_mapping;
468 
474 static void AddStringForMapping(StringID source, StringID *target)
475 {
476  *target = STR_UNDEFINED;
477  _string_to_grf_mapping.push_back({_cur.grffile->grfid, source, target});
478 }
479 
488 {
489  /* StringID table for TextIDs 0x4E->0x6D */
490  static const StringID units_volume[] = {
491  STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
492  STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
493  STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
494  STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495  STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
496  STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
497  STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
498  STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
499  };
500 
501  /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
502  assert(!IsInsideMM(str, 0xD000, 0xD7FF));
503 
504 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
505  static_assert(stringend - stringid == end - begin); \
506  if (str >= begin && str <= end) return str + (stringid - begin)
507 
508  /* We have some changes in our cargo strings, resulting in some missing. */
509  TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
510  TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
511  if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
512  TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
513  TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
514  TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
515 
516  /* Map building names according to our lang file changes. There are several
517  * ranges of house ids, all of which need to be remapped to allow newgrfs
518  * to use original house names. */
519  TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
520  TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
521  TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
522 
523  /* Same thing for industries */
524  TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
525  TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
526  TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
527  TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
528  TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
529 
530  switch (str) {
531  case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
532  case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
533  case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
534  }
535 #undef TEXTID_TO_STRINGID
536 
537  if (str == STR_NULL) return STR_EMPTY;
538 
539  DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
540 
541  return STR_EMPTY;
542 }
543 
551 StringID MapGRFStringID(uint32 grfid, StringID str)
552 {
553  if (IsInsideMM(str, 0xD800, 0xE000)) {
554  /* General text provided by NewGRF.
555  * In the specs this is called the 0xDCxx range (misc persistent texts),
556  * but we meanwhile extended the range to 0xD800-0xDFFF.
557  * Note: We are not involved in the "persistent" business, since we do not store
558  * any NewGRF strings in savegames. */
559  return GetGRFStringID(grfid, str);
560  } else if (IsInsideMM(str, 0xD000, 0xD800)) {
561  /* Callback text provided by NewGRF.
562  * In the specs this is called the 0xD0xx range (misc graphics texts).
563  * These texts can be returned by various callbacks.
564  *
565  * Due to how TTDP implements the GRF-local- to global-textid translation
566  * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
567  * We do not care about that difference and just mask out the 0x400 bit.
568  */
569  str &= ~0x400;
570  return GetGRFStringID(grfid, str);
571  } else {
572  /* The NewGRF wants to include/reference an original TTD string.
573  * Try our best to find an equivalent one. */
575  }
576 }
577 
578 static std::map<uint32, uint32> _grf_id_overrides;
579 
585 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
586 {
587  _grf_id_overrides[source_grfid] = target_grfid;
588  grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
589 }
590 
599 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
600 {
601  /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
602  * them use the same engine slots. */
603  uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
605  /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
606  scope_grfid = file->grfid;
607  uint32 override = _grf_id_overrides[file->grfid];
608  if (override != 0) {
609  scope_grfid = override;
610  const GRFFile *grf_match = GetFileByGRFID(override);
611  if (grf_match == nullptr) {
612  grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
613  } else {
614  grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
615  }
616  }
617 
618  /* Check if the engine is registered in the override manager */
619  EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
620  if (engine != INVALID_ENGINE) {
621  Engine *e = Engine::Get(engine);
622  if (e->grf_prop.grffile == nullptr) e->grf_prop.grffile = file;
623  return e;
624  }
625  }
626 
627  /* Check if there is an unreserved slot */
628  EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
629  if (engine != INVALID_ENGINE) {
630  Engine *e = Engine::Get(engine);
631 
632  if (e->grf_prop.grffile == nullptr) {
633  e->grf_prop.grffile = file;
634  grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
635  }
636 
637  /* Reserve the engine slot */
638  if (!static_access) {
639  EngineIDMapping *eid = _engine_mngr.data() + engine;
640  eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
641  }
642 
643  return e;
644  }
645 
646  if (static_access) return nullptr;
647 
648  if (!Engine::CanAllocateItem()) {
649  grfmsg(0, "Can't allocate any more engines");
650  return nullptr;
651  }
652 
653  size_t engine_pool_size = Engine::GetPoolSize();
654 
655  /* ... it's not, so create a new one based off an existing engine */
656  Engine *e = new Engine(type, internal_id);
657  e->grf_prop.grffile = file;
658 
659  /* Reserve the engine slot */
660  assert(_engine_mngr.size() == e->index);
661  _engine_mngr.push_back({
662  scope_grfid, // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
663  internal_id,
664  type,
665  std::min<uint8>(internal_id, _engine_counts[type]) // substitute_id == _engine_counts[subtype] means "no substitute"
666  });
667 
668  if (engine_pool_size != Engine::GetPoolSize()) {
669  /* Resize temporary engine data ... */
671 
672  /* and blank the new block. */
673  size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
674  memset(_gted + engine_pool_size, 0, len);
675  }
676  if (type == VEH_TRAIN) {
677  _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
678  }
679 
680  grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
681 
682  return e;
683 }
684 
695 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
696 {
697  uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
699  scope_grfid = file->grfid;
700  uint32 override = _grf_id_overrides[file->grfid];
701  if (override != 0) scope_grfid = override;
702  }
703 
704  return _engine_mngr.GetID(type, internal_id, scope_grfid);
705 }
706 
711 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
712 {
713  if (HasBit(grf_sprite->pal, 14)) {
714  ClrBit(grf_sprite->pal, 14);
715  SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
716  }
717 
718  if (HasBit(grf_sprite->sprite, 14)) {
719  ClrBit(grf_sprite->sprite, 14);
721  }
722 
723  if (HasBit(grf_sprite->sprite, 15)) {
724  ClrBit(grf_sprite->sprite, 15);
725  SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
726  }
727 }
728 
742 static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = nullptr, uint16 *max_palette_offset = nullptr)
743 {
744  grf_sprite->sprite = buf->ReadWord();
745  grf_sprite->pal = buf->ReadWord();
746  TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
747 
748  MapSpriteMappingRecolour(grf_sprite);
749 
750  bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
751  ClrBit(grf_sprite->pal, 15);
752  if (custom_sprite) {
753  /* Use sprite from Action 1 */
754  uint index = GB(grf_sprite->sprite, 0, 14);
755  if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
756  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
757  grf_sprite->sprite = SPR_IMG_QUERY;
758  grf_sprite->pal = PAL_NONE;
759  } else {
760  SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
761  if (max_sprite_offset != nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
762  SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
764  }
765  } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
766  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
768  return flags;
769  }
770 
771  if (flags & TLF_CUSTOM_PALETTE) {
772  /* Use palette from Action 1 */
773  uint index = GB(grf_sprite->pal, 0, 14);
774  if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
775  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
776  grf_sprite->pal = PAL_NONE;
777  } else {
778  SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
779  if (max_palette_offset != nullptr) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
780  SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
782  }
783  } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
784  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
786  return flags;
787  }
788 
789  return flags;
790 }
791 
800 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
801 {
802  if (!(flags & TLF_DRAWING_FLAGS)) return;
803 
804  if (dts->registers == nullptr) dts->AllocateRegisters();
805  TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
806  regs.flags = flags & TLF_DRAWING_FLAGS;
807 
808  if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
809  if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
810  if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
811 
812  if (is_parent) {
813  if (flags & TLF_BB_XY_OFFSET) {
814  regs.delta.parent[0] = buf->ReadByte();
815  regs.delta.parent[1] = buf->ReadByte();
816  }
817  if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
818  } else {
819  if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
820  if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
821  }
822 
823  if (flags & TLF_SPRITE_VAR10) {
824  regs.sprite_var10 = buf->ReadByte();
825  if (regs.sprite_var10 > TLR_MAX_VAR10) {
826  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
827  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
828  return;
829  }
830  }
831 
832  if (flags & TLF_PALETTE_VAR10) {
833  regs.palette_var10 = buf->ReadByte();
834  if (regs.palette_var10 > TLR_MAX_VAR10) {
835  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
836  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
837  return;
838  }
839  }
840 }
841 
853 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
854 {
855  bool has_flags = HasBit(num_building_sprites, 6);
856  ClrBit(num_building_sprites, 6);
857  TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
858  if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
859  dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
860 
861  uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
862  uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
863  MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
864  MemSetT(max_palette_offset, 0, num_building_sprites + 1);
865 
866  /* Groundsprite */
867  TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
868  if (_cur.skip_sprites < 0) return true;
869 
870  if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
871  grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
872  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
873  return true;
874  }
875 
876  ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
877  if (_cur.skip_sprites < 0) return true;
878 
879  for (uint i = 0; i < num_building_sprites; i++) {
880  DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
881 
882  flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
883  if (_cur.skip_sprites < 0) return true;
884 
885  if (flags & ~valid_flags) {
886  grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
887  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
888  return true;
889  }
890 
891  seq->delta_x = buf->ReadByte();
892  seq->delta_y = buf->ReadByte();
893 
894  if (!no_z_position) seq->delta_z = buf->ReadByte();
895 
896  if (seq->IsParentSprite()) {
897  seq->size_x = buf->ReadByte();
898  seq->size_y = buf->ReadByte();
899  seq->size_z = buf->ReadByte();
900  }
901 
902  ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
903  if (_cur.skip_sprites < 0) return true;
904  }
905 
906  /* Check if the number of sprites per spriteset is consistent */
907  bool is_consistent = true;
908  dts->consistent_max_offset = 0;
909  for (uint i = 0; i < num_building_sprites + 1; i++) {
910  if (max_sprite_offset[i] > 0) {
911  if (dts->consistent_max_offset == 0) {
912  dts->consistent_max_offset = max_sprite_offset[i];
913  } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
914  is_consistent = false;
915  break;
916  }
917  }
918  if (max_palette_offset[i] > 0) {
919  if (dts->consistent_max_offset == 0) {
920  dts->consistent_max_offset = max_palette_offset[i];
921  } else if (dts->consistent_max_offset != max_palette_offset[i]) {
922  is_consistent = false;
923  break;
924  }
925  }
926  }
927 
928  /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
929  assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
930 
931  if (!is_consistent || dts->registers != nullptr) {
932  dts->consistent_max_offset = 0;
933  if (dts->registers == nullptr) dts->AllocateRegisters();
934 
935  for (uint i = 0; i < num_building_sprites + 1; i++) {
936  TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
937  regs.max_sprite_offset = max_sprite_offset[i];
938  regs.max_palette_offset = max_palette_offset[i];
939  }
940  }
941 
942  return false;
943 }
944 
948 static CargoTypes TranslateRefitMask(uint32 refit_mask)
949 {
950  CargoTypes result = 0;
951  uint8 bit;
952  FOR_EACH_SET_BIT(bit, refit_mask) {
953  CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
954  if (cargo != CT_INVALID) SetBit(result, cargo);
955  }
956  return result;
957 }
958 
966 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
967 {
968  /* Special value for 'none' */
969  if (base_pointer == 0) {
970  *index = INVALID_PRICE;
971  return;
972  }
973 
974  static const uint32 start = 0x4B34;
975  static const uint32 size = 6;
976 
977  if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
978  grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
979  return;
980  }
981 
982  *index = (Price)((base_pointer - start) / size);
983 }
984 
992 };
993 
994 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
995 
1004 {
1005  switch (prop) {
1006  case 0x00: // Introduction date
1007  ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1008  break;
1009 
1010  case 0x02: // Decay speed
1011  ei->decay_speed = buf->ReadByte();
1012  break;
1013 
1014  case 0x03: // Vehicle life
1015  ei->lifelength = buf->ReadByte();
1016  break;
1017 
1018  case 0x04: // Model life
1019  ei->base_life = buf->ReadByte();
1020  break;
1021 
1022  case 0x06: // Climates available
1023  ei->climates = buf->ReadByte();
1024  break;
1025 
1026  case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1027  /* Amount of cargo loaded during a vehicle's "loading tick" */
1028  ei->load_amount = buf->ReadByte();
1029  break;
1030 
1031  default:
1032  return CIR_UNKNOWN;
1033  }
1034 
1035  return CIR_SUCCESS;
1036 }
1037 
1046 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1047 {
1049 
1050  for (int i = 0; i < numinfo; i++) {
1051  Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1052  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1053 
1054  EngineInfo *ei = &e->info;
1055  RailVehicleInfo *rvi = &e->u.rail;
1056 
1057  switch (prop) {
1058  case 0x05: { // Track type
1059  uint8 tracktype = buf->ReadByte();
1060 
1061  if (tracktype < _cur.grffile->railtype_list.size()) {
1062  _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1063  break;
1064  }
1065 
1066  switch (tracktype) {
1067  case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1068  case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1069  case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1070  default:
1071  grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1072  break;
1073  }
1074  break;
1075  }
1076 
1077  case 0x08: // AI passenger service
1078  /* Tells the AI that this engine is designed for
1079  * passenger services and shouldn't be used for freight. */
1080  rvi->ai_passenger_only = buf->ReadByte();
1081  break;
1082 
1083  case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1084  uint16 speed = buf->ReadWord();
1085  if (speed == 0xFFFF) speed = 0;
1086 
1087  rvi->max_speed = speed;
1088  break;
1089  }
1090 
1091  case PROP_TRAIN_POWER: // 0x0B Power
1092  rvi->power = buf->ReadWord();
1093 
1094  /* Set engine / wagon state based on power */
1095  if (rvi->power != 0) {
1096  if (rvi->railveh_type == RAILVEH_WAGON) {
1097  rvi->railveh_type = RAILVEH_SINGLEHEAD;
1098  }
1099  } else {
1100  rvi->railveh_type = RAILVEH_WAGON;
1101  }
1102  break;
1103 
1104  case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1105  rvi->running_cost = buf->ReadByte();
1106  break;
1107 
1108  case 0x0E: // Running cost base
1109  ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1110  break;
1111 
1112  case 0x12: { // Sprite ID
1113  uint8 spriteid = buf->ReadByte();
1114  uint8 orig_spriteid = spriteid;
1115 
1116  /* TTD sprite IDs point to a location in a 16bit array, but we use it
1117  * as an array index, so we need it to be half the original value. */
1118  if (spriteid < 0xFD) spriteid >>= 1;
1119 
1120  if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1121  rvi->image_index = spriteid;
1122  } else {
1123  grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1124  rvi->image_index = 0;
1125  }
1126  break;
1127  }
1128 
1129  case 0x13: { // Dual-headed
1130  uint8 dual = buf->ReadByte();
1131 
1132  if (dual != 0) {
1133  rvi->railveh_type = RAILVEH_MULTIHEAD;
1134  } else {
1135  rvi->railveh_type = rvi->power == 0 ?
1137  }
1138  break;
1139  }
1140 
1141  case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1142  rvi->capacity = buf->ReadByte();
1143  break;
1144 
1145  case 0x15: { // Cargo type
1146  _gted[e->index].defaultcargo_grf = _cur.grffile;
1147  uint8 ctype = buf->ReadByte();
1148 
1149  if (ctype == 0xFF) {
1150  /* 0xFF is specified as 'use first refittable' */
1151  ei->cargo_type = CT_INVALID;
1152  } else if (_cur.grffile->grf_version >= 8) {
1153  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1154  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1155  } else if (ctype < NUM_CARGO) {
1156  /* Use untranslated cargo. */
1157  ei->cargo_type = ctype;
1158  } else {
1159  ei->cargo_type = CT_INVALID;
1160  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1161  }
1162  break;
1163  }
1164 
1165  case PROP_TRAIN_WEIGHT: // 0x16 Weight
1166  SB(rvi->weight, 0, 8, buf->ReadByte());
1167  break;
1168 
1169  case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1170  rvi->cost_factor = buf->ReadByte();
1171  break;
1172 
1173  case 0x18: // AI rank
1174  grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1175  buf->ReadByte();
1176  break;
1177 
1178  case 0x19: { // Engine traction type
1179  /* What do the individual numbers mean?
1180  * 0x00 .. 0x07: Steam
1181  * 0x08 .. 0x27: Diesel
1182  * 0x28 .. 0x31: Electric
1183  * 0x32 .. 0x37: Monorail
1184  * 0x38 .. 0x41: Maglev
1185  */
1186  uint8 traction = buf->ReadByte();
1187  EngineClass engclass;
1188 
1189  if (traction <= 0x07) {
1190  engclass = EC_STEAM;
1191  } else if (traction <= 0x27) {
1192  engclass = EC_DIESEL;
1193  } else if (traction <= 0x31) {
1194  engclass = EC_ELECTRIC;
1195  } else if (traction <= 0x37) {
1196  engclass = EC_MONORAIL;
1197  } else if (traction <= 0x41) {
1198  engclass = EC_MAGLEV;
1199  } else {
1200  break;
1201  }
1202 
1203  if (_cur.grffile->railtype_list.size() == 0) {
1204  /* Use traction type to select between normal and electrified
1205  * rail only when no translation list is in place. */
1206  if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1207  if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1208  }
1209 
1210  rvi->engclass = engclass;
1211  break;
1212  }
1213 
1214  case 0x1A: // Alter purchase list sort order
1215  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1216  break;
1217 
1218  case 0x1B: // Powered wagons power bonus
1219  rvi->pow_wag_power = buf->ReadWord();
1220  break;
1221 
1222  case 0x1C: // Refit cost
1223  ei->refit_cost = buf->ReadByte();
1224  break;
1225 
1226  case 0x1D: { // Refit cargo
1227  uint32 mask = buf->ReadDWord();
1228  _gted[e->index].UpdateRefittability(mask != 0);
1229  ei->refit_mask = TranslateRefitMask(mask);
1230  _gted[e->index].defaultcargo_grf = _cur.grffile;
1231  break;
1232  }
1233 
1234  case 0x1E: // Callback
1235  ei->callback_mask = buf->ReadByte();
1236  break;
1237 
1238  case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1239  rvi->tractive_effort = buf->ReadByte();
1240  break;
1241 
1242  case 0x20: // Air drag
1243  rvi->air_drag = buf->ReadByte();
1244  break;
1245 
1246  case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1247  rvi->shorten_factor = buf->ReadByte();
1248  break;
1249 
1250  case 0x22: // Visual effect
1251  rvi->visual_effect = buf->ReadByte();
1252  /* Avoid accidentally setting visual_effect to the default value
1253  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1254  if (rvi->visual_effect == VE_DEFAULT) {
1255  assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1257  }
1258  break;
1259 
1260  case 0x23: // Powered wagons weight bonus
1261  rvi->pow_wag_weight = buf->ReadByte();
1262  break;
1263 
1264  case 0x24: { // High byte of vehicle weight
1265  byte weight = buf->ReadByte();
1266 
1267  if (weight > 4) {
1268  grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1269  } else {
1270  SB(rvi->weight, 8, 8, weight);
1271  }
1272  break;
1273  }
1274 
1275  case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1276  rvi->user_def_data = buf->ReadByte();
1277  break;
1278 
1279  case 0x26: // Retire vehicle early
1280  ei->retire_early = buf->ReadByte();
1281  break;
1282 
1283  case 0x27: // Miscellaneous flags
1284  ei->misc_flags = buf->ReadByte();
1286  _gted[e->index].prop27_set = true;
1287  break;
1288 
1289  case 0x28: // Cargo classes allowed
1290  _gted[e->index].cargo_allowed = buf->ReadWord();
1291  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1292  _gted[e->index].defaultcargo_grf = _cur.grffile;
1293  break;
1294 
1295  case 0x29: // Cargo classes disallowed
1296  _gted[e->index].cargo_disallowed = buf->ReadWord();
1297  _gted[e->index].UpdateRefittability(false);
1298  break;
1299 
1300  case 0x2A: // Long format introduction date (days since year 0)
1301  ei->base_intro = buf->ReadDWord();
1302  break;
1303 
1304  case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1305  ei->cargo_age_period = buf->ReadWord();
1306  break;
1307 
1308  case 0x2C: // CTT refit include list
1309  case 0x2D: { // CTT refit exclude list
1310  uint8 count = buf->ReadByte();
1311  _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1312  if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1313  CargoTypes &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1314  ctt = 0;
1315  while (count--) {
1316  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1317  if (ctype == CT_INVALID) continue;
1318  SetBit(ctt, ctype);
1319  }
1320  break;
1321  }
1322 
1323  default:
1324  ret = CommonVehicleChangeInfo(ei, prop, buf);
1325  break;
1326  }
1327  }
1328 
1329  return ret;
1330 }
1331 
1340 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1341 {
1343 
1344  for (int i = 0; i < numinfo; i++) {
1345  Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1346  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1347 
1348  EngineInfo *ei = &e->info;
1349  RoadVehicleInfo *rvi = &e->u.road;
1350 
1351  switch (prop) {
1352  case 0x05: // Road/tram type
1353  /* RoadTypeLabel is looked up later after the engine's road/tram
1354  * flag is set, however 0 means the value has not been set. */
1355  _gted[e->index].roadtramtype = buf->ReadByte() + 1;
1356  break;
1357 
1358  case 0x08: // Speed (1 unit is 0.5 kmh)
1359  rvi->max_speed = buf->ReadByte();
1360  break;
1361 
1362  case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1363  rvi->running_cost = buf->ReadByte();
1364  break;
1365 
1366  case 0x0A: // Running cost base
1367  ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1368  break;
1369 
1370  case 0x0E: { // Sprite ID
1371  uint8 spriteid = buf->ReadByte();
1372  uint8 orig_spriteid = spriteid;
1373 
1374  /* cars have different custom id in the GRF file */
1375  if (spriteid == 0xFF) spriteid = 0xFD;
1376 
1377  if (spriteid < 0xFD) spriteid >>= 1;
1378 
1379  if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1380  rvi->image_index = spriteid;
1381  } else {
1382  grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1383  rvi->image_index = 0;
1384  }
1385  break;
1386  }
1387 
1388  case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1389  rvi->capacity = buf->ReadByte();
1390  break;
1391 
1392  case 0x10: { // Cargo type
1393  _gted[e->index].defaultcargo_grf = _cur.grffile;
1394  uint8 ctype = buf->ReadByte();
1395 
1396  if (ctype == 0xFF) {
1397  /* 0xFF is specified as 'use first refittable' */
1398  ei->cargo_type = CT_INVALID;
1399  } else if (_cur.grffile->grf_version >= 8) {
1400  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1401  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1402  } else if (ctype < NUM_CARGO) {
1403  /* Use untranslated cargo. */
1404  ei->cargo_type = ctype;
1405  } else {
1406  ei->cargo_type = CT_INVALID;
1407  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1408  }
1409  break;
1410  }
1411 
1412  case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1413  rvi->cost_factor = buf->ReadByte();
1414  break;
1415 
1416  case 0x12: // SFX
1417  rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1418  break;
1419 
1420  case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1421  rvi->power = buf->ReadByte();
1422  break;
1423 
1424  case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1425  rvi->weight = buf->ReadByte();
1426  break;
1427 
1428  case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1429  _gted[e->index].rv_max_speed = buf->ReadByte();
1430  break;
1431 
1432  case 0x16: { // Cargoes available for refitting
1433  uint32 mask = buf->ReadDWord();
1434  _gted[e->index].UpdateRefittability(mask != 0);
1435  ei->refit_mask = TranslateRefitMask(mask);
1436  _gted[e->index].defaultcargo_grf = _cur.grffile;
1437  break;
1438  }
1439 
1440  case 0x17: // Callback mask
1441  ei->callback_mask = buf->ReadByte();
1442  break;
1443 
1444  case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1445  rvi->tractive_effort = buf->ReadByte();
1446  break;
1447 
1448  case 0x19: // Air drag
1449  rvi->air_drag = buf->ReadByte();
1450  break;
1451 
1452  case 0x1A: // Refit cost
1453  ei->refit_cost = buf->ReadByte();
1454  break;
1455 
1456  case 0x1B: // Retire vehicle early
1457  ei->retire_early = buf->ReadByte();
1458  break;
1459 
1460  case 0x1C: // Miscellaneous flags
1461  ei->misc_flags = buf->ReadByte();
1463  break;
1464 
1465  case 0x1D: // Cargo classes allowed
1466  _gted[e->index].cargo_allowed = buf->ReadWord();
1467  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1468  _gted[e->index].defaultcargo_grf = _cur.grffile;
1469  break;
1470 
1471  case 0x1E: // Cargo classes disallowed
1472  _gted[e->index].cargo_disallowed = buf->ReadWord();
1473  _gted[e->index].UpdateRefittability(false);
1474  break;
1475 
1476  case 0x1F: // Long format introduction date (days since year 0)
1477  ei->base_intro = buf->ReadDWord();
1478  break;
1479 
1480  case 0x20: // Alter purchase list sort order
1481  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1482  break;
1483 
1484  case 0x21: // Visual effect
1485  rvi->visual_effect = buf->ReadByte();
1486  /* Avoid accidentally setting visual_effect to the default value
1487  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1488  if (rvi->visual_effect == VE_DEFAULT) {
1489  assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1491  }
1492  break;
1493 
1494  case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1495  ei->cargo_age_period = buf->ReadWord();
1496  break;
1497 
1498  case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1499  rvi->shorten_factor = buf->ReadByte();
1500  break;
1501 
1502  case 0x24: // CTT refit include list
1503  case 0x25: { // CTT refit exclude list
1504  uint8 count = buf->ReadByte();
1505  _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1506  if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1507  CargoTypes &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1508  ctt = 0;
1509  while (count--) {
1510  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1511  if (ctype == CT_INVALID) continue;
1512  SetBit(ctt, ctype);
1513  }
1514  break;
1515  }
1516 
1517  default:
1518  ret = CommonVehicleChangeInfo(ei, prop, buf);
1519  break;
1520  }
1521  }
1522 
1523  return ret;
1524 }
1525 
1534 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1535 {
1537 
1538  for (int i = 0; i < numinfo; i++) {
1539  Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1540  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1541 
1542  EngineInfo *ei = &e->info;
1543  ShipVehicleInfo *svi = &e->u.ship;
1544 
1545  switch (prop) {
1546  case 0x08: { // Sprite ID
1547  uint8 spriteid = buf->ReadByte();
1548  uint8 orig_spriteid = spriteid;
1549 
1550  /* ships have different custom id in the GRF file */
1551  if (spriteid == 0xFF) spriteid = 0xFD;
1552 
1553  if (spriteid < 0xFD) spriteid >>= 1;
1554 
1555  if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1556  svi->image_index = spriteid;
1557  } else {
1558  grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1559  svi->image_index = 0;
1560  }
1561  break;
1562  }
1563 
1564  case 0x09: // Refittable
1565  svi->old_refittable = (buf->ReadByte() != 0);
1566  break;
1567 
1568  case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1569  svi->cost_factor = buf->ReadByte();
1570  break;
1571 
1572  case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1573  svi->max_speed = buf->ReadByte();
1574  break;
1575 
1576  case 0x0C: { // Cargo type
1577  _gted[e->index].defaultcargo_grf = _cur.grffile;
1578  uint8 ctype = buf->ReadByte();
1579 
1580  if (ctype == 0xFF) {
1581  /* 0xFF is specified as 'use first refittable' */
1582  ei->cargo_type = CT_INVALID;
1583  } else if (_cur.grffile->grf_version >= 8) {
1584  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1585  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1586  } else if (ctype < NUM_CARGO) {
1587  /* Use untranslated cargo. */
1588  ei->cargo_type = ctype;
1589  } else {
1590  ei->cargo_type = CT_INVALID;
1591  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1592  }
1593  break;
1594  }
1595 
1596  case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1597  svi->capacity = buf->ReadWord();
1598  break;
1599 
1600  case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1601  svi->running_cost = buf->ReadByte();
1602  break;
1603 
1604  case 0x10: // SFX
1605  svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1606  break;
1607 
1608  case 0x11: { // Cargoes available for refitting
1609  uint32 mask = buf->ReadDWord();
1610  _gted[e->index].UpdateRefittability(mask != 0);
1611  ei->refit_mask = TranslateRefitMask(mask);
1612  _gted[e->index].defaultcargo_grf = _cur.grffile;
1613  break;
1614  }
1615 
1616  case 0x12: // Callback mask
1617  ei->callback_mask = buf->ReadByte();
1618  break;
1619 
1620  case 0x13: // Refit cost
1621  ei->refit_cost = buf->ReadByte();
1622  break;
1623 
1624  case 0x14: // Ocean speed fraction
1625  svi->ocean_speed_frac = buf->ReadByte();
1626  break;
1627 
1628  case 0x15: // Canal speed fraction
1629  svi->canal_speed_frac = buf->ReadByte();
1630  break;
1631 
1632  case 0x16: // Retire vehicle early
1633  ei->retire_early = buf->ReadByte();
1634  break;
1635 
1636  case 0x17: // Miscellaneous flags
1637  ei->misc_flags = buf->ReadByte();
1639  break;
1640 
1641  case 0x18: // Cargo classes allowed
1642  _gted[e->index].cargo_allowed = buf->ReadWord();
1643  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1644  _gted[e->index].defaultcargo_grf = _cur.grffile;
1645  break;
1646 
1647  case 0x19: // Cargo classes disallowed
1648  _gted[e->index].cargo_disallowed = buf->ReadWord();
1649  _gted[e->index].UpdateRefittability(false);
1650  break;
1651 
1652  case 0x1A: // Long format introduction date (days since year 0)
1653  ei->base_intro = buf->ReadDWord();
1654  break;
1655 
1656  case 0x1B: // Alter purchase list sort order
1657  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1658  break;
1659 
1660  case 0x1C: // Visual effect
1661  svi->visual_effect = buf->ReadByte();
1662  /* Avoid accidentally setting visual_effect to the default value
1663  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1664  if (svi->visual_effect == VE_DEFAULT) {
1665  assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1667  }
1668  break;
1669 
1670  case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1671  ei->cargo_age_period = buf->ReadWord();
1672  break;
1673 
1674  case 0x1E: // CTT refit include list
1675  case 0x1F: { // CTT refit exclude list
1676  uint8 count = buf->ReadByte();
1677  _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1678  if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1679  CargoTypes &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1680  ctt = 0;
1681  while (count--) {
1682  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1683  if (ctype == CT_INVALID) continue;
1684  SetBit(ctt, ctype);
1685  }
1686  break;
1687  }
1688 
1689  default:
1690  ret = CommonVehicleChangeInfo(ei, prop, buf);
1691  break;
1692  }
1693  }
1694 
1695  return ret;
1696 }
1697 
1706 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1707 {
1709 
1710  for (int i = 0; i < numinfo; i++) {
1711  Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1712  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1713 
1714  EngineInfo *ei = &e->info;
1715  AircraftVehicleInfo *avi = &e->u.air;
1716 
1717  switch (prop) {
1718  case 0x08: { // Sprite ID
1719  uint8 spriteid = buf->ReadByte();
1720  uint8 orig_spriteid = spriteid;
1721 
1722  /* aircraft have different custom id in the GRF file */
1723  if (spriteid == 0xFF) spriteid = 0xFD;
1724 
1725  if (spriteid < 0xFD) spriteid >>= 1;
1726 
1727  if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1728  avi->image_index = spriteid;
1729  } else {
1730  grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1731  avi->image_index = 0;
1732  }
1733  break;
1734  }
1735 
1736  case 0x09: // Helicopter
1737  if (buf->ReadByte() == 0) {
1738  avi->subtype = AIR_HELI;
1739  } else {
1740  SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1741  }
1742  break;
1743 
1744  case 0x0A: // Large
1745  SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1746  break;
1747 
1748  case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1749  avi->cost_factor = buf->ReadByte();
1750  break;
1751 
1752  case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1753  avi->max_speed = (buf->ReadByte() * 128) / 10;
1754  break;
1755 
1756  case 0x0D: // Acceleration
1757  avi->acceleration = buf->ReadByte();
1758  break;
1759 
1760  case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1761  avi->running_cost = buf->ReadByte();
1762  break;
1763 
1764  case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1765  avi->passenger_capacity = buf->ReadWord();
1766  break;
1767 
1768  case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1769  avi->mail_capacity = buf->ReadByte();
1770  break;
1771 
1772  case 0x12: // SFX
1773  avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1774  break;
1775 
1776  case 0x13: { // Cargoes available for refitting
1777  uint32 mask = buf->ReadDWord();
1778  _gted[e->index].UpdateRefittability(mask != 0);
1779  ei->refit_mask = TranslateRefitMask(mask);
1780  _gted[e->index].defaultcargo_grf = _cur.grffile;
1781  break;
1782  }
1783 
1784  case 0x14: // Callback mask
1785  ei->callback_mask = buf->ReadByte();
1786  break;
1787 
1788  case 0x15: // Refit cost
1789  ei->refit_cost = buf->ReadByte();
1790  break;
1791 
1792  case 0x16: // Retire vehicle early
1793  ei->retire_early = buf->ReadByte();
1794  break;
1795 
1796  case 0x17: // Miscellaneous flags
1797  ei->misc_flags = buf->ReadByte();
1799  break;
1800 
1801  case 0x18: // Cargo classes allowed
1802  _gted[e->index].cargo_allowed = buf->ReadWord();
1803  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1804  _gted[e->index].defaultcargo_grf = _cur.grffile;
1805  break;
1806 
1807  case 0x19: // Cargo classes disallowed
1808  _gted[e->index].cargo_disallowed = buf->ReadWord();
1809  _gted[e->index].UpdateRefittability(false);
1810  break;
1811 
1812  case 0x1A: // Long format introduction date (days since year 0)
1813  ei->base_intro = buf->ReadDWord();
1814  break;
1815 
1816  case 0x1B: // Alter purchase list sort order
1817  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1818  break;
1819 
1820  case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1821  ei->cargo_age_period = buf->ReadWord();
1822  break;
1823 
1824  case 0x1D: // CTT refit include list
1825  case 0x1E: { // CTT refit exclude list
1826  uint8 count = buf->ReadByte();
1827  _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1828  if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1829  CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1830  ctt = 0;
1831  while (count--) {
1832  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1833  if (ctype == CT_INVALID) continue;
1834  SetBit(ctt, ctype);
1835  }
1836  break;
1837  }
1838 
1839  case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1840  avi->max_range = buf->ReadWord();
1841  break;
1842 
1843  default:
1844  ret = CommonVehicleChangeInfo(ei, prop, buf);
1845  break;
1846  }
1847  }
1848 
1849  return ret;
1850 }
1851 
1860 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1861 {
1863 
1864  if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1865  grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1866  return CIR_INVALID_ID;
1867  }
1868 
1869  /* Allocate station specs if necessary */
1870  if (_cur.grffile->stations == nullptr) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1871 
1872  for (int i = 0; i < numinfo; i++) {
1873  StationSpec *statspec = _cur.grffile->stations[stid + i];
1874 
1875  /* Check that the station we are modifying is defined. */
1876  if (statspec == nullptr && prop != 0x08) {
1877  grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1878  return CIR_INVALID_ID;
1879  }
1880 
1881  switch (prop) {
1882  case 0x08: { // Class ID
1883  StationSpec **spec = &_cur.grffile->stations[stid + i];
1884 
1885  /* Property 0x08 is special; it is where the station is allocated */
1886  if (*spec == nullptr) *spec = CallocT<StationSpec>(1);
1887 
1888  /* Swap classid because we read it in BE meaning WAYP or DFLT */
1889  uint32 classid = buf->ReadDWord();
1890  (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1891  break;
1892  }
1893 
1894  case 0x09: // Define sprite layout
1895  statspec->tiles = buf->ReadExtendedByte();
1896  delete[] statspec->renderdata; // delete earlier loaded stuff
1897  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1898 
1899  for (uint t = 0; t < statspec->tiles; t++) {
1900  NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1901  dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1902 
1903  if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1904  buf->Skip(4);
1905  extern const DrawTileSprites _station_display_datas_rail[8];
1906  dts->Clone(&_station_display_datas_rail[t % 8]);
1907  continue;
1908  }
1909 
1910  ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1911  /* On error, bail out immediately. Temporary GRF data was already freed */
1912  if (_cur.skip_sprites < 0) return CIR_DISABLED;
1913 
1914  static std::vector<DrawTileSeqStruct> tmp_layout;
1915  tmp_layout.clear();
1916  for (;;) {
1917  /* no relative bounding box support */
1918  DrawTileSeqStruct &dtss = tmp_layout.emplace_back();
1919  MemSetT(&dtss, 0);
1920 
1921  dtss.delta_x = buf->ReadByte();
1922  if (dtss.IsTerminator()) break;
1923  dtss.delta_y = buf->ReadByte();
1924  dtss.delta_z = buf->ReadByte();
1925  dtss.size_x = buf->ReadByte();
1926  dtss.size_y = buf->ReadByte();
1927  dtss.size_z = buf->ReadByte();
1928 
1929  ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss.image);
1930  /* On error, bail out immediately. Temporary GRF data was already freed */
1931  if (_cur.skip_sprites < 0) return CIR_DISABLED;
1932  }
1933  dts->Clone(tmp_layout.data());
1934  }
1935  break;
1936 
1937  case 0x0A: { // Copy sprite layout
1938  byte srcid = buf->ReadByte();
1939  const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1940 
1941  if (srcstatspec == nullptr) {
1942  grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1943  continue;
1944  }
1945 
1946  delete[] statspec->renderdata; // delete earlier loaded stuff
1947 
1948  statspec->tiles = srcstatspec->tiles;
1949  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1950  for (uint t = 0; t < statspec->tiles; t++) {
1951  statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1952  }
1953  break;
1954  }
1955 
1956  case 0x0B: // Callback mask
1957  statspec->callback_mask = buf->ReadByte();
1958  break;
1959 
1960  case 0x0C: // Disallowed number of platforms
1961  statspec->disallowed_platforms = buf->ReadByte();
1962  break;
1963 
1964  case 0x0D: // Disallowed platform lengths
1965  statspec->disallowed_lengths = buf->ReadByte();
1966  break;
1967 
1968  case 0x0E: // Define custom layout
1969  statspec->copied_layouts = false;
1970 
1971  while (buf->HasData()) {
1972  byte length = buf->ReadByte();
1973  byte number = buf->ReadByte();
1974  StationLayout layout;
1975  uint l, p;
1976 
1977  if (length == 0 || number == 0) break;
1978 
1979  if (length > statspec->lengths) {
1980  byte diff_length = length - statspec->lengths;
1981  statspec->platforms = ReallocT(statspec->platforms, length);
1982  memset(statspec->platforms + statspec->lengths, 0, diff_length);
1983 
1984  statspec->layouts = ReallocT(statspec->layouts, length);
1985  memset(statspec->layouts + statspec->lengths, 0, diff_length * sizeof(*statspec->layouts));
1986 
1987  statspec->lengths = length;
1988  }
1989  l = length - 1; // index is zero-based
1990 
1991  if (number > statspec->platforms[l]) {
1992  statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1993  /* We expect nullptr being 0 here, but C99 guarantees that. */
1994  memset(statspec->layouts[l] + statspec->platforms[l], 0,
1995  (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1996 
1997  statspec->platforms[l] = number;
1998  }
1999 
2000  p = 0;
2001  layout = MallocT<byte>(length * number);
2002  try {
2003  for (l = 0; l < length; l++) {
2004  for (p = 0; p < number; p++) {
2005  layout[l * number + p] = buf->ReadByte();
2006  }
2007  }
2008  } catch (...) {
2009  free(layout);
2010  throw;
2011  }
2012 
2013  l--;
2014  p--;
2015  free(statspec->layouts[l][p]);
2016  statspec->layouts[l][p] = layout;
2017  }
2018  break;
2019 
2020  case 0x0F: { // Copy custom layout
2021  byte srcid = buf->ReadByte();
2022  const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2023 
2024  if (srcstatspec == nullptr) {
2025  grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2026  continue;
2027  }
2028 
2029  statspec->lengths = srcstatspec->lengths;
2030  statspec->platforms = srcstatspec->platforms;
2031  statspec->layouts = srcstatspec->layouts;
2032  statspec->copied_layouts = true;
2033  break;
2034  }
2035 
2036  case 0x10: // Little/lots cargo threshold
2037  statspec->cargo_threshold = buf->ReadWord();
2038  break;
2039 
2040  case 0x11: // Pylon placement
2041  statspec->pylons = buf->ReadByte();
2042  break;
2043 
2044  case 0x12: // Cargo types for random triggers
2045  if (_cur.grffile->grf_version >= 7) {
2046  statspec->cargo_triggers = TranslateRefitMask(buf->ReadDWord());
2047  } else {
2048  statspec->cargo_triggers = (CargoTypes)buf->ReadDWord();
2049  }
2050  break;
2051 
2052  case 0x13: // General flags
2053  statspec->flags = buf->ReadByte();
2054  break;
2055 
2056  case 0x14: // Overhead wire placement
2057  statspec->wires = buf->ReadByte();
2058  break;
2059 
2060  case 0x15: // Blocked tiles
2061  statspec->blocked = buf->ReadByte();
2062  break;
2063 
2064  case 0x16: // Animation info
2065  statspec->animation.frames = buf->ReadByte();
2066  statspec->animation.status = buf->ReadByte();
2067  break;
2068 
2069  case 0x17: // Animation speed
2070  statspec->animation.speed = buf->ReadByte();
2071  break;
2072 
2073  case 0x18: // Animation triggers
2074  statspec->animation.triggers = buf->ReadWord();
2075  break;
2076 
2077  case 0x1A: // Advanced sprite layout
2078  statspec->tiles = buf->ReadExtendedByte();
2079  delete[] statspec->renderdata; // delete earlier loaded stuff
2080  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2081 
2082  for (uint t = 0; t < statspec->tiles; t++) {
2083  NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2084  uint num_building_sprites = buf->ReadByte();
2085  /* On error, bail out immediately. Temporary GRF data was already freed */
2086  if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2087  }
2088  break;
2089 
2090  default:
2091  ret = CIR_UNKNOWN;
2092  break;
2093  }
2094  }
2095 
2096  return ret;
2097 }
2098 
2107 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2108 {
2110 
2111  if (id + numinfo > CF_END) {
2112  grfmsg(1, "CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring", id + numinfo, CF_END);
2113  return CIR_INVALID_ID;
2114  }
2115 
2116  for (int i = 0; i < numinfo; i++) {
2117  CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2118 
2119  switch (prop) {
2120  case 0x08:
2121  cp->callback_mask = buf->ReadByte();
2122  break;
2123 
2124  case 0x09:
2125  cp->flags = buf->ReadByte();
2126  break;
2127 
2128  default:
2129  ret = CIR_UNKNOWN;
2130  break;
2131  }
2132  }
2133 
2134  return ret;
2135 }
2136 
2145 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2146 {
2148 
2149  if (brid + numinfo > MAX_BRIDGES) {
2150  grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2151  return CIR_INVALID_ID;
2152  }
2153 
2154  for (int i = 0; i < numinfo; i++) {
2155  BridgeSpec *bridge = &_bridge[brid + i];
2156 
2157  switch (prop) {
2158  case 0x08: { // Year of availability
2159  /* We treat '0' as always available */
2160  byte year = buf->ReadByte();
2161  bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2162  break;
2163  }
2164 
2165  case 0x09: // Minimum length
2166  bridge->min_length = buf->ReadByte();
2167  break;
2168 
2169  case 0x0A: // Maximum length
2170  bridge->max_length = buf->ReadByte();
2171  if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2172  break;
2173 
2174  case 0x0B: // Cost factor
2175  bridge->price = buf->ReadByte();
2176  break;
2177 
2178  case 0x0C: // Maximum speed
2179  bridge->speed = buf->ReadWord();
2180  break;
2181 
2182  case 0x0D: { // Bridge sprite tables
2183  byte tableid = buf->ReadByte();
2184  byte numtables = buf->ReadByte();
2185 
2186  if (bridge->sprite_table == nullptr) {
2187  /* Allocate memory for sprite table pointers and zero out */
2188  bridge->sprite_table = CallocT<PalSpriteID*>(7);
2189  }
2190 
2191  for (; numtables-- != 0; tableid++) {
2192  if (tableid >= 7) { // skip invalid data
2193  grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2194  for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2195  continue;
2196  }
2197 
2198  if (bridge->sprite_table[tableid] == nullptr) {
2199  bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2200  }
2201 
2202  for (byte sprite = 0; sprite < 32; sprite++) {
2203  SpriteID image = buf->ReadWord();
2204  PaletteID pal = buf->ReadWord();
2205 
2206  bridge->sprite_table[tableid][sprite].sprite = image;
2207  bridge->sprite_table[tableid][sprite].pal = pal;
2208 
2209  MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2210  }
2211  }
2212  break;
2213  }
2214 
2215  case 0x0E: // Flags; bit 0 - disable far pillars
2216  bridge->flags = buf->ReadByte();
2217  break;
2218 
2219  case 0x0F: // Long format year of availability (year since year 0)
2220  bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2221  break;
2222 
2223  case 0x10: { // purchase string
2224  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2225  if (newone != STR_UNDEFINED) bridge->material = newone;
2226  break;
2227  }
2228 
2229  case 0x11: // description of bridge with rails or roads
2230  case 0x12: {
2231  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2232  if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2233  break;
2234  }
2235 
2236  case 0x13: // 16 bits cost multiplier
2237  bridge->price = buf->ReadWord();
2238  break;
2239 
2240  default:
2241  ret = CIR_UNKNOWN;
2242  break;
2243  }
2244  }
2245 
2246  return ret;
2247 }
2248 
2256 {
2258 
2259  switch (prop) {
2260  case 0x09:
2261  case 0x0B:
2262  case 0x0C:
2263  case 0x0D:
2264  case 0x0E:
2265  case 0x0F:
2266  case 0x11:
2267  case 0x14:
2268  case 0x15:
2269  case 0x16:
2270  case 0x18:
2271  case 0x19:
2272  case 0x1A:
2273  case 0x1B:
2274  case 0x1C:
2275  case 0x1D:
2276  case 0x1F:
2277  buf->ReadByte();
2278  break;
2279 
2280  case 0x0A:
2281  case 0x10:
2282  case 0x12:
2283  case 0x13:
2284  case 0x21:
2285  case 0x22:
2286  buf->ReadWord();
2287  break;
2288 
2289  case 0x1E:
2290  buf->ReadDWord();
2291  break;
2292 
2293  case 0x17:
2294  for (uint j = 0; j < 4; j++) buf->ReadByte();
2295  break;
2296 
2297  case 0x20: {
2298  byte count = buf->ReadByte();
2299  for (byte j = 0; j < count; j++) buf->ReadByte();
2300  break;
2301  }
2302 
2303  case 0x23:
2304  buf->Skip(buf->ReadByte() * 2);
2305  break;
2306 
2307  default:
2308  ret = CIR_UNKNOWN;
2309  break;
2310  }
2311  return ret;
2312 }
2313 
2322 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2323 {
2325 
2326  if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2327  grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2328  return CIR_INVALID_ID;
2329  }
2330 
2331  /* Allocate house specs if they haven't been allocated already. */
2332  if (_cur.grffile->housespec == nullptr) {
2333  _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2334  }
2335 
2336  for (int i = 0; i < numinfo; i++) {
2337  HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2338 
2339  if (prop != 0x08 && housespec == nullptr) {
2340  /* If the house property 08 is not yet set, ignore this property */
2341  ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2342  if (cir > ret) ret = cir;
2343  continue;
2344  }
2345 
2346  switch (prop) {
2347  case 0x08: { // Substitute building type, and definition of a new house
2348  HouseSpec **house = &_cur.grffile->housespec[hid + i];
2349  byte subs_id = buf->ReadByte();
2350 
2351  if (subs_id == 0xFF) {
2352  /* Instead of defining a new house, a substitute house id
2353  * of 0xFF disables the old house with the current id. */
2354  HouseSpec::Get(hid + i)->enabled = false;
2355  continue;
2356  } else if (subs_id >= NEW_HOUSE_OFFSET) {
2357  /* The substitute id must be one of the original houses. */
2358  grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2359  continue;
2360  }
2361 
2362  /* Allocate space for this house. */
2363  if (*house == nullptr) *house = CallocT<HouseSpec>(1);
2364 
2365  housespec = *house;
2366 
2367  MemCpyT(housespec, HouseSpec::Get(subs_id));
2368 
2369  housespec->enabled = true;
2370  housespec->grf_prop.local_id = hid + i;
2371  housespec->grf_prop.subst_id = subs_id;
2372  housespec->grf_prop.grffile = _cur.grffile;
2373  housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2374  housespec->random_colour[1] = 0x08; // for all new houses
2375  housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2376  housespec->random_colour[3] = 0x06;
2377 
2378  /* Make sure that the third cargo type is valid in this
2379  * climate. This can cause problems when copying the properties
2380  * of a house that accepts food, where the new house is valid
2381  * in the temperate climate. */
2382  if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2383  housespec->cargo_acceptance[2] = 0;
2384  }
2385  break;
2386  }
2387 
2388  case 0x09: // Building flags
2389  housespec->building_flags = (BuildingFlags)buf->ReadByte();
2390  break;
2391 
2392  case 0x0A: { // Availability years
2393  uint16 years = buf->ReadWord();
2394  housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2395  housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2396  break;
2397  }
2398 
2399  case 0x0B: // Population
2400  housespec->population = buf->ReadByte();
2401  break;
2402 
2403  case 0x0C: // Mail generation multiplier
2404  housespec->mail_generation = buf->ReadByte();
2405  break;
2406 
2407  case 0x0D: // Passenger acceptance
2408  case 0x0E: // Mail acceptance
2409  housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2410  break;
2411 
2412  case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2413  int8 goods = buf->ReadByte();
2414 
2415  /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2416  * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2417  CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2418  ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2419 
2420  /* Make sure the cargo type is valid in this climate. */
2421  if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2422 
2423  housespec->accepts_cargo[2] = cid;
2424  housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2425  break;
2426  }
2427 
2428  case 0x10: // Local authority rating decrease on removal
2429  housespec->remove_rating_decrease = buf->ReadWord();
2430  break;
2431 
2432  case 0x11: // Removal cost multiplier
2433  housespec->removal_cost = buf->ReadByte();
2434  break;
2435 
2436  case 0x12: // Building name ID
2437  AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2438  break;
2439 
2440  case 0x13: // Building availability mask
2441  housespec->building_availability = (HouseZones)buf->ReadWord();
2442  break;
2443 
2444  case 0x14: // House callback mask
2445  housespec->callback_mask |= buf->ReadByte();
2446  break;
2447 
2448  case 0x15: { // House override byte
2449  byte override = buf->ReadByte();
2450 
2451  /* The house being overridden must be an original house. */
2452  if (override >= NEW_HOUSE_OFFSET) {
2453  grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2454  continue;
2455  }
2456 
2457  _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2458  break;
2459  }
2460 
2461  case 0x16: // Periodic refresh multiplier
2462  housespec->processing_time = std::min<byte>(buf->ReadByte(), 63u);
2463  break;
2464 
2465  case 0x17: // Four random colours to use
2466  for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2467  break;
2468 
2469  case 0x18: // Relative probability of appearing
2470  housespec->probability = buf->ReadByte();
2471  break;
2472 
2473  case 0x19: // Extra flags
2474  housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2475  break;
2476 
2477  case 0x1A: // Animation frames
2478  housespec->animation.frames = buf->ReadByte();
2479  housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2480  SB(housespec->animation.frames, 7, 1, 0);
2481  break;
2482 
2483  case 0x1B: // Animation speed
2484  housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2485  break;
2486 
2487  case 0x1C: // Class of the building type
2488  housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2489  break;
2490 
2491  case 0x1D: // Callback mask part 2
2492  housespec->callback_mask |= (buf->ReadByte() << 8);
2493  break;
2494 
2495  case 0x1E: { // Accepted cargo types
2496  uint32 cargotypes = buf->ReadDWord();
2497 
2498  /* Check if the cargo types should not be changed */
2499  if (cargotypes == 0xFFFFFFFF) break;
2500 
2501  for (uint j = 0; j < 3; j++) {
2502  /* Get the cargo number from the 'list' */
2503  uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2504  CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2505 
2506  if (cargo == CT_INVALID) {
2507  /* Disable acceptance of invalid cargo type */
2508  housespec->cargo_acceptance[j] = 0;
2509  } else {
2510  housespec->accepts_cargo[j] = cargo;
2511  }
2512  }
2513  break;
2514  }
2515 
2516  case 0x1F: // Minimum life span
2517  housespec->minimum_life = buf->ReadByte();
2518  break;
2519 
2520  case 0x20: { // Cargo acceptance watch list
2521  byte count = buf->ReadByte();
2522  for (byte j = 0; j < count; j++) {
2523  CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2524  if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2525  }
2526  break;
2527  }
2528 
2529  case 0x21: // long introduction year
2530  housespec->min_year = buf->ReadWord();
2531  break;
2532 
2533  case 0x22: // long maximum year
2534  housespec->max_year = buf->ReadWord();
2535  break;
2536 
2537  case 0x23: { // variable length cargo types accepted
2538  uint count = buf->ReadByte();
2539  if (count > lengthof(housespec->accepts_cargo)) {
2540  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
2541  error->param_value[1] = prop;
2542  return CIR_DISABLED;
2543  }
2544  /* Always write the full accepts_cargo array, and check each index for being inside the
2545  * provided data. This ensures all values are properly initialized, and also avoids
2546  * any risks of array overrun. */
2547  for (uint i = 0; i < lengthof(housespec->accepts_cargo); i++) {
2548  if (i < count) {
2549  housespec->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2550  housespec->cargo_acceptance[i] = buf->ReadByte();
2551  } else {
2552  housespec->accepts_cargo[i] = CT_INVALID;
2553  housespec->cargo_acceptance[i] = 0;
2554  }
2555  }
2556  break;
2557  }
2558 
2559  default:
2560  ret = CIR_UNKNOWN;
2561  break;
2562  }
2563  }
2564 
2565  return ret;
2566 }
2567 
2574 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2575 {
2576  /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2577  const GRFFile *grffile = GetFileByGRFID(grfid);
2578  return (grffile != nullptr && grffile->language_map != nullptr && language_id < MAX_LANG) ? &grffile->language_map[language_id] : nullptr;
2579 }
2580 
2590 template <typename T>
2591 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2592 {
2593  if (gvid != 0) {
2594  grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2595  return CIR_INVALID_ID;
2596  }
2597 
2598  translation_table.clear();
2599  for (int i = 0; i < numinfo; i++) {
2600  uint32 item = buf->ReadDWord();
2601  translation_table.push_back(BSWAP32(item));
2602  }
2603 
2604  return CIR_SUCCESS;
2605 }
2606 
2615 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2616 {
2617  /* Properties which are handled as a whole */
2618  switch (prop) {
2619  case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2620  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2621 
2622  case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2623  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2624 
2625  case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2626  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type");
2627 
2628  case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2629  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type");
2630 
2631  default:
2632  break;
2633  }
2634 
2635  /* Properties which are handled per item */
2637  for (int i = 0; i < numinfo; i++) {
2638  switch (prop) {
2639  case 0x08: { // Cost base factor
2640  int factor = buf->ReadByte();
2641  uint price = gvid + i;
2642 
2643  if (price < PR_END) {
2644  _cur.grffile->price_base_multipliers[price] = std::min<int>(factor - 8, MAX_PRICE_MODIFIER);
2645  } else {
2646  grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2647  }
2648  break;
2649  }
2650 
2651  case 0x0A: { // Currency display names
2652  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2653  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2654 
2655  if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2656  _currency_specs[curidx].name = newone;
2657  }
2658  break;
2659  }
2660 
2661  case 0x0B: { // Currency multipliers
2662  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2663  uint32 rate = buf->ReadDWord();
2664 
2665  if (curidx < CURRENCY_END) {
2666  /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2667  * which OTTD does not. For this reason, divide grf value by 1000,
2668  * to be compatible */
2669  _currency_specs[curidx].rate = rate / 1000;
2670  } else {
2671  grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2672  }
2673  break;
2674  }
2675 
2676  case 0x0C: { // Currency options
2677  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2678  uint16 options = buf->ReadWord();
2679 
2680  if (curidx < CURRENCY_END) {
2681  _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2682  _currency_specs[curidx].separator[1] = '\0';
2683  /* By specifying only one bit, we prevent errors,
2684  * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2685  _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2686  } else {
2687  grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2688  }
2689  break;
2690  }
2691 
2692  case 0x0D: { // Currency prefix symbol
2693  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2694  uint32 tempfix = buf->ReadDWord();
2695 
2696  if (curidx < CURRENCY_END) {
2697  memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2698  _currency_specs[curidx].prefix[4] = 0;
2699  } else {
2700  grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2701  }
2702  break;
2703  }
2704 
2705  case 0x0E: { // Currency suffix symbol
2706  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2707  uint32 tempfix = buf->ReadDWord();
2708 
2709  if (curidx < CURRENCY_END) {
2710  memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2711  _currency_specs[curidx].suffix[4] = 0;
2712  } else {
2713  grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2714  }
2715  break;
2716  }
2717 
2718  case 0x0F: { // Euro introduction dates
2719  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2720  Year year_euro = buf->ReadWord();
2721 
2722  if (curidx < CURRENCY_END) {
2723  _currency_specs[curidx].to_euro = year_euro;
2724  } else {
2725  grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2726  }
2727  break;
2728  }
2729 
2730  case 0x10: // Snow line height table
2731  if (numinfo > 1 || IsSnowLineSet()) {
2732  grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2733  } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2734  grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2735  } else {
2736  byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2737 
2738  for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2739  for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2740  table[i][j] = buf->ReadByte();
2741  if (_cur.grffile->grf_version >= 8) {
2742  if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2743  } else {
2744  if (table[i][j] >= 128) {
2745  /* no snow */
2746  table[i][j] = 0xFF;
2747  } else {
2748  table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2749  }
2750  }
2751  }
2752  }
2753  SetSnowLine(table);
2754  }
2755  break;
2756 
2757  case 0x11: // GRF match for engine allocation
2758  /* This is loaded during the reservation stage, so just skip it here. */
2759  /* Each entry is 8 bytes. */
2760  buf->Skip(8);
2761  break;
2762 
2763  case 0x13: // Gender translation table
2764  case 0x14: // Case translation table
2765  case 0x15: { // Plural form translation
2766  uint curidx = gvid + i; // The current index, i.e. language.
2767  const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
2768  if (lang == nullptr) {
2769  grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2770  /* Skip over the data. */
2771  if (prop == 0x15) {
2772  buf->ReadByte();
2773  } else {
2774  while (buf->ReadByte() != 0) {
2775  buf->ReadString();
2776  }
2777  }
2778  break;
2779  }
2780 
2781  if (_cur.grffile->language_map == nullptr) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2782 
2783  if (prop == 0x15) {
2784  uint plural_form = buf->ReadByte();
2785  if (plural_form >= LANGUAGE_MAX_PLURAL) {
2786  grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2787  } else {
2788  _cur.grffile->language_map[curidx].plural_form = plural_form;
2789  }
2790  break;
2791  }
2792 
2793  byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2794  while (newgrf_id != 0) {
2795  const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2796 
2797  /* We'll just ignore the UTF8 identifier character. This is (fairly)
2798  * safe as OpenTTD's strings gender/cases are usually in ASCII which
2799  * is just a subset of UTF8, or they need the bigger UTF8 characters
2800  * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2801  WChar c;
2802  size_t len = Utf8Decode(&c, name);
2803  if (c == NFO_UTF8_IDENTIFIER) name += len;
2804 
2806  map.newgrf_id = newgrf_id;
2807  if (prop == 0x13) {
2808  map.openttd_id = lang->GetGenderIndex(name);
2809  if (map.openttd_id >= MAX_NUM_GENDERS) {
2810  grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2811  } else {
2812  _cur.grffile->language_map[curidx].gender_map.push_back(map);
2813  }
2814  } else {
2815  map.openttd_id = lang->GetCaseIndex(name);
2816  if (map.openttd_id >= MAX_NUM_CASES) {
2817  grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2818  } else {
2819  _cur.grffile->language_map[curidx].case_map.push_back(map);
2820  }
2821  }
2822  newgrf_id = buf->ReadByte();
2823  }
2824  break;
2825  }
2826 
2827  default:
2828  ret = CIR_UNKNOWN;
2829  break;
2830  }
2831  }
2832 
2833  return ret;
2834 }
2835 
2836 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2837 {
2838  /* Properties which are handled as a whole */
2839  switch (prop) {
2840  case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2841  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2842 
2843  case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2844  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2845 
2846  case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
2847  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type");
2848 
2849  case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
2850  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type");
2851 
2852  default:
2853  break;
2854  }
2855 
2856  /* Properties which are handled per item */
2858  for (int i = 0; i < numinfo; i++) {
2859  switch (prop) {
2860  case 0x08: // Cost base factor
2861  case 0x15: // Plural form translation
2862  buf->ReadByte();
2863  break;
2864 
2865  case 0x0A: // Currency display names
2866  case 0x0C: // Currency options
2867  case 0x0F: // Euro introduction dates
2868  buf->ReadWord();
2869  break;
2870 
2871  case 0x0B: // Currency multipliers
2872  case 0x0D: // Currency prefix symbol
2873  case 0x0E: // Currency suffix symbol
2874  buf->ReadDWord();
2875  break;
2876 
2877  case 0x10: // Snow line height table
2878  buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2879  break;
2880 
2881  case 0x11: { // GRF match for engine allocation
2882  uint32 s = buf->ReadDWord();
2883  uint32 t = buf->ReadDWord();
2884  SetNewGRFOverride(s, t);
2885  break;
2886  }
2887 
2888  case 0x13: // Gender translation table
2889  case 0x14: // Case translation table
2890  while (buf->ReadByte() != 0) {
2891  buf->ReadString();
2892  }
2893  break;
2894 
2895  default:
2896  ret = CIR_UNKNOWN;
2897  break;
2898  }
2899  }
2900 
2901  return ret;
2902 }
2903 
2904 
2913 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2914 {
2916 
2917  if (cid + numinfo > NUM_CARGO) {
2918  grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2919  return CIR_INVALID_ID;
2920  }
2921 
2922  for (int i = 0; i < numinfo; i++) {
2923  CargoSpec *cs = CargoSpec::Get(cid + i);
2924 
2925  switch (prop) {
2926  case 0x08: // Bit number of cargo
2927  cs->bitnum = buf->ReadByte();
2928  if (cs->IsValid()) {
2929  cs->grffile = _cur.grffile;
2930  SetBit(_cargo_mask, cid + i);
2931  } else {
2932  ClrBit(_cargo_mask, cid + i);
2933  }
2934  break;
2935 
2936  case 0x09: // String ID for cargo type name
2937  AddStringForMapping(buf->ReadWord(), &cs->name);
2938  break;
2939 
2940  case 0x0A: // String for 1 unit of cargo
2941  AddStringForMapping(buf->ReadWord(), &cs->name_single);
2942  break;
2943 
2944  case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2945  case 0x1B: // String for cargo units
2946  /* String for units of cargo. This is different in OpenTTD
2947  * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2948  * Property 1B is used to set OpenTTD's behaviour. */
2949  AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2950  break;
2951 
2952  case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2953  case 0x1C: // String for any amount of cargo
2954  /* Strings for an amount of cargo. This is different in OpenTTD
2955  * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2956  * Property 1C is used to set OpenTTD's behaviour. */
2957  AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2958  break;
2959 
2960  case 0x0D: // String for two letter cargo abbreviation
2961  AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2962  break;
2963 
2964  case 0x0E: // Sprite ID for cargo icon
2965  cs->sprite = buf->ReadWord();
2966  break;
2967 
2968  case 0x0F: // Weight of one unit of cargo
2969  cs->weight = buf->ReadByte();
2970  break;
2971 
2972  case 0x10: // Used for payment calculation
2973  cs->transit_days[0] = buf->ReadByte();
2974  break;
2975 
2976  case 0x11: // Used for payment calculation
2977  cs->transit_days[1] = buf->ReadByte();
2978  break;
2979 
2980  case 0x12: // Base cargo price
2981  cs->initial_payment = buf->ReadDWord();
2982  break;
2983 
2984  case 0x13: // Colour for station rating bars
2985  cs->rating_colour = buf->ReadByte();
2986  break;
2987 
2988  case 0x14: // Colour for cargo graph
2989  cs->legend_colour = buf->ReadByte();
2990  break;
2991 
2992  case 0x15: // Freight status
2993  cs->is_freight = (buf->ReadByte() != 0);
2994  break;
2995 
2996  case 0x16: // Cargo classes
2997  cs->classes = buf->ReadWord();
2998  break;
2999 
3000  case 0x17: // Cargo label
3001  cs->label = buf->ReadDWord();
3002  cs->label = BSWAP32(cs->label);
3003  break;
3004 
3005  case 0x18: { // Town growth substitute type
3006  uint8 substitute_type = buf->ReadByte();
3007 
3008  switch (substitute_type) {
3009  case 0x00: cs->town_effect = TE_PASSENGERS; break;
3010  case 0x02: cs->town_effect = TE_MAIL; break;
3011  case 0x05: cs->town_effect = TE_GOODS; break;
3012  case 0x09: cs->town_effect = TE_WATER; break;
3013  case 0x0B: cs->town_effect = TE_FOOD; break;
3014  default:
3015  grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3016  FALLTHROUGH;
3017  case 0xFF: cs->town_effect = TE_NONE; break;
3018  }
3019  break;
3020  }
3021 
3022  case 0x19: // Town growth coefficient
3023  cs->multipliertowngrowth = buf->ReadWord();
3024  break;
3025 
3026  case 0x1A: // Bitmask of callbacks to use
3027  cs->callback_mask = buf->ReadByte();
3028  break;
3029 
3030  case 0x1D: // Vehicle capacity muliplier
3031  cs->multiplier = std::max<uint16>(1u, buf->ReadWord());
3032  break;
3033 
3034  default:
3035  ret = CIR_UNKNOWN;
3036  break;
3037  }
3038  }
3039 
3040  return ret;
3041 }
3042 
3043 
3052 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3053 {
3055 
3056  if (_cur.grffile->sound_offset == 0) {
3057  grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3058  return CIR_INVALID_ID;
3059  }
3060 
3061  if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3062  grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3063  return CIR_INVALID_ID;
3064  }
3065 
3066  for (int i = 0; i < numinfo; i++) {
3067  SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3068 
3069  switch (prop) {
3070  case 0x08: // Relative volume
3071  sound->volume = buf->ReadByte();
3072  break;
3073 
3074  case 0x09: // Priority
3075  sound->priority = buf->ReadByte();
3076  break;
3077 
3078  case 0x0A: { // Override old sound
3079  SoundID orig_sound = buf->ReadByte();
3080 
3081  if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3082  grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3083  } else {
3084  SoundEntry *old_sound = GetSound(orig_sound);
3085 
3086  /* Literally copy the data of the new sound over the original */
3087  *old_sound = *sound;
3088  }
3089  break;
3090  }
3091 
3092  default:
3093  ret = CIR_UNKNOWN;
3094  break;
3095  }
3096  }
3097 
3098  return ret;
3099 }
3100 
3108 {
3110 
3111  switch (prop) {
3112  case 0x09:
3113  case 0x0D:
3114  case 0x0E:
3115  case 0x10:
3116  case 0x11:
3117  case 0x12:
3118  buf->ReadByte();
3119  break;
3120 
3121  case 0x0A:
3122  case 0x0B:
3123  case 0x0C:
3124  case 0x0F:
3125  buf->ReadWord();
3126  break;
3127 
3128  case 0x13:
3129  buf->Skip(buf->ReadByte() * 2);
3130  break;
3131 
3132  default:
3133  ret = CIR_UNKNOWN;
3134  break;
3135  }
3136  return ret;
3137 }
3138 
3147 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3148 {
3150 
3151  if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3152  grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3153  return CIR_INVALID_ID;
3154  }
3155 
3156  /* Allocate industry tile specs if they haven't been allocated already. */
3157  if (_cur.grffile->indtspec == nullptr) {
3158  _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3159  }
3160 
3161  for (int i = 0; i < numinfo; i++) {
3162  IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3163 
3164  if (prop != 0x08 && tsp == nullptr) {
3166  if (cir > ret) ret = cir;
3167  continue;
3168  }
3169 
3170  switch (prop) {
3171  case 0x08: { // Substitute industry tile type
3172  IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3173  byte subs_id = buf->ReadByte();
3174 
3175  if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3176  /* The substitute id must be one of the original industry tile. */
3177  grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3178  continue;
3179  }
3180 
3181  /* Allocate space for this industry. */
3182  if (*tilespec == nullptr) {
3183  *tilespec = CallocT<IndustryTileSpec>(1);
3184  tsp = *tilespec;
3185 
3186  memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3187  tsp->enabled = true;
3188 
3189  /* A copied tile should not have the animation infos copied too.
3190  * The anim_state should be left untouched, though
3191  * It is up to the author to animate them himself */
3194 
3195  tsp->grf_prop.local_id = indtid + i;
3196  tsp->grf_prop.subst_id = subs_id;
3197  tsp->grf_prop.grffile = _cur.grffile;
3198  _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3199  }
3200  break;
3201  }
3202 
3203  case 0x09: { // Industry tile override
3204  byte ovrid = buf->ReadByte();
3205 
3206  /* The industry being overridden must be an original industry. */
3207  if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3208  grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3209  continue;
3210  }
3211 
3212  _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3213  break;
3214  }
3215 
3216  case 0x0A: // Tile acceptance
3217  case 0x0B:
3218  case 0x0C: {
3219  uint16 acctp = buf->ReadWord();
3220  tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3221  tsp->acceptance[prop - 0x0A] = Clamp(GB(acctp, 8, 8), 0, 16);
3222  break;
3223  }
3224 
3225  case 0x0D: // Land shape flags
3226  tsp->slopes_refused = (Slope)buf->ReadByte();
3227  break;
3228 
3229  case 0x0E: // Callback mask
3230  tsp->callback_mask = buf->ReadByte();
3231  break;
3232 
3233  case 0x0F: // Animation information
3234  tsp->animation.frames = buf->ReadByte();
3235  tsp->animation.status = buf->ReadByte();
3236  break;
3237 
3238  case 0x10: // Animation speed
3239  tsp->animation.speed = buf->ReadByte();
3240  break;
3241 
3242  case 0x11: // Triggers for callback 25
3243  tsp->animation.triggers = buf->ReadByte();
3244  break;
3245 
3246  case 0x12: // Special flags
3247  tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3248  break;
3249 
3250  case 0x13: { // variable length cargo acceptance
3251  byte num_cargoes = buf->ReadByte();
3252  if (num_cargoes > lengthof(tsp->acceptance)) {
3253  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3254  error->param_value[1] = prop;
3255  return CIR_DISABLED;
3256  }
3257  for (uint i = 0; i < lengthof(tsp->acceptance); i++) {
3258  if (i < num_cargoes) {
3259  tsp->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3260  /* Tile acceptance can be negative to counteract the INDTILE_SPECIAL_ACCEPTS_ALL_CARGO flag */
3261  tsp->acceptance[i] = (int8)buf->ReadByte();
3262  } else {
3263  tsp->accepts_cargo[i] = CT_INVALID;
3264  tsp->acceptance[i] = 0;
3265  }
3266  }
3267  break;
3268  }
3269 
3270  default:
3271  ret = CIR_UNKNOWN;
3272  break;
3273  }
3274  }
3275 
3276  return ret;
3277 }
3278 
3286 {
3288 
3289  switch (prop) {
3290  case 0x09:
3291  case 0x0B:
3292  case 0x0F:
3293  case 0x12:
3294  case 0x13:
3295  case 0x14:
3296  case 0x17:
3297  case 0x18:
3298  case 0x19:
3299  case 0x21:
3300  case 0x22:
3301  buf->ReadByte();
3302  break;
3303 
3304  case 0x0C:
3305  case 0x0D:
3306  case 0x0E:
3307  case 0x10:
3308  case 0x1B:
3309  case 0x1F:
3310  case 0x24:
3311  buf->ReadWord();
3312  break;
3313 
3314  case 0x11:
3315  case 0x1A:
3316  case 0x1C:
3317  case 0x1D:
3318  case 0x1E:
3319  case 0x20:
3320  case 0x23:
3321  buf->ReadDWord();
3322  break;
3323 
3324  case 0x0A: {
3325  byte num_table = buf->ReadByte();
3326  for (byte j = 0; j < num_table; j++) {
3327  for (uint k = 0;; k++) {
3328  byte x = buf->ReadByte();
3329  if (x == 0xFE && k == 0) {
3330  buf->ReadByte();
3331  buf->ReadByte();
3332  break;
3333  }
3334 
3335  byte y = buf->ReadByte();
3336  if (x == 0 && y == 0x80) break;
3337 
3338  byte gfx = buf->ReadByte();
3339  if (gfx == 0xFE) buf->ReadWord();
3340  }
3341  }
3342  break;
3343  }
3344 
3345  case 0x16:
3346  for (byte j = 0; j < 3; j++) buf->ReadByte();
3347  break;
3348 
3349  case 0x15:
3350  case 0x25:
3351  case 0x26:
3352  case 0x27:
3353  buf->Skip(buf->ReadByte());
3354  break;
3355 
3356  case 0x28: {
3357  int num_inputs = buf->ReadByte();
3358  int num_outputs = buf->ReadByte();
3359  buf->Skip(num_inputs * num_outputs * 2);
3360  break;
3361  }
3362 
3363  default:
3364  ret = CIR_UNKNOWN;
3365  break;
3366  }
3367  return ret;
3368 }
3369 
3375 static bool ValidateIndustryLayout(const IndustryTileLayout &layout)
3376 {
3377  const size_t size = layout.size();
3378  for (size_t i = 0; i < size - 1; i++) {
3379  for (size_t j = i + 1; j < size; j++) {
3380  if (layout[i].ti.x == layout[j].ti.x &&
3381  layout[i].ti.y == layout[j].ti.y) {
3382  return false;
3383  }
3384  }
3385  }
3386  return true;
3387 }
3388 
3397 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3398 {
3400 
3401  if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3402  grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3403  return CIR_INVALID_ID;
3404  }
3405 
3406  /* Allocate industry specs if they haven't been allocated already. */
3407  if (_cur.grffile->industryspec == nullptr) {
3408  _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3409  }
3410 
3411  for (int i = 0; i < numinfo; i++) {
3412  IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3413 
3414  if (prop != 0x08 && indsp == nullptr) {
3415  ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3416  if (cir > ret) ret = cir;
3417  continue;
3418  }
3419 
3420  switch (prop) {
3421  case 0x08: { // Substitute industry type
3422  IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3423  byte subs_id = buf->ReadByte();
3424 
3425  if (subs_id == 0xFF) {
3426  /* Instead of defining a new industry, a substitute industry id
3427  * of 0xFF disables the old industry with the current id. */
3428  _industry_specs[indid + i].enabled = false;
3429  continue;
3430  } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3431  /* The substitute id must be one of the original industry. */
3432  grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3433  continue;
3434  }
3435 
3436  /* Allocate space for this industry.
3437  * Only need to do it once. If ever it is called again, it should not
3438  * do anything */
3439  if (*indspec == nullptr) {
3440  *indspec = new IndustrySpec;
3441  indsp = *indspec;
3442 
3443  *indsp = _origin_industry_specs[subs_id];
3444  indsp->enabled = true;
3445  indsp->grf_prop.local_id = indid + i;
3446  indsp->grf_prop.subst_id = subs_id;
3447  indsp->grf_prop.grffile = _cur.grffile;
3448  /* If the grf industry needs to check its surrounding upon creation, it should
3449  * rely on callbacks, not on the original placement functions */
3450  indsp->check_proc = CHECK_NOTHING;
3451  }
3452  break;
3453  }
3454 
3455  case 0x09: { // Industry type override
3456  byte ovrid = buf->ReadByte();
3457 
3458  /* The industry being overridden must be an original industry. */
3459  if (ovrid >= NEW_INDUSTRYOFFSET) {
3460  grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3461  continue;
3462  }
3463  indsp->grf_prop.override = ovrid;
3464  _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3465  break;
3466  }
3467 
3468  case 0x0A: { // Set industry layout(s)
3469  byte new_num_layouts = buf->ReadByte();
3470  uint32 definition_size = buf->ReadDWord();
3471  uint32 bytes_read = 0;
3472  std::vector<IndustryTileLayout> new_layouts;
3473  IndustryTileLayout layout;
3474 
3475  for (byte j = 0; j < new_num_layouts; j++) {
3476  layout.clear();
3477 
3478  for (uint k = 0;; k++) {
3479  if (bytes_read >= definition_size) {
3480  grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3481  /* Avoid warning twice */
3482  definition_size = UINT32_MAX;
3483  }
3484 
3485  layout.push_back(IndustryTileLayoutTile{});
3486  IndustryTileLayoutTile &it = layout.back();
3487 
3488  it.ti.x = buf->ReadByte(); // Offsets from northermost tile
3489  ++bytes_read;
3490 
3491  if (it.ti.x == 0xFE && k == 0) {
3492  /* This means we have to borrow the layout from an old industry */
3493  IndustryType type = buf->ReadByte();
3494  byte laynbr = buf->ReadByte();
3495  bytes_read += 2;
3496 
3497  if (type >= lengthof(_origin_industry_specs)) {
3498  grfmsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3499  DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
3500  return CIR_DISABLED;
3501  }
3502  if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3503  grfmsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3504  DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
3505  return CIR_DISABLED;
3506  }
3507  layout = _origin_industry_specs[type].layouts[laynbr];
3508  break;
3509  }
3510 
3511  it.ti.y = buf->ReadByte(); // Or table definition finalisation
3512  ++bytes_read;
3513 
3514  if (it.ti.x == 0 && it.ti.y == 0x80) {
3515  /* Terminator, remove and finish up */
3516  layout.pop_back();
3517  break;
3518  }
3519 
3520  it.gfx = buf->ReadByte();
3521  ++bytes_read;
3522 
3523  if (it.gfx == 0xFE) {
3524  /* Use a new tile from this GRF */
3525  int local_tile_id = buf->ReadWord();
3526  bytes_read += 2;
3527 
3528  /* Read the ID from the _industile_mngr. */
3529  int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3530 
3531  if (tempid == INVALID_INDUSTRYTILE) {
3532  grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3533  } else {
3534  /* Declared as been valid, can be used */
3535  it.gfx = tempid;
3536  }
3537  } else if (it.gfx == 0xFF) {
3538  it.ti.x = (int8)GB(it.ti.x, 0, 8);
3539  it.ti.y = (int8)GB(it.ti.y, 0, 8);
3540 
3541  /* When there were only 256x256 maps, TileIndex was a uint16 and
3542  * it.ti was just a TileIndexDiff that was added to it.
3543  * As such negative "x" values were shifted into the "y" position.
3544  * x = -1, y = 1 -> x = 255, y = 0
3545  * Since GRF version 8 the position is interpreted as pair of independent int8.
3546  * For GRF version < 8 we need to emulate the old shifting behaviour.
3547  */
3548  if (_cur.grffile->grf_version < 8 && it.ti.x < 0) it.ti.y += 1;
3549  }
3550  }
3551 
3552  if (!ValidateIndustryLayout(layout)) {
3553  /* The industry layout was not valid, so skip this one. */
3554  grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3555  new_num_layouts--;
3556  j--;
3557  } else {
3558  new_layouts.push_back(layout);
3559  }
3560  }
3561 
3562  /* Install final layout construction in the industry spec */
3563  indsp->layouts = new_layouts;
3564  break;
3565  }
3566 
3567  case 0x0B: // Industry production flags
3568  indsp->life_type = (IndustryLifeType)buf->ReadByte();
3569  break;
3570 
3571  case 0x0C: // Industry closure message
3572  AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3573  break;
3574 
3575  case 0x0D: // Production increase message
3576  AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3577  break;
3578 
3579  case 0x0E: // Production decrease message
3580  AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3581  break;
3582 
3583  case 0x0F: // Fund cost multiplier
3584  indsp->cost_multiplier = buf->ReadByte();
3585  break;
3586 
3587  case 0x10: // Production cargo types
3588  for (byte j = 0; j < 2; j++) {
3589  indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3590  }
3591  break;
3592 
3593  case 0x11: // Acceptance cargo types
3594  for (byte j = 0; j < 3; j++) {
3595  indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3596  }
3597  buf->ReadByte(); // Unnused, eat it up
3598  break;
3599 
3600  case 0x12: // Production multipliers
3601  case 0x13:
3602  indsp->production_rate[prop - 0x12] = buf->ReadByte();
3603  break;
3604 
3605  case 0x14: // Minimal amount of cargo distributed
3606  indsp->minimal_cargo = buf->ReadByte();
3607  break;
3608 
3609  case 0x15: { // Random sound effects
3610  indsp->number_of_sounds = buf->ReadByte();
3611  uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3612 
3613  try {
3614  for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3615  sounds[j] = buf->ReadByte();
3616  }
3617  } catch (...) {
3618  free(sounds);
3619  throw;
3620  }
3621 
3622  if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3623  free(indsp->random_sounds);
3624  }
3625  indsp->random_sounds = sounds;
3627  break;
3628  }
3629 
3630  case 0x16: // Conflicting industry types
3631  for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3632  break;
3633 
3634  case 0x17: // Probability in random game
3635  indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3636  break;
3637 
3638  case 0x18: // Probability during gameplay
3639  indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3640  break;
3641 
3642  case 0x19: // Map colour
3643  indsp->map_colour = buf->ReadByte();
3644  break;
3645 
3646  case 0x1A: // Special industry flags to define special behavior
3647  indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3648  break;
3649 
3650  case 0x1B: // New industry text ID
3651  AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3652  break;
3653 
3654  case 0x1C: // Input cargo multipliers for the three input cargo types
3655  case 0x1D:
3656  case 0x1E: {
3657  uint32 multiples = buf->ReadDWord();
3658  indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3659  indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3660  break;
3661  }
3662 
3663  case 0x1F: // Industry name
3664  AddStringForMapping(buf->ReadWord(), &indsp->name);
3665  break;
3666 
3667  case 0x20: // Prospecting success chance
3668  indsp->prospecting_chance = buf->ReadDWord();
3669  break;
3670 
3671  case 0x21: // Callback mask
3672  case 0x22: { // Callback additional mask
3673  byte aflag = buf->ReadByte();
3674  SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3675  break;
3676  }
3677 
3678  case 0x23: // removal cost multiplier
3679  indsp->removal_cost_multiplier = buf->ReadDWord();
3680  break;
3681 
3682  case 0x24: { // name for nearby station
3683  uint16 str = buf->ReadWord();
3684  if (str == 0) {
3685  indsp->station_name = STR_NULL;
3686  } else {
3687  AddStringForMapping(str, &indsp->station_name);
3688  }
3689  break;
3690  }
3691 
3692  case 0x25: { // variable length produced cargoes
3693  byte num_cargoes = buf->ReadByte();
3694  if (num_cargoes > lengthof(indsp->produced_cargo)) {
3695  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3696  error->param_value[1] = prop;
3697  return CIR_DISABLED;
3698  }
3699  for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) {
3700  if (i < num_cargoes) {
3701  CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3702  indsp->produced_cargo[i] = cargo;
3703  } else {
3704  indsp->produced_cargo[i] = CT_INVALID;
3705  }
3706  }
3707  break;
3708  }
3709 
3710  case 0x26: { // variable length accepted cargoes
3711  byte num_cargoes = buf->ReadByte();
3712  if (num_cargoes > lengthof(indsp->accepts_cargo)) {
3713  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3714  error->param_value[1] = prop;
3715  return CIR_DISABLED;
3716  }
3717  for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
3718  if (i < num_cargoes) {
3719  CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3720  indsp->accepts_cargo[i] = cargo;
3721  } else {
3722  indsp->accepts_cargo[i] = CT_INVALID;
3723  }
3724  }
3725  break;
3726  }
3727 
3728  case 0x27: { // variable length production rates
3729  byte num_cargoes = buf->ReadByte();
3730  if (num_cargoes > lengthof(indsp->production_rate)) {
3731  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3732  error->param_value[1] = prop;
3733  return CIR_DISABLED;
3734  }
3735  for (uint i = 0; i < lengthof(indsp->production_rate); i++) {
3736  if (i < num_cargoes) {
3737  indsp->production_rate[i] = buf->ReadByte();
3738  } else {
3739  indsp->production_rate[i] = 0;
3740  }
3741  }
3742  break;
3743  }
3744 
3745  case 0x28: { // variable size input/output production multiplier table
3746  byte num_inputs = buf->ReadByte();
3747  byte num_outputs = buf->ReadByte();
3748  if (num_inputs > lengthof(indsp->accepts_cargo) || num_outputs > lengthof(indsp->produced_cargo)) {
3749  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3750  error->param_value[1] = prop;
3751  return CIR_DISABLED;
3752  }
3753  for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
3754  for (uint j = 0; j < lengthof(indsp->produced_cargo); j++) {
3755  uint16 mult = 0;
3756  if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3757  indsp->input_cargo_multiplier[i][j] = mult;
3758  }
3759  }
3760  break;
3761  }
3762 
3763  default:
3764  ret = CIR_UNKNOWN;
3765  break;
3766  }
3767  }
3768 
3769  return ret;
3770 }
3771 
3778 {
3779  AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3780  for (int i = 0; i < as->num_table; i++) {
3781  uint num_tiles = 1;
3782  const AirportTileTable *it = as->table[0];
3783  do {
3784  num_tiles++;
3785  } while ((++it)->ti.x != -0x80);
3786  table_list[i] = MallocT<AirportTileTable>(num_tiles);
3787  MemCpyT(table_list[i], as->table[i], num_tiles);
3788  }
3789  as->table = table_list;
3790  HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3791  MemCpyT(depot_table, as->depot_table, as->nof_depots);
3792  as->depot_table = depot_table;
3793  Direction *rotation = MallocT<Direction>(as->num_table);
3794  MemCpyT(rotation, as->rotation, as->num_table);
3795  as->rotation = rotation;
3796 }
3797 
3806 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3807 {
3809 
3810  if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3811  grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3812  return CIR_INVALID_ID;
3813  }
3814 
3815  /* Allocate industry specs if they haven't been allocated already. */
3816  if (_cur.grffile->airportspec == nullptr) {
3817  _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3818  }
3819 
3820  for (int i = 0; i < numinfo; i++) {
3821  AirportSpec *as = _cur.grffile->airportspec[airport + i];
3822 
3823  if (as == nullptr && prop != 0x08 && prop != 0x09) {
3824  grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3825  return CIR_INVALID_ID;
3826  }
3827 
3828  switch (prop) {
3829  case 0x08: { // Modify original airport
3830  byte subs_id = buf->ReadByte();
3831 
3832  if (subs_id == 0xFF) {
3833  /* Instead of defining a new airport, an airport id
3834  * of 0xFF disables the old airport with the current id. */
3835  AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3836  continue;
3837  } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3838  /* The substitute id must be one of the original airports. */
3839  grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3840  continue;
3841  }
3842 
3843  AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3844  /* Allocate space for this airport.
3845  * Only need to do it once. If ever it is called again, it should not
3846  * do anything */
3847  if (*spec == nullptr) {
3848  *spec = MallocT<AirportSpec>(1);
3849  as = *spec;
3850 
3851  memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3852  as->enabled = true;
3853  as->grf_prop.local_id = airport + i;
3854  as->grf_prop.subst_id = subs_id;
3855  as->grf_prop.grffile = _cur.grffile;
3856  /* override the default airport */
3857  _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3858  /* Create a copy of the original tiletable so it can be freed later. */
3859  DuplicateTileTable(as);
3860  }
3861  break;
3862  }
3863 
3864  case 0x0A: { // Set airport layout
3865  free(as->rotation);
3866  as->num_table = buf->ReadByte(); // Number of layaouts
3867  as->rotation = MallocT<Direction>(as->num_table);
3868  uint32 defsize = buf->ReadDWord(); // Total size of the definition
3869  AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3870  AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3871  int size;
3872  const AirportTileTable *copy_from;
3873  try {
3874  for (byte j = 0; j < as->num_table; j++) {
3875  const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
3876  for (int k = 0;; k++) {
3877  att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3878  att[k].ti.y = buf->ReadByte();
3879 
3880  if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3881  /* Not the same terminator. The one we are using is rather
3882  * x = -80, y = 0 . So, adjust it. */
3883  att[k].ti.x = -0x80;
3884  att[k].ti.y = 0;
3885  att[k].gfx = 0;
3886 
3887  size = k + 1;
3888  copy_from = att;
3889  break;
3890  }
3891 
3892  att[k].gfx = buf->ReadByte();
3893 
3894  if (att[k].gfx == 0xFE) {
3895  /* Use a new tile from this GRF */
3896  int local_tile_id = buf->ReadWord();
3897 
3898  /* Read the ID from the _airporttile_mngr. */
3899  uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3900 
3901  if (tempid == INVALID_AIRPORTTILE) {
3902  grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3903  } else {
3904  /* Declared as been valid, can be used */
3905  att[k].gfx = tempid;
3906  }
3907  } else if (att[k].gfx == 0xFF) {
3908  att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3909  att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3910  }
3911 
3912  if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3913  as->size_x = std::max<byte>(as->size_x, att[k].ti.y + 1);
3914  as->size_y = std::max<byte>(as->size_y, att[k].ti.x + 1);
3915  } else {
3916  as->size_x = std::max<byte>(as->size_x, att[k].ti.x + 1);
3917  as->size_y = std::max<byte>(as->size_y, att[k].ti.y + 1);
3918  }
3919  }
3920  tile_table[j] = CallocT<AirportTileTable>(size);
3921  memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3922  }
3923  /* Install final layout construction in the airport spec */
3924  as->table = tile_table;
3925  free(att);
3926  } catch (...) {
3927  for (int i = 0; i < as->num_table; i++) {
3928  free(tile_table[i]);
3929  }
3930  free(tile_table);
3931  free(att);
3932  throw;
3933  }
3934  break;
3935  }
3936 
3937  case 0x0C:
3938  as->min_year = buf->ReadWord();
3939  as->max_year = buf->ReadWord();
3940  if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3941  break;
3942 
3943  case 0x0D:
3944  as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3945  break;
3946 
3947  case 0x0E:
3948  as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3949  break;
3950 
3951  case 0x0F:
3952  as->noise_level = buf->ReadByte();
3953  break;
3954 
3955  case 0x10:
3956  AddStringForMapping(buf->ReadWord(), &as->name);
3957  break;
3958 
3959  case 0x11: // Maintenance cost factor
3960  as->maintenance_cost = buf->ReadWord();
3961  break;
3962 
3963  default:
3964  ret = CIR_UNKNOWN;
3965  break;
3966  }
3967  }
3968 
3969  return ret;
3970 }
3971 
3979 {
3981 
3982  switch (prop) {
3983  case 0x0B:
3984  case 0x0C:
3985  case 0x0D:
3986  case 0x12:
3987  case 0x14:
3988  case 0x16:
3989  case 0x17:
3990  buf->ReadByte();
3991  break;
3992 
3993  case 0x09:
3994  case 0x0A:
3995  case 0x10:
3996  case 0x11:
3997  case 0x13:
3998  case 0x15:
3999  buf->ReadWord();
4000  break;
4001 
4002  case 0x08:
4003  case 0x0E:
4004  case 0x0F:
4005  buf->ReadDWord();
4006  break;
4007 
4008  default:
4009  ret = CIR_UNKNOWN;
4010  break;
4011  }
4012 
4013  return ret;
4014 }
4015 
4024 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4025 {
4027 
4028  if (id + numinfo > NUM_OBJECTS_PER_GRF) {
4029  grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
4030  return CIR_INVALID_ID;
4031  }
4032 
4033  /* Allocate object specs if they haven't been allocated already. */
4034  if (_cur.grffile->objectspec == nullptr) {
4035  _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
4036  }
4037 
4038  for (int i = 0; i < numinfo; i++) {
4039  ObjectSpec *spec = _cur.grffile->objectspec[id + i];
4040 
4041  if (prop != 0x08 && spec == nullptr) {
4042  /* If the object property 08 is not yet set, ignore this property */
4043  ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
4044  if (cir > ret) ret = cir;
4045  continue;
4046  }
4047 
4048  switch (prop) {
4049  case 0x08: { // Class ID
4050  ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
4051 
4052  /* Allocate space for this object. */
4053  if (*ospec == nullptr) {
4054  *ospec = CallocT<ObjectSpec>(1);
4055  (*ospec)->views = 1; // Default for NewGRFs that don't set it.
4056  }
4057 
4058  /* Swap classid because we read it in BE. */
4059  uint32 classid = buf->ReadDWord();
4060  (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
4061  (*ospec)->enabled = true;
4062  break;
4063  }
4064 
4065  case 0x09: { // Class name
4066  ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
4067  AddStringForMapping(buf->ReadWord(), &objclass->name);
4068  break;
4069  }
4070 
4071  case 0x0A: // Object name
4072  AddStringForMapping(buf->ReadWord(), &spec->name);
4073  break;
4074 
4075  case 0x0B: // Climate mask
4076  spec->climate = buf->ReadByte();
4077  break;
4078 
4079  case 0x0C: // Size
4080  spec->size = buf->ReadByte();
4081  break;
4082 
4083  case 0x0D: // Build cost multipler
4084  spec->build_cost_multiplier = buf->ReadByte();
4086  break;
4087 
4088  case 0x0E: // Introduction date
4089  spec->introduction_date = buf->ReadDWord();
4090  break;
4091 
4092  case 0x0F: // End of life
4093  spec->end_of_life_date = buf->ReadDWord();
4094  break;
4095 
4096  case 0x10: // Flags
4097  spec->flags = (ObjectFlags)buf->ReadWord();
4099  break;
4100 
4101  case 0x11: // Animation info
4102  spec->animation.frames = buf->ReadByte();
4103  spec->animation.status = buf->ReadByte();
4104  break;
4105 
4106  case 0x12: // Animation speed
4107  spec->animation.speed = buf->ReadByte();
4108  break;
4109 
4110  case 0x13: // Animation triggers
4111  spec->animation.triggers = buf->ReadWord();
4112  break;
4113 
4114  case 0x14: // Removal cost multiplier
4115  spec->clear_cost_multiplier = buf->ReadByte();
4116  break;
4117 
4118  case 0x15: // Callback mask
4119  spec->callback_mask = buf->ReadWord();
4120  break;
4121 
4122  case 0x16: // Building height
4123  spec->height = buf->ReadByte();
4124  break;
4125 
4126  case 0x17: // Views
4127  spec->views = buf->ReadByte();
4128  if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4129  grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4130  spec->views = 1;
4131  }
4132  break;
4133 
4134  case 0x18: // Amount placed on 256^2 map on map creation
4135  spec->generate_amount = buf->ReadByte();
4136  break;
4137 
4138  default:
4139  ret = CIR_UNKNOWN;
4140  break;
4141  }
4142  }
4143 
4144  return ret;
4145 }
4146 
4155 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4156 {
4158 
4159  extern RailtypeInfo _railtypes[RAILTYPE_END];
4160 
4161  if (id + numinfo > RAILTYPE_END) {
4162  grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4163  return CIR_INVALID_ID;
4164  }
4165 
4166  for (int i = 0; i < numinfo; i++) {
4167  RailType rt = _cur.grffile->railtype_map[id + i];
4168  if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4169 
4170  RailtypeInfo *rti = &_railtypes[rt];
4171 
4172  switch (prop) {
4173  case 0x08: // Label of rail type
4174  /* Skipped here as this is loaded during reservation stage. */
4175  buf->ReadDWord();
4176  break;
4177 
4178  case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4179  uint16 str = buf->ReadWord();
4181  if (_cur.grffile->grf_version < 8) {
4182  AddStringForMapping(str, &rti->strings.name);
4183  }
4184  break;
4185  }
4186 
4187  case 0x0A: // Menu text of railtype
4188  AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4189  break;
4190 
4191  case 0x0B: // Build window caption
4192  AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4193  break;
4194 
4195  case 0x0C: // Autoreplace text
4196  AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4197  break;
4198 
4199  case 0x0D: // New locomotive text
4200  AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4201  break;
4202 
4203  case 0x0E: // Compatible railtype list
4204  case 0x0F: // Powered railtype list
4205  case 0x18: // Railtype list required for date introduction
4206  case 0x19: // Introduced railtype list
4207  {
4208  /* Rail type compatibility bits are added to the existing bits
4209  * to allow multiple GRFs to modify compatibility with the
4210  * default rail types. */
4211  int n = buf->ReadByte();
4212  for (int j = 0; j != n; j++) {
4213  RailTypeLabel label = buf->ReadDWord();
4214  RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4215  if (rt != INVALID_RAILTYPE) {
4216  switch (prop) {
4217  case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4218  case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4219  case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4220  case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4221  }
4222  }
4223  }
4224  break;
4225  }
4226 
4227  case 0x10: // Rail Type flags
4228  rti->flags = (RailTypeFlags)buf->ReadByte();
4229  break;
4230 
4231  case 0x11: // Curve speed advantage
4232  rti->curve_speed = buf->ReadByte();
4233  break;
4234 
4235  case 0x12: // Station graphic
4236  rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4237  break;
4238 
4239  case 0x13: // Construction cost factor
4240  rti->cost_multiplier = buf->ReadWord();
4241  break;
4242 
4243  case 0x14: // Speed limit
4244  rti->max_speed = buf->ReadWord();
4245  break;
4246 
4247  case 0x15: // Acceleration model
4248  rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4249  break;
4250 
4251  case 0x16: // Map colour
4252  rti->map_colour = buf->ReadByte();
4253  break;
4254 
4255  case 0x17: // Introduction date
4256  rti->introduction_date = buf->ReadDWord();
4257  break;
4258 
4259  case 0x1A: // Sort order
4260  rti->sorting_order = buf->ReadByte();
4261  break;
4262 
4263  case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4264  AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4265  break;
4266 
4267  case 0x1C: // Maintenance cost factor
4268  rti->maintenance_multiplier = buf->ReadWord();
4269  break;
4270 
4271  case 0x1D: // Alternate rail type label list
4272  /* Skipped here as this is loaded during reservation stage. */
4273  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4274  break;
4275 
4276  default:
4277  ret = CIR_UNKNOWN;
4278  break;
4279  }
4280  }
4281 
4282  return ret;
4283 }
4284 
4285 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4286 {
4288 
4289  extern RailtypeInfo _railtypes[RAILTYPE_END];
4290 
4291  if (id + numinfo > RAILTYPE_END) {
4292  grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4293  return CIR_INVALID_ID;
4294  }
4295 
4296  for (int i = 0; i < numinfo; i++) {
4297  switch (prop) {
4298  case 0x08: // Label of rail type
4299  {
4300  RailTypeLabel rtl = buf->ReadDWord();
4301  rtl = BSWAP32(rtl);
4302 
4303  RailType rt = GetRailTypeByLabel(rtl, false);
4304  if (rt == INVALID_RAILTYPE) {
4305  /* Set up new rail type */
4306  rt = AllocateRailType(rtl);
4307  }
4308 
4309  _cur.grffile->railtype_map[id + i] = rt;
4310  break;
4311  }
4312 
4313  case 0x09: // Toolbar caption of railtype
4314  case 0x0A: // Menu text
4315  case 0x0B: // Build window caption
4316  case 0x0C: // Autoreplace text
4317  case 0x0D: // New loco
4318  case 0x13: // Construction cost
4319  case 0x14: // Speed limit
4320  case 0x1B: // Name of railtype
4321  case 0x1C: // Maintenance cost factor
4322  buf->ReadWord();
4323  break;
4324 
4325  case 0x1D: // Alternate rail type label list
4326  if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4327  int n = buf->ReadByte();
4328  for (int j = 0; j != n; j++) {
4329  _railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord()));
4330  }
4331  break;
4332  }
4333  grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4334  FALLTHROUGH;
4335 
4336  case 0x0E: // Compatible railtype list
4337  case 0x0F: // Powered railtype list
4338  case 0x18: // Railtype list required for date introduction
4339  case 0x19: // Introduced railtype list
4340  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4341  break;
4342 
4343  case 0x10: // Rail Type flags
4344  case 0x11: // Curve speed advantage
4345  case 0x12: // Station graphic
4346  case 0x15: // Acceleration model
4347  case 0x16: // Map colour
4348  case 0x1A: // Sort order
4349  buf->ReadByte();
4350  break;
4351 
4352  case 0x17: // Introduction date
4353  buf->ReadDWord();
4354  break;
4355 
4356  default:
4357  ret = CIR_UNKNOWN;
4358  break;
4359  }
4360  }
4361 
4362  return ret;
4363 }
4364 
4373 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
4374 {
4376 
4377  extern RoadTypeInfo _roadtypes[ROADTYPE_END];
4378  RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
4379 
4380  if (id + numinfo > ROADTYPE_END) {
4381  grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
4382  return CIR_INVALID_ID;
4383  }
4384 
4385  for (int i = 0; i < numinfo; i++) {
4386  RoadType rt = type_map[id + i];
4387  if (rt == INVALID_ROADTYPE) return CIR_INVALID_ID;
4388 
4389  RoadTypeInfo *rti = &_roadtypes[rt];
4390 
4391  switch (prop) {
4392  case 0x08: // Label of road type
4393  /* Skipped here as this is loaded during reservation stage. */
4394  buf->ReadDWord();
4395  break;
4396 
4397  case 0x09: { // Toolbar caption of roadtype (sets name as well for backwards compatibility for grf ver < 8)
4398  uint16 str = buf->ReadWord();
4400  break;
4401  }
4402 
4403  case 0x0A: // Menu text of roadtype
4404  AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4405  break;
4406 
4407  case 0x0B: // Build window caption
4408  AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4409  break;
4410 
4411  case 0x0C: // Autoreplace text
4412  AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4413  break;
4414 
4415  case 0x0D: // New engine text
4416  AddStringForMapping(buf->ReadWord(), &rti->strings.new_engine);
4417  break;
4418 
4419  case 0x0F: // Powered roadtype list
4420  case 0x18: // Roadtype list required for date introduction
4421  case 0x19: { // Introduced roadtype list
4422  /* Road type compatibility bits are added to the existing bits
4423  * to allow multiple GRFs to modify compatibility with the
4424  * default road types. */
4425  int n = buf->ReadByte();
4426  for (int j = 0; j != n; j++) {
4427  RoadTypeLabel label = buf->ReadDWord();
4428  RoadType rt = GetRoadTypeByLabel(BSWAP32(label), false);
4429  if (rt != INVALID_ROADTYPE) {
4430  switch (prop) {
4431  case 0x0F: SetBit(rti->powered_roadtypes, rt); break;
4432  case 0x18: SetBit(rti->introduction_required_roadtypes, rt); break;
4433  case 0x19: SetBit(rti->introduces_roadtypes, rt); break;
4434  }
4435  }
4436  }
4437  break;
4438  }
4439 
4440  case 0x10: // Road Type flags
4441  rti->flags = (RoadTypeFlags)buf->ReadByte();
4442  break;
4443 
4444  case 0x13: // Construction cost factor
4445  rti->cost_multiplier = buf->ReadWord();
4446  break;
4447 
4448  case 0x14: // Speed limit
4449  rti->max_speed = buf->ReadWord();
4450  break;
4451 
4452  case 0x16: // Map colour
4453  rti->map_colour = buf->ReadByte();
4454  break;
4455 
4456  case 0x17: // Introduction date
4457  rti->introduction_date = buf->ReadDWord();
4458  break;
4459 
4460  case 0x1A: // Sort order
4461  rti->sorting_order = buf->ReadByte();
4462  break;
4463 
4464  case 0x1B: // Name of roadtype
4465  AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4466  break;
4467 
4468  case 0x1C: // Maintenance cost factor
4469  rti->maintenance_multiplier = buf->ReadWord();
4470  break;
4471 
4472  case 0x1D: // Alternate road type label list
4473  /* Skipped here as this is loaded during reservation stage. */
4474  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4475  break;
4476 
4477  default:
4478  ret = CIR_UNKNOWN;
4479  break;
4480  }
4481  }
4482 
4483  return ret;
4484 }
4485 
4486 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4487 {
4488  return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_ROAD);
4489 }
4490 
4491 static ChangeInfoResult TramTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4492 {
4493  return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_TRAM);
4494 }
4495 
4496 
4497 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
4498 {
4500 
4501  extern RoadTypeInfo _roadtypes[ROADTYPE_END];
4502  RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
4503 
4504  if (id + numinfo > ROADTYPE_END) {
4505  grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
4506  return CIR_INVALID_ID;
4507  }
4508 
4509  for (int i = 0; i < numinfo; i++) {
4510  switch (prop) {
4511  case 0x08: { // Label of road type
4512  RoadTypeLabel rtl = buf->ReadDWord();
4513  rtl = BSWAP32(rtl);
4514 
4515  RoadType rt = GetRoadTypeByLabel(rtl, false);
4516  if (rt == INVALID_ROADTYPE) {
4517  /* Set up new road type */
4518  rt = AllocateRoadType(rtl, rtt);
4519  } else if (GetRoadTramType(rt) != rtt) {
4520  grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring", id + numinfo);
4521  return CIR_INVALID_ID;
4522  }
4523 
4524  type_map[id + i] = rt;
4525  break;
4526  }
4527  case 0x09: // Toolbar caption of roadtype
4528  case 0x0A: // Menu text
4529  case 0x0B: // Build window caption
4530  case 0x0C: // Autoreplace text
4531  case 0x0D: // New loco
4532  case 0x13: // Construction cost
4533  case 0x14: // Speed limit
4534  case 0x1B: // Name of roadtype
4535  case 0x1C: // Maintenance cost factor
4536  buf->ReadWord();
4537  break;
4538 
4539  case 0x1D: // Alternate road type label list
4540  if (type_map[id + i] != INVALID_ROADTYPE) {
4541  int n = buf->ReadByte();
4542  for (int j = 0; j != n; j++) {
4543  _roadtypes[type_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord()));
4544  }
4545  break;
4546  }
4547  grfmsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set", id + i);
4548  /* FALL THROUGH */
4549 
4550  case 0x0F: // Powered roadtype list
4551  case 0x18: // Roadtype list required for date introduction
4552  case 0x19: // Introduced roadtype list
4553  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4554  break;
4555 
4556  case 0x10: // Road Type flags
4557  case 0x16: // Map colour
4558  case 0x1A: // Sort order
4559  buf->ReadByte();
4560  break;
4561 
4562  case 0x17: // Introduction date
4563  buf->ReadDWord();
4564  break;
4565 
4566  default:
4567  ret = CIR_UNKNOWN;
4568  break;
4569  }
4570  }
4571 
4572  return ret;
4573 }
4574 
4575 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4576 {
4577  return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_ROAD);
4578 }
4579 
4580 static ChangeInfoResult TramTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4581 {
4582  return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_TRAM);
4583 }
4584 
4585 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4586 {
4588 
4589  if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4590  grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4591  return CIR_INVALID_ID;
4592  }
4593 
4594  /* Allocate airport tile specs if they haven't been allocated already. */
4595  if (_cur.grffile->airtspec == nullptr) {
4596  _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4597  }
4598 
4599  for (int i = 0; i < numinfo; i++) {
4600  AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4601 
4602  if (prop != 0x08 && tsp == nullptr) {
4603  grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4604  return CIR_INVALID_ID;
4605  }
4606 
4607  switch (prop) {
4608  case 0x08: { // Substitute airport tile type
4609  AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4610  byte subs_id = buf->ReadByte();
4611 
4612  if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4613  /* The substitute id must be one of the original airport tiles. */
4614  grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4615  continue;
4616  }
4617 
4618  /* Allocate space for this airport tile. */
4619  if (*tilespec == nullptr) {
4620  *tilespec = CallocT<AirportTileSpec>(1);
4621  tsp = *tilespec;
4622 
4623  memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4624  tsp->enabled = true;
4625 
4627 
4628  tsp->grf_prop.local_id = airtid + i;
4629  tsp->grf_prop.subst_id = subs_id;
4630  tsp->grf_prop.grffile = _cur.grffile;
4631  _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4632  }
4633  break;
4634  }
4635 
4636  case 0x09: { // Airport tile override
4637  byte override = buf->ReadByte();
4638 
4639  /* The airport tile being overridden must be an original airport tile. */
4640  if (override >= NEW_AIRPORTTILE_OFFSET) {
4641  grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4642  continue;
4643  }
4644 
4645  _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4646  break;
4647  }
4648 
4649  case 0x0E: // Callback mask
4650  tsp->callback_mask = buf->ReadByte();
4651  break;
4652 
4653  case 0x0F: // Animation information
4654  tsp->animation.frames = buf->ReadByte();
4655  tsp->animation.status = buf->ReadByte();
4656  break;
4657 
4658  case 0x10: // Animation speed
4659  tsp->animation.speed = buf->ReadByte();
4660  break;
4661 
4662  case 0x11: // Animation triggers
4663  tsp->animation.triggers = buf->ReadByte();
4664  break;
4665 
4666  default:
4667  ret = CIR_UNKNOWN;
4668  break;
4669  }
4670  }
4671 
4672  return ret;
4673 }
4674 
4675 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4676 {
4677  switch (cir) {
4678  default: NOT_REACHED();
4679 
4680  case CIR_DISABLED:
4681  /* Error has already been printed; just stop parsing */
4682  return true;
4683 
4684  case CIR_SUCCESS:
4685  return false;
4686 
4687  case CIR_UNHANDLED:
4688  grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4689  return false;
4690 
4691  case CIR_UNKNOWN:
4692  grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4693  FALLTHROUGH;
4694 
4695  case CIR_INVALID_ID: {
4696  /* No debug message for an invalid ID, as it has already been output */
4697  GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4698  if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4699  return true;
4700  }
4701  }
4702 }
4703 
4704 /* Action 0x00 */
4705 static void FeatureChangeInfo(ByteReader *buf)
4706 {
4707  /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4708  *
4709  * B feature
4710  * B num-props how many properties to change per vehicle/station
4711  * B num-info how many vehicles/stations to change
4712  * E id ID of first vehicle/station to change, if num-info is
4713  * greater than one, this one and the following
4714  * vehicles/stations will be changed
4715  * B property what property to change, depends on the feature
4716  * V new-info new bytes of info (variable size; depends on properties) */
4717 
4718  static const VCI_Handler handler[] = {
4719  /* GSF_TRAINS */ RailVehicleChangeInfo,
4720  /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4721  /* GSF_SHIPS */ ShipVehicleChangeInfo,
4722  /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4723  /* GSF_STATIONS */ StationChangeInfo,
4724  /* GSF_CANALS */ CanalChangeInfo,
4725  /* GSF_BRIDGES */ BridgeChangeInfo,
4726  /* GSF_HOUSES */ TownHouseChangeInfo,
4727  /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4728  /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4729  /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4730  /* GSF_CARGOES */ nullptr, // Cargo is handled during reservation
4731  /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4732  /* GSF_AIRPORTS */ AirportChangeInfo,
4733  /* GSF_SIGNALS */ nullptr,
4734  /* GSF_OBJECTS */ ObjectChangeInfo,
4735  /* GSF_RAILTYPES */ RailTypeChangeInfo,
4736  /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4737  /* GSF_ROADTYPES */ RoadTypeChangeInfo,
4738  /* GSF_TRAMTYPES */ TramTypeChangeInfo,
4739  };
4740 
4741  uint8 feature = buf->ReadByte();
4742  uint8 numprops = buf->ReadByte();
4743  uint numinfo = buf->ReadByte();
4744  uint engine = buf->ReadExtendedByte();
4745 
4746  if (feature >= GSF_END) {
4747  grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4748  return;
4749  }
4750 
4751  grfmsg(6, "FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4752  feature, numprops, engine, numinfo);
4753 
4754  if (feature >= lengthof(handler) || handler[feature] == nullptr) {
4755  if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4756  return;
4757  }
4758 
4759  /* Mark the feature as used by the grf */
4760  SetBit(_cur.grffile->grf_features, feature);
4761 
4762  while (numprops-- && buf->HasData()) {
4763  uint8 prop = buf->ReadByte();
4764 
4765  ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4766  if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4767  }
4768 }
4769 
4770 /* Action 0x00 (GLS_SAFETYSCAN) */
4771 static void SafeChangeInfo(ByteReader *buf)
4772 {
4773  uint8 feature = buf->ReadByte();
4774  uint8 numprops = buf->ReadByte();
4775  uint numinfo = buf->ReadByte();
4776  buf->ReadExtendedByte(); // id
4777 
4778  if (feature == GSF_BRIDGES && numprops == 1) {
4779  uint8 prop = buf->ReadByte();
4780  /* Bridge property 0x0D is redefinition of sprite layout tables, which
4781  * is considered safe. */
4782  if (prop == 0x0D) return;
4783  } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4784  uint8 prop = buf->ReadByte();
4785  /* Engine ID Mappings are safe, if the source is static */
4786  if (prop == 0x11) {
4787  bool is_safe = true;
4788  for (uint i = 0; i < numinfo; i++) {
4789  uint32 s = buf->ReadDWord();
4790  buf->ReadDWord(); // dest
4791  const GRFConfig *grfconfig = GetGRFConfig(s);
4792  if (grfconfig != nullptr && !HasBit(grfconfig->flags, GCF_STATIC)) {
4793  is_safe = false;
4794  break;
4795  }
4796  }
4797  if (is_safe) return;
4798  }
4799  }
4800 
4801  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4802 
4803  /* Skip remainder of GRF */
4804  _cur.skip_sprites = -1;
4805 }
4806 
4807 /* Action 0x00 (GLS_RESERVE) */
4808 static void ReserveChangeInfo(ByteReader *buf)
4809 {
4810  uint8 feature = buf->ReadByte();
4811 
4812  if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES) return;
4813 
4814  uint8 numprops = buf->ReadByte();
4815  uint8 numinfo = buf->ReadByte();
4816  uint8 index = buf->ReadExtendedByte();
4817 
4818  while (numprops-- && buf->HasData()) {
4819  uint8 prop = buf->ReadByte();
4821 
4822  switch (feature) {
4823  default: NOT_REACHED();
4824  case GSF_CARGOES:
4825  cir = CargoChangeInfo(index, numinfo, prop, buf);
4826  break;
4827 
4828  case GSF_GLOBALVAR:
4829  cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4830  break;
4831 
4832  case GSF_RAILTYPES:
4833  cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4834  break;
4835 
4836  case GSF_ROADTYPES:
4837  cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4838  break;
4839 
4840  case GSF_TRAMTYPES:
4841  cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4842  break;
4843  }
4844 
4845  if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4846  }
4847 }
4848 
4849 /* Action 0x01 */
4850 static void NewSpriteSet(ByteReader *buf)
4851 {
4852  /* Basic format: <01> <feature> <num-sets> <num-ent>
4853  * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4854  *
4855  * B feature feature to define sprites for
4856  * 0, 1, 2, 3: veh-type, 4: train stations
4857  * E first-set first sprite set to define
4858  * B num-sets number of sprite sets (extended byte in extended format)
4859  * E num-ent how many entries per sprite set
4860  * For vehicles, this is the number of different
4861  * vehicle directions in each sprite set
4862  * Set num-dirs=8, unless your sprites are symmetric.
4863  * In that case, use num-dirs=4.
4864  */
4865 
4866  uint8 feature = buf->ReadByte();
4867  uint16 num_sets = buf->ReadByte();
4868  uint16 first_set = 0;
4869 
4870  if (num_sets == 0 && buf->HasData(3)) {
4871  /* Extended Action1 format.
4872  * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4873  first_set = buf->ReadExtendedByte();
4874  num_sets = buf->ReadExtendedByte();
4875  }
4876  uint16 num_ents = buf->ReadExtendedByte();
4877 
4878  if (feature >= GSF_END) {
4879  _cur.skip_sprites = num_sets * num_ents;
4880  grfmsg(1, "NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.skip_sprites);
4881  return;
4882  }
4883 
4884  _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4885 
4886  grfmsg(7, "New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4887  _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4888  );
4889 
4890  for (int i = 0; i < num_sets * num_ents; i++) {
4891  _cur.nfo_line++;
4892  LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4893  }
4894 }
4895 
4896 /* Action 0x01 (SKIP) */
4897 static void SkipAct1(ByteReader *buf)
4898 {
4899  buf->ReadByte();
4900  uint16 num_sets = buf->ReadByte();
4901 
4902  if (num_sets == 0 && buf->HasData(3)) {
4903  /* Extended Action1 format.
4904  * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4905  buf->ReadExtendedByte(); // first_set
4906  num_sets = buf->ReadExtendedByte();
4907  }
4908  uint16 num_ents = buf->ReadExtendedByte();
4909 
4910  _cur.skip_sprites = num_sets * num_ents;
4911 
4912  grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4913 }
4914 
4915 /* Helper function to either create a callback or link to a previously
4916  * defined spritegroup. */
4917 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4918 {
4919  if (HasBit(groupid, 15)) {
4921  return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4922  }
4923 
4924  if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
4925  grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4926  return nullptr;
4927  }
4928 
4929  return _cur.spritegroups[groupid];
4930 }
4931 
4940 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4941 {
4942  if (HasBit(spriteid, 15)) {
4944  return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4945  }
4946 
4947  if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4948  grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4949  return nullptr;
4950  }
4951 
4952  SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4953  uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4954 
4955  /* Ensure that the sprites are loeded */
4956  assert(spriteset_start + num_sprites <= _cur.spriteid);
4957 
4959  return new ResultSpriteGroup(spriteset_start, num_sprites);
4960 }
4961 
4962 /* Action 0x02 */
4963 static void NewSpriteGroup(ByteReader *buf)
4964 {
4965  /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4966  *
4967  * B feature see action 1
4968  * B set-id ID of this particular definition
4969  * B type/num-entries
4970  * if 80 or greater, this is a randomized or variational
4971  * list definition, see below
4972  * otherwise it specifies a number of entries, the exact
4973  * meaning depends on the feature
4974  * V feature-specific-data (huge mess, don't even look it up --pasky) */
4975  SpriteGroup *act_group = nullptr;
4976 
4977  uint8 feature = buf->ReadByte();
4978  if (feature >= GSF_END) {
4979  grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
4980  return;
4981  }
4982 
4983  uint8 setid = buf->ReadByte();
4984  uint8 type = buf->ReadByte();
4985 
4986  /* Sprite Groups are created here but they are allocated from a pool, so
4987  * we do not need to delete anything if there is an exception from the
4988  * ByteReader. */
4989 
4990  switch (type) {
4991  /* Deterministic Sprite Group */
4992  case 0x81: // Self scope, byte
4993  case 0x82: // Parent scope, byte
4994  case 0x85: // Self scope, word
4995  case 0x86: // Parent scope, word
4996  case 0x89: // Self scope, dword
4997  case 0x8A: // Parent scope, dword
4998  {
4999  byte varadjust;
5000  byte varsize;
5001 
5004  group->nfo_line = _cur.nfo_line;
5005  act_group = group;
5006  group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
5007 
5008  switch (GB(type, 2, 2)) {
5009  default: NOT_REACHED();
5010  case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
5011  case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
5012  case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
5013  }
5014 
5015  static std::vector<DeterministicSpriteGroupAdjust> adjusts;
5016  adjusts.clear();
5017 
5018  /* Loop through the var adjusts. Unfortunately we don't know how many we have
5019  * from the outset, so we shall have to keep reallocing. */
5020  do {
5021  DeterministicSpriteGroupAdjust &adjust = adjusts.emplace_back();
5022 
5023  /* The first var adjust doesn't have an operation specified, so we set it to add. */
5024  adjust.operation = adjusts.size() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
5025  adjust.variable = buf->ReadByte();
5026  if (adjust.variable == 0x7E) {
5027  /* Link subroutine group */
5028  adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5029  } else {
5030  adjust.parameter = IsInsideMM(adjust.variable, 0x60, 0x80) ? buf->ReadByte() : 0;
5031  }
5032 
5033  varadjust = buf->ReadByte();
5034  adjust.shift_num = GB(varadjust, 0, 5);
5035  adjust.type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
5036  adjust.and_mask = buf->ReadVarSize(varsize);
5037 
5038  if (adjust.type != DSGA_TYPE_NONE) {
5039  adjust.add_val = buf->ReadVarSize(varsize);
5040  adjust.divmod_val = buf->ReadVarSize(varsize);
5041  } else {
5042  adjust.add_val = 0;
5043  adjust.divmod_val = 0;
5044  }
5045 
5046  /* Continue reading var adjusts while bit 5 is set. */
5047  } while (HasBit(varadjust, 5));
5048 
5049  group->num_adjusts = (uint)adjusts.size();
5050  group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
5051  MemCpyT(group->adjusts, adjusts.data(), group->num_adjusts);
5052 
5053  std::vector<DeterministicSpriteGroupRange> ranges;
5054  ranges.resize(buf->ReadByte());
5055  for (uint i = 0; i < ranges.size(); i++) {
5056  ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5057  ranges[i].low = buf->ReadVarSize(varsize);
5058  ranges[i].high = buf->ReadVarSize(varsize);
5059  }
5060 
5061  group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5062  group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5063  /* nvar == 0 is a special case -- we turn our value into a callback result */
5064  group->calculated_result = ranges.size() == 0;
5065 
5066  /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
5067  std::vector<uint32> bounds;
5068  for (uint i = 0; i < ranges.size(); i++) {
5069  bounds.push_back(ranges[i].low);
5070  if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5071  }
5072  std::sort(bounds.begin(), bounds.end());
5073  bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5074 
5075  std::vector<const SpriteGroup *> target;
5076  for (uint j = 0; j < bounds.size(); ++j) {
5077  uint32 v = bounds[j];
5078  const SpriteGroup *t = group->default_group;
5079  for (uint i = 0; i < ranges.size(); i++) {
5080  if (ranges[i].low <= v && v <= ranges[i].high) {
5081  t = ranges[i].group;
5082  break;
5083  }
5084  }
5085  target.push_back(t);
5086  }
5087  assert(target.size() == bounds.size());
5088 
5089  std::vector<DeterministicSpriteGroupRange> optimised;
5090  for (uint j = 0; j < bounds.size(); ) {
5091  if (target[j] != group->default_group) {
5093  r.group = target[j];
5094  r.low = bounds[j];
5095  while (j < bounds.size() && target[j] == r.group) {
5096  j++;
5097  }
5098  r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5099  optimised.push_back(r);
5100  } else {
5101  j++;
5102  }
5103  }
5104 
5105  group->num_ranges = (uint)optimised.size(); // cast is safe, there should never be 2**31 elements here
5106  if (group->num_ranges > 0) {
5107  group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
5108  MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
5109  }
5110  break;
5111  }
5112 
5113  /* Randomized Sprite Group */
5114  case 0x80: // Self scope
5115  case 0x83: // Parent scope
5116  case 0x84: // Relative scope
5117  {
5120  group->nfo_line = _cur.nfo_line;
5121  act_group = group;
5122  group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
5123 
5124  if (HasBit(type, 2)) {
5125  if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
5126  group->count = buf->ReadByte();
5127  }
5128 
5129  uint8 triggers = buf->ReadByte();
5130  group->triggers = GB(triggers, 0, 7);
5131  group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5132  group->lowest_randbit = buf->ReadByte();
5133  group->num_groups = buf->ReadByte();
5134  group->groups = CallocT<const SpriteGroup*>(group->num_groups);
5135 
5136  for (uint i = 0; i < group->num_groups; i++) {
5137  group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
5138  }
5139 
5140  break;
5141  }
5142 
5143  /* Neither a variable or randomized sprite group... must be a real group */
5144  default:
5145  {
5146  switch (feature) {
5147  case GSF_TRAINS:
5148  case GSF_ROADVEHICLES:
5149  case GSF_SHIPS:
5150  case GSF_AIRCRAFT:
5151  case GSF_STATIONS:
5152  case GSF_CANALS:
5153  case GSF_CARGOES:
5154  case GSF_AIRPORTS:
5155  case GSF_RAILTYPES:
5156  case GSF_ROADTYPES:
5157  case GSF_TRAMTYPES:
5158  {
5159  byte num_loaded = type;
5160  byte num_loading = buf->ReadByte();
5161 
5162  if (!_cur.HasValidSpriteSets(feature)) {
5163  grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
5164  return;
5165  }
5166 
5168  RealSpriteGroup *group = new RealSpriteGroup();
5169  group->nfo_line = _cur.nfo_line;
5170  act_group = group;
5171 
5172  group->num_loaded = num_loaded;
5173  group->num_loading = num_loading;
5174  if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
5175  if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
5176 
5177  grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5178  setid, num_loaded, num_loading);
5179 
5180  for (uint i = 0; i < num_loaded; i++) {
5181  uint16 spriteid = buf->ReadWord();
5182  group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5183  grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
5184  }
5185 
5186  for (uint i = 0; i < num_loading; i++) {
5187  uint16 spriteid = buf->ReadWord();
5188  group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5189  grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
5190  }
5191 
5192  break;
5193  }
5194 
5195  case GSF_HOUSES:
5196  case GSF_AIRPORTTILES:
5197  case GSF_OBJECTS:
5198  case GSF_INDUSTRYTILES: {
5199  byte num_building_sprites = std::max((uint8)1, type);
5200 
5203  group->nfo_line = _cur.nfo_line;
5204  act_group = group;
5205 
5206  /* On error, bail out immediately. Temporary GRF data was already freed */
5207  if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
5208  break;
5209  }
5210 
5211  case GSF_INDUSTRIES: {
5212  if (type > 2) {
5213  grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5214  break;
5215  }
5216 
5219  group->nfo_line = _cur.nfo_line;
5220  act_group = group;
5221  group->version = type;
5222  if (type == 0) {
5223  group->num_input = 3;
5224  for (uint i = 0; i < 3; i++) {
5225  group->subtract_input[i] = (int16)buf->ReadWord(); // signed
5226  }
5227  group->num_output = 2;
5228  for (uint i = 0; i < 2; i++) {
5229  group->add_output[i] = buf->ReadWord(); // unsigned
5230  }
5231  group->again = buf->ReadByte();
5232  } else if (type == 1) {
5233  group->num_input = 3;
5234  for (uint i = 0; i < 3; i++) {
5235  group->subtract_input[i] = buf->ReadByte();
5236  }
5237  group->num_output = 2;
5238  for (uint i = 0; i < 2; i++) {
5239  group->add_output[i] = buf->ReadByte();
5240  }
5241  group->again = buf->ReadByte();
5242  } else if (type == 2) {
5243  group->num_input = buf->ReadByte();
5244  if (group->num_input > lengthof(group->subtract_input)) {
5245  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5246  error->data = "too many inputs (max 16)";
5247  return;
5248  }
5249  for (uint i = 0; i < group->num_input; i++) {
5250  byte rawcargo = buf->ReadByte();
5251  CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
5252  if (cargo == CT_INVALID) {
5253  /* The mapped cargo is invalid. This is permitted at this point,
5254  * as long as the result is not used. Mark it invalid so this
5255  * can be tested later. */
5256  group->version = 0xFF;
5257  } else if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) {
5258  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5259  error->data = "duplicate input cargo";
5260  return;
5261  }
5262  group->cargo_input[i] = cargo;
5263  group->subtract_input[i] = buf->ReadByte();
5264  }
5265  group->num_output = buf->ReadByte();
5266  if (group->num_output > lengthof(group->add_output)) {
5267  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5268  error->data = "too many outputs (max 16)";
5269  return;
5270  }
5271  for (uint i = 0; i < group->num_output; i++) {
5272  byte rawcargo = buf->ReadByte();
5273  CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
5274  if (cargo == CT_INVALID) {
5275  /* Mark this result as invalid to use */
5276  group->version = 0xFF;
5277  } else if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) {
5278  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5279  error->data = "duplicate output cargo";
5280  return;
5281  }
5282  group->cargo_output[i] = cargo;
5283  group->add_output[i] = buf->ReadByte();
5284  }
5285  group->again = buf->ReadByte();
5286  } else {
5287  NOT_REACHED();
5288  }
5289  break;
5290  }
5291 
5292  /* Loading of Tile Layout and Production Callback groups would happen here */
5293  default: grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5294  }
5295  }
5296  }
5297 
5298  _cur.spritegroups[setid] = act_group;
5299 }
5300 
5301 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5302 {
5303  if (feature == GSF_OBJECTS) {
5304  switch (ctype) {
5305  case 0: return 0;
5306  case 0xFF: return CT_PURCHASE_OBJECT;
5307  default:
5308  grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5309  return CT_INVALID;
5310  }
5311  }
5312  /* Special cargo types for purchase list and stations */
5313  if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
5314  if (ctype == 0xFF) return CT_PURCHASE;
5315 
5316  if (_cur.grffile->cargo_list.size() == 0) {
5317  /* No cargo table, so use bitnum values */
5318  if (ctype >= 32) {
5319  grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5320  return CT_INVALID;
5321  }
5322 
5323  const CargoSpec *cs;
5324  FOR_ALL_CARGOSPECS(cs) {
5325  if (cs->bitnum == ctype) {
5326  grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5327  return cs->Index();
5328  }
5329  }
5330 
5331  grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5332  return CT_INVALID;
5333  }
5334 
5335  /* Check if the cargo type is out of bounds of the cargo translation table */
5336  if (ctype >= _cur.grffile->cargo_list.size()) {
5337  grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (unsigned int)_cur.grffile->cargo_list.size() - 1);
5338  return CT_INVALID;
5339  }
5340 
5341  /* Look up the cargo label from the translation table */
5342  CargoLabel cl = _cur.grffile->cargo_list[ctype];
5343  if (cl == 0) {
5344  grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5345  return CT_INVALID;
5346  }
5347 
5348  ctype = GetCargoIDByLabel(cl);
5349  if (ctype == CT_INVALID) {
5350  grfmsg(5, "TranslateCargo: Cargo '%c%c%c%c' unsupported, skipping.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8));
5351  return CT_INVALID;
5352  }
5353 
5354  grfmsg(6, "TranslateCargo: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
5355  return ctype;
5356 }
5357 
5358 
5359 static bool IsValidGroupID(uint16 groupid, const char *function)
5360 {
5361  if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
5362  grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
5363  return false;
5364  }
5365 
5366  return true;
5367 }
5368 
5369 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
5370 {
5371  static EngineID *last_engines;
5372  static uint last_engines_count;
5373  bool wagover = false;
5374 
5375  /* Test for 'wagon override' flag */
5376  if (HasBit(idcount, 7)) {
5377  wagover = true;
5378  /* Strip off the flag */
5379  idcount = GB(idcount, 0, 7);
5380 
5381  if (last_engines_count == 0) {
5382  grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5383  return;
5384  }
5385 
5386  grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5387  last_engines_count, idcount);
5388  } else {
5389  if (last_engines_count != idcount) {
5390  last_engines = ReallocT(last_engines, idcount);
5391  last_engines_count = idcount;
5392  }
5393  }
5394 
5395  EngineID *engines = AllocaM(EngineID, idcount);
5396  for (uint i = 0; i < idcount; i++) {
5397  Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
5398  if (e == nullptr) {
5399  /* No engine could be allocated?!? Deal with it. Okay,
5400  * this might look bad. Also make sure this NewGRF
5401  * gets disabled, as a half loaded one is bad. */
5402  HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
5403  return;
5404  }
5405 
5406  engines[i] = e->index;
5407  if (!wagover) last_engines[i] = engines[i];
5408  }
5409 
5410  uint8 cidcount = buf->ReadByte();
5411  for (uint c = 0; c < cidcount; c++) {
5412  uint8 ctype = buf->ReadByte();
5413  uint16 groupid = buf->ReadWord();
5414  if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
5415 
5416  grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5417 
5418  ctype = TranslateCargo(feature, ctype);
5419  if (ctype == CT_INVALID) continue;
5420 
5421  for (uint i = 0; i < idcount; i++) {
5422  EngineID engine = engines[i];
5423 
5424  grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5425 
5426  if (wagover) {
5427  SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5428  } else {
5429  SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5430  }
5431  }
5432  }
5433 
5434  uint16 groupid = buf->ReadWord();
5435  if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5436 
5437  grfmsg(8, "-- Default group id 0x%04X", groupid);
5438 
5439  for (uint i = 0; i < idcount; i++) {
5440  EngineID engine = engines[i];
5441 
5442  if (wagover) {
5443  SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5444  } else {
5445  SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5446  SetEngineGRF(engine, _cur.grffile);
5447  }
5448  }
5449 }
5450 
5451 
5452 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5453 {
5454  CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5455  for (uint i = 0; i < idcount; i++) {
5456  cfs[i] = (CanalFeature)buf->ReadByte();
5457  }
5458 
5459  uint8 cidcount = buf->ReadByte();
5460  buf->Skip(cidcount * 3);
5461 
5462  uint16 groupid = buf->ReadWord();
5463  if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5464 
5465  for (uint i = 0; i < idcount; i++) {
5466  CanalFeature cf = cfs[i];
5467 
5468  if (cf >= CF_END) {
5469  grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5470  continue;
5471  }
5472 
5473  _water_feature[cf].grffile = _cur.grffile;
5474  _water_feature[cf].group = _cur.spritegroups[groupid];
5475  }
5476 }
5477 
5478 
5479 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5480 {
5481  uint8 *stations = AllocaM(uint8, idcount);
5482  for (uint i = 0; i < idcount; i++) {
5483  stations[i] = buf->ReadByte();
5484  }
5485 
5486  uint8 cidcount = buf->ReadByte();
5487  for (uint c = 0; c < cidcount; c++) {
5488  uint8 ctype = buf->ReadByte();
5489  uint16 groupid = buf->ReadWord();
5490  if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5491 
5492  ctype = TranslateCargo(GSF_STATIONS, ctype);
5493  if (ctype == CT_INVALID) continue;
5494 
5495  for (uint i = 0; i < idcount; i++) {
5496  StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5497 
5498  if (statspec == nullptr) {
5499  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5500  continue;
5501  }
5502 
5503  statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5504  }
5505  }
5506 
5507  uint16 groupid = buf->ReadWord();
5508  if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5509 
5510  for (uint i = 0; i < idcount; i++) {
5511  StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5512 
5513  if (statspec == nullptr) {
5514  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5515  continue;
5516  }
5517 
5518  if (statspec->grf_prop.grffile != nullptr) {
5519  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5520  continue;
5521  }
5522 
5523  statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5524  statspec->grf_prop.grffile = _cur.grffile;
5525  statspec->grf_prop.local_id = stations[i];
5526  StationClass::Assign(statspec);
5527  }
5528 }
5529 
5530 
5531 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5532 {
5533  uint8 *houses = AllocaM(uint8, idcount);
5534  for (uint i = 0; i < idcount; i++) {
5535  houses[i] = buf->ReadByte();
5536  }
5537 
5538  /* Skip the cargo type section, we only care about the default group */
5539  uint8 cidcount = buf->ReadByte();
5540  buf->Skip(cidcount * 3);
5541 
5542  uint16 groupid = buf->ReadWord();
5543  if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5544 
5545  if (_cur.grffile->housespec == nullptr) {
5546  grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5547  return;
5548  }
5549 
5550  for (uint i = 0; i < idcount; i++) {
5551  HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5552 
5553  if (hs == nullptr) {
5554  grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5555  continue;
5556  }
5557 
5558  hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5559  }
5560 }
5561 
5562 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5563 {
5564  uint8 *industries = AllocaM(uint8, idcount);
5565  for (uint i = 0; i < idcount; i++) {
5566  industries[i] = buf->ReadByte();
5567  }
5568 
5569  /* Skip the cargo type section, we only care about the default group */
5570  uint8 cidcount = buf->ReadByte();
5571  buf->Skip(cidcount * 3);
5572 
5573  uint16 groupid = buf->ReadWord();
5574  if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5575 
5576  if (_cur.grffile->industryspec == nullptr) {
5577  grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5578  return;
5579  }
5580 
5581  for (uint i = 0; i < idcount; i++) {
5582  IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5583 
5584  if (indsp == nullptr) {
5585  grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5586  continue;
5587  }
5588 
5589  indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5590  }
5591 }
5592 
5593 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5594 {
5595  uint8 *indtiles = AllocaM(uint8, idcount);
5596  for (uint i = 0; i < idcount; i++) {
5597  indtiles[i] = buf->ReadByte();
5598  }
5599 
5600  /* Skip the cargo type section, we only care about the default group */
5601  uint8 cidcount = buf->ReadByte();
5602  buf->Skip(cidcount * 3);
5603 
5604  uint16 groupid = buf->ReadWord();
5605  if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5606 
5607  if (_cur.grffile->indtspec == nullptr) {
5608  grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5609  return;
5610  }
5611 
5612  for (uint i = 0; i < idcount; i++) {
5613  IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5614 
5615  if (indtsp == nullptr) {
5616  grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5617  continue;
5618  }
5619 
5620  indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5621  }
5622 }
5623 
5624 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5625 {
5626  CargoID *cargoes = AllocaM(CargoID, idcount);
5627  for (uint i = 0; i < idcount; i++) {
5628  cargoes[i] = buf->ReadByte();
5629  }
5630 
5631  /* Skip the cargo type section, we only care about the default group */
5632  uint8 cidcount = buf->ReadByte();
5633  buf->Skip(cidcount * 3);
5634 
5635  uint16 groupid = buf->ReadWord();
5636  if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5637 
5638  for (uint i = 0; i < idcount; i++) {
5639  CargoID cid = cargoes[i];
5640 
5641  if (cid >= NUM_CARGO) {
5642  grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5643  continue;
5644  }
5645 
5646  CargoSpec *cs = CargoSpec::Get(cid);
5647  cs->grffile = _cur.grffile;
5648  cs->group = _cur.spritegroups[groupid];
5649  }
5650 }
5651 
5652 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5653 {
5654  if (_cur.grffile->objectspec == nullptr) {
5655  grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5656  return;
5657  }
5658 
5659  uint8 *objects = AllocaM(uint8, idcount);
5660  for (uint i = 0; i < idcount; i++) {
5661  objects[i] = buf->ReadByte();
5662  }
5663 
5664  uint8 cidcount = buf->ReadByte();
5665  for (uint c = 0; c < cidcount; c++) {
5666  uint8 ctype = buf->ReadByte();
5667  uint16 groupid = buf->ReadWord();
5668  if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5669 
5670  ctype = TranslateCargo(GSF_OBJECTS, ctype);
5671  if (ctype == CT_INVALID) continue;
5672 
5673  for (uint i = 0; i < idcount; i++) {
5674  ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5675 
5676  if (spec == nullptr) {
5677  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5678  continue;
5679  }
5680 
5681  spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5682  }
5683  }
5684 
5685  uint16 groupid = buf->ReadWord();
5686  if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5687 
5688  for (uint i = 0; i < idcount; i++) {
5689  ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5690 
5691  if (spec == nullptr) {
5692  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5693  continue;
5694  }
5695 
5696  if (spec->grf_prop.grffile != nullptr) {
5697  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5698  continue;
5699  }
5700 
5701  spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5702  spec->grf_prop.grffile = _cur.grffile;
5703  spec->grf_prop.local_id = objects[i];
5704  }
5705 }
5706 
5707 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5708 {
5709  uint8 *railtypes = AllocaM(uint8, idcount);
5710  for (uint i = 0; i < idcount; i++) {
5711  uint8 id = buf->ReadByte();
5712  railtypes[i] = id < RAILTYPE_END ? _cur.grffile->railtype_map[id] : INVALID_RAILTYPE;
5713  }
5714 
5715  uint8 cidcount = buf->ReadByte();
5716  for (uint c = 0; c < cidcount; c++) {
5717  uint8 ctype = buf->ReadByte();
5718  uint16 groupid = buf->ReadWord();
5719  if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5720 
5721  if (ctype >= RTSG_END) continue;
5722 
5723  extern RailtypeInfo _railtypes[RAILTYPE_END];
5724  for (uint i = 0; i < idcount; i++) {
5725  if (railtypes[i] != INVALID_RAILTYPE) {
5726  RailtypeInfo *rti = &_railtypes[railtypes[i]];
5727 
5728  rti->grffile[ctype] = _cur.grffile;
5729  rti->group[ctype] = _cur.spritegroups[groupid];
5730  }
5731  }
5732  }
5733 
5734  /* Railtypes do not use the default group. */
5735  buf->ReadWord();
5736 }
5737 
5738 static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadTramType rtt)
5739 {
5740  RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
5741 
5742  uint8 *roadtypes = AllocaM(uint8, idcount);
5743  for (uint i = 0; i < idcount; i++) {
5744  uint8 id = buf->ReadByte();
5745  roadtypes[i] = id < ROADTYPE_END ? type_map[id] : INVALID_ROADTYPE;
5746  }
5747 
5748  uint8 cidcount = buf->ReadByte();
5749  for (uint c = 0; c < cidcount; c++) {
5750  uint8 ctype = buf->ReadByte();
5751  uint16 groupid = buf->ReadWord();
5752  if (!IsValidGroupID(groupid, "RoadTypeMapSpriteGroup")) continue;
5753 
5754  if (ctype >= ROTSG_END) continue;
5755 
5756  extern RoadTypeInfo _roadtypes[ROADTYPE_END];
5757  for (uint i = 0; i < idcount; i++) {
5758  if (roadtypes[i] != INVALID_ROADTYPE) {
5759  RoadTypeInfo *rti = &_roadtypes[roadtypes[i]];
5760 
5761  rti->grffile[ctype] = _cur.grffile;
5762  rti->group[ctype] = _cur.spritegroups[groupid];
5763  }
5764  }
5765  }
5766 
5767  /* Roadtypes do not use the default group. */
5768  buf->ReadWord();
5769 }
5770 
5771 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5772 {
5773  uint8 *airports = AllocaM(uint8, idcount);
5774  for (uint i = 0; i < idcount; i++) {
5775  airports[i] = buf->ReadByte();
5776  }
5777 
5778  /* Skip the cargo type section, we only care about the default group */
5779  uint8 cidcount = buf->ReadByte();
5780  buf->Skip(cidcount * 3);
5781 
5782  uint16 groupid = buf->ReadWord();
5783  if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5784 
5785  if (_cur.grffile->airportspec == nullptr) {
5786  grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5787  return;
5788  }
5789 
5790  for (uint i = 0; i < idcount; i++) {
5791  AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5792 
5793  if (as == nullptr) {
5794  grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5795  continue;
5796  }
5797 
5798  as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5799  }
5800 }
5801 
5802 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5803 {
5804  uint8 *airptiles = AllocaM(uint8, idcount);
5805  for (uint i = 0; i < idcount; i++) {
5806  airptiles[i] = buf->ReadByte();
5807  }
5808 
5809  /* Skip the cargo type section, we only care about the default group */
5810  uint8 cidcount = buf->ReadByte();
5811  buf->Skip(cidcount * 3);
5812 
5813  uint16 groupid = buf->ReadWord();
5814  if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5815 
5816  if (_cur.grffile->airtspec == nullptr) {
5817  grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5818  return;
5819  }
5820 
5821  for (uint i = 0; i < idcount; i++) {
5822  AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5823 
5824  if (airtsp == nullptr) {
5825  grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5826  continue;
5827  }
5828 
5829  airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5830  }
5831 }
5832 
5833 
5834 /* Action 0x03 */
5835 static void FeatureMapSpriteGroup(ByteReader *buf)
5836 {
5837  /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5838  * id-list := [<id>] [id-list]
5839  * cargo-list := <cargo-type> <cid> [cargo-list]
5840  *
5841  * B feature see action 0
5842  * B n-id bits 0-6: how many IDs this definition applies to
5843  * bit 7: if set, this is a wagon override definition (see below)
5844  * B ids the IDs for which this definition applies
5845  * B num-cid number of cargo IDs (sprite group IDs) in this definition
5846  * can be zero, in that case the def-cid is used always
5847  * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5848  * W cid cargo ID (sprite group ID) for this type of cargo
5849  * W def-cid default cargo ID (sprite group ID) */
5850 
5851  uint8 feature = buf->ReadByte();
5852  uint8 idcount = buf->ReadByte();
5853 
5854  if (feature >= GSF_END) {
5855  grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5856  return;
5857  }
5858 
5859  /* If idcount is zero, this is a feature callback */
5860  if (idcount == 0) {
5861  /* Skip number of cargo ids? */
5862  buf->ReadByte();
5863  uint16 groupid = buf->ReadWord();
5864  if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5865 
5866  grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5867 
5868  AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5869  return;
5870  }
5871 
5872  /* Mark the feature as used by the grf (generic callbacks do not count) */
5873  SetBit(_cur.grffile->grf_features, feature);
5874 
5875  grfmsg(6, "FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5876 
5877  switch (feature) {
5878  case GSF_TRAINS:
5879  case GSF_ROADVEHICLES:
5880  case GSF_SHIPS:
5881  case GSF_AIRCRAFT:
5882  VehicleMapSpriteGroup(buf, feature, idcount);
5883  return;
5884 
5885  case GSF_CANALS:
5886  CanalMapSpriteGroup(buf, idcount);
5887  return;
5888 
5889  case GSF_STATIONS:
5890  StationMapSpriteGroup(buf, idcount);
5891  return;
5892 
5893  case GSF_HOUSES:
5894  TownHouseMapSpriteGroup(buf, idcount);
5895  return;
5896 
5897  case GSF_INDUSTRIES:
5898  IndustryMapSpriteGroup(buf, idcount);
5899  return;
5900 
5901  case GSF_INDUSTRYTILES:
5902  IndustrytileMapSpriteGroup(buf, idcount);
5903  return;
5904 
5905  case GSF_CARGOES:
5906  CargoMapSpriteGroup(buf, idcount);
5907  return;
5908 
5909  case GSF_AIRPORTS:
5910  AirportMapSpriteGroup(buf, idcount);
5911  return;
5912 
5913  case GSF_OBJECTS:
5914  ObjectMapSpriteGroup(buf, idcount);
5915  break;
5916 
5917  case GSF_RAILTYPES:
5918  RailTypeMapSpriteGroup(buf, idcount);
5919  break;
5920 
5921  case GSF_ROADTYPES:
5922  RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5923  break;
5924 
5925  case GSF_TRAMTYPES:
5926  RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5927  break;
5928 
5929  case GSF_AIRPORTTILES:
5930  AirportTileMapSpriteGroup(buf, idcount);
5931  return;
5932 
5933  default:
5934  grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5935  return;
5936  }
5937 }
5938 
5939 /* Action 0x04 */
5940 static void FeatureNewName(ByteReader *buf)
5941 {
5942  /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5943  *
5944  * B veh-type see action 0 (as 00..07, + 0A
5945  * But IF veh-type = 48, then generic text
5946  * B language-id If bit 6 is set, This is the extended language scheme,
5947  * with up to 64 language.
5948  * Otherwise, it is a mapping where set bits have meaning
5949  * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5950  * Bit 7 set means this is a generic text, not a vehicle one (or else)
5951  * B num-veh number of vehicles which are getting a new name
5952  * B/W offset number of the first vehicle that gets a new name
5953  * Byte : ID of vehicle to change
5954  * Word : ID of string to change/add
5955  * S data new texts, each of them zero-terminated, after
5956  * which the next name begins. */
5957 
5958  bool new_scheme = _cur.grffile->grf_version >= 7;
5959 
5960  uint8 feature = buf->ReadByte();
5961  if (feature >= GSF_END && feature != 0x48) {
5962  grfmsg(1, "FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
5963  return;
5964  }
5965 
5966  uint8 lang = buf->ReadByte();
5967  uint8 num = buf->ReadByte();
5968  bool generic = HasBit(lang, 7);
5969  uint16 id;
5970  if (generic) {
5971  id = buf->ReadWord();
5972  } else if (feature <= GSF_AIRCRAFT) {
5973  id = buf->ReadExtendedByte();
5974  } else {
5975  id = buf->ReadByte();
5976  }
5977 
5978  ClrBit(lang, 7);
5979 
5980  uint16 endid = id + num;
5981 
5982  grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
5983  id, endid, feature, lang);
5984 
5985  for (; id < endid && buf->HasData(); id++) {
5986  const char *name = buf->ReadString();
5987  grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5988 
5989  switch (feature) {
5990  case GSF_TRAINS:
5991  case GSF_ROADVEHICLES:
5992  case GSF_SHIPS:
5993  case GSF_AIRCRAFT:
5994  if (!generic) {
5995  Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5996  if (e == nullptr) break;
5997  StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5998  e->info.string_id = string;
5999  } else {
6000  AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
6001  }
6002  break;
6003 
6004  default:
6005  if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
6006  AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
6007  break;
6008  }
6009 
6010  switch (GB(id, 8, 8)) {
6011  case 0xC4: // Station class name
6012  if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
6013  grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
6014  } else {
6015  StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
6016  StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6017  }
6018  break;
6019 
6020  case 0xC5: // Station name
6021  if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
6022  grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
6023  } else {
6024  _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6025  }
6026  break;
6027 
6028  case 0xC7: // Airporttile name
6029  if (_cur.grffile->airtspec == nullptr || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) {
6030  grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
6031  } else {
6032  _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6033  }
6034  break;
6035 
6036  case 0xC9: // House name
6037  if (_cur.grffile->housespec == nullptr || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) {
6038  grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
6039  } else {
6040  _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6041  }
6042  break;
6043 
6044  default:
6045  grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
6046  break;
6047  }
6048  break;
6049  }
6050  }
6051 }
6052 
6061 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
6062 {
6063 
6064  if (offset >= max_sprites) {
6065  grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6066  uint orig_num = num;
6067  num = 0;
6068  return orig_num;
6069  }
6070 
6071  if (offset + num > max_sprites) {
6072  grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
6073  uint orig_num = num;
6074  num = std::max(max_sprites - offset, 0);
6075  return orig_num - num;
6076  }
6077 
6078  return 0;
6079 }
6080 
6081 
6087 };
6089 struct Action5Type {
6092  uint16 min_sprites;
6093  uint16 max_sprites;
6094  const char *name;
6095 };
6096 
6098 static const Action5Type _action5_types[] = {
6099  /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
6100  /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
6101  /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
6102  /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
6103  /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
6104  /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
6105  /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
6106  /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
6107  /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
6108  /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
6109  /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
6110  /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
6111  /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
6112  /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
6113  /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
6114  /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
6115  /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
6116  /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
6117  /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
6118  /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
6119  /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
6120  /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
6121  /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
6122  /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
6123  /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
6124  /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
6125 };
6126 
6127 /* Action 0x05 */
6128 static void GraphicsNew(ByteReader *buf)
6129 {
6130  /* <05> <graphics-type> <num-sprites> <other data...>
6131  *
6132  * B graphics-type What set of graphics the sprites define.
6133  * E num-sprites How many sprites are in this set?
6134  * V other data Graphics type specific data. Currently unused. */
6135 
6136  uint8 type = buf->ReadByte();
6137  uint16 num = buf->ReadExtendedByte();
6138  uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6139  ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
6140 
6141  if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
6142  /* Special not-TTDP-compatible case used in openttd.grf
6143  * Missing shore sprites and initialisation of SPR_SHORE_BASE */
6144  grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6145  LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
6146  LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
6147  LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
6148  LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
6149  LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
6150  LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
6151  LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
6152  LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
6153  LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
6154  LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
6156  return;
6157  }
6158 
6159  /* Supported type? */
6160  if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
6161  grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6162  _cur.skip_sprites = num;
6163  return;
6164  }
6165 
6166  const Action5Type *action5_type = &_action5_types[type];
6167 
6168  /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
6169  * except for the long version of the shore type:
6170  * Ignore offset if not allowed */
6171  if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
6172  grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
6173  offset = 0;
6174  }
6175 
6176  /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
6177  * This does not make sense, if <offset> is allowed */
6178  if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
6179  grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
6180  _cur.skip_sprites = num;
6181  return;
6182  }
6183 
6184  /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extensions) */
6185  uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
6186  SpriteID replace = action5_type->sprite_base + offset;
6187 
6188  /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
6189  grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace);
6190 
6192 
6193  if (type == 0x0B) {
6194  static const SpriteID depot_with_track_offset = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_TRAMWAY_BASE;
6195  static const SpriteID depot_no_track_offset = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_TRAMWAY_BASE;
6196  if (offset <= depot_with_track_offset && offset + num > depot_with_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_WITH_TRACK;
6197  if (offset <= depot_no_track_offset && offset + num > depot_no_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NO_TRACK;
6198  }
6199 
6200  for (; num > 0; num--) {
6201  _cur.nfo_line++;
6202  LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
6203  }
6204 
6205  _cur.skip_sprites = skip_num;
6206 }
6207 
6208 /* Action 0x05 (SKIP) */
6209 static void SkipAct5(ByteReader *buf)
6210 {
6211  /* Ignore type byte */
6212  buf->ReadByte();
6213 
6214  /* Skip the sprites of this action */
6215  _cur.skip_sprites = buf->ReadExtendedByte();
6216 
6217  grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
6218 }
6219 
6231 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
6232 {
6233  switch (param) {
6234  case 0x00: // current date
6235  *value = std::max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
6236  return true;
6237 
6238  case 0x01: // current year
6240  return true;
6241 
6242  case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
6243  YearMonthDay ymd;
6244  ConvertDateToYMD(_date, &ymd);
6245  Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
6246  *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
6247  return true;
6248  }
6249 
6250  case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
6252  return true;
6253 
6254  case 0x06: // road traffic side, bit 4 clear=left, set=right
6255  *value = _settings_game.vehicle.road_side << 4;
6256  return true;
6257 
6258  case 0x09: // date fraction
6259  *value = _date_fract * 885;
6260  return true;
6261 
6262  case 0x0A: // animation counter
6263  *value = _tick_counter;
6264  return true;
6265 
6266  case 0x0B: { // TTDPatch version
6267  uint major = 2;
6268  uint minor = 6;
6269  uint revision = 1; // special case: 2.0.1 is 2.0.10
6270  uint build = 1382;
6271  *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6272  return true;
6273  }
6274 
6275  case 0x0D: // TTD Version, 00=DOS, 01=Windows
6276  *value = _cur.grfconfig->palette & GRFP_USE_MASK;
6277  return true;
6278 
6279  case 0x0E: // Y-offset for train sprites
6280  *value = _cur.grffile->traininfo_vehicle_pitch;
6281  return true;
6282 
6283  case 0x0F: // Rail track type cost factors
6284  *value = 0;
6285  SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
6287  /* skip elrail multiplier - disabled */
6288  SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
6289  } else {
6290  SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
6291  /* Skip monorail multiplier - no space in result */
6292  }
6293  SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
6294  return true;
6295 
6296  case 0x11: // current rail tool type
6297  *value = 0; // constant fake value to avoid desync
6298  return true;
6299 
6300  case 0x12: // Game mode
6301  *value = _game_mode;
6302  return true;
6303 
6304  /* case 0x13: // Tile refresh offset to left not implemented */
6305  /* case 0x14: // Tile refresh offset to right not implemented */
6306  /* case 0x15: // Tile refresh offset upwards not implemented */
6307  /* case 0x16: // Tile refresh offset downwards not implemented */
6308  /* case 0x17: // temperate snow line not implemented */
6309 
6310  case 0x1A: // Always -1
6311  *value = UINT_MAX;
6312  return true;
6313 
6314  case 0x1B: // Display options
6315  *value = 0x3F; // constant fake value to avoid desync
6316  return true;
6317 
6318  case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
6319  *value = 1;
6320  return true;
6321 
6322  case 0x1E: // Miscellaneous GRF features
6323  *value = _misc_grf_features;
6324 
6325  /* Add the local flags */
6326  assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
6327  if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
6328  return true;
6329 
6330  /* case 0x1F: // locale dependent settings not implemented to avoid desync */
6331 
6332  case 0x20: { // snow line height
6333  byte snowline = GetSnowLine();
6335  *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
6336  } else {
6337  /* No snow */
6338  *value = 0xFF;
6339  }
6340  return true;
6341  }
6342 
6343  case 0x21: // OpenTTD version
6344  *value = _openttd_newgrf_version;
6345  return true;
6346 
6347  case 0x22: // difficulty level
6348  *value = SP_CUSTOM;
6349  return true;
6350 
6351  case 0x23: // long format date
6352  *value = _date;
6353  return true;
6354 
6355  case 0x24: // long format year
6356  *value = _cur_year;
6357  return true;
6358 
6359  default: return false;
6360  }
6361 }
6362 
6363 static uint32 GetParamVal(byte param, uint32 *cond_val)
6364 {
6365  /* First handle variable common with VarAction2 */
6366  uint32 value;
6367  if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
6368 
6369  /* Non-common variable */
6370  switch (param) {
6371  case 0x84: { // GRF loading stage
6372  uint32 res = 0;
6373 
6374  if (_cur.stage > GLS_INIT) SetBit(res, 0);
6375  if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
6376  if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
6377  return res;
6378  }
6379 
6380  case 0x85: // TTDPatch flags, only for bit tests
6381  if (cond_val == nullptr) {
6382  /* Supported in Action 0x07 and 0x09, not 0x0D */
6383  return 0;
6384  } else {
6385  uint32 index = *cond_val / 0x20;
6386  uint32 param_val = index < lengthof(_ttdpatch_flags) ? _ttdpatch_flags[index] : 0;
6387  *cond_val %= 0x20;
6388  return param_val;
6389  }
6390 
6391  case 0x88: // GRF ID check
6392  return 0;
6393 
6394  /* case 0x99: Global ID offset not implemented */
6395 
6396  default:
6397  /* GRF Parameter */
6398  if (param < 0x80) return _cur.grffile->GetParam(param);
6399 
6400  /* In-game variable. */
6401  grfmsg(1, "Unsupported in-game variable 0x%02X", param);
6402  return UINT_MAX;
6403  }
6404 }
6405 
6406 /* Action 0x06 */
6407 static void CfgApply(ByteReader *buf)
6408 {
6409  /* <06> <param-num> <param-size> <offset> ... <FF>
6410  *
6411  * B param-num Number of parameter to substitute (First = "zero")
6412  * Ignored if that parameter was not specified in newgrf.cfg
6413  * B param-size How many bytes to replace. If larger than 4, the
6414  * bytes of the following parameter are used. In that
6415  * case, nothing is applied unless *all* parameters
6416  * were specified.
6417  * B offset Offset into data from beginning of next sprite
6418  * to place where parameter is to be stored. */
6419 
6420  /* Preload the next sprite */
6421  size_t pos = FioGetPos();
6422  uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
6423  uint8 type = FioReadByte();
6424  byte *preload_sprite = nullptr;
6425 
6426  /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
6427  if (type == 0xFF) {
6428  preload_sprite = MallocT<byte>(num);
6429  FioReadBlock(preload_sprite, num);
6430  }
6431 
6432  /* Reset the file position to the start of the next sprite */
6433  FioSeekTo(pos, SEEK_SET);
6434 
6435  if (type != 0xFF) {
6436  grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
6437  free(preload_sprite);
6438  return;
6439  }
6440 
6441  GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
6442  GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6443  if (it != _grf_line_to_action6_sprite_override.end()) {
6444  free(preload_sprite);
6445  preload_sprite = _grf_line_to_action6_sprite_override[location];
6446  } else {
6447  _grf_line_to_action6_sprite_override[location] = preload_sprite;
6448  }
6449 
6450  /* Now perform the Action 0x06 on our data. */
6451 
6452  for (;;) {
6453  uint i;
6454  uint param_num;
6455  uint param_size;
6456  uint offset;
6457  bool add_value;
6458 
6459  /* Read the parameter to apply. 0xFF indicates no more data to change. */
6460  param_num = buf->ReadByte();
6461  if (param_num == 0xFF) break;
6462 
6463  /* Get the size of the parameter to use. If the size covers multiple
6464  * double words, sequential parameter values are used. */
6465  param_size = buf->ReadByte();
6466 
6467  /* Bit 7 of param_size indicates we should add to the original value
6468  * instead of replacing it. */
6469  add_value = HasBit(param_size, 7);
6470  param_size = GB(param_size, 0, 7);
6471 
6472  /* Where to apply the data to within the pseudo sprite data. */
6473  offset = buf->ReadExtendedByte();
6474 
6475  /* If the parameter is a GRF parameter (not an internal variable) check
6476  * if it (and all further sequential parameters) has been defined. */
6477  if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6478  grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6479  break;
6480  }
6481 
6482  grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6483 
6484  bool carry = false;
6485  for (i = 0; i < param_size && offset + i < num; i++) {
6486  uint32 value = GetParamVal(param_num + i / 4, nullptr);
6487  /* Reset carry flag for each iteration of the variable (only really
6488  * matters if param_size is greater than 4) */
6489  if (i % 4 == 0) carry = false;
6490 
6491  if (add_value) {
6492  uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6493  preload_sprite[offset + i] = GB(new_value, 0, 8);
6494  /* Check if the addition overflowed */
6495  carry = new_value >= 256;
6496  } else {
6497  preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6498  }
6499  }
6500  }
6501 }
6502 
6513 {
6514  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6515  error->data = _cur.grfconfig->GetName();
6516 }
6517 
6518 /* Action 0x07
6519  * Action 0x09 */
6520 static void SkipIf(ByteReader *buf)
6521 {
6522  /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6523  *
6524  * B param-num
6525  * B param-size
6526  * B condition-type
6527  * V value
6528  * B num-sprites */
6529  uint32 cond_val = 0;
6530  uint32 mask = 0;
6531  bool result;
6532 
6533  uint8 param = buf->ReadByte();
6534  uint8 paramsize = buf->ReadByte();
6535  uint8 condtype = buf->ReadByte();
6536 
6537  if (condtype < 2) {
6538  /* Always 1 for bit tests, the given value should be ignored. */
6539  paramsize = 1;
6540  }
6541 
6542  switch (paramsize) {
6543  case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6544  case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6545  case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6546  case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6547  default: break;
6548  }
6549 
6550  if (param < 0x80 && _cur.grffile->param_end <= param) {
6551  grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6552  return;
6553  }
6554 
6555  grfmsg(7, "SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6556 
6557  /* condtypes that do not use 'param' are always valid.
6558  * condtypes that use 'param' are either not valid for param 0x88, or they are only valid for param 0x88.
6559  */
6560  if (condtype >= 0x0B) {
6561  /* Tests that ignore 'param' */
6562  switch (condtype) {
6563  case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6564  break;
6565  case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6566  break;
6567  case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6568  break;
6569  case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6570  break;
6571  case 0x0F: {
6572  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6573  result = rt == INVALID_ROADTYPE || !RoadTypeIsRoad(rt);
6574  break;
6575  }
6576  case 0x10: {
6577  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6578  result = rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt);
6579  break;
6580  }
6581  case 0x11: {
6582  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6583  result = rt == INVALID_ROADTYPE || !RoadTypeIsTram(rt);
6584  break;
6585  }
6586  case 0x12: {
6587  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6588  result = rt != INVALID_ROADTYPE && RoadTypeIsTram(rt);
6589  break;
6590  }
6591  default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6592  }
6593  } else if (param == 0x88) {
6594  /* GRF ID checks */
6595 
6596  GRFConfig *c = GetGRFConfig(cond_val, mask);
6597 
6598  if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6600  c = nullptr;
6601  }
6602 
6603  if (condtype != 10 && c == nullptr) {
6604  grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6605  return;
6606  }
6607 
6608  switch (condtype) {
6609  /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6610  case 0x06: // Is GRFID active?
6611  result = c->status == GCS_ACTIVATED;
6612  break;
6613 
6614  case 0x07: // Is GRFID non-active?
6615  result = c->status != GCS_ACTIVATED;
6616  break;
6617 
6618  case 0x08: // GRFID is not but will be active?
6619  result = c->status == GCS_INITIALISED;
6620  break;
6621 
6622  case 0x09: // GRFID is or will be active?
6623  result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6624  break;
6625 
6626  case 0x0A: // GRFID is not nor will be active
6627  /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6628  result = c == nullptr || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6629  break;
6630 
6631  default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6632  }
6633  } else {
6634  /* Tests that use 'param' and are not GRF ID checks. */
6635  uint32 param_val = GetParamVal(param, &cond_val); // cond_val is modified for param == 0x85
6636  switch (condtype) {
6637  case 0x00: result = !!(param_val & (1 << cond_val));
6638  break;
6639  case 0x01: result = !(param_val & (1 << cond_val));
6640  break;
6641  case 0x02: result = (param_val & mask) == cond_val;
6642  break;
6643  case 0x03: result = (param_val & mask) != cond_val;
6644  break;
6645  case 0x04: result = (param_val & mask) < cond_val;
6646  break;
6647  case 0x05: result = (param_val & mask) > cond_val;
6648  break;
6649  default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6650  }
6651  }
6652 
6653  if (!result) {
6654  grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6655  return;
6656  }
6657 
6658  uint8 numsprites = buf->ReadByte();
6659 
6660  /* numsprites can be a GOTO label if it has been defined in the GRF
6661  * file. The jump will always be the first matching label that follows
6662  * the current nfo_line. If no matching label is found, the first matching
6663  * label in the file is used. */
6664  GRFLabel *choice = nullptr;
6665  for (GRFLabel *label = _cur.grffile->label; label != nullptr; label = label->next) {
6666  if (label->label != numsprites) continue;
6667 
6668  /* Remember a goto before the current line */
6669  if (choice == nullptr) choice = label;
6670  /* If we find a label here, this is definitely good */
6671  if (label->nfo_line > _cur.nfo_line) {
6672  choice = label;
6673  break;
6674  }
6675  }
6676 
6677  if (choice != nullptr) {
6678  grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6679  FioSeekTo(choice->pos, SEEK_SET);
6680  _cur.nfo_line = choice->nfo_line;
6681  return;
6682  }
6683 
6684  grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6685  _cur.skip_sprites = numsprites;
6686  if (_cur.skip_sprites == 0) {
6687  /* Zero means there are no sprites to skip, so
6688  * we use -1 to indicate that all further
6689  * sprites should be skipped. */
6690  _cur.skip_sprites = -1;
6691 
6692  /* If an action 8 hasn't been encountered yet, disable the grf. */
6693  if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6694  DisableGrf();
6695  }
6696  }
6697 }
6698 
6699 
6700 /* Action 0x08 (GLS_FILESCAN) */
6701 static void ScanInfo(ByteReader *buf)
6702 {
6703  uint8 grf_version = buf->ReadByte();
6704  uint32 grfid = buf->ReadDWord();
6705  const char *name = buf->ReadString();
6706 
6707  _cur.grfconfig->ident.grfid = grfid;
6708 
6709  if (grf_version < 2 || grf_version > 8) {
6711  DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, name, BSWAP32(grfid), grf_version);
6712  }
6713 
6714  /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6715  if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6716 
6717  AddGRFTextToList(_cur.grfconfig->name, 0x7F, grfid, false, name);
6718 
6719  if (buf->HasData()) {
6720  const char *info = buf->ReadString();
6721  AddGRFTextToList(_cur.grfconfig->info, 0x7F, grfid, true, info);
6722  }
6723 
6724  /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6725  _cur.skip_sprites = -1;
6726 }
6727 
6728 /* Action 0x08 */
6729 static void GRFInfo(ByteReader *buf)
6730 {
6731  /* <08> <version> <grf-id> <name> <info>
6732  *
6733  * B version newgrf version, currently 06
6734  * 4*B grf-id globally unique ID of this .grf file
6735  * S name name of this .grf set
6736  * S info string describing the set, and e.g. author and copyright */
6737 
6738  uint8 version = buf->ReadByte();
6739  uint32 grfid = buf->ReadDWord();
6740  const char *name = buf->ReadString();
6741 
6742  if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6743  DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6744  return;
6745  }
6746 
6747  if (_cur.grffile->grfid != grfid) {
6748  DEBUG(grf, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur.grffile->grfid), BSWAP32(grfid));
6749  _cur.grffile->grfid = grfid;
6750  }
6751 
6752  _cur.grffile->grf_version = version;
6753  _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6754 
6755  /* Do swap the GRFID for displaying purposes since people expect that */
6756  DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
6757 }
6758 
6759 /* Action 0x0A */
6760 static void SpriteReplace(ByteReader *buf)
6761 {
6762  /* <0A> <num-sets> <set1> [<set2> ...]
6763  * <set>: <num-sprites> <first-sprite>
6764  *
6765  * B num-sets How many sets of sprites to replace.
6766  * Each set:
6767  * B num-sprites How many sprites are in this set
6768  * W first-sprite First sprite number to replace */
6769 
6770  uint8 num_sets = buf->ReadByte();
6771 
6772  for (uint i = 0; i < num_sets; i++) {
6773  uint8 num_sprites = buf->ReadByte();
6774  uint16 first_sprite = buf->ReadWord();
6775 
6776  grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6777  i, num_sprites, first_sprite
6778  );
6779 
6780  for (uint j = 0; j < num_sprites; j++) {
6781  int load_index = first_sprite + j;
6782  _cur.nfo_line++;
6783  LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6784 
6785  /* Shore sprites now located at different addresses.
6786  * So detect when the old ones get replaced. */
6787  if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6789  }
6790  }
6791  }
6792 }
6793 
6794 /* Action 0x0A (SKIP) */
6795 static void SkipActA(ByteReader *buf)
6796 {
6797  uint8 num_sets = buf->ReadByte();
6798 
6799  for (uint i = 0; i < num_sets; i++) {
6800  /* Skip the sprites this replaces */
6801  _cur.skip_sprites += buf->ReadByte();
6802  /* But ignore where they go */
6803  buf->ReadWord();
6804  }
6805 
6806  grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6807 }
6808 
6809 /* Action 0x0B */
6810 static void GRFLoadError(ByteReader *buf)
6811 {
6812  /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6813  *
6814  * B severity 00: notice, continue loading grf file
6815  * 01: warning, continue loading grf file
6816  * 02: error, but continue loading grf file, and attempt
6817  * loading grf again when loading or starting next game
6818  * 03: error, abort loading and prevent loading again in
6819  * the future (only when restarting the patch)
6820  * B language-id see action 4, use 1F for built-in error messages
6821  * B message-id message to show, see below
6822  * S message for custom messages (message-id FF), text of the message
6823  * not present for built-in messages.
6824  * V data additional data for built-in (or custom) messages
6825  * B parnum parameter numbers to be shown in the message (maximum of 2) */
6826 
6827  static const StringID msgstr[] = {
6828  STR_NEWGRF_ERROR_VERSION_NUMBER,
6829  STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6830  STR_NEWGRF_ERROR_UNSET_SWITCH,
6831  STR_NEWGRF_ERROR_INVALID_PARAMETER,
6832  STR_NEWGRF_ERROR_LOAD_BEFORE,
6833  STR_NEWGRF_ERROR_LOAD_AFTER,
6834  STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6835  };
6836 
6837  static const StringID sevstr[] = {
6838  STR_NEWGRF_ERROR_MSG_INFO,
6839  STR_NEWGRF_ERROR_MSG_WARNING,
6840  STR_NEWGRF_ERROR_MSG_ERROR,
6841  STR_NEWGRF_ERROR_MSG_FATAL
6842  };
6843 
6844  byte severity = buf->ReadByte();
6845  byte lang = buf->ReadByte();
6846  byte message_id = buf->ReadByte();
6847 
6848  /* Skip the error if it isn't valid for the current language. */
6849  if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6850 
6851  /* Skip the error until the activation stage unless bit 7 of the severity
6852  * is set. */
6853  if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6854  grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6855  return;
6856  }
6857  ClrBit(severity, 7);
6858 
6859  if (severity >= lengthof(sevstr)) {
6860  grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6861  severity = 2;
6862  } else if (severity == 3) {
6863  /* This is a fatal error, so make sure the GRF is deactivated and no
6864  * more of it gets loaded. */
6865  DisableGrf();
6866 
6867  /* Make sure we show fatal errors, instead of silly infos from before */
6868  delete _cur.grfconfig->error;
6869  _cur.grfconfig->error = nullptr;
6870  }
6871 
6872  if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6873  grfmsg(7, "GRFLoadError: Invalid message id.");
6874  return;
6875  }
6876 
6877  if (buf->Remaining() <= 1) {
6878  grfmsg(7, "GRFLoadError: No message data supplied.");
6879  return;
6880  }
6881 
6882  /* For now we can only show one message per newgrf file. */
6883  if (_cur.grfconfig->error != nullptr) return;
6884 
6885  GRFError *error = new GRFError(sevstr[severity]);
6886 
6887  if (message_id == 0xFF) {
6888  /* This is a custom error message. */
6889  if (buf->HasData()) {
6890  const char *message = buf->ReadString();
6891 
6892  error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER);
6893  } else {
6894  grfmsg(7, "GRFLoadError: No custom message supplied.");
6895  error->custom_message.clear();
6896  }
6897  } else {
6898  error->message = msgstr[message_id];
6899  }
6900 
6901  if (buf->HasData()) {
6902  const char *data = buf->ReadString();
6903 
6904  error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6905  } else {
6906  grfmsg(7, "GRFLoadError: No message data supplied.");
6907  error->data.clear();
6908  }
6909 
6910  /* Only two parameter numbers can be used in the string. */
6911  for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6912  uint param_number = buf->ReadByte();
6913  error->param_value[i] = _cur.grffile->GetParam(param_number);
6914  }
6915 
6916  _cur.grfconfig->error = error;
6917 }
6918 
6919 /* Action 0x0C */
6920 static void GRFComment(ByteReader *buf)
6921 {
6922  /* <0C> [<ignored...>]
6923  *
6924  * V ignored Anything following the 0C is ignored */
6925 
6926  if (!buf->HasData()) return;
6927 
6928  const char *text = buf->ReadString();
6929  grfmsg(2, "GRFComment: %s", text);
6930 }
6931 
6932 /* Action 0x0D (GLS_SAFETYSCAN) */
6933 static void SafeParamSet(ByteReader *buf)
6934 {
6935  uint8 target = buf->ReadByte();
6936 
6937  /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6938  if (target < 0x80 || target == 0x9E) return;
6939 
6940  /* GRM could be unsafe, but as here it can only happen after other GRFs
6941  * are loaded, it should be okay. If the GRF tried to use the slots it
6942  * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6943  * sprites is considered safe. */
6944 
6945  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6946 
6947  /* Skip remainder of GRF */
6948  _cur.skip_sprites = -1;
6949 }
6950 
6951 
6952 static uint32 GetPatchVariable(uint8 param)
6953 {
6954  switch (param) {
6955  /* start year - 1920 */
6957 
6958  /* freight trains weight factor */
6959  case 0x0E: return _settings_game.vehicle.freight_trains;
6960 
6961  /* empty wagon speed increase */
6962  case 0x0F: return 0;
6963 
6964  /* plane speed factor; our patch option is reversed from TTDPatch's,
6965  * the following is good for 1x, 2x and 4x (most common?) and...
6966  * well not really for 3x. */
6967  case 0x10:
6969  default:
6970  case 4: return 1;
6971  case 3: return 2;
6972  case 2: return 2;
6973  case 1: return 4;
6974  }
6975 
6976 
6977  /* 2CC colourmap base sprite */
6978  case 0x11: return SPR_2CCMAP_BASE;
6979 
6980  /* map size: format = -MABXYSS
6981  * M : the type of map
6982  * bit 0 : set : squared map. Bit 1 is now not relevant
6983  * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6984  * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6985  * clear : X is the bigger edge.
6986  * A : minimum edge(log2) of the map
6987  * B : maximum edge(log2) of the map
6988  * XY : edges(log2) of each side of the map.
6989  * SS : combination of both X and Y, thus giving the size(log2) of the map
6990  */
6991  case 0x13: {
6992  byte map_bits = 0;
6993  byte log_X = MapLogX() - 6; // subtraction is required to make the minimal size (64) zero based
6994  byte log_Y = MapLogY() - 6;
6995  byte max_edge = std::max(log_X, log_Y);
6996 
6997  if (log_X == log_Y) { // we have a squared map, since both edges are identical
6998  SetBit(map_bits, 0);
6999  } else {
7000  if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
7001  }
7002 
7003  return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7004  (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7005  }
7006 
7007  /* The maximum height of the map. */
7008  case 0x14:
7010 
7011  /* Extra foundations base sprite */
7012  case 0x15:
7013  return SPR_SLOPES_BASE;
7014 
7015  /* Shore base sprite */
7016  case 0x16:
7017  return SPR_SHORE_BASE;
7018 
7019  default:
7020  grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
7021  return 0;
7022  }
7023 }
7024 
7025 
7026 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
7027 {
7028  uint start = 0;
7029  uint size = 0;
7030 
7031  if (op == 6) {
7032  /* Return GRFID of set that reserved ID */
7033  return grm[_cur.grffile->GetParam(target)];
7034  }
7035 
7036  /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
7037  if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
7038 
7039  for (uint i = start; i < num_ids; i++) {
7040  if (grm[i] == 0) {
7041  size++;
7042  } else {
7043  if (op == 2 || op == 3) break;
7044  start = i + 1;
7045  size = 0;
7046  }
7047 
7048  if (size == count) break;
7049  }
7050 
7051  if (size == count) {
7052  /* Got the slot... */
7053  if (op == 0 || op == 3) {
7054  grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7055  for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
7056  }
7057  return start;
7058  }
7059 
7060  /* Unable to allocate */
7061  if (op != 4 && op != 5) {
7062  /* Deactivate GRF */
7063  grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7064  DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
7065  return UINT_MAX;
7066  }
7067 
7068  grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
7069  return UINT_MAX;
7070 }
7071 
7072 
7074 static void ParamSet(ByteReader *buf)
7075 {
7076  /* <0D> <target> <operation> <source1> <source2> [<data>]
7077  *
7078  * B target parameter number where result is stored
7079  * B operation operation to perform, see below
7080  * B source1 first source operand
7081  * B source2 second source operand
7082  * D data data to use in the calculation, not necessary
7083  * if both source1 and source2 refer to actual parameters
7084  *
7085  * Operations
7086  * 00 Set parameter equal to source1
7087  * 01 Addition, source1 + source2
7088  * 02 Subtraction, source1 - source2
7089  * 03 Unsigned multiplication, source1 * source2 (both unsigned)
7090  * 04 Signed multiplication, source1 * source2 (both signed)
7091  * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
7092  * signed quantity; left shift if positive and right shift if
7093  * negative, source1 is unsigned)
7094  * 06 Signed bit shift, source1 by source2
7095  * (source2 like in 05, and source1 as well)
7096  */
7097 
7098  uint8 target = buf->ReadByte();
7099  uint8 oper = buf->ReadByte();
7100  uint32 src1 = buf->ReadByte();
7101  uint32 src2 = buf->ReadByte();
7102 
7103  uint32 data = 0;
7104  if (buf->Remaining() >= 4) data = buf->ReadDWord();
7105 
7106  /* You can add 80 to the operation to make it apply only if the target
7107  * is not defined yet. In this respect, a parameter is taken to be
7108  * defined if any of the following applies:
7109  * - it has been set to any value in the newgrf(w).cfg parameter list
7110  * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
7111  * an earlier action D */
7112  if (HasBit(oper, 7)) {
7113  if (target < 0x80 && target < _cur.grffile->param_end) {
7114  grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
7115  return;
7116  }
7117 
7118  oper = GB(oper, 0, 7);
7119  }
7120 
7121  if (src2 == 0xFE) {
7122  if (GB(data, 0, 8) == 0xFF) {
7123  if (data == 0x0000FFFF) {
7124  /* Patch variables */
7125  src1 = GetPatchVariable(src1);
7126  } else {
7127  /* GRF Resource Management */
7128  uint8 op = src1;
7129  uint8 feature = GB(data, 8, 8);
7130  uint16 count = GB(data, 16, 16);
7131 
7132  if (_cur.stage == GLS_RESERVE) {
7133  if (feature == 0x08) {
7134  /* General sprites */
7135  if (op == 0) {
7136  /* Check if the allocated sprites will fit below the original sprite limit */
7137  if (_cur.spriteid + count >= 16384) {
7138  grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7139  DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
7140  return;
7141  }
7142 
7143  /* Reserve space at the current sprite ID */
7144  grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
7145  _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
7146  _cur.spriteid += count;
7147  }
7148  }
7149  /* Ignore GRM result during reservation */
7150  src1 = 0;
7151  } else if (_cur.stage == GLS_ACTIVATION) {
7152  switch (feature) {
7153  case 0x00: // Trains
7154  case 0x01: // Road Vehicles
7155  case 0x02: // Ships
7156  case 0x03: // Aircraft
7158  src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
7159  if (_cur.skip_sprites == -1) return;
7160  } else {
7161  /* GRM does not apply for dynamic engine allocation. */
7162  switch (op) {
7163  case 2:
7164  case 3:
7165  src1 = _cur.grffile->GetParam(target);
7166  break;
7167 
7168  default:
7169  src1 = 0;
7170  break;
7171  }
7172  }
7173  break;
7174 
7175  case 0x08: // General sprites
7176  switch (op) {
7177  case 0:
7178  /* Return space reserved during reservation stage */
7179  src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
7180  grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7181  break;
7182 
7183  case 1:
7184  src1 = _cur.spriteid;
7185  break;
7186 
7187  default:
7188  grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
7189  return;
7190  }
7191  break;
7192 
7193  case 0x0B: // Cargo
7194  /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
7195  src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
7196  if (_cur.skip_sprites == -1) return;
7197  break;
7198 
7199  default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
7200  }
7201  } else {
7202  /* Ignore GRM during initialization */
7203  src1 = 0;
7204  }
7205  }
7206  } else {
7207  /* Read another GRF File's parameter */
7208  const GRFFile *file = GetFileByGRFID(data);
7209  GRFConfig *c = GetGRFConfig(data);
7210  if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
7211  /* Disable the read GRF if it is a static NewGRF. */
7213  src1 = 0;
7214  } else if (file == nullptr || c == nullptr || c->status == GCS_DISABLED) {
7215  src1 = 0;
7216  } else if (src1 == 0xFE) {
7217  src1 = c->version;
7218  } else {
7219  src1 = file->GetParam(src1);
7220  }
7221  }
7222  } else {
7223  /* The source1 and source2 operands refer to the grf parameter number
7224  * like in action 6 and 7. In addition, they can refer to the special
7225  * variables available in action 7, or they can be FF to use the value
7226  * of <data>. If referring to parameters that are undefined, a value
7227  * of 0 is used instead. */
7228  src1 = (src1 == 0xFF) ? data : GetParamVal(src1, nullptr);
7229  src2 = (src2 == 0xFF) ? data : GetParamVal(src2, nullptr);
7230  }
7231 
7232  uint32 res;
7233  switch (oper) {
7234  case 0x00:
7235  res = src1;
7236  break;
7237 
7238  case 0x01:
7239  res = src1 + src2;
7240  break;
7241 
7242  case 0x02:
7243  res = src1 - src2;
7244  break;
7245 
7246  case 0x03:
7247  res = src1 * src2;
7248  break;
7249 
7250  case 0x04:
7251  res = (int32)src1 * (int32)src2;
7252  break;
7253 
7254  case 0x05:
7255  if ((int32)src2 < 0) {
7256  res = src1 >> -(int32)src2;
7257  } else {
7258  res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7259  }
7260  break;
7261 
7262  case 0x06:
7263  if ((int32)src2 < 0) {
7264  res = (int32)src1 >> -(int32)src2;
7265  } else {
7266  res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7267  }
7268  break;
7269 
7270  case 0x07: // Bitwise AND
7271  res = src1 & src2;
7272  break;
7273 
7274  case 0x08: // Bitwise OR
7275  res = src1 | src2;
7276  break;
7277 
7278  case 0x09: // Unsigned division
7279  if (src2 == 0) {
7280  res = src1;
7281  } else {
7282  res = src1 / src2;
7283  }
7284  break;
7285 
7286  case 0x0A: // Signed division
7287  if (src2 == 0) {
7288  res = src1;
7289  } else {
7290  res = (int32)src1 / (int32)src2;
7291  }
7292  break;
7293 
7294  case 0x0B: // Unsigned modulo
7295  if (src2 == 0) {
7296  res = src1;
7297  } else {
7298  res = src1 % src2;
7299  }
7300  break;
7301 
7302  case 0x0C: // Signed modulo
7303  if (src2 == 0) {
7304  res = src1;
7305  } else {
7306  res = (int32)src1 % (int32)src2;
7307  }
7308  break;
7309 
7310  default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
7311  }
7312 
7313  switch (target) {
7314  case 0x8E: // Y-Offset for train sprites
7315  _cur.grffile->traininfo_vehicle_pitch = res;
7316  break;
7317 
7318  case 0x8F: { // Rail track type cost factors
7319  extern RailtypeInfo _railtypes[RAILTYPE_END];
7320  _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
7322  _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
7323  _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
7324  } else {
7325  _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
7326  _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
7327  }
7328  _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
7329  break;
7330  }
7331 
7332  /* not implemented */
7333  case 0x93: // Tile refresh offset to left -- Intended to allow support for larger sprites, not necessary for OTTD
7334  case 0x94: // Tile refresh offset to right
7335  case 0x95: // Tile refresh offset upwards
7336  case 0x96: // Tile refresh offset downwards
7337  case 0x97: // Snow line height -- Better supported by feature 8 property 10h (snow line table) TODO: implement by filling the entire snow line table with the given value
7338  case 0x99: // Global ID offset -- Not necessary since IDs are remapped automatically
7339  grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7340  break;
7341 
7342  case 0x9E: // Miscellaneous GRF features
7343  /* Set train list engine width */
7344  _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
7345  /* Remove the local flags from the global flags */
7347 
7348  /* Only copy safe bits for static grfs */
7349  if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
7350  uint32 safe_bits = 0;
7351  SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7352 
7353  _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
7354  } else {
7355  _misc_grf_features = res;
7356  }
7357  break;
7358 
7359  case 0x9F: // locale-dependent settings
7360  grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7361  break;
7362 
7363  default:
7364  if (target < 0x80) {
7365  _cur.grffile->param[target] = res;
7366  /* param is zeroed by default */
7367  if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
7368  } else {
7369  grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
7370  }
7371  break;
7372  }
7373 }
7374 
7375 /* Action 0x0E (GLS_SAFETYSCAN) */
7376 static void SafeGRFInhibit(ByteReader *buf)
7377 {
7378  /* <0E> <num> <grfids...>
7379  *
7380  * B num Number of GRFIDs that follow
7381  * D grfids GRFIDs of the files to deactivate */
7382 
7383  uint8 num = buf->ReadByte();
7384 
7385  for (uint i = 0; i < num; i++) {
7386  uint32 grfid = buf->ReadDWord();
7387 
7388  /* GRF is unsafe it if tries to deactivate other GRFs */
7389  if (grfid != _cur.grfconfig->ident.grfid) {
7390  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7391 
7392  /* Skip remainder of GRF */
7393  _cur.skip_sprites = -1;
7394 
7395  return;
7396  }
7397  }
7398 }
7399 
7400 /* Action 0x0E */
7401 static void GRFInhibit(ByteReader *buf)
7402 {
7403  /* <0E> <num> <grfids...>
7404  *
7405  * B num Number of GRFIDs that follow
7406  * D grfids GRFIDs of the files to deactivate */
7407 
7408  uint8 num = buf->ReadByte();
7409 
7410  for (uint i = 0; i < num; i++) {
7411  uint32 grfid = buf->ReadDWord();
7412  GRFConfig *file = GetGRFConfig(grfid);
7413 
7414  /* Unset activation flag */
7415  if (file != nullptr && file != _cur.grfconfig) {
7416  grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
7417  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
7418  error->data = stredup(_cur.grfconfig->GetName());
7419  }
7420  }
7421 }
7422 
7424 static void FeatureTownName(ByteReader *buf)
7425 {
7426  /* <0F> <id> <style-name> <num-parts> <parts>
7427  *
7428  * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
7429  * V style-name Name of the style (only for final definition)
7430  * B num-parts Number of parts in this definition
7431  * V parts The parts */
7432 
7433  uint32 grfid = _cur.grffile->grfid;
7434 
7435  GRFTownName *townname = AddGRFTownName(grfid);
7436 
7437  byte id = buf->ReadByte();
7438  grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
7439 
7440  if (HasBit(id, 7)) {
7441  /* Final definition */
7442  ClrBit(id, 7);
7443  bool new_scheme = _cur.grffile->grf_version >= 7;
7444 
7445  byte lang = buf->ReadByte();
7446 
7447  byte nb_gen = townname->nb_gen;
7448  do {
7449  ClrBit(lang, 7);
7450 
7451  const char *name = buf->ReadString();
7452 
7453  std::string lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
7454  grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7455 
7456  townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
7457 
7458  lang = buf->ReadByte();
7459  } while (lang != 0);
7460  townname->id[nb_gen] = id;
7461  townname->nb_gen++;
7462  }
7463 
7464  byte nb = buf->ReadByte();
7465  grfmsg(6, "FeatureTownName: %u parts", nb);
7466 
7467  townname->nbparts[id] = nb;
7468  townname->partlist[id] = CallocT<NamePartList>(nb);
7469 
7470  for (int i = 0; i < nb; i++) {
7471  byte nbtext = buf->ReadByte();
7472  townname->partlist[id][i].bitstart = buf->ReadByte();
7473  townname->partlist[id][i].bitcount = buf->ReadByte();
7474  townname->partlist[id][i].maxprob = 0;
7475  townname->partlist[id][i].partcount = nbtext;
7476  townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7477  grfmsg(6, "FeatureTownName: part %d contains %d texts and will use GB(seed, %d, %d)", i, nbtext, townname->partlist[id][i].bitstart, townname->partlist[id][i].bitcount);
7478 
7479  for (int j = 0; j < nbtext; j++) {
7480  byte prob = buf->ReadByte();
7481 
7482  if (HasBit(prob, 7)) {
7483  byte ref_id = buf->ReadByte();
7484 
7485  if (townname->nbparts[ref_id] == 0) {
7486  grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7487  DelGRFTownName(grfid);
7488  DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
7489  return;
7490  }
7491 
7492  grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7493  townname->partlist[id][i].parts[j].data.id = ref_id;
7494  } else {
7495  const char *text = buf->ReadString();
7496  townname->partlist[id][i].parts[j].data.text = stredup(TranslateTTDPatchCodes(grfid, 0, false, text).c_str());
7497  grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7498  }
7499  townname->partlist[id][i].parts[j].prob = prob;
7500  townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7501  }
7502  grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7503  }
7504 }
7505 
7507 static void DefineGotoLabel(ByteReader *buf)
7508 {
7509  /* <10> <label> [<comment>]
7510  *
7511  * B label The label to define
7512  * V comment Optional comment - ignored */
7513 
7514  byte nfo_label = buf->ReadByte();
7515 
7516  GRFLabel *label = MallocT<GRFLabel>(1);
7517  label->label = nfo_label;
7518  label->nfo_line = _cur.nfo_line;
7519  label->pos = FioGetPos();
7520  label->next = nullptr;
7521 
7522  /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7523  if (_cur.grffile->label == nullptr) {
7524  _cur.grffile->label = label;
7525  } else {
7526  /* Attach the label to the end of the list */
7527  GRFLabel *l;
7528  for (l = _cur.grffile->label; l->next != nullptr; l = l->next) {}
7529  l->next = label;
7530  }
7531 
7532  grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7533 }
7534 
7539 static void ImportGRFSound(SoundEntry *sound)
7540 {
7541  const GRFFile *file;
7542  uint32 grfid = FioReadDword();
7543  SoundID sound_id = FioReadWord();
7544 
7545  file = GetFileByGRFID(grfid);
7546  if (file == nullptr || file->sound_offset == 0) {
7547  grfmsg(1, "ImportGRFSound: Source file not available");
7548  return;
7549  }
7550 
7551  if (sound_id >= file->num_sounds) {
7552  grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7553  return;
7554  }
7555 
7556  grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7557 
7558  *sound = *GetSound(file->sound_offset + sound_id);
7559 
7560  /* Reset volume and priority, which TTDPatch doesn't copy */
7561  sound->volume = 128;
7562  sound->priority = 0;
7563 }
7564 
7570 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7571 {
7572  /* Set default volume and priority */
7573  sound->volume = 0x80;
7574  sound->priority = 0;
7575 
7576  if (offs != SIZE_MAX) {
7577  /* Sound is present in the NewGRF. */
7578  sound->file_slot = _cur.file_index;
7579  sound->file_offset = offs;
7580  sound->grf_container_ver = _cur.grf_container_ver;
7581  }
7582 }
7583 
7584 /* Action 0x11 */
7585 static void GRFSound(ByteReader *buf)
7586 {
7587  /* <11> <num>
7588  *
7589  * W num Number of sound files that follow */
7590 
7591  uint16 num = buf->ReadWord();
7592  if (num == 0) return;
7593 
7594  SoundEntry *sound;
7595  if (_cur.grffile->sound_offset == 0) {
7596  _cur.grffile->sound_offset = GetNumSounds();
7597  _cur.grffile->num_sounds = num;
7598  sound = AllocateSound(num);
7599  } else {
7600  sound = GetSound(_cur.grffile->sound_offset);
7601  }
7602 
7603  for (int i = 0; i < num; i++) {
7604  _cur.nfo_line++;
7605 
7606  /* Check whether the index is in range. This might happen if multiple action 11 are present.
7607  * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7608  bool invalid = i >= _cur.grffile->num_sounds;
7609 
7610  size_t offs = FioGetPos();
7611 
7612  uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7613  byte type = FioReadByte();
7614 
7615  if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7616  /* Reference to sprite section. */
7617  if (invalid) {
7618  grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7619  FioSkipBytes(len);
7620  } else if (len != 4) {
7621  grfmsg(1, "GRFSound: Invalid sprite section import");
7622  FioSkipBytes(len);
7623  } else {
7624  uint32 id = FioReadDword();
7625  if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7626  }
7627  continue;
7628  }
7629 
7630  if (type != 0xFF) {
7631  grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7632  FioSkipBytes(7);
7633  SkipSpriteData(type, len - 8);
7634  continue;
7635  }
7636 
7637  if (invalid) {
7638  grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7639  FioSkipBytes(len);
7640  }
7641 
7642  byte action = FioReadByte();
7643  switch (action) {
7644  case 0xFF:
7645  /* Allocate sound only in init stage. */
7646  if (_cur.stage == GLS_INIT) {
7647  if (_cur.grf_container_ver >= 2) {
7648  grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7649  } else {
7650  LoadGRFSound(offs, sound + i);
7651  }
7652  }
7653  FioSkipBytes(len - 1); // already read <action>
7654  break;
7655 
7656  case 0xFE:
7657  if (_cur.stage == GLS_ACTIVATION) {
7658  /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7659  * importing sounds, so this is probably all wrong... */
7660  if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7661  ImportGRFSound(sound + i);
7662  } else {
7663  FioSkipBytes(len - 1); // already read <action>
7664  }
7665  break;
7666 
7667  default:
7668  grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7669  FioSkipBytes(len - 1); // already read <action>
7670  break;
7671  }
7672  }
7673 }
7674 
7675 /* Action 0x11 (SKIP) */
7676 static void SkipAct11(ByteReader *buf)
7677 {
7678  /* <11> <num>
7679  *
7680  * W num Number of sound files that follow */
7681 
7682  _cur.skip_sprites = buf->ReadWord();
7683 
7684  grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7685 }
7686 
7688 static void LoadFontGlyph(ByteReader *buf)
7689 {
7690  /* <12> <num_def> <font_size> <num_char> <base_char>
7691  *
7692  * B num_def Number of definitions
7693  * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7694  * B num_char Number of consecutive glyphs
7695  * W base_char First character index */
7696 
7697  uint8 num_def = buf->ReadByte();
7698 
7699  for (uint i = 0; i < num_def; i++) {
7700  FontSize size = (FontSize)buf->ReadByte();
7701  uint8 num_char = buf->ReadByte();
7702  uint16 base_char = buf->ReadWord();
7703 
7704  if (size >= FS_END) {
7705  grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7706  }
7707 
7708  grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7709 
7710  for (uint c = 0; c < num_char; c++) {
7711  if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7712  _cur.nfo_line++;
7713  LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7714  }
7715  }
7716 }
7717 
7719 static void SkipAct12(ByteReader *buf)
7720 {
7721  /* <12> <num_def> <font_size> <num_char> <base_char>
7722  *
7723  * B num_def Number of definitions
7724  * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7725  * B num_char Number of consecutive glyphs
7726  * W base_char First character index */
7727 
7728  uint8 num_def = buf->ReadByte();
7729 
7730  for (uint i = 0; i < num_def; i++) {
7731  /* Ignore 'size' byte */
7732  buf->ReadByte();
7733 
7734  /* Sum up number of characters */
7735  _cur.skip_sprites += buf->ReadByte();
7736 
7737  /* Ignore 'base_char' word */
7738  buf->ReadWord();
7739  }
7740 
7741  grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7742 }
7743 
7746 {
7747  /* <13> <grfid> <num-ent> <offset> <text...>
7748  *
7749  * 4*B grfid The GRFID of the file whose texts are to be translated
7750  * B num-ent Number of strings
7751  * W offset First text ID
7752  * S text... Zero-terminated strings */
7753 
7754  uint32 grfid = buf->ReadDWord();
7755  const GRFConfig *c = GetGRFConfig(grfid);
7756  if (c == nullptr || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7757  grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7758  return;
7759  }
7760 
7761  if (c->status == GCS_INITIALISED) {
7762  /* If the file is not active but will be activated later, give an error
7763  * and disable this file. */
7764  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7765 
7766  char tmp[256];
7767  GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7768  error->data = tmp;
7769 
7770  return;
7771  }
7772 
7773  /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7774  * to be added as a generic string, thus the language id of 0x7F. For this to work
7775  * new_scheme has to be true as well, which will also be implicitly the case for version 8
7776  * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7777  * not change anything if a string has been provided specifically for this language. */
7778  byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7779  byte num_strings = buf->ReadByte();
7780  uint16 first_id = buf->ReadWord();
7781 
7782  if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7783  grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7784  return;
7785  }
7786 
7787  for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7788  const char *string = buf->ReadString();
7789 
7790  if (StrEmpty(string)) {
7791  grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7792  continue;
7793  }
7794 
7795  AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7796  }
7797 }
7798 
7800 static bool ChangeGRFName(byte langid, const char *str)
7801 {
7802  AddGRFTextToList(_cur.grfconfig->name, langid, _cur.grfconfig->ident.grfid, false, str);
7803  return true;
7804 }
7805 
7807 static bool ChangeGRFDescription(byte langid, const char *str)
7808 {
7809  AddGRFTextToList(_cur.grfconfig->info, langid, _cur.grfconfig->ident.grfid, true, str);
7810  return true;
7811 }
7812 
7814 static bool ChangeGRFURL(byte langid, const char *str)
7815 {
7816  AddGRFTextToList(_cur.grfconfig->url, langid, _cur.grfconfig->ident.grfid, false, str);
7817  return true;
7818 }
7819 
7821 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7822 {
7823  if (len != 1) {
7824  grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7825  buf->Skip(len);
7826  } else {
7827  _cur.grfconfig->num_valid_params = std::min<byte>(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7828  }
7829  return true;
7830 }
7831 
7833 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7834 {
7835  if (len != 1) {
7836  grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7837  buf->Skip(len);
7838  } else {
7839  char data = buf->ReadByte();
7840  GRFPalette pal = GRFP_GRF_UNSET;
7841  switch (data) {
7842  case '*':
7843  case 'A': pal = GRFP_GRF_ANY; break;
7844  case 'W': pal = GRFP_GRF_WINDOWS; break;
7845  case 'D': pal = GRFP_GRF_DOS; break;
7846  default:
7847  grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7848  break;
7849  }
7850  if (pal != GRFP_GRF_UNSET) {
7851  _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7852  _cur.grfconfig->palette |= pal;
7853  }
7854  }
7855  return true;
7856 }
7857 
7859 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7860 {
7861  if (len != 1) {
7862  grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7863  buf->Skip(len);
7864  } else {
7865  char data = buf->ReadByte();
7866  GRFPalette pal = GRFP_BLT_UNSET;
7867  switch (data) {
7868  case '8': pal = GRFP_BLT_UNSET; break;
7869  case '3': pal = GRFP_BLT_32BPP; break;
7870  default:
7871  grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7872  return true;
7873  }
7874  _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7875  _cur.grfconfig->palette |= pal;
7876  }
7877  return true;
7878 }
7879 
7881 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7882 {
7883  if (len != 4) {
7884  grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7885  buf->Skip(len);
7886  } else {
7887  /* Set min_loadable_version as well (default to minimal compatibility) */
7888  _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7889  }
7890  return true;
7891 }
7892 
7894 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7895 {
7896  if (len != 4) {
7897  grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7898  buf->Skip(len);
7899  } else {
7900  _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7901  if (_cur.grfconfig->version == 0) {
7902  grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7903  _cur.grfconfig->min_loadable_version = 0;
7904  }
7905  if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7906  grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7908  }
7909  }
7910  return true;
7911 }
7912 
7914 
7916 static bool ChangeGRFParamName(byte langid, const char *str)
7917 {
7918  AddGRFTextToList(_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7919  return true;
7920 }
7921 
7923 static bool ChangeGRFParamDescription(byte langid, const char *str)
7924 {
7925  AddGRFTextToList(_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7926  return true;
7927 }
7928 
7930 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7931 {
7932  if (len != 1) {
7933  grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7934  buf->Skip(len);
7935  } else {
7936  GRFParameterType type = (GRFParameterType)buf->ReadByte();
7937  if (type < PTYPE_END) {
7938  _cur_parameter->type = type;
7939  } else {
7940  grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7941  }
7942  }
7943  return true;
7944 }
7945 
7947 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7948 {
7950  grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7951  buf->Skip(len);
7952  } else if (len != 8) {
7953  grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7954  buf->Skip(len);
7955  } else {
7956  uint32 min_value = buf->ReadDWord();
7957  uint32 max_value = buf->ReadDWord();
7958  if (min_value <= max_value) {
7959  _cur_parameter->min_value = min_value;
7960  _cur_parameter->max_value = max_value;
7961  } else {
7962  grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7963  }
7964  }
7965  return true;
7966 }
7967 
7969 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7970 {
7971  if (len < 1 || len > 3) {
7972  grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7973  buf->Skip(len);
7974  } else {
7975  byte param_nr = buf->ReadByte();
7976  if (param_nr >= lengthof(_cur.grfconfig->param)) {
7977  grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7978  buf->Skip(len - 1);
7979  } else {
7980  _cur_parameter->param_nr = param_nr;
7981  if (len >= 2) _cur_parameter->first_bit = std::min<byte>(buf->ReadByte(), 31);
7982  if (len >= 3) _cur_parameter->num_bit = std::min<byte>(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7983  }
7984  }
7985 
7986  return true;
7987 }
7988 
7990 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7991 {
7992  if (len != 4) {
7993  grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7994  buf->Skip(len);
7995  } else {
7996  _cur_parameter->def_value = buf->ReadDWord();
7997  }
7998  _cur.grfconfig->has_param_defaults = true;
7999  return true;
8000 }
8001 
8002 typedef bool (*DataHandler)(size_t, ByteReader *);
8003 typedef bool (*TextHandler)(byte, const char *str);
8004 typedef bool (*BranchHandler)(ByteReader *);
8005 
8016  id(0),
8017  type(0)
8018  {}
8019 
8025  AllowedSubtags(uint32 id, DataHandler handler) :
8026  id(id),
8027  type('B')
8028  {
8029  this->handler.data = handler;
8030  }
8031 
8037  AllowedSubtags(uint32 id, TextHandler handler) :
8038  id(id),
8039  type('T')
8040  {
8041  this->handler.text = handler;
8042  }
8043 
8049  AllowedSubtags(uint32 id, BranchHandler handler) :
8050  id(id),
8051  type('C')
8052  {
8053  this->handler.call_handler = true;
8054  this->handler.u.branch = handler;
8055  }
8056 
8063  id(id),
8064  type('C')
8065  {
8066  this->handler.call_handler = false;
8067  this->handler.u.subtags = subtags;
8068  }
8069 
8070  uint32 id;
8071  byte type;
8072  union {
8075  struct {
8076  union {
8079  } u;
8081  };
8082  } handler;
8083 };
8084 
8085 static bool SkipUnknownInfo(ByteReader *buf, byte type);
8086 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
8087 
8095 {
8096  byte type = buf->ReadByte();
8097  while (type != 0) {
8098  uint32 id = buf->ReadDWord();
8099  if (type != 'T' || id > _cur_parameter->max_value) {
8100  grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8101  if (!SkipUnknownInfo(buf, type)) return false;
8102  type = buf->ReadByte();
8103  continue;
8104  }
8105 
8106  byte langid = buf->ReadByte();
8107  const char *name_string = buf->ReadString();
8108 
8109  std::pair<uint32, GRFTextList> *val_name = _cur_parameter->value_names.Find(id);
8110  if (val_name != _cur_parameter->value_names.End()) {
8111  AddGRFTextToList(val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
8112  } else {
8113  GRFTextList list;
8114  AddGRFTextToList(list, langid, _cur.grfconfig->ident.grfid, false, name_string);
8115  _cur_parameter->value_names.Insert(id, list);
8116  }
8117 
8118  type = buf->ReadByte();
8119  }
8120  return true;
8121 }
8122 
8132  AllowedSubtags()
8133 };
8134 
8142 {
8143  byte type = buf->ReadByte();
8144  while (type != 0) {
8145  uint32 id = buf->ReadDWord();
8146  if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
8147  grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8148  if (!SkipUnknownInfo(buf, type)) return false;
8149  type = buf->ReadByte();
8150  continue;
8151  }
8152 
8153  if (id >= _cur.grfconfig->param_info.size()) {
8154  _cur.grfconfig->param_info.resize(id + 1);
8155  }
8156  if (_cur.grfconfig->param_info[id] == nullptr) {
8157  _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
8158  }
8159  _cur_parameter = _cur.grfconfig->param_info[id];
8160  /* Read all parameter-data and process each node. */
8161  if (!HandleNodes(buf, _tags_parameters)) return false;
8162  type = buf->ReadByte();
8163  }
8164  return true;
8165 }
8166 
8169  AllowedSubtags('NAME', ChangeGRFName),
8171  AllowedSubtags('URL_', ChangeGRFURL),
8178  AllowedSubtags()
8179 };
8180 
8183  AllowedSubtags('INFO', _tags_info),
8184  AllowedSubtags()
8185 };
8186 
8187 
8194 static bool SkipUnknownInfo(ByteReader *buf, byte type)
8195 {
8196  /* type and id are already read */
8197  switch (type) {
8198  case 'C': {
8199  byte new_type = buf->ReadByte();
8200  while (new_type != 0) {
8201  buf->ReadDWord(); // skip the id
8202  if (!SkipUnknownInfo(buf, new_type)) return false;
8203  new_type = buf->ReadByte();
8204  }
8205  break;
8206  }
8207 
8208  case 'T':
8209  buf->ReadByte(); // lang
8210  buf->ReadString(); // actual text
8211  break;
8212 
8213  case 'B': {
8214  uint16 size = buf->ReadWord();
8215  buf->Skip(size);
8216  break;
8217  }
8218 
8219  default:
8220  return false;
8221  }
8222 
8223  return true;
8224 }
8225 
8234 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
8235 {
8236  uint i = 0;
8237  AllowedSubtags *tag;
8238  while ((tag = &subtags[i++])->type != 0) {
8239  if (tag->id != BSWAP32(id) || tag->type != type) continue;
8240  switch (type) {
8241  default: NOT_REACHED();
8242 
8243  case 'T': {
8244  byte langid = buf->ReadByte();
8245  return tag->handler.text(langid, buf->ReadString());
8246  }
8247 
8248  case 'B': {
8249  size_t len = buf->ReadWord();
8250  if (buf->Remaining() < len) return false;
8251  return tag->handler.data(len, buf);
8252  }
8253 
8254  case 'C': {
8255  if (tag->handler.call_handler) {
8256  return tag->handler.u.branch(buf);
8257  }
8258  return HandleNodes(buf, tag->handler.u.subtags);
8259  }
8260  }
8261  }
8262  grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
8263  return SkipUnknownInfo(buf, type);
8264 }
8265 
8272 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
8273 {
8274  byte type = buf->ReadByte();
8275  while (type != 0) {
8276  uint32 id = buf->ReadDWord();
8277  if (!HandleNode(type, id, buf, subtags)) return false;
8278  type = buf->ReadByte();
8279  }
8280  return true;
8281 }
8282 
8287 static void StaticGRFInfo(ByteReader *buf)
8288 {
8289  /* <14> <type> <id> <text/data...> */
8290  HandleNodes(buf, _tags_root);
8291 }
8292 
8298 static void GRFUnsafe(ByteReader *buf)
8299 {
8300  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
8301 
8302  /* Skip remainder of GRF */
8303  _cur.skip_sprites = -1;
8304 }
8305 
8306 
8309 {
8310  _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
8311  | (1 << 0x0D) // newairports
8312  | (1 << 0x0E) // largestations
8313  | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
8314  | (0 << 0x10) // loadtime
8315  | (1 << 0x12) // presignals
8316  | (1 << 0x13) // extpresignals
8317  | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
8318  | (1 << 0x1B) // multihead
8319  | (1 << 0x1D) // lowmemory
8320  | (1 << 0x1E); // generalfixes
8321 
8322  _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
8323  | (1 << 0x08) // mammothtrains
8324  | (1 << 0x09) // trainrefit
8325  | (0 << 0x0B) // subsidiaries
8326  | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
8327  | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
8328  | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
8329  | (1 << 0x14) // bridgespeedlimits
8330  | (1 << 0x16) // eternalgame
8331  | (1 << 0x17) // newtrains
8332  | (1 << 0x18) // newrvs
8333  | (1 << 0x19) // newships
8334  | (1 << 0x1A) // newplanes
8335  | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
8336  | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
8337 
8338  _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
8339  | (1 << 0x03) // semaphores
8340  | (1 << 0x0A) // newobjects
8341  | (0 << 0x0B) // enhancedgui
8342  | (0 << 0x0C) // newagerating
8343  | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
8344  | (1 << 0x0E) // fullloadany
8345  | (1 << 0x0F) // planespeed
8346  | (0 << 0x10) // moreindustriesperclimate - obsolete
8347  | (0 << 0x11) // moretoylandfeatures
8348  | (1 << 0x12) // newstations
8349  | (1 << 0x13) // tracktypecostdiff
8350  | (1 << 0x14) // manualconvert
8351  | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
8352  | (1 << 0x16) // canals
8353  | (1 << 0x17) // newstartyear
8354  | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
8355  | (1 << 0x19) // newhouses
8356  | (1 << 0x1A) // newbridges
8357  | (1 << 0x1B) // newtownnames
8358  | (1 << 0x1C) // moreanimation
8359  | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
8360  | (1 << 0x1E) // newshistory
8361  | (0 << 0x1F); // custombridgeheads
8362 
8363  _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
8364  | (1 << 0x01) // windowsnap
8365  | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
8366  | (1 << 0x03) // pathbasedsignalling
8367  | (0 << 0x04) // aichoosechance
8368  | (1 << 0x05) // resolutionwidth
8369  | (1 << 0x06) // resolutionheight
8370  | (1 << 0x07) // newindustries
8371  | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
8372  | (0 << 0x09) // townroadbranchprob
8373  | (0 << 0x0A) // tempsnowline
8374  | (1 << 0x0B) // newcargo
8375  | (1 << 0x0C) // enhancemultiplayer
8376  | (1 << 0x0D) // onewayroads
8377  | (1 << 0x0E) // irregularstations
8378  | (1 << 0x0F) // statistics
8379  | (1 << 0x10) // newsounds
8380  | (1 << 0x11) // autoreplace
8381  | (1 << 0x12) // autoslope
8382  | (0 << 0x13) // followvehicle
8383  | (1 << 0x14) // trams
8384  | (0 << 0x15) // enhancetunnels
8385  | (1 << 0x16) // shortrvs
8386  | (1 << 0x17) // articulatedrvs
8387  | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
8388  | (1 << 0x1E) // variablerunningcosts
8389  | (1 << 0x1F); // any switch is on
8390 
8391  _ttdpatch_flags[4] = (1 << 0x00) // larger persistent storage
8392  | ((_settings_game.economy.inflation ? 1 : 0) << 0x01); // inflation is on
8393 }
8394 
8396 static void ResetCustomStations()
8397 {
8398  for (GRFFile * const file : _grf_files) {
8399  StationSpec **&stations = file->stations;
8400  if (stations == nullptr) continue;
8401  for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
8402  if (stations[i] == nullptr) continue;
8403  StationSpec *statspec = stations[i];
8404 
8405  delete[] statspec->renderdata;
8406 
8407  /* Release platforms and layouts */
8408  if (!statspec->copied_layouts) {
8409  for (uint l = 0; l < statspec->lengths; l++) {
8410  for (uint p = 0; p < statspec->platforms[l]; p++) {
8411  free(statspec->layouts[l][p]);
8412  }
8413  free(statspec->layouts[l]);
8414  }
8415  free(statspec->layouts);
8416  free(statspec->platforms);
8417  }
8418 
8419  /* Release this station */
8420  free(statspec);
8421  }
8422 
8423  /* Free and reset the station data */
8424  free(stations);
8425  stations = nullptr;
8426  }
8427 }
8428 
8430 static void ResetCustomHouses()
8431 {
8432  for (GRFFile * const file : _grf_files) {
8433  HouseSpec **&housespec = file->housespec;
8434  if (housespec == nullptr) continue;
8435  for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8436  free(housespec[i]);
8437  }
8438 
8439  free(housespec);
8440  housespec = nullptr;
8441  }
8442 }
8443 
8445 static void ResetCustomAirports()
8446 {
8447  for (GRFFile * const file : _grf_files) {
8448  AirportSpec **aslist = file->airportspec;
8449  if (aslist != nullptr) {
8450  for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8451  AirportSpec *as = aslist[i];
8452 
8453  if (as != nullptr) {
8454  /* We need to remove the tiles layouts */
8455  for (int j = 0; j < as->num_table; j++) {
8456  /* remove the individual layouts */
8457  free(as->table[j]);
8458  }
8459  free(as->table);
8460  free(as->depot_table);
8461  free(as->rotation);
8462 
8463  free(as);
8464  }
8465  }
8466  free(aslist);
8467  file->airportspec = nullptr;
8468  }
8469 
8470  AirportTileSpec **&airporttilespec = file->airtspec;
8471  if (airporttilespec != nullptr) {
8472  for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8473  free(airporttilespec[i]);
8474  }
8475  free(airporttilespec);
8476  airporttilespec = nullptr;
8477  }
8478  }
8479 }
8480 
8483 {
8484  for (GRFFile * const file : _grf_files) {
8485  IndustrySpec **&industryspec = file->industryspec;
8486  IndustryTileSpec **&indtspec = file->indtspec;
8487 
8488  /* We are verifiying both tiles and industries specs loaded from the grf file
8489  * First, let's deal with industryspec */
8490  if (industryspec != nullptr) {
8491  for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8492  IndustrySpec *ind = industryspec[i];
8493  delete ind;
8494  }
8495 
8496  free(industryspec);
8497  industryspec = nullptr;
8498  }
8499 
8500  if (indtspec == nullptr) continue;
8501  for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8502  free(indtspec[i]);
8503  }
8504 
8505  free(indtspec);
8506  indtspec = nullptr;
8507  }
8508 }
8509 
8511 static void ResetCustomObjects()
8512 {
8513  for (GRFFile * const file : _grf_files) {
8514  ObjectSpec **&objectspec = file->objectspec;
8515  if (objectspec == nullptr) continue;
8516  for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8517  free(objectspec[i]);
8518  }
8519 
8520  free(objectspec);
8521  objectspec = nullptr;
8522  }
8523 }
8524 
8526 static void ResetNewGRF()
8527 {
8528  for (GRFFile * const file : _grf_files) {
8529  delete file;
8530  }
8531 
8532  _grf_files.clear();
8533  _cur.grffile = nullptr;
8534 }
8535 
8537 static void ResetNewGRFErrors()
8538 {
8539  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
8540  if (!HasBit(c->flags, GCF_COPY) && c->error != nullptr) {
8541  delete c->error;
8542  c->error = nullptr;
8543  }
8544  }
8545 }
8546 
8551 {
8552  CleanUpStrings();
8553  CleanUpGRFTownNames();
8554 
8555  /* Copy/reset original engine info data */
8556  SetupEngines();
8557 
8558  /* Copy/reset original bridge info data */
8559  ResetBridges();
8560 
8561  /* Reset rail type information */
8562  ResetRailTypes();
8563 
8564  /* Copy/reset original road type info data */
8565  ResetRoadTypes();
8566 
8567  /* Allocate temporary refit/cargo class data */
8568  _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8569 
8570  /* Fill rail type label temporary data for default trains */
8571  for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
8572  _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8573  }
8574 
8575  /* Reset GRM reservations */
8576  memset(&_grm_engines, 0, sizeof(_grm_engines));
8577  memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8578 
8579  /* Reset generic feature callback lists */
8581 
8582  /* Reset price base data */
8584 
8585  /* Reset the curencies array */
8586  ResetCurrencies();
8587 
8588  /* Reset the house array */
8590  ResetHouses();
8591 
8592  /* Reset the industries structures*/
8594  ResetIndustries();
8595 
8596  /* Reset the objects. */
8597  ObjectClass::Reset();
8599  ResetObjects();
8600 
8601  /* Reset station classes */
8602  StationClass::Reset();
8604 
8605  /* Reset airport-related structures */
8606  AirportClass::Reset();
8610 
8611  /* Reset canal sprite groups and flags */
8612  memset(_water_feature, 0, sizeof(_water_feature));
8613 
8614  /* Reset the snowline table. */
8615  ClearSnowLine();
8616 
8617  /* Reset NewGRF files */
8618  ResetNewGRF();
8619 
8620  /* Reset NewGRF errors. */
8622 
8623  /* Set up the default cargo types */
8625 
8626  /* Reset misc GRF features and train list display variables */
8627  _misc_grf_features = 0;
8628 
8630  _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8633 
8634  /* Clear all GRF overrides */
8635  _grf_id_overrides.clear();
8636 
8637  InitializeSoundPool();
8638  _spritegroup_pool.CleanPool();
8639 }
8640 
8645 {
8646  /* Reset override managers */
8647  _engine_mngr.ResetToDefaultMapping();
8648  _house_mngr.ResetMapping();
8649  _industry_mngr.ResetMapping();
8650  _industile_mngr.ResetMapping();
8651  _airport_mngr.ResetMapping();
8652  _airporttile_mngr.ResetMapping();
8653 }
8654 
8660 {
8661  memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8662 
8663  for (CargoID c = 0; c < NUM_CARGO; c++) {
8664  const CargoSpec *cs = CargoSpec::Get(c);
8665  if (!cs->IsValid()) continue;
8666 
8667  if (_cur.grffile->cargo_list.size() == 0) {
8668  /* Default translation table, so just a straight mapping to bitnum */
8669  _cur.grffile->cargo_map[c] = cs->bitnum;
8670  } else {
8671  /* Check the translation table for this cargo's label */
8672  int idx = find_index(_cur.grffile->cargo_list, {cs->label});
8673  if (idx >= 0) _cur.grffile->cargo_map[c] = idx;
8674  }
8675  }
8676 }
8677 
8682 static void InitNewGRFFile(const GRFConfig *config)
8683 {
8684  GRFFile *newfile = GetFileByFilename(config->filename);
8685  if (newfile != nullptr) {
8686  /* We already loaded it once. */
8687  _cur.grffile = newfile;
8688  return;
8689  }
8690 
8691  newfile = new GRFFile(config);
8692  _grf_files.push_back(_cur.grffile = newfile);
8693 }
8694 
8700 {
8701  this->filename = stredup(config->filename);
8702  this->grfid = config->ident.grfid;
8703 
8704  /* Initialise local settings to defaults */
8705  this->traininfo_vehicle_pitch = 0;
8706  this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8707 
8708  /* Mark price_base_multipliers as 'not set' */
8709  for (Price i = PR_BEGIN; i < PR_END; i++) {
8710  this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8711  }
8712 
8713  /* Initialise rail type map with default rail types */
8714  std::fill(std::begin(this->railtype_map), std::end(this->railtype_map), INVALID_RAILTYPE);
8715  this->railtype_map[0] = RAILTYPE_RAIL;
8716  this->railtype_map[1] = RAILTYPE_ELECTRIC;
8717  this->railtype_map[2] = RAILTYPE_MONO;
8718  this->railtype_map[3] = RAILTYPE_MAGLEV;
8719 
8720  /* Initialise road type map with default road types */
8721  std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map), INVALID_ROADTYPE);
8722  this->roadtype_map[0] = ROADTYPE_ROAD;
8723 
8724  /* Initialise tram type map with default tram types */
8725  std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map), INVALID_ROADTYPE);
8726  this->tramtype_map[0] = ROADTYPE_TRAM;
8727 
8728  /* Copy the initial parameter list
8729  * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8730  static_assert(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8731 
8732  assert(config->num_params <= lengthof(config->param));
8733  this->param_end = config->num_params;
8734  if (this->param_end > 0) {
8735  MemCpyT(this->param, config->param, this->param_end);
8736  }
8737 }
8738 
8739 GRFFile::~GRFFile()
8740 {
8741  free(this->filename);
8742  delete[] this->language_map;
8743 }
8744 
8745 
8751  'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8752  'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8753  'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8754  'PLST', 'FZDR',
8755  0 };
8756 
8757 static const CargoLabel _default_refitmasks_road[] = {
8758  0 };
8759 
8760 static const CargoLabel _default_refitmasks_ships[] = {
8761  'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8762  'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8763  'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8764  'PLST', 'FZDR',
8765  0 };
8766 
8767 static const CargoLabel _default_refitmasks_aircraft[] = {
8768  'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8769  'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8770  0 };
8771 
8772 static const CargoLabel * const _default_refitmasks[] = {
8774  _default_refitmasks_road,
8775  _default_refitmasks_ships,
8776  _default_refitmasks_aircraft,
8777 };
8778 
8779 
8783 static void CalculateRefitMasks()
8784 {
8785  for (Engine *e : Engine::Iterate()) {
8786  EngineID engine = e->index;
8787  EngineInfo *ei = &e->info;
8788  bool only_defaultcargo;
8789 
8790  /* Did the newgrf specify any refitting? If not, use defaults. */
8791  if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8792  CargoTypes mask = 0;
8793  CargoTypes not_mask = 0;
8794  CargoTypes xor_mask = ei->refit_mask;
8795 
8796  /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8797  * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8798  only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8799 
8800  if (_gted[engine].cargo_allowed != 0) {
8801  /* Build up the list of cargo types from the set cargo classes. */
8802  const CargoSpec *cs;
8803  FOR_ALL_CARGOSPECS(cs) {
8804  if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8805  if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8806  }
8807  }
8808 
8809  ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8810 
8811  /* Apply explicit refit includes/excludes. */
8812  ei->refit_mask |= _gted[engine].ctt_include_mask;
8813  ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8814  } else {
8815  CargoTypes xor_mask = 0;
8816 
8817  /* Don't apply default refit mask to wagons nor engines with no capacity */
8818  if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8819  const CargoLabel *cl = _default_refitmasks[e->type];
8820  for (uint i = 0;; i++) {
8821  if (cl[i] == 0) break;
8822 
8823  CargoID cargo = GetCargoIDByLabel(cl[i]);
8824  if (cargo == CT_INVALID) continue;
8825 
8826  SetBit(xor_mask, cargo);
8827  }
8828  }
8829 
8830  ei->refit_mask = xor_mask & _cargo_mask;
8831 
8832  /* If the mask is zero, the vehicle shall only carry the default cargo */
8833  only_defaultcargo = (ei->refit_mask == 0);
8834  }
8835 
8836  /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8837  if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8838 
8839  /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8840  * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8841  if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8842  ei->cargo_type = CT_INVALID;
8843  }
8844 
8845  /* Check if this engine's cargo type is valid. If not, set to the first refittable
8846  * cargo type. Finally disable the vehicle, if there is still no cargo. */
8847  if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8848  /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8849  const uint8 *cargo_map_for_first_refittable = nullptr;
8850  {
8851  const GRFFile *file = _gted[engine].defaultcargo_grf;
8852  if (file == nullptr) file = e->GetGRF();
8853  if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) {
8854  cargo_map_for_first_refittable = file->cargo_map;
8855  }
8856  }
8857 
8858  if (cargo_map_for_first_refittable != nullptr) {
8859  /* Use first refittable cargo from cargo translation table */
8860  byte best_local_slot = 0xFF;
8861  CargoID cargo_type;
8862  FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8863  byte local_slot = cargo_map_for_first_refittable[cargo_type];
8864  if (local_slot < best_local_slot) {
8865  best_local_slot = local_slot;
8866  ei->cargo_type = cargo_type;
8867  }
8868  }
8869  }
8870 
8871  if (ei->cargo_type == CT_INVALID) {
8872  /* Use first refittable cargo slot */
8873  ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8874  }
8875  }
8876  if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8877 
8878  /* Clear refit_mask for not refittable ships */
8879  if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8880  ei->refit_mask = 0;
8881  }
8882  }
8883 }
8884 
8886 static void FinaliseCanals()
8887 {
8888  for (uint i = 0; i < CF_END; i++) {
8889  if (_water_feature[i].grffile != nullptr) {
8892  }
8893  }
8894 }
8895 
8897 static void FinaliseEngineArray()
8898 {
8899  for (Engine *e : Engine::Iterate()) {
8900  if (e->GetGRF() == nullptr) {
8901  const EngineIDMapping &eid = _engine_mngr[e->index];
8902  if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8903  e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8904  }
8905  }
8906 
8907  if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
8908 
8909  /* When the train does not set property 27 (misc flags), but it
8910  * is overridden by a NewGRF graphically we want to disable the
8911  * flipping possibility. */
8912  if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) {
8913  ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8914  }
8915 
8916  /* Skip wagons, there livery is defined via the engine */
8917  if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8920  /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8921 
8922  if (e->type == VEH_TRAIN) {
8923  SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8924  switch (ls) {
8925  case LS_STEAM:
8926  case LS_DIESEL:
8927  case LS_ELECTRIC:
8928  case LS_MONORAIL:
8929  case LS_MAGLEV:
8930  SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8931  break;
8932 
8933  case LS_DMU:
8934  case LS_EMU:
8935  SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8936  break;
8937 
8938  default: NOT_REACHED();
8939  }
8940  }
8941  }
8942  }
8943 }
8944 
8946 static void FinaliseCargoArray()
8947 {
8948  for (CargoID c = 0; c < NUM_CARGO; c++) {
8949  CargoSpec *cs = CargoSpec::Get(c);
8950  if (!cs->IsValid()) {
8951  cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8952  cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8953  cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8954  }
8955  }
8956 }
8957 
8969 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8970 {
8971  if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8972  (next1 == nullptr || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8973  ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8974  (next2 == nullptr || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8975  next3 == nullptr || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8976  hs->enabled = false;
8977  if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
8978  return false;
8979  }
8980 
8981  /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8982  * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8983  * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8984  if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8985  ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8986  hs->enabled = false;
8987  if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
8988  return false;
8989  }
8990 
8991  /* Substitute type is also used for override, and having an override with a different size causes crashes.
8992  * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8993  if (filename != nullptr && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8994  hs->enabled = false;
8995  DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id);
8996  return false;
8997  }
8998 
8999  /* Make sure that additional parts of multitile houses are not available. */
9000  if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
9001  hs->enabled = false;
9002  if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
9003  return false;
9004  }
9005 
9006  return true;
9007 }
9008 
9015 static void EnsureEarlyHouse(HouseZones bitmask)
9016 {
9017  Year min_year = MAX_YEAR;
9018 
9019  for (int i = 0; i < NUM_HOUSES; i++) {
9020  HouseSpec *hs = HouseSpec::Get(i);
9021  if (hs == nullptr || !hs->enabled) continue;
9022  if ((hs->building_availability & bitmask) != bitmask) continue;
9023  if (hs->min_year < min_year) min_year = hs->min_year;
9024  }
9025 
9026  if (min_year == 0) return;
9027 
9028  for (int i = 0; i < NUM_HOUSES; i++) {
9029  HouseSpec *hs = HouseSpec::Get(i);
9030  if (hs == nullptr || !hs->enabled) continue;
9031  if ((hs->building_availability & bitmask) != bitmask) continue;
9032  if (hs->min_year == min_year) hs->min_year = 0;
9033  }
9034 }
9035 
9042 static void FinaliseHouseArray()
9043 {
9044  /* If there are no houses with start dates before 1930, then all houses
9045  * with start dates of 1930 have them reset to 0. This is in order to be
9046  * compatible with TTDPatch, where if no houses have start dates before
9047  * 1930 and the date is before 1930, the game pretends that this is 1930.
9048  * If there have been any houses defined with start dates before 1930 then
9049  * the dates are left alone.
9050  * On the other hand, why 1930? Just 'fix' the houses with the lowest
9051  * minimum introduction date to 0.
9052  */
9053  for (GRFFile * const file : _grf_files) {
9054  HouseSpec **&housespec = file->housespec;
9055  if (housespec == nullptr) continue;
9056 
9057  for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
9058  HouseSpec *hs = housespec[i];
9059 
9060  if (hs == nullptr) continue;
9061 
9062  const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : nullptr);
9063  const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : nullptr);
9064  const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : nullptr);
9065 
9066  if (!IsHouseSpecValid(hs, next1, next2, next3, file->filename)) continue;
9067 
9068  _house_mngr.SetEntitySpec(hs);
9069  }
9070  }
9071 
9072  for (int i = 0; i < NUM_HOUSES; i++) {
9073  HouseSpec *hs = HouseSpec::Get(i);
9074  const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
9075  const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
9076  const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
9077 
9078  /* We need to check all houses again to we are sure that multitile houses
9079  * did get consecutive IDs and none of the parts are missing. */
9080  if (!IsHouseSpecValid(hs, next1, next2, next3, nullptr)) {
9081  /* GetHouseNorthPart checks 3 houses that are directly before
9082  * it in the house pool. If any of those houses have multi-tile
9083  * flags set it assumes it's part of a multitile house. Since
9084  * we can have invalid houses in the pool marked as disabled, we
9085  * don't want to have them influencing valid tiles. As such set
9086  * building_flags to zero here to make sure any house following
9087  * this one in the pool is properly handled as 1x1 house. */
9088  hs->building_flags = TILE_NO_FLAG;
9089  }
9090  }
9091 
9092  HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
9093  EnsureEarlyHouse(HZ_ZON1 | climate_mask);
9094  EnsureEarlyHouse(HZ_ZON2 | climate_mask);
9095  EnsureEarlyHouse(HZ_ZON3 | climate_mask);
9096  EnsureEarlyHouse(HZ_ZON4 | climate_mask);
9097  EnsureEarlyHouse(HZ_ZON5 | climate_mask);
9098 
9099  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
9105  }
9106 }
9107 
9114 {
9115  for (GRFFile * const file : _grf_files) {
9116  IndustrySpec **&industryspec = file->industryspec;
9117  IndustryTileSpec **&indtspec = file->indtspec;
9118  if (industryspec != nullptr) {
9119  for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
9120  IndustrySpec *indsp = industryspec[i];
9121 
9122  if (indsp != nullptr && indsp->enabled) {
9123  StringID strid;
9124  /* process the conversion of text at the end, so to be sure everything will be fine
9125  * and available. Check if it does not return undefind marker, which is a very good sign of a
9126  * substitute industry who has not changed the string been examined, thus using it as such */
9127  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
9128  if (strid != STR_UNDEFINED) indsp->name = strid;
9129 
9130  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
9131  if (strid != STR_UNDEFINED) indsp->closure_text = strid;
9132 
9133  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
9134  if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
9135 
9136  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
9137  if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
9138 
9139  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
9140  if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
9141 
9142  if (indsp->station_name != STR_NULL) {
9143  /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
9144  * station's name. Don't want to lose the value, therefore, do not process. */
9145  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
9146  if (strid != STR_UNDEFINED) indsp->station_name = strid;
9147  }
9148 
9149  _industry_mngr.SetEntitySpec(indsp);
9150  }
9151  }
9152  }
9153 
9154  if (indtspec != nullptr) {
9155  for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
9156  IndustryTileSpec *indtsp = indtspec[i];
9157  if (indtsp != nullptr) {
9158  _industile_mngr.SetEntitySpec(indtsp);
9159  }
9160  }
9161  }
9162  }
9163 
9164  for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
9165  IndustrySpec *indsp = &_industry_specs[j];
9166  if (indsp->enabled && indsp->grf_prop.grffile != nullptr) {
9167  for (uint i = 0; i < 3; i++) {
9168  indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
9169  }
9170  }
9171  if (!indsp->enabled) {
9172  indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9173  }
9174  }
9175 }
9176 
9183 {
9184  for (GRFFile * const file : _grf_files) {
9185  ObjectSpec **&objectspec = file->objectspec;
9186  if (objectspec != nullptr) {
9187  for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
9188  if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->enabled) {
9189  _object_mngr.SetEntitySpec(objectspec[i]);
9190  }
9191  }
9192  }
9193  }
9194 }
9195 
9202 {
9203  for (GRFFile * const file : _grf_files) {
9204  AirportSpec **&airportspec = file->airportspec;
9205  if (airportspec != nullptr) {
9206  for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
9207  if (airportspec[i] != nullptr && airportspec[i]->enabled) {
9208  _airport_mngr.SetEntitySpec(airportspec[i]);
9209  }
9210  }
9211  }
9212 
9213  AirportTileSpec **&airporttilespec = file->airtspec;
9214  if (airporttilespec != nullptr) {
9215  for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
9216  if (airporttilespec[i] != nullptr && airporttilespec[i]->enabled) {
9217  _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9218  }
9219  }
9220  }
9221  }
9222 }
9223 
9224 /* Here we perform initial decoding of some special sprites (as are they
9225  * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
9226  * partial implementation yet).
9227  * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
9228  * a crafted invalid GRF file. We should tell that to the user somehow, or
9229  * better make this more robust in the future. */
9230 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
9231 {
9232  /* XXX: There is a difference between staged loading in TTDPatch and
9233  * here. In TTDPatch, for some reason actions 1 and 2 are carried out
9234  * during stage 1, whilst action 3 is carried out during stage 2 (to
9235  * "resolve" cargo IDs... wtf). This is a little problem, because cargo
9236  * IDs are valid only within a given set (action 1) block, and may be
9237  * overwritten after action 3 associates them. But overwriting happens
9238  * in an earlier stage than associating, so... We just process actions
9239  * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
9240  * --pasky
9241  * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
9242  * is not in memory and scanning the file every time would be too expensive.
9243  * In other stages we skip action 0x10 since it's already dealt with. */
9244  static const SpecialSpriteHandler handlers[][GLS_END] = {
9245  /* 0x00 */ { nullptr, SafeChangeInfo, nullptr, nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9246  /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9247  /* 0x02 */ { nullptr, nullptr, nullptr, nullptr, nullptr, NewSpriteGroup, },
9248  /* 0x03 */ { nullptr, GRFUnsafe, nullptr, nullptr, nullptr, FeatureMapSpriteGroup, },
9249  /* 0x04 */ { nullptr, nullptr, nullptr, nullptr, nullptr, FeatureNewName, },
9250  /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9251  /* 0x06 */ { nullptr, nullptr, nullptr, CfgApply, CfgApply, CfgApply, },
9252  /* 0x07 */ { nullptr, nullptr, nullptr, nullptr, SkipIf, SkipIf, },
9253  /* 0x08 */ { ScanInfo, nullptr, nullptr, GRFInfo, GRFInfo, GRFInfo, },
9254  /* 0x09 */ { nullptr, nullptr, nullptr, SkipIf, SkipIf, SkipIf, },
9255  /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9256  /* 0x0B */ { nullptr, nullptr, nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9257  /* 0x0C */ { nullptr, nullptr, nullptr, GRFComment, nullptr, GRFComment, },
9258  /* 0x0D */ { nullptr, SafeParamSet, nullptr, ParamSet, ParamSet, ParamSet, },
9259  /* 0x0E */ { nullptr, SafeGRFInhibit, nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9260  /* 0x0F */ { nullptr, GRFUnsafe, nullptr, FeatureTownName, nullptr, nullptr, },
9261  /* 0x10 */ { nullptr, nullptr, DefineGotoLabel, nullptr, nullptr, nullptr, },
9262  /* 0x11 */ { SkipAct11, GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9264  /* 0x13 */ { nullptr, nullptr, nullptr, nullptr, nullptr, TranslateGRFStrings, },
9265  /* 0x14 */ { StaticGRFInfo, nullptr, nullptr, nullptr, nullptr, nullptr, },
9266  };
9267 
9268  GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
9269 
9270  GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9271  if (it == _grf_line_to_action6_sprite_override.end()) {
9272  /* No preloaded sprite to work with; read the
9273  * pseudo sprite content. */
9274  FioReadBlock(buf, num);
9275  } else {
9276  /* Use the preloaded sprite data. */
9277  buf = _grf_line_to_action6_sprite_override[location];
9278  grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
9279 
9280  /* Skip the real (original) content of this action. */
9281  FioSeekTo(num, SEEK_CUR);
9282  }
9283 
9284  ByteReader br(buf, buf + num);
9285  ByteReader *bufp = &br;
9286 
9287  try {
9288  byte action = bufp->ReadByte();
9289 
9290  if (action == 0xFF) {
9291  grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
9292  } else if (action == 0xFE) {
9293  grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
9294  } else if (action >= lengthof(handlers)) {
9295  grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9296  } else if (handlers[action][stage] == nullptr) {
9297  grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9298  } else {
9299  grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9300  handlers[action][stage](bufp);
9301  }
9302  } catch (...) {
9303  grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9304  DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
9305  }
9306 }
9307 
9308 
9310 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9311 
9317 {
9318  size_t pos = FioGetPos();
9319 
9320  if (FioReadWord() == 0) {
9321  /* Check for GRF container version 2, which is identified by the bytes
9322  * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
9323  for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
9324  if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
9325  }
9326 
9327  return 2;
9328  }
9329 
9330  /* Container version 1 has no header, rewind to start. */
9331  FioSeekTo(pos, SEEK_SET);
9332  return 1;
9333 }
9334 
9342 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
9343 {
9344  const char *filename = config->filename;
9345 
9346  /* A .grf file is activated only if it was active when the game was
9347  * started. If a game is loaded, only its active .grfs will be
9348  * reactivated, unless "loadallgraphics on" is used. A .grf file is
9349  * considered active if its action 8 has been processed, i.e. its
9350  * action 8 hasn't been skipped using an action 7.
9351  *
9352  * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
9353  * carried out. All others are ignored, because they only need to be
9354  * processed once at initialization. */
9355  if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9356  _cur.grffile = GetFileByFilename(filename);
9357  if (_cur.grffile == nullptr) usererror("File '%s' lost in cache.\n", filename);
9358  if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
9359  if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
9360  }
9361 
9362  if (file_index >= MAX_FILE_SLOTS) {
9363  DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
9364  config->status = GCS_DISABLED;
9365  config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9366  return;
9367  }
9368 
9369  FioOpenFile(file_index, filename, subdir);
9370  _cur.file_index = file_index; // XXX
9371  _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
9372 
9373  _cur.grfconfig = config;
9374 
9375  DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
9376 
9378  if (_cur.grf_container_ver == 0) {
9379  DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9380  return;
9381  }
9382 
9383  if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9384  /* We need the sprite offsets in the init stage for NewGRF sounds
9385  * and in the activation stage for real sprites. */
9387  } else {
9388  /* Skip sprite section offset if present. */
9389  if (_cur.grf_container_ver >= 2) FioReadDword();
9390  }
9391 
9392  if (_cur.grf_container_ver >= 2) {
9393  /* Read compression value. */
9394  byte compression = FioReadByte();
9395  if (compression != 0) {
9396  DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
9397  return;
9398  }
9399  }
9400 
9401  /* Skip the first sprite; we don't care about how many sprites this
9402  * does contain; newest TTDPatches and George's longvehicles don't
9403  * neither, apparently. */
9404  uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
9405  if (num == 4 && FioReadByte() == 0xFF) {
9406  FioReadDword();
9407  } else {
9408  DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9409  return;
9410  }
9411 
9412  _cur.ClearDataForNextFile();
9413 
9415 
9416  while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
9417  byte type = FioReadByte();
9418  _cur.nfo_line++;
9419 
9420  if (type == 0xFF) {
9421  if (_cur.skip_sprites == 0) {
9422  DecodeSpecialSprite(buf.Allocate(num), num, stage);
9423 
9424  /* Stop all processing if we are to skip the remaining sprites */
9425  if (_cur.skip_sprites == -1) break;
9426 
9427  continue;
9428  } else {
9429  FioSkipBytes(num);
9430  }
9431  } else {
9432  if (_cur.skip_sprites == 0) {
9433  grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
9434  DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9435  break;
9436  }
9437 
9438  if (_cur.grf_container_ver >= 2 && type == 0xFD) {
9439  /* Reference to data section. Container version >= 2 only. */
9440  FioSkipBytes(num);
9441  } else {
9442  FioSkipBytes(7);
9443  SkipSpriteData(type, num - 8);
9444  }
9445  }
9446 
9447  if (_cur.skip_sprites > 0) _cur.skip_sprites--;
9448  }
9449 }
9450 
9458 static void ActivateOldShore()
9459 {
9460  /* Use default graphics, if no shore sprites were loaded.
9461  * Should not happen, as the base set's extra grf should include some. */
9463 
9465  DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
9466  DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
9467  DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
9468  DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
9469  DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
9470  DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
9471  DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
9472  DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
9473  }
9474 
9476  DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
9477  DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
9478  DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
9479  DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
9480  DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
9481  DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
9482  DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
9483  DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
9484 
9485  /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9486  * If they would be used somewhen, then these grass tiles will most like not look as needed */
9487  DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
9488  DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
9489  }
9490 }
9491 
9496 {
9498  DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
9499  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9500  DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
9501  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9502  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9503  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9504  }
9505 }
9506 
9511 {
9512  extern const PriceBaseSpec _price_base_specs[];
9514  static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9515 
9516  /* Evaluate grf overrides */
9517  int num_grfs = (uint)_grf_files.size();
9518  int *grf_overrides = AllocaM(int, num_grfs);
9519  for (int i = 0; i < num_grfs; i++) {
9520  grf_overrides[i] = -1;
9521 
9522  GRFFile *source = _grf_files[i];
9523  uint32 override = _grf_id_overrides[source->grfid];
9524  if (override == 0) continue;
9525 
9526  GRFFile *dest = GetFileByGRFID(override);
9527  if (dest == nullptr) continue;
9528 
9529  grf_overrides[i] = find_index(_grf_files, dest);
9530  assert(grf_overrides[i] >= 0);
9531  }
9532 
9533  /* Override features and price base multipliers of earlier loaded grfs */
9534  for (int i = 0; i < num_grfs; i++) {
9535  if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9536  GRFFile *source = _grf_files[i];
9537  GRFFile *dest = _grf_files[grf_overrides[i]];
9538 
9539  uint32 features = (source->grf_features | dest->grf_features) & override_features;
9540  source->grf_features |= features;
9541  dest->grf_features |= features;
9542 
9543  for (Price p = PR_BEGIN; p < PR_END; p++) {
9544  /* No price defined -> nothing to do */
9545  if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9546  DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9547  dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9548  }
9549  }
9550 
9551  /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9552  for (int i = num_grfs - 1; i >= 0; i--) {
9553  if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9554  GRFFile *source = _grf_files[i];
9555  GRFFile *dest = _grf_files[grf_overrides[i]];
9556 
9557  uint32 features = (source->grf_features | dest->grf_features) & override_features;
9558  source->grf_features |= features;
9559  dest->grf_features |= features;
9560 
9561  for (Price p = PR_BEGIN; p < PR_END; p++) {
9562  /* Already a price defined -> nothing to do */
9563  if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9564  DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9565  dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9566  }
9567  }
9568 
9569  /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9570  for (int i = 0; i < num_grfs; i++) {
9571  if (grf_overrides[i] < 0) continue;
9572  GRFFile *source = _grf_files[i];
9573  GRFFile *dest = _grf_files[grf_overrides[i]];
9574 
9575  uint32 features = (source->grf_features | dest->grf_features) & override_features;
9576  source->grf_features |= features;
9577  dest->grf_features |= features;
9578 
9579  for (Price p = PR_BEGIN; p < PR_END; p++) {
9580  if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9581  if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9582  DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9583  }
9584  source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9585  }
9586  }
9587 
9588  /* Apply fallback prices for grf version < 8 */
9589  for (GRFFile * const file : _grf_files) {
9590  if (file->grf_version >= 8) continue;
9591  PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9592  for (Price p = PR_BEGIN; p < PR_END; p++) {
9593  Price fallback_price = _price_base_specs[p].fallback_price;
9594  if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9595  /* No price multiplier has been set.
9596  * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9597  price_base_multipliers[p] = price_base_multipliers[fallback_price];
9598  }
9599  }
9600  }
9601 
9602  /* Decide local/global scope of price base multipliers */
9603  for (GRFFile * const file : _grf_files) {
9604  PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9605  for (Price p = PR_BEGIN; p < PR_END; p++) {
9606  if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9607  /* No multiplier was set; set it to a neutral value */
9608  price_base_multipliers[p] = 0;
9609  } else {
9610  if (!HasBit(file->grf_features, _price_base_specs[p].grf_feature)) {
9611  /* The grf does not define any objects of the feature,
9612  * so it must be a difficulty setting. Apply it globally */
9613  DEBUG(grf, 3, "'%s' sets global price base multiplier %d", file->filename, p);
9614  SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9615  price_base_multipliers[p] = 0;
9616  } else {
9617  DEBUG(grf, 3, "'%s' sets local price base multiplier %d", file->filename, p);
9618  }
9619  }
9620  }
9621  }
9622 }
9623 
9624 extern void InitGRFTownGeneratorNames();
9625 
9627 static void AfterLoadGRFs()
9628 {
9629  for (StringIDMapping &it : _string_to_grf_mapping) {
9630  *it.target = MapGRFStringID(it.grfid, it.source);
9631  }
9632  _string_to_grf_mapping.clear();
9633 
9634  /* Free the action 6 override sprites. */
9635  for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9636  free((*it).second);
9637  }
9638  _grf_line_to_action6_sprite_override.clear();
9639 
9640  /* Polish cargoes */
9642 
9643  /* Pre-calculate all refit masks after loading GRF files. */
9645 
9646  /* Polish engines */
9648 
9649  /* Set the actually used Canal properties */
9650  FinaliseCanals();
9651 
9652  /* Add all new houses to the house array. */
9654 
9655  /* Add all new industries to the industry array. */
9657 
9658  /* Add all new objects to the object array. */
9660 
9662 
9663  /* Sort the list of industry types. */
9665 
9666  /* Create dynamic list of industry legends for smallmap_gui.cpp */
9668 
9669  /* Build the routemap legend, based on the available cargos */
9671 
9672  /* Add all new airports to the airports array. */
9674  BindAirportSpecs();
9675 
9676  /* Update the townname generators list */
9678 
9679  /* Run all queued vehicle list order changes */
9681 
9682  /* Load old shore sprites in new position, if they were replaced by ActionA */
9683  ActivateOldShore();
9684 
9685  /* Load old tram depot sprites in new position, if no new ones are present */
9687 
9688  /* Set up custom rail types */
9689  InitRailTypes();
9690  InitRoadTypes();
9691 
9692  for (Engine *e : Engine::IterateType(VEH_ROAD)) {
9693  if (_gted[e->index].rv_max_speed != 0) {
9694  /* Set RV maximum speed from the mph/0.8 unit value */
9695  e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9696  }
9697 
9698  RoadTramType rtt = HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? RTT_TRAM : RTT_ROAD;
9699 
9700  const GRFFile *file = e->GetGRF();
9701  if (file == nullptr || _gted[e->index].roadtramtype == 0) {
9702  e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
9703  continue;
9704  }
9705 
9706  /* Remove +1 offset. */
9707  _gted[e->index].roadtramtype--;
9708 
9709  const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
9710  if (_gted[e->index].roadtramtype < list->size())
9711  {
9712  RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
9713  RoadType rt = GetRoadTypeByLabel(rtl);
9714  if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
9715  e->u.road.roadtype = rt;
9716  continue;
9717  }
9718  }
9719 
9720  /* Road type is not available, so disable this engine */
9721  e->info.climates = 0;
9722  }
9723 
9724  for (Engine *e : Engine::IterateType(VEH_TRAIN)) {
9725  RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9726  if (railtype == INVALID_RAILTYPE) {
9727  /* Rail type is not available, so disable this engine */
9728  e->info.climates = 0;
9729  } else {
9730  e->u.rail.railtype = railtype;
9731  }
9732  }
9733 
9735 
9737 
9738  /* Deallocate temporary loading data */
9739  free(_gted);
9740  _grm_sprites.clear();
9741 }
9742 
9749 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9750 {
9751  /* In case of networking we need to "sync" the start values
9752  * so all NewGRFs are loaded equally. For this we use the
9753  * start date of the game and we set the counters, etc. to
9754  * 0 so they're the same too. */
9755  Date date = _date;
9756  Year year = _cur_year;
9757  DateFract date_fract = _date_fract;
9758  uint16 tick_counter = _tick_counter;
9759  byte display_opt = _display_opt;
9760 
9761  if (_networking) {
9763  _date = ConvertYMDToDate(_cur_year, 0, 1);
9764  _date_fract = 0;
9765  _tick_counter = 0;
9766  _display_opt = 0;
9767  }
9768 
9770 
9771  ResetNewGRFData();
9772 
9773  /*
9774  * Reset the status of all files, so we can 'retry' to load them.
9775  * This is needed when one for example rearranges the NewGRFs in-game
9776  * and a previously disabled NewGRF becomes usable. If it would not
9777  * be reset, the NewGRF would remain disabled even though it should
9778  * have been enabled.
9779  */
9780  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9781  if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9782  }
9783 
9784  _cur.spriteid = load_index;
9785 
9786  /* Load newgrf sprites
9787  * in each loading stage, (try to) open each file specified in the config
9788  * and load information from it. */
9789  for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9790  /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9791  * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9792  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9793  if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9794  }
9795 
9796  if (stage == GLS_RESERVE) {
9797  static const uint32 overrides[][2] = {
9798  { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9799  { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9800  { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9801  };
9802  for (size_t i = 0; i < lengthof(overrides); i++) {
9803  SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9804  }
9805  }
9806 
9807  uint slot = file_index;
9808  uint num_non_static = 0;
9809 
9810  _cur.stage = stage;
9811  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9812  if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9813  if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9814 
9815  Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9816  if (!FioCheckFileExists(c->filename, subdir)) {
9817  DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9818  c->status = GCS_NOT_FOUND;
9819  continue;
9820  }
9821 
9822  if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9823 
9824  if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9825  if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9826  DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9827  c->status = GCS_DISABLED;
9828  c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9829  continue;
9830  }
9831  num_non_static++;
9832  }
9833  LoadNewGRFFile(c, slot++, stage, subdir);
9834  if (stage == GLS_RESERVE) {
9835  SetBit(c->flags, GCF_RESERVED);
9836  } else if (stage == GLS_ACTIVATION) {
9837  ClrBit(c->flags, GCF_RESERVED);
9838  assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9841  DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9842  } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9843  /* We're not going to activate this, so free whatever data we allocated */
9845  }
9846  }
9847  }
9848 
9849  /* Pseudo sprite processing is finished; free temporary stuff */
9850  _cur.ClearDataForNextFile();
9851 
9852  /* Call any functions that should be run after GRFs have been loaded. */
9853  AfterLoadGRFs();
9854 
9855  /* Now revert back to the original situation */
9856  _cur_year = year;
9857  _date = date;
9858  _date_fract = date_fract;
9859  _tick_counter = tick_counter;
9860  _display_opt = display_opt;
9861 }
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
MapLogX
static uint MapLogX()
Logarithm of the map size along the X side.
Definition: map_func.h:51
GRFConfig::version
uint32 version
NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown.
Definition: newgrf_config.h:165
ResetCustomHouses
static void ResetCustomHouses()
Reset and clear all NewGRF houses.
Definition: newgrf.cpp:8430
AirportSpec::min_year
Year min_year
first year the airport is available
Definition: newgrf_airport.h:109
RoadTypeInfo::flags
RoadTypeFlags flags
Bit mask of road type flags.
Definition: road.h:124
ChangeGRFName
static bool ChangeGRFName(byte langid, const char *str)
Callback function for 'INFO'->'NAME' to add a translation to the newgrf name.
Definition: newgrf.cpp:7800
AllowedSubtags::call_handler
bool call_handler
True if there is a callback function for this node, false if there is a list of subnodes.
Definition: newgrf.cpp:8080
RoadTypeInfo::new_engine
StringID new_engine
Name of an engine for this type of road in the engine preview GUI.
Definition: road.h:105
StationChangeInfo
static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
Define properties for stations.
Definition: newgrf.cpp:1860
ParamSet
static void ParamSet(ByteReader *buf)
Action 0x0D: Set parameter.
Definition: newgrf.cpp:7074
GRFLocation
Definition: newgrf.cpp:348
TE_WATER
@ TE_WATER
Cargo behaves water-like.
Definition: cargotype.h:30
CalculateRefitMasks
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition: newgrf.cpp:8783
GRFP_USE_MASK
@ GRFP_USE_MASK
Bitmask to get only the use palette use states.
Definition: newgrf_config.h:68
RoadTypeInfo::toolbar_caption
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition: road.h:101
HouseSpec::removal_cost
byte removal_cost
cost multiplier for removing it
Definition: house.h:103
AllocateSound
SoundEntry * AllocateSound(uint num)
Allocate sound slots.
Definition: newgrf_sound.cpp:31
GRFTempEngineData::UpdateRefittability
void UpdateRefittability(bool non_empty)
Update the summary refittability on setting a refittability property.
Definition: newgrf.cpp:327
INVALID_ENGINE
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:174
EngineInfo::base_life
Year base_life
Basic duration of engine availability (without random parts). 0xFF means infinite life.
Definition: engine_type.h:135
YearMonthDay::day
Day day
Day (1..31)
Definition: date_type.h:106
Action5Type::sprite_base
SpriteID sprite_base
Load the sprites starting from this sprite.
Definition: newgrf.cpp:6091
OrderSettings::improved_load
bool improved_load
improved loading algorithm
Definition: settings_type.h:439
MAX_NUM_GENDERS
static const uint8 MAX_NUM_GENDERS
Maximum number of supported genders.
Definition: language.h:20
INVALID_AIRPORTTILE
static const uint INVALID_AIRPORTTILE
id for an invalid airport tile
Definition: airport.h:25
RoadTypeInfo
Definition: road.h:75
GRFConfig::num_valid_params
uint8 num_valid_params
NOSAVE: Number of valid parameters (action 0x14)
Definition: newgrf_config.h:172
DuplicateTileTable
static void DuplicateTileTable(AirportSpec *as)
Create a copy of the tile table so it can be freed later without problems.
Definition: newgrf.cpp:3777
NUM_STATIONS_PER_GRF
static const uint NUM_STATIONS_PER_GRF
Number of StationSpecs per NewGRF; limited to 255 to allow extending Action3 with an extended byte la...
Definition: newgrf.cpp:301
PROP_TRAIN_SPEED
@ PROP_TRAIN_SPEED
Max. speed: 1 unit = 1/1.6 mph = 1 km-ish/h.
Definition: newgrf_properties.h:21
GRFConfig::info
GRFTextWrapper info
NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
Definition: newgrf_config.h:161
CargoSpec::callback_mask
uint8 callback_mask
Bitmask of cargo callbacks that have to be called.
Definition: cargotype.h:68
AllowedSubtags::AllowedSubtags
AllowedSubtags()
Create empty subtags object used to identify the end of a list.
Definition: newgrf.cpp:8015
RealSpriteGroup::loaded
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
Definition: newgrf_spritegroup.h:92
GRFFileProps::override
uint16 override
id of the entity been replaced by
Definition: newgrf_commons.h:333
NUM_INDUSTRYTYPES
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like INV...
Definition: industry_type.h:26
RAILTYPE_MAGLEV
@ RAILTYPE_MAGLEV
Maglev.
Definition: rail_type.h:32
ResetCustomObjects
static void ResetCustomObjects()
Reset and clear all NewObjects.
Definition: newgrf.cpp:8511
RailVehicleInfo::pow_wag_weight
byte pow_wag_weight
Extra weight applied to consist if wagon should be powered.
Definition: engine_type.h:56
Engine::IterateType
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
Definition: engine_base.h:157
IndustrySpec::map_colour
byte map_colour
colour used for the small map
Definition: industrytype.h:126
LanguageMetadata
Make sure the size is right.
Definition: language.h:92
VE_DISABLE_EFFECT
@ VE_DISABLE_EFFECT
Flag to disable visual effect.
Definition: vehicle_base.h:88
RailtypeInfo::max_speed
uint16 max_speed
Maximum speed for vehicles travelling on this rail type.
Definition: rail.h:228
newgrf_station.h
newgrf_house.h
GRFFile::language_map
struct LanguageMap * language_map
Mappings related to the languages.
Definition: newgrf.h:140
GRFFile::roadtype_list
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition: newgrf.h:132
Pool::PoolItem<&_engine_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:329
EngineOverrideManager::ResetToDefaultMapping
void ResetToDefaultMapping()
Initializes the EngineOverrideManager with the default engines.
Definition: engine.cpp:484
CargoSpec::label
CargoLabel label
Unique label of the cargo type.
Definition: cargotype.h:57
StationSpec::flags
byte flags
Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size.
Definition: newgrf_station.h:160
LanguageMap::case_map
std::vector< Mapping > case_map
Mapping of NewGRF and OpenTTD IDs for cases.
Definition: newgrf_text.h:72
PROP_TRAIN_CARGO_CAPACITY
@ PROP_TRAIN_CARGO_CAPACITY
Capacity (if dualheaded: for each single vehicle)
Definition: newgrf_properties.h:24
Direction
Direction
Defines the 8 directions on the map.
Definition: direction_type.h:24
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, AllowedSubtags *subtags)
Create a branch node with a list of sub-nodes.
Definition: newgrf.cpp:8062
GRFConfig::error
GRFError * error
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
Definition: newgrf_config.h:163
GameSettings::station
StationSettings station
settings related to station management
Definition: settings_type.h:559
WChar
char32_t WChar
Type for wide characters, i.e.
Definition: string_type.h:35
ResetCustomAirports
static void ResetCustomAirports()
Reset and clear all NewGRF airports.
Definition: newgrf.cpp:8445
GRFTextList
std::vector< GRFText > GRFTextList
A GRF text with a list of translations.
Definition: newgrf_text.h:31
PROP_ROADVEH_TRACTIVE_EFFORT
@ PROP_ROADVEH_TRACTIVE_EFFORT
Tractive effort coefficient in 1/256.
Definition: newgrf_properties.h:38
SNOW_LINE_DAYS
static const uint SNOW_LINE_DAYS
Number of days in each month in the snow line table.
Definition: landscape.h:17
ObjectChangeInfo
static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for objects.
Definition: newgrf.cpp:4024
FioReadBlock
void FioReadBlock(void *ptr, size_t size)
Read a block.
Definition: fileio.cpp:161
EngineIDMapping::grfid
uint32 grfid
The GRF ID of the file the entity belongs to.
Definition: engine_base.h:164
RoadTypeInfo::menu_text
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition: road.h:102
IndustryProductionSpriteGroup::subtract_input
int16 subtract_input[INDUSTRY_NUM_INPUTS]
Take this much of the input cargo (can be negative, is indirect in cb version 1+)
Definition: newgrf_spritegroup.h:281
usererror
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
Definition: openttd.cpp:100
DeterministicSpriteGroupRange
Definition: newgrf_spritegroup.h:163
NUM_INDUSTRYTYPES_PER_GRF
static const IndustryType NUM_INDUSTRYTYPES_PER_GRF
maximum number of industry types per NewGRF; limited to 128 because bit 7 has a special meaning in so...
Definition: industry_type.h:23
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:32
SPR_SHORE_BASE
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition: sprites.h:218
TLF_DODRAW
@ TLF_DODRAW
Only draw sprite if value of register TileLayoutRegisters::dodraw is non-zero.
Definition: newgrf_commons.h:36
ReusableBuffer
A reusable buffer that can be used for places that temporary allocate a bit of memory and do that ver...
Definition: alloc_type.hpp:24
AircraftVehicleInfo::subtype
byte subtype
Type of aircraft.
Definition: engine_type.h:101
OBJECT_FLAG_2CC_COLOUR
@ OBJECT_FLAG_2CC_COLOUR
Object wants 2CC colour mapping.
Definition: newgrf_object.h:34
ShipVehicleChangeInfo
static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for ships.
Definition: newgrf.cpp:1534
FioReadWord
uint16 FioReadWord()
Read a word (16 bits) from the file (in low endian format).
Definition: fileio.cpp:140
GetRoadTypeByLabel
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition: road.cpp:243
HouseSpec::random_colour
byte random_colour[4]
4 "random" colours
Definition: house.h:116
PROP_ROADVEH_COST_FACTOR
@ PROP_ROADVEH_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:34
GCS_ACTIVATED
@ GCS_ACTIVATED
GRF file has been activated.
Definition: newgrf_config.h:39
ObjectSpec
Allow incrementing of ObjectClassID variables.
Definition: newgrf_object.h:58
CanalProperties::callback_mask
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf.h:40
RailtypeInfo::menu_text
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition: rail.h:175
ObjectSpec::grf_prop
GRFFilePropsBase< 2 > grf_prop
Properties related the the grf file.
Definition: newgrf_object.h:60
GrfProcessingState::grffile
GRFFile * grffile
Currently processed GRF file.
Definition: newgrf.cpp:103
RoadTypeInfo::strings
struct RoadTypeInfo::@44 strings
Strings associated with the rail type.
ObjectFlags
ObjectFlags
Various object behaviours.
Definition: newgrf_object.h:24
DrawTileSeqStruct::IsParentSprite
bool IsParentSprite() const
Check whether this is a parent sprite with a boundingbox.
Definition: sprite.h:47
ConstructionSettings::max_heightlevel
uint8 max_heightlevel
maximum allowed heightlevel
Definition: settings_type.h:305
BridgeSpec::flags
byte flags
bit 0 set: disable drawing of far pillars.
Definition: bridge.h:52
ObjectSpec::build_cost_multiplier
uint8 build_cost_multiplier
Build cost multiplier per tile.
Definition: newgrf_object.h:66
BridgeSpec::avail_year
Year avail_year
the year where it becomes available
Definition: bridge.h:42
ResetCustomIndustries
static void ResetCustomIndustries()
Reset and clear all NewGRF industries.
Definition: newgrf.cpp:8482
PROP_TRAIN_RUNNING_COST_FACTOR
@ PROP_TRAIN_RUNNING_COST_FACTOR
Yearly runningcost (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:23
smallmap_gui.h
_grf_files
static std::vector< GRFFile * > _grf_files
List of all loaded GRF files.
Definition: newgrf.cpp:66
SPRITE_WIDTH
@ SPRITE_WIDTH
number of bits for the sprite number
Definition: sprites.h:1519
GameCreationSettings::landscape
byte landscape
the landscape we're currently in
Definition: settings_type.h:293
StringIDMapping::grfid
uint32 grfid
Source NewGRF.
Definition: newgrf.cpp:462
ShipVehicleInfo::canal_speed_frac
byte canal_speed_frac
Fraction of maximum speed for canal/river tiles.
Definition: engine_type.h:75
TLF_CHILD_X_OFFSET
@ TLF_CHILD_X_OFFSET
Add signed offset to child sprite X positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:44
RoadTypeInfo::introduces_roadtypes
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition: road.h:174
_engine_counts
const uint8 _engine_counts[4]
Number of engines of each vehicle type in original engine data.
Definition: engine.cpp:50
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, DataHandler handler)
Create a binary leaf node.
Definition: newgrf.cpp:8025
GRFFile::price_base_multipliers
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition: newgrf.h:146
FeatureTownName
static void FeatureTownName(ByteReader *buf)
Action 0x0F - Define Town names.
Definition: newgrf.cpp:7424
grfmsg
void CDECL grfmsg(int severity, const char *str,...)
DEBUG() function dedicated to newGRF debugging messages Function is essentially the same as DEBUG(grf...
Definition: newgrf.cpp:379
_cur_year
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:25
IndustriesChangeInfo
static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
Define properties for industries.
Definition: newgrf.cpp:3397
DeterministicSpriteGroup
Definition: newgrf_spritegroup.h:170
TileLayoutRegisters::sprite
uint8 sprite
Register specifying a signed offset for the sprite.
Definition: newgrf_commons.h:94
PROP_TRAIN_TRACTIVE_EFFORT
@ PROP_TRAIN_TRACTIVE_EFFORT
Tractive effort coefficient in 1/256.
Definition: newgrf_properties.h:27
AllowedSubtags::branch
BranchHandler branch
Callback function for a branch node, only valid if type == 'C' && call_handler.
Definition: newgrf.cpp:8077
FioOpenFile
void FioOpenFile(int slot, const std::string &filename, Subdirectory subdir)
Open a slotted file.
Definition: fileio.cpp:196
HandleNodes
static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
Handle the contents of a 'C' choice of an Action14.
Definition: newgrf.cpp:8272
HouseSpec::accepts_cargo
CargoID accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition: house.h:108
RoadTypeInfo::sorting_order
byte sorting_order
The sorting order of this roadtype for the toolbar dropdown.
Definition: road.h:179
AirportSpec::size_y
byte size_y
size of airport in y direction
Definition: newgrf_airport.h:106
CargoSpec::town_effect
TownEffect town_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
Definition: cargotype.h:66
NewGRFSpriteLayout::AllocateRegisters
void AllocateRegisters()
Allocate memory for register modifiers.
Definition: newgrf_commons.cpp:636
RealSpriteGroup::num_loaded
byte num_loaded
Number of loaded groups.
Definition: newgrf_spritegroup.h:90
Pool::CleanPool
virtual void CleanPool()
Virtual method that deletes all items in the pool.
PALETTE_MODIFIER_COLOUR
@ PALETTE_MODIFIER_COLOUR
this bit is set when a recolouring process is in action
Definition: sprites.h:1534
BASESET_DIR
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition: fileio_type.h:116
currency.h
GRFConfig::num_params
uint8 num_params
Number of used parameters.
Definition: newgrf_config.h:171
GetNewEngine
static Engine * GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access=false)
Returns the engine associated to a certain internal_id, resp.
Definition: newgrf.cpp:599
_date_fract
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:28
TileLayoutRegisters::parent
uint8 parent[3]
Registers for signed offsets for the bounding box position of parent sprites.
Definition: newgrf_commons.h:99
NamePart::prob
byte prob
The relative probability of the following name to appear in the bottom 7 bits.
Definition: newgrf_townname.h:19
Price
Price
Enumeration of all base prices for use with Prices.
Definition: economy_type.h:74
PROP_AIRCRAFT_MAIL_CAPACITY
@ PROP_AIRCRAFT_MAIL_CAPACITY
Mail Capacity.
Definition: newgrf_properties.h:52
AirportSpec::name
StringID name
name of this airport
Definition: newgrf_airport.h:111
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition: road_type.h:27
FinaliseCanals
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition: newgrf.cpp:8886
RailtypeInfo::replace_text
StringID replace_text
Text used in the autoreplace GUI.
Definition: rail.h:177
TE_FOOD
@ TE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition: cargotype.h:31
GRFFile::grf_features
uint32 grf_features
Bitset of GrfSpecFeature the grf uses.
Definition: newgrf.h:145
LanguageMap::plural_form
int plural_form
The plural form used for this language.
Definition: newgrf_text.h:73
CurrencySpec::symbol_pos
byte symbol_pos
The currency symbol is represented by two possible values, prefix and suffix Usage of one or the othe...
Definition: currency.h:84
EC_STEAM
@ EC_STEAM
Steam rail engine.
Definition: engine_type.h:34
PriceBaseSpec::grf_feature
uint grf_feature
GRF Feature that decides whether price multipliers apply locally or globally, #GSF_END if none.
Definition: economy_type.h:193
AircraftVehicleInfo::passenger_capacity
uint16 passenger_capacity
Passenger capacity (persons).
Definition: engine_type.h:106
IndustrySpec::removal_cost_multiplier
uint32 removal_cost_multiplier
Base removal cost multiplier.
Definition: industrytype.h:110
RandomizedSpriteGroup::cmp_mode
RandomizedSpriteGroupCompareMode cmp_mode
Check for these triggers:
Definition: newgrf_spritegroup.h:202
DeterministicSpriteGroupAdjust::parameter
byte parameter
Used for variables between 0x60 and 0x7F inclusive.
Definition: newgrf_spritegroup.h:154
VE_DEFAULT
@ VE_DEFAULT
Default value to indicate that visual effect should be based on engine class.
Definition: vehicle_base.h:92
A5BLOCK_INVALID
@ A5BLOCK_INVALID
unknown/not-implemented type
Definition: newgrf.cpp:6086
Action5BlockType
Action5BlockType
The type of action 5 type.
Definition: newgrf.cpp:6083
ChangeGRFParamLimits
static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter.
Definition: newgrf.cpp:7947
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:227
PROP_ROADVEH_SHORTEN_FACTOR
@ PROP_ROADVEH_SHORTEN_FACTOR
Shorter vehicles.
Definition: newgrf_properties.h:40
BridgeSpec::sprite_table
PalSpriteID ** sprite_table
table of sprites for drawing the bridge
Definition: bridge.h:51
IsValidNewGRFImageIndex
static bool IsValidNewGRFImageIndex(uint8 image_index)
Helper to check whether an image index is valid for a particular NewGRF vehicle.
Definition: newgrf.cpp:205
AirportSpec::max_year
Year max_year
last year the airport is available
Definition: newgrf_airport.h:110
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:117
IndustryProductionSpriteGroup::num_input
uint8 num_input
How many subtract_input values are valid.
Definition: newgrf_spritegroup.h:280
ResetPersistentNewGRFData
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition: newgrf.cpp:8644
PROP_SHIP_CARGO_CAPACITY
@ PROP_SHIP_CARGO_CAPACITY
Capacity.
Definition: newgrf_properties.h:44
TileLayoutRegisters::palette_var10
uint8 palette_var10
Value for variable 10 when resolving the palette.
Definition: newgrf_commons.h:103
HouseExtraFlags
HouseExtraFlags
Definition: house.h:88
_grf_cont_v2_sig
const byte _grf_cont_v2_sig[8]
Signature of a container version 2 GRF.
_bridge
BridgeSpec _bridge[MAX_BRIDGES]
The specification of all bridges.
Definition: tunnelbridge_cmd.cpp:49
PalSpriteID::sprite
SpriteID sprite
The 'real' sprite.
Definition: gfx_type.h:23
GrfProcessingState::ClearDataForNextFile
void ClearDataForNextFile()
Clear temporary data before processing the next file in the current loading stage.
Definition: newgrf.cpp:115
GrfProcessingState::grf_container_ver
byte grf_container_ver
Container format of the current GRF file.
Definition: newgrf.cpp:106
PROP_AIRCRAFT_RUNNING_COST_FACTOR
@ PROP_AIRCRAFT_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:50
RAILTYPE_MONO
@ RAILTYPE_MONO
Monorail.
Definition: rail_type.h:31
HouseSpec::enabled
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition: house.h:111
AirportSpec::noise_level
byte noise_level
noise that this airport generates
Definition: newgrf_airport.h:107
ChangeGRFVersion
static bool ChangeGRFVersion(size_t len, ByteReader *buf)
Callback function for 'INFO'->'VRSN' to the version of the NewGRF.
Definition: newgrf.cpp:7881
SortIndustryTypes
void SortIndustryTypes()
Initialize the list of sorted industry types.
Definition: industry_gui.cpp:206
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103
ResetPriceBaseMultipliers
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition: economy.cpp:871
ChangeGRFParamName
static bool ChangeGRFParamName(byte langid, const char *str)
Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter.
Definition: newgrf.cpp:7916
ResetRailTypes
void ResetRailTypes()
Reset all rail type information to its default values.
Definition: rail_cmd.cpp:63
GrfProcessingState::spritesets
std::map< uint, SpriteSet > spritesets[GSF_END]
Currently referenceable spritesets.
Definition: newgrf.cpp:94
GrfProcessingState::spriteid
SpriteID spriteid
First available SpriteID for loading realsprites.
Definition: newgrf.cpp:99
RailtypeInfo
This struct contains all the info that is needed to draw and construct tracks.
Definition: rail.h:124
WaterFeature::callback_mask
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf_canal.h:25
ClrBit
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
Definition: bitmath_func.hpp:151
VehicleSettings::wagon_speed_limits
bool wagon_speed_limits
enable wagon speed limits
Definition: settings_type.h:454
CIR_INVALID_ID
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
Definition: newgrf.cpp:991
GRFParameterInfo::param_nr
byte param_nr
GRF parameter to store content in.
Definition: newgrf_config.h:140
TLF_CUSTOM_PALETTE
@ TLF_CUSTOM_PALETTE
Palette is from Action 1 (moved to SPRITE_MODIFIER_CUSTOM_SPRITE in palette during loading).
Definition: newgrf_commons.h:39
RailtypeInfo::grffile
const GRFFile * grffile[RTSG_END]
NewGRF providing the Action3 for the railtype.
Definition: rail.h:273
SetNewGRFOverride
static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
Set the override for a NewGRF.
Definition: newgrf.cpp:585
_tags_info
AllowedSubtags _tags_info[]
Action14 tags for the INFO node.
Definition: newgrf.cpp:8168
Year
int32 Year
Type for the year, note: 0 based, i.e. starts at the year 0.
Definition: date_type.h:18
ReadGRFSpriteOffsets
void ReadGRFSpriteOffsets(byte container_version)
Parse the sprite section of GRFs.
Definition: spritecache.cpp:502
vehicle_base.h
GRFUnsafe
static void GRFUnsafe(ByteReader *buf)
Set the current NewGRF as unsafe for static use.
Definition: newgrf.cpp:8298
GRFParameterInfo::def_value
uint32 def_value
Default value of this parameter.
Definition: newgrf_config.h:139
ROADTYPE_END
@ ROADTYPE_END
Used for iterations.
Definition: road_type.h:26
fileio_func.h
GCS_NOT_FOUND
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition: newgrf_config.h:37
ConvertTTDBasePrice
static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
Converts TTD(P) Base Price pointers into the enum used by OTTD See http://wiki.ttdpatch....
Definition: newgrf.cpp:966
newgrf_airport.h
SetupCargoForClimate
void SetupCargoForClimate(LandscapeID l)
Set up the default cargo types for the given landscape type.
Definition: cargotype.cpp:39
build_industry.h
GRFTempEngineData::ctt_include_mask
CargoTypes ctt_include_mask
Cargo types always included in the refit mask.
Definition: newgrf.cpp:320
HouseSpec::building_name
StringID building_name
building name
Definition: house.h:104
ObjectSpec::end_of_life_date
Date end_of_life_date
When can't this object be built anymore.
Definition: newgrf_object.h:69
SetupEngines
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition: engine.cpp:540
GetGRFContainerVersion
byte GetGRFContainerVersion()
Get the container version of the currently opened GRF file.
Definition: newgrf.cpp:9316
OverrideManagerBase::GetID
virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const
Return the ID (if ever available) of a previously inserted entity.
Definition: newgrf_commons.cpp:102
GRFConfig::ident
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
Definition: newgrf_config.h:157
newgrf_townname.h
TE_NONE
@ TE_NONE
Cargo has no effect.
Definition: cargotype.h:26
AircraftVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 8 mph = 12.8 km-ish/h)
Definition: engine_type.h:104
AirportSpec::ResetAirports
static void ResetAirports()
This function initializes the airportspec array.
Definition: newgrf_airport.cpp:155
GCF_COPY
@ GCF_COPY
The data is copied from a grf in _all_grfs.
Definition: newgrf_config.h:27
CargoSpec
Specification of a cargo type.
Definition: cargotype.h:55
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, TextHandler handler)
Create a text leaf node.
Definition: newgrf.cpp:8037
ReusableBuffer::Allocate
T * Allocate(size_t count)
Get buffer of at least count times T.
Definition: alloc_type.hpp:42
GRFConfig::status
GRFStatus status
NOSAVE: GRFStatus, enum.
Definition: newgrf_config.h:168
GetNewGRFSoundID
SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id)
Resolve NewGRF sound ID.
Definition: newgrf_sound.cpp:168
VE_TYPE_COUNT
@ VE_TYPE_COUNT
Number of bits used for the effect type.
Definition: vehicle_base.h:82
town.h
ORIGINAL_BASE_YEAR
static const Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
Definition: date_type.h:49
NUM_OBJECTS_PER_GRF
static const ObjectType NUM_OBJECTS_PER_GRF
Number of supported objects per NewGRF; limited to 255 to allow extending Action3 with an extended by...
Definition: object_type.h:22
RailVehicleInfo::power
uint16 power
Power of engine (hp); For multiheaded engines the sum of both engine powers.
Definition: engine_type.h:48
GRFP_GRF_UNSET
@ GRFP_GRF_UNSET
The NewGRF provided no information.
Definition: newgrf_config.h:70
EngineInfo
Information about a vehicle.
Definition: engine_type.h:132
ChangeGRFParamType
static bool ChangeGRFParamType(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter.
Definition: newgrf.cpp:7930
DSGA_OP_ADD
@ DSGA_OP_ADD
a + b
Definition: newgrf_spritegroup.h:124
GMB_TRAIN_WIDTH_32_PIXELS
@ GMB_TRAIN_WIDTH_32_PIXELS
Use 32 pixels per train vehicle in depot gui and vehicle details. Never set in the global variable;.
Definition: newgrf.h:60
IndustrySpec::station_name
StringID station_name
Default name for nearby station.
Definition: industrytype.h:132
CreateGroupFromGroupID
static const SpriteGroup * CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
Helper function to either create a callback or a result sprite group.
Definition: newgrf.cpp:4940
DIR_W
@ DIR_W
West.
Definition: direction_type.h:32
_display_opt
byte _display_opt
What do we want to draw/do?
Definition: transparency_gui.cpp:26
OverrideManagerBase::Add
void Add(uint8 local_id, uint32 grfid, uint entity_type)
Since the entity IDs defined by the GRF file does not necessarily correlate to those used by the game...
Definition: newgrf_commons.cpp:72
EngineInfo::base_intro
Date base_intro
Basic date of engine introduction (without random parts).
Definition: engine_type.h:133
CIR_SUCCESS
@ CIR_SUCCESS
Variable was parsed and read.
Definition: newgrf.cpp:987
MAX_SPRITEGROUP
static const uint MAX_SPRITEGROUP
Maximum GRF-local ID for a spritegroup.
Definition: newgrf.cpp:82
GRFLoadedFeatures::used_liveries
uint64 used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition: newgrf.h:176
HouseSpec::max_year
Year max_year
last year it can be built
Definition: house.h:101
VehicleSettings::road_side
byte road_side
the side of the road vehicles drive on
Definition: settings_type.h:465
RoadTypeInfo::replace_text
StringID replace_text
Text used in the autoreplace GUI.
Definition: road.h:104
AllowedSubtags::text
TextHandler text
Callback function for a text node, only valid if type == 'T'.
Definition: newgrf.cpp:8074
VSG_SCOPE_PARENT
@ VSG_SCOPE_PARENT
Related object of the resolved one.
Definition: newgrf_spritegroup.h:104
RailtypeInfo::fallback_railtype
byte fallback_railtype
Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations.
Definition: rail.h:198
Engine
Definition: engine_base.h:21
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
EngineIDMapping::internal_id
uint16 internal_id
The internal ID within the GRF file.
Definition: engine_base.h:165
GRFParameterInfo::type
GRFParameterType type
The type of this parameter.
Definition: newgrf_config.h:136
SoundEffectChangeInfo
static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
Define properties for sound effects.
Definition: newgrf.cpp:3052
_tags_parameters
AllowedSubtags _tags_parameters[]
Action14 parameter tags.
Definition: newgrf.cpp:8124
RoadVehicleInfo::roadtype
RoadType roadtype
Road type.
Definition: engine_type.h:125
RoadTypeInfo::introduction_date
Date introduction_date
Introduction date.
Definition: road.h:163
ROADTYPE_ROAD
@ ROADTYPE_ROAD
Basic road type.
Definition: road_type.h:24
SoundEntry::grf_container_ver
byte grf_container_ver
NewGRF container version if the sound is from a NewGRF.
Definition: sound_type.h:22
fios.h
TranslateGRFStrings
static void TranslateGRFStrings(ByteReader *buf)
Action 0x13.
Definition: newgrf.cpp:7745
SmallMap::Insert
bool Insert(const T &key, const U &data)
Adds new item to this map.
Definition: smallmap_type.hpp:127
BridgeSpec::speed
uint16 speed
maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: bridge.h:46
FinalisePriceBaseMultipliers
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition: newgrf.cpp:9510
TranslateTTDPatchCodes
std::string TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const std::string &str, StringControlCode byte80)
Translate TTDPatch string codes into something OpenTTD can handle (better).
Definition: newgrf_text.cpp:241
MemCpyT
static void MemCpyT(T *destination, const T *source, size_t num=1)
Type-safe version of memcpy().
Definition: mem_func.hpp:23
TLF_BB_Z_OFFSET
@ TLF_BB_Z_OFFSET
Add signed offset to bounding box Z positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:42
GRFTempEngineData::rv_max_speed
uint8 rv_max_speed
Temporary storage of RV prop 15, maximum speed in mph/0.8.
Definition: newgrf.cpp:319
ObjectSpec::size
uint8 size
The size of this objects; low nibble for X, high nibble for Y.
Definition: newgrf_object.h:65
GRFFile::GetParam
uint32 GetParam(uint number) const
Get GRF Parameter with range checking.
Definition: newgrf.h:152
AirportSpec
Defines the data structure for an airport.
Definition: newgrf_airport.h:98
EngineOverrideManager::GetID
EngineID GetID(VehicleType type, uint16 grf_local_id, uint32 grfid)
Looks up an EngineID in the EngineOverrideManager.
Definition: engine.cpp:507
ObjectSpec::callback_mask
uint16 callback_mask
Bitmask of requested/allowed callbacks.
Definition: newgrf_object.h:72
NUM_HOUSES_PER_GRF
static const HouseID NUM_HOUSES_PER_GRF
Number of supported houses per NewGRF; limited to 255 to allow extending Action3 with an extended byt...
Definition: house.h:25
genworld.h
RailtypeInfo::sorting_order
byte sorting_order
The sorting order of this railtype for the toolbar dropdown.
Definition: rail.h:268
TileLayoutRegisters
Additional modifiers for items in sprite layouts.
Definition: newgrf_commons.h:91
AnimationInfo::speed
uint8 speed
The speed, i.e. the amount of time between frames.
Definition: newgrf_animation_type.h:21
TileLayoutRegisters::dodraw
uint8 dodraw
Register deciding whether the sprite shall be drawn at all. Non-zero means drawing.
Definition: newgrf_commons.h:93
GRFIdentifier::grfid
uint32 grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:84
GRFP_BLT_UNSET
@ GRFP_BLT_UNSET
The NewGRF provided no information or doesn't care about a 32 bpp blitter.
Definition: newgrf_config.h:76
CargoLabel
uint32 CargoLabel
Globally unique label of a cargo type.
Definition: cargotype.h:21
ObjectSpec::animation
AnimationInfo animation
Information about the animation.
Definition: newgrf_object.h:71
CIR_UNHANDLED
@ CIR_UNHANDLED
Variable was parsed but unread.
Definition: newgrf.cpp:989
RoadVehicleInfo::air_drag
uint8 air_drag
Coefficient of air drag.
Definition: engine_type.h:122
AirportSpec::maintenance_cost
uint16 maintenance_cost
maintenance cost multiplier
Definition: newgrf_airport.h:115
VSG_SCOPE_SELF
@ VSG_SCOPE_SELF
Resolved object itself.
Definition: newgrf_spritegroup.h:103
CargoSpec::bitnum
uint8 bitnum
Cargo bit number, is INVALID_CARGO for a non-used spec.
Definition: cargotype.h:56
SPR_AQUEDUCT_BASE
static const SpriteID SPR_AQUEDUCT_BASE
Sprites for the Aqueduct.
Definition: sprites.h:180
RailVehicleInfo::cost_factor
byte cost_factor
Purchase cost factor; For multiheaded engines the sum of both engine prices.
Definition: engine_type.h:45
StationSpec::renderdata
NewGRFSpriteLayout * renderdata
Array of tile layouts.
Definition: newgrf_station.h:148
DeterministicSpriteGroupAdjustOperation
DeterministicSpriteGroupAdjustOperation
Definition: newgrf_spritegroup.h:123
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:548
GRFParameterInfo::num_bit
byte num_bit
Number of bits to use for this parameter.
Definition: newgrf_config.h:142
RAILTYPE_ELECTRIC
@ RAILTYPE_ELECTRIC
Electric rails.
Definition: rail_type.h:30
RandomizedSpriteGroup::var_scope
VarSpriteGroupScope var_scope
Take this object:
Definition: newgrf_spritegroup.h:200
GCF_INVALID
@ GCF_INVALID
GRF is unusable with this version of OpenTTD.
Definition: newgrf_config.h:30
AllocateRoadType
RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
Allocate a new road type label.
Definition: road_cmd.cpp:138
FioReadDword
uint32 FioReadDword()
Read a double word (32 bits) from the file (in low endian format).
Definition: fileio.cpp:150
AirportChangeInfo
static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
Define properties for airports.
Definition: newgrf.cpp:3806
IndustryTileLayout
std::vector< IndustryTileLayoutTile > IndustryTileLayout
A complete tile layout for an industry is a list of tiles.
Definition: industrytype.h:102
GCF_INIT_ONLY
@ GCF_INIT_ONLY
GRF file is processed up to GLS_INIT.
Definition: newgrf_config.h:28
EC_ELECTRIC
@ EC_ELECTRIC
Electric rail engine.
Definition: engine_type.h:36
AddGRFString
StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string)
Add the new read string into our structure.
Definition: newgrf_text.cpp:552
IsInsideMM
static bool IsInsideMM(const T x, const size_t min, const size_t max)
Checks if a value is in an interval.
Definition: math_func.hpp:204
GetFileByGRFID
static GRFFile * GetFileByGRFID(uint32 grfid)
Obtain a NewGRF file by its grfID.
Definition: newgrf.cpp:396
SpriteID
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
ObjectSpec::introduction_date
Date introduction_date
From when can this object be built.
Definition: newgrf_object.h:68
TE_MAIL
@ TE_MAIL
Cargo behaves mail-like.
Definition: cargotype.h:28
StringIDMapping::target
StringID * target
Destination for mapping result.
Definition: newgrf.cpp:464
StationSpec::tiles
uint tiles
Number of tile layouts.
Definition: newgrf_station.h:147
RailtypeInfo::introduction_required_railtypes
RailTypes introduction_required_railtypes
Bitmask of railtypes that are required for this railtype to be introduced at a given introduction_dat...
Definition: rail.h:258
BridgeSpec
Struct containing information about a single bridge type.
Definition: bridge.h:41
RailtypeInfo::name
StringID name
Name of this rail type.
Definition: rail.h:173
IndustrySpec::closure_text
StringID closure_text
Message appearing when the industry closes.
Definition: industrytype.h:129
EngineInfo::lifelength
Year lifelength
Lifetime of a single vehicle.
Definition: engine_type.h:134
Engine::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:138
GrfProcessingState::SpriteSet::sprite
SpriteID sprite
SpriteID of the first sprite of the set.
Definition: newgrf.cpp:89
RandomizedSpriteGroup::num_groups
byte num_groups
must be power of 2
Definition: newgrf_spritegroup.h:207
GRFFile::traininfo_vehicle_pitch
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition: newgrf.h:142
AirportTileSpec::ResetAirportTiles
static void ResetAirportTiles()
This function initializes the tile array of AirportTileSpec.
Definition: newgrf_airporttiles.cpp:57
TLF_KNOWN_FLAGS
@ TLF_KNOWN_FLAGS
Known flags. Any unknown set flag will disable the GRF.
Definition: newgrf_commons.h:50
TE_PASSENGERS
@ TE_PASSENGERS
Cargo behaves passenger-like.
Definition: cargotype.h:27
ShipVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:73
RoadVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:117
DrawTileSprites::ground
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
HouseSpec::extra_flags
HouseExtraFlags extra_flags
some more flags
Definition: house.h:118
GetRailTypeInfo
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:304
AirportTileSpec
Defines the data structure of each individual tile of an airport.
Definition: newgrf_airporttiles.h:66
HouseSpec::probability
byte probability
Relative probability of appearing (16 is the standard value)
Definition: house.h:117
NETWORK_MAX_GRF_COUNT
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition: config.h:58
IndustryTileSpec::special_flags
IndustryTileSpecialFlags special_flags
Bitmask of extra flags used by the tile.
Definition: industrytype.h:170
StationSpec::cls_id
StationClassID cls_id
The class to which this spec belongs.
Definition: newgrf_station.h:125
EC_MAGLEV
@ EC_MAGLEV
Maglev engine.
Definition: engine_type.h:38
GRFTempEngineData::Refittability
Refittability
Summary state of refittability properties.
Definition: newgrf.cpp:306
RealSpriteGroup::loading
const SpriteGroup ** loading
List of loading groups (can be SpriteIDs or Callback results)
Definition: newgrf_spritegroup.h:93
NFO_UTF8_IDENTIFIER
static const WChar NFO_UTF8_IDENTIFIER
This character, the thorn ('þ'), indicates a unicode string to NFO.
Definition: newgrf_text.h:22
IndustryProductionSpriteGroup::num_output
uint8 num_output
How many add_output values are valid.
Definition: newgrf_spritegroup.h:283
newgrf_airporttiles.h
GameSettings::order
OrderSettings order
settings related to orders
Definition: settings_type.h:555
Pool::PoolItem<&_engine_pool >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:350
InitGRFTownGeneratorNames
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
Definition: settings_gui.cpp:83
GRFP_GRF_DOS
@ GRFP_GRF_DOS
The NewGRF says the DOS palette can be used.
Definition: newgrf_config.h:71
_grm_engines
static uint32 _grm_engines[256]
Contains the GRF ID of the owner of a vehicle if it has been reserved.
Definition: newgrf.cpp:343
FioSkipBytes
void FioSkipBytes(int n)
Skip n bytes ahead in the file.
Definition: fileio.cpp:124
MAX_CATCHMENT
@ MAX_CATCHMENT
Maximum catchment for airports with "modified catchment" enabled.
Definition: station_type.h:84
AnimationInfo::frames
uint8 frames
The number of frames.
Definition: newgrf_animation_type.h:19
DrawTileSeqStruct::delta_x
int8 delta_x
0x80 is sequence terminator
Definition: sprite.h:26
GRFLoadedFeatures::has_2CC
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
Definition: newgrf.h:175
PROP_ROADVEH_SPEED
@ PROP_ROADVEH_SPEED
Max. speed: 1 unit = 1/0.8 mph = 2 km-ish/h.
Definition: newgrf_properties.h:37
RailVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:57
TileIndexDiffC::y
int16 y
The y value of the coordinate.
Definition: map_type.h:59
GrfProcessingState::HasValidSpriteSets
bool HasValidSpriteSets(byte feature) const
Check whether there are any valid spritesets for a feature.
Definition: newgrf.cpp:151
DisableStaticNewGRFInfluencingNonStaticNewGRFs
static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition: newgrf.cpp:6512
CargoSpec::Index
CargoID Index() const
Determines index of this cargospec.
Definition: cargotype.h:88
AirportSpec::rotation
const Direction * rotation
the rotation of each tiletable
Definition: newgrf_airport.h:101
EngineID
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:21
SHORE_REPLACE_NONE
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition: newgrf.h:162
RailVehicleInfo::ai_passenger_only
byte ai_passenger_only
Bit value to tell AI that this engine is for passenger use only.
Definition: engine_type.h:54
EconomySettings::station_noise_level
bool station_noise_level
build new airports when the town noise level is still within accepted limits
Definition: settings_type.h:491
RailVehicleInfo
Information about a rail vehicle.
Definition: engine_type.h:42
GRFLoadedFeatures::shore
ShoreReplacement shore
In which way shore sprites were replaced.
Definition: newgrf.h:177
_gted
static GRFTempEngineData * _gted
Temporary engine data used during NewGRF loading.
Definition: newgrf.cpp:337
RoadTypeInfo::powered_roadtypes
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power
Definition: road.h:119
NUM_AIRPORTTILES_PER_GRF
static const uint NUM_AIRPORTTILES_PER_GRF
Number of airport tiles per NewGRF; limited to 255 to allow extending Action3 with an extended byte l...
Definition: airport.h:21
RailVehicleInfo::engclass
EngineClass engclass
Class of engine for this vehicle.
Definition: engine_type.h:52
IndustryTileSpec::acceptance
int8 acceptance[INDUSTRY_NUM_INPUTS]
Level of acceptance per cargo type (signed, may be negative!)
Definition: industrytype.h:158
BindAirportSpecs
void BindAirportSpecs()
Tie all airportspecs to their class.
Definition: newgrf_airport.cpp:167
VE_TYPE_START
@ VE_TYPE_START
First bit used for the type of effect.
Definition: vehicle_base.h:81
RailType
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:27
GRFFile::tramtype_list
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition: newgrf.h:135
GetSnowLine
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:644
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:27
PROP_AIRCRAFT_CARGO_AGE_PERIOD
@ PROP_AIRCRAFT_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:53
NEW_INDUSTRYOFFSET
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
Definition: industry_type.h:25
RailVehicleInfo::air_drag
byte air_drag
Coefficient of air drag.
Definition: engine_type.h:60
LanguageMap::GetLanguageMap
static const LanguageMap * GetLanguageMap(uint32 grfid, uint8 language_id)
Get the language map associated with a given NewGRF and language.
Definition: newgrf.cpp:2574
GCF_UNSAFE
@ GCF_UNSAFE
GRF file is unsafe for static usage.
Definition: newgrf_config.h:24
GCS_INITIALISED
@ GCS_INITIALISED
GRF file has been initialised.
Definition: newgrf_config.h:38
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:152
NUM_HOUSES
static const HouseID NUM_HOUSES
Total number of houses.
Definition: house.h:29
newgrf_engine.h
PROP_ROADVEH_CARGO_AGE_PERIOD
@ PROP_ROADVEH_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:39
MAX_BRIDGES
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition: bridge.h:34
DrawTileSeqStruct::delta_z
int8 delta_z
0x80 identifies child sprites
Definition: sprite.h:28
StringIDMapping::source
StringID source
Source StringID (GRF local).
Definition: newgrf.cpp:463
AirportSpec::num_table
byte num_table
number of elements in the table
Definition: newgrf_airport.h:102
SetPriceBaseMultiplier
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition: economy.cpp:883
IndustrySpec::conflicting
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:112
EngineInfo::callback_mask
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:143
TLF_BB_XY_OFFSET
@ TLF_BB_XY_OFFSET
Add signed offset to bounding box X and Y positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:41
DIR_E
@ DIR_E
East.
Definition: direction_type.h:28
MIN_YEAR
static const Year MIN_YEAR
The absolute minimum & maximum years in OTTD.
Definition: date_type.h:83
OverrideManagerBase::ResetMapping
void ResetMapping()
Resets the mapping, which is used while initializing game.
Definition: newgrf_commons.cpp:82
FinaliseIndustriesArray
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition: newgrf.cpp:9113
TLF_CHILD_Y_OFFSET
@ TLF_CHILD_Y_OFFSET
Add signed offset to child sprite Y positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:45
GRFP_GRF_ANY
@ GRFP_GRF_ANY
The NewGRF says any palette can be used.
Definition: newgrf_config.h:73
GCF_SYSTEM
@ GCF_SYSTEM
GRF file is an openttd-internal system grf.
Definition: newgrf_config.h:23
YearMonthDay::month
Month month
Month (0..11)
Definition: date_type.h:105
NEW_HOUSE_OFFSET
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition: house.h:28
HandleParameterInfo
static bool HandleParameterInfo(ByteReader *buf)
Callback function for 'INFO'->'PARA' to set extra information about the parameters.
Definition: newgrf.cpp:8141
StationSpec::pylons
byte pylons
Bitmask of base tiles (0 - 7) which should contain elrail pylons.
Definition: newgrf_station.h:162
DEBUG
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
AirportTileTable::gfx
StationGfx gfx
AirportTile to use for this tile.
Definition: newgrf_airport.h:25
CallbackResultSpriteGroup
Definition: newgrf_spritegroup.h:218
CargoSpec::units_volume
StringID units_volume
Name of a single unit of cargo of this type.
Definition: cargotype.h:72
CargoSpec::IsValid
bool IsValid() const
Tests for validity of this cargospec.
Definition: cargotype.h:98
RailtypeInfo::alternate_labels
RailTypeLabelList alternate_labels
Rail type labels this type provides in addition to the main label.
Definition: rail.h:238
HouseSpec::building_flags
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition: house.h:109
SkipSpriteData
bool SkipSpriteData(byte type, uint16 num)
Skip the given amount of sprite graphics data.
Definition: spritecache.cpp:94
RoadVehicleInfo
Information about a road vehicle.
Definition: engine_type.h:111
GRFConfig::flags
uint8 flags
NOSAVE: GCF_Flags, bitset.
Definition: newgrf_config.h:167
BranchHandler
bool(* BranchHandler)(ByteReader *)
Type of callback function for branch nodes.
Definition: newgrf.cpp:8004
LanguageMap::Mapping::openttd_id
byte openttd_id
OpenTTD's internal ID for a case/gender.
Definition: newgrf_text.h:62
SB
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
Definition: bitmath_func.hpp:58
RoadVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:123
IndustryProductionSpriteGroup
Definition: newgrf_spritegroup.h:276
ConvertYMDToDate
Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition: date.cpp:148
IndustrySpec::layouts
std::vector< IndustryTileLayout > layouts
List of possible tile layouts for the industry.
Definition: industrytype.h:108
SPRITE_MODIFIER_OPAQUE
@ SPRITE_MODIFIER_OPAQUE
Set when a sprite must not ever be displayed transparently.
Definition: sprites.h:1532
IndustrySpec::accepts_cargo
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 accepted cargoes.
Definition: industrytype.h:121
INDUSTRYTILE_NOANIM
static const IndustryGfx INDUSTRYTILE_NOANIM
flag to mark industry tiles as having no animation
Definition: industry_type.h:31
INVALID_INDUSTRYTILE
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
Definition: industry_type.h:34
GetGRFSpriteOffset
size_t GetGRFSpriteOffset(uint32 id)
Get the file offset for a specific sprite in the sprite section of a GRF.
Definition: spritecache.cpp:493
EF_USES_2CC
@ EF_USES_2CC
Vehicle uses two company colours.
Definition: engine_type.h:155
ROADTYPE_TRAM
@ ROADTYPE_TRAM
Trams.
Definition: road_type.h:25
SHORE_REPLACE_ONLY_NEW
@ SHORE_REPLACE_ONLY_NEW
Only corner-shores were loaded by Action5 (openttd(w/d).grf only).
Definition: newgrf.h:165
IndustrySpec::number_of_sounds
uint8 number_of_sounds
Number of sounds available in the sounds array.
Definition: industrytype.h:135
find_index
int find_index(std::vector< T > const &vec, T const &item)
Helper function to get the index of an item Consider using std::set, std::unordered_set or std::flat_...
Definition: smallvec_type.hpp:44
BridgeSpec::transport_name
StringID transport_name[2]
description of the bridge, when built for road or rail
Definition: bridge.h:50
_cargo_mask
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition: cargotype.cpp:28
AircraftVehicleInfo::max_range
uint16 max_range
Maximum range of this aircraft.
Definition: engine_type.h:107
AddGenericCallback
void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group)
Add a generic feature callback sprite group to the appropriate feature list.
Definition: newgrf_generic.cpp:111
SP_CUSTOM
@ SP_CUSTOM
No profile, special "custom" highscore.
Definition: settings_type.h:34
NUM_AIRPORTS_PER_GRF
@ NUM_AIRPORTS_PER_GRF
Maximal number of airports per NewGRF.
Definition: airport.h:40
IndustrySpec::production_up_text
StringID production_up_text
Message appearing when the industry's production is increasing.
Definition: industrytype.h:130
CleanUpStrings
void CleanUpStrings()
House cleaning.
Definition: newgrf_text.cpp:696
Date
int32 Date
The type to store our dates in.
Definition: date_type.h:14
EnsureEarlyHouse
static void EnsureEarlyHouse(HouseZones bitmask)
Make sure there is at least one house available in the year 0 for the given climate / housezone combi...
Definition: newgrf.cpp:9015
GrfProcessingState::SpriteSet
Definition of a single Action1 spriteset.
Definition: newgrf.cpp:88
CargoSpec::multipliertowngrowth
uint16 multipliertowngrowth
Size of the effect.
Definition: cargotype.h:67
IndustrySpec::input_cargo_multiplier
uint16 input_cargo_multiplier[INDUSTRY_NUM_INPUTS][INDUSTRY_NUM_OUTPUTS]
Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes)
Definition: industrytype.h:122
CargoSpec::grffile
const struct GRFFile * grffile
NewGRF where #group belongs to.
Definition: cargotype.h:79
StaticGRFInfo
static void StaticGRFInfo(ByteReader *buf)
Handle Action 0x14.
Definition: newgrf.cpp:8287
EC_DIESEL
@ EC_DIESEL
Diesel rail engine.
Definition: engine_type.h:35
HZ_ZONALL
@ HZ_ZONALL
1F This is just to englobe all above types at once
Definition: house.h:78
NewGRFClass
Struct containing information relating to NewGRF classes for stations and airports.
Definition: newgrf_class.h:19
StationSettings::never_expire_airports
bool never_expire_airports
never expire airports
Definition: settings_type.h:523
AfterLoadGRFs
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition: newgrf.cpp:9627
_cur_parameter
static GRFParameterInfo * _cur_parameter
The parameter which info is currently changed by the newgrf.
Definition: newgrf.cpp:7913
IndustrySpec::minimal_cargo
byte minimal_cargo
minimum amount of cargo transported to the stations.
Definition: industrytype.h:120
RoadTypeInfo::group
const SpriteGroup * group[ROTSG_END]
Sprite groups for resolving sprites.
Definition: road.h:189
LanguageMap::gender_map
std::vector< Mapping > gender_map
Mapping of NewGRF and OpenTTD IDs for genders.
Definition: newgrf_text.h:71
SHORE_REPLACE_ACTION_5
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition: newgrf.h:163
StringIDMapping
Information for mapping static StringIDs.
Definition: newgrf.cpp:461
RailtypeInfo::introduction_date
Date introduction_date
Introduction date.
Definition: rail.h:252
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:80
HouseSpec::animation
AnimationInfo animation
information about the animation.
Definition: house.h:120
NUM_INDUSTRYTILES_PER_GRF
static const IndustryGfx NUM_INDUSTRYTILES_PER_GRF
Maximum number of industry tiles per NewGRF; limited to 255 to allow extending Action3 with an extend...
Definition: industry_type.h:29
ANIM_STATUS_NO_ANIMATION
static const uint8 ANIM_STATUS_NO_ANIMATION
There is no animation.
Definition: newgrf_animation_type.h:15
ValidateIndustryLayout
static bool ValidateIndustryLayout(const IndustryTileLayout &layout)
Validate the industry layout; e.g.
Definition: newgrf.cpp:3375
MAX_FILE_SLOTS
@ MAX_FILE_SLOTS
Maximum number of slots.
Definition: fios.h:99
RoadTypeInfo::alternate_labels
RoadTypeLabelList alternate_labels
Road type labels this type provides in addition to the main label.
Definition: road.h:149
MapNewGRFIndustryType
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id)
Map the GRF local type to an industry type.
Definition: newgrf_industries.cpp:39
ChangeGRFURL
static bool ChangeGRFURL(byte langid, const char *str)
Callback function for 'INFO'->'URL_' to set the newgrf url.
Definition: newgrf.cpp:7814
_water_feature
WaterFeature _water_feature[CF_END]
Table of canal 'feature' sprite groups.
Definition: newgrf_canal.cpp:21
PriceBaseSpec::fallback_price
Price fallback_price
Fallback price multiplier for new prices but old grfs.
Definition: economy_type.h:194
GRFParameterInfo
Information about one grf parameter.
Definition: newgrf_config.h:131
CargoSpec::sprite
SpriteID sprite
Icon to display this cargo type, may be 0xFFF (which means to resolve an action123 chain).
Definition: cargotype.h:76
ConvertDateToYMD
void ConvertDateToYMD(Date date, YearMonthDay *ymd)
Converts a Date to a Year, Month & Day.
Definition: date.cpp:93
GameSettings::economy
EconomySettings economy
settings to change the economy
Definition: settings_type.h:557
DrawTileSeqStruct::IsTerminator
bool IsTerminator() const
Check whether this is a sequence terminator.
Definition: sprite.h:41
AirportSpec::ttd_airport_type
TTDPAirportType ttd_airport_type
ttdpatch airport type (Small/Large/Helipad/Oilrig)
Definition: newgrf_airport.h:112
PROP_SHIP_CARGO_AGE_PERIOD
@ PROP_SHIP_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:46
HandleNode
static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
Handle the nodes of an Action14.
Definition: newgrf.cpp:8234
_tick_counter
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:29
TileLayoutRegisters::child
uint8 child[2]
Registers for signed offsets for the position of child sprites.
Definition: newgrf_commons.h:100
_action5_types
static const Action5Type _action5_types[]
The information about action 5 types.
Definition: newgrf.cpp:6098
NewGRFSpriteLayout
NewGRF supplied spritelayout.
Definition: newgrf_commons.h:113
MAX_LANG
static const uint MAX_LANG
Maximum number of languages supported by the game, and the NewGRF specs.
Definition: strings_type.h:19
safeguards.h
GRFFile::label
GRFLabel * label
Pointer to the first label. This is a linked list, not an array.
Definition: newgrf.h:124
ChangeGRFParamMask
static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use.
Definition: newgrf.cpp:7969
StationSpec::name
StringID name
Name of this station.
Definition: newgrf_station.h:126
ObjectOverrideManager::SetEntitySpec
void SetEntitySpec(ObjectSpec *spec)
Method to install the new object data in its proper slot The slot assignment is internal of this meth...
Definition: newgrf_commons.cpp:315
GRFP_BLT_32BPP
@ GRFP_BLT_32BPP
The NewGRF prefers a 32 bpp blitter.
Definition: newgrf_config.h:77
HouseSpec::callback_mask
uint16 callback_mask
Bitmask of house callbacks that have to be called.
Definition: house.h:115
IndustryTileSpec::slopes_refused
Slope slopes_refused
slope pattern on which this tile cannot be built
Definition: industrytype.h:159
ChangeGRFParamValueNames
static bool ChangeGRFParamValueNames(ByteReader *buf)
Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names of some parameter values (ty...
Definition: newgrf.cpp:8094
ImportGRFSound
static void ImportGRFSound(SoundEntry *sound)
Process a sound import from another GRF file.
Definition: newgrf.cpp:7539
GRFConfig::has_param_defaults
bool has_param_defaults
NOSAVE: did this newgrf specify any defaults for it's parameters.
Definition: newgrf_config.h:175
GRFFile::param_end
uint param_end
one more than the highest set parameter
Definition: newgrf.h:122
TLR_MAX_VAR10
static const uint TLR_MAX_VAR10
Maximum value for var 10.
Definition: newgrf_commons.h:106
GetGRFStringID
StringID GetGRFStringID(uint32 grfid, StringID stringid)
Returns the index for this stringid associated with its grfID.
Definition: newgrf_text.cpp:602
ttd_strnlen
static size_t ttd_strnlen(const char *str, size_t maxlen)
Get the length of a string, within a limited buffer.
Definition: string_func.h:72
GrfProcessingState
Temporary data during loading of GRFs.
Definition: newgrf.cpp:85
SPRITE_MODIFIER_CUSTOM_SPRITE
@ SPRITE_MODIFIER_CUSTOM_SPRITE
Set when a sprite originates from an Action 1.
Definition: sprites.h:1531
IndustryTileSpec::enabled
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:171
StrEmpty
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:60
_tags_root
AllowedSubtags _tags_root[]
Action14 root tags.
Definition: newgrf.cpp:8182
CargoSpec::weight
uint8 weight
Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
Definition: cargotype.h:60
FinaliseObjectsArray
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition: newgrf.cpp:9182
GRFTempEngineData::EMPTY
@ EMPTY
GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
Definition: newgrf.cpp:308
TranslateRefitMask
static CargoTypes TranslateRefitMask(uint32 refit_mask)
Translate the refit mask.
Definition: newgrf.cpp:948
ObjectSpec::height
uint8 height
The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
Definition: newgrf_object.h:73
WaterFeature::flags
uint8 flags
Flags controlling display.
Definition: newgrf_canal.h:26
NamePart::text
char * text
If probability bit 7 is clear.
Definition: newgrf_townname.h:21
DrawTileSprites
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
HouseSpec::minimum_life
byte minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition: house.h:122
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:52
TTDPAirportType
TTDPAirportType
Allow incrementing of AirportClassID variables.
Definition: newgrf_airport.h:81
CanalChangeInfo
static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for water features.
Definition: newgrf.cpp:2107
LoadTranslationTable
static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
Load a cargo- or railtype-translation table.
Definition: newgrf.cpp:2591
GlobalVarChangeInfo
static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
Define properties for global variables.
Definition: newgrf.cpp:2615
newgrf_text.h
road.h
vseprintf
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
Safer implementation of vsnprintf; same as vsnprintf except:
Definition: string.cpp:61
LoadNewGRFFile
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
Load a particular NewGRF.
Definition: newgrf.cpp:9342
RoadTypeInfo::name
StringID name
Name of this rail type.
Definition: road.h:100
error.h
GrfProcessingState::GetSprite
SpriteID GetSprite(byte feature, uint set) const
Returns the first sprite of a spriteset.
Definition: newgrf.cpp:176
RailVehicleChangeInfo
static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for rail vehicles.
Definition: newgrf.cpp:1046
CargoSpec::is_freight
bool is_freight
Cargo type is considered to be freight (affects train freight multiplier).
Definition: cargotype.h:65
RandomizedSpriteGroup::groups
const SpriteGroup ** groups
Take the group with appropriate index:
Definition: newgrf_spritegroup.h:209
Slope
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
HZ_ZON5
@ HZ_ZON5
center of town
Definition: house.h:77
GRFTempEngineData::ctt_exclude_mask
CargoTypes ctt_exclude_mask
Cargo types always excluded from the refit mask.
Definition: newgrf.cpp:321
GRFTempEngineData::defaultcargo_grf
const GRFFile * defaultcargo_grf
GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
Definition: newgrf.cpp:316
ResetCurrencies
void ResetCurrencies(bool preserve_custom)
Will fill _currency_specs array with default values from origin_currency_specs Called only from newgr...
Definition: currency.cpp:155
EngineIDMapping
Definition: engine_base.h:163
AirportTileTable
Tile-offset / AirportTileID pair.
Definition: newgrf_airport.h:23
IndustrySpec::appear_creation
byte appear_creation[NUM_LANDSCAPE]
Probability of appearance during map creation.
Definition: industrytype.h:134
GRFP_GRF_MASK
@ GRFP_GRF_MASK
Bitmask to get only the NewGRF supplied information.
Definition: newgrf_config.h:74
_loaded_newgrf_features
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition: newgrf.cpp:80
language.h
IndustryTileSpec::anim_production
byte anim_production
Animation frame to start when goods are produced.
Definition: industrytype.h:160
EngineInfo::retire_early
int8 retire_early
Number of years early to retire vehicle.
Definition: engine_type.h:144
GetNewEngineID
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
Return the ID of a new engine.
Definition: newgrf.cpp:695
RailVehicleInfo::tractive_effort
byte tractive_effort
Tractive effort coefficient.
Definition: engine_type.h:59
GRFFile::traininfo_vehicle_width
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition: newgrf.h:143
EngineIDMapping::substitute_id
uint8 substitute_id
The (original) entity ID to use if this GRF is not available (currently not used)
Definition: engine_base.h:167
CargoChangeInfo
static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
Define properties for cargoes.
Definition: newgrf.cpp:2913
date_func.h
SoundEntry
Definition: sound_type.h:13
StationSpec::disallowed_platforms
byte disallowed_platforms
Bitmask of number of platforms available for the station.
Definition: newgrf_station.h:132
stdafx.h
GrfProcessingState::grfconfig
GRFConfig * grfconfig
Config of the currently processed GRF file.
Definition: newgrf.cpp:104
FioSeekTo
void FioSeekTo(size_t pos, int mode)
Seek in the current file.
Definition: fileio.cpp:79
TLF_NON_GROUND_FLAGS
@ TLF_NON_GROUND_FLAGS
Flags which do not work for the (first) ground sprite.
Definition: newgrf_commons.h:56
RoadType
RoadType
The different roadtypes we support.
Definition: road_type.h:22
VehicleType
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
IsLeapYear
static bool IsLeapYear(Year yr)
Checks whether the given year is a leap year or not.
Definition: date_func.h:30
landscape.h
ObjectSpec::enabled
bool enabled
Is this spec enabled?
Definition: newgrf_object.h:76
RailVehicleInfo::pow_wag_power
uint16 pow_wag_power
Extra power applied to consist if wagon should be powered.
Definition: engine_type.h:55
RailtypeInfo::toolbar_caption
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition: rail.h:174
OTTDByteReaderSignal
Definition: newgrf.cpp:210
PROP_AIRCRAFT_COST_FACTOR
@ PROP_AIRCRAFT_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:48
IndustrySpec
Defines the data structure for constructing industry.
Definition: industrytype.h:107
RailVehicleInfo::weight
uint16 weight
Weight of vehicle (tons); For multiheaded engines the weight of each single engine.
Definition: engine_type.h:49
IndustryTileSpec::grf_prop
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:172
BSWAP32
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Definition: bitmath_func.hpp:380
SPR_RAILTYPE_TUNNEL_BASE
static const SpriteID SPR_RAILTYPE_TUNNEL_BASE
Tunnel sprites with grass only for custom railtype tunnel.
Definition: sprites.h:295
EngineClass
EngineClass
Type of rail engine.
Definition: engine_type.h:33
PALETTE_MODIFIER_TRANSPARENT
@ PALETTE_MODIFIER_TRANSPARENT
when a sprite is to be displayed transparently, this bit needs to be set.
Definition: sprites.h:1533
NEWGRF_DIR
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition: fileio_type.h:117
IgnoreIndustryProperty
static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
Ignore an industry property.
Definition: newgrf.cpp:3285
GRFTempEngineData::refittability
Refittability refittability
Did the newgrf set any refittability property? If not, default refittability will be applied.
Definition: newgrf.cpp:317
EngineInfo::misc_flags
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:142
HouseSpec::mail_generation
byte mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition: house.h:106
A5BLOCK_FIXED
@ A5BLOCK_FIXED
Only allow replacing a whole block of sprites. (TTDP compatible)
Definition: newgrf.cpp:6084
GRFTownName
Definition: newgrf_townname.h:34
A5BLOCK_ALLOW_OFFSET
@ A5BLOCK_ALLOW_OFFSET
Allow replacing any subset by specifiing an offset.
Definition: newgrf.cpp:6085
HouseSpec::population
byte population
population (Zero on other tiles in multi tile house.)
Definition: house.h:102
PROP_SHIP_RUNNING_COST_FACTOR
@ PROP_SHIP_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:45
RailtypeInfo::powered_railtypes
RailTypes powered_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype generates power
Definition: rail.h:185
RAILVEH_WAGON
@ RAILVEH_WAGON
simple wagon, not motorized
Definition: engine_type.h:29
LanguageMap::Mapping
Mapping between NewGRF and OpenTTD IDs.
Definition: newgrf_text.h:60
BuildCargoTranslationMap
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition: newgrf.cpp:8659
Utf8Decode
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition: string.cpp:481
HouseSpec::cargo_acceptance
byte cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition: house.h:107
RailtypeInfo::map_colour
byte map_colour
Colour on mini-map.
Definition: rail.h:243
WaterFeature::grffile
const GRFFile * grffile
NewGRF where 'group' belongs to.
Definition: newgrf_canal.h:24
_engine_offsets
const uint8 _engine_offsets[4]
Offset of the first engine of each vehicle type in original engine data.
Definition: engine.cpp:58
ShipVehicleInfo::old_refittable
bool old_refittable
Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask.
Definition: engine_type.h:72
AllowedSubtags::type
byte type
The type of the node, must be one of 'C', 'B' or 'T'.
Definition: newgrf.cpp:8071
GRFParameterInfo::first_bit
byte first_bit
First bit to use in the GRF parameter.
Definition: newgrf_config.h:141
BuildIndustriesLegend
void BuildIndustriesLegend()
Fills an array for the industries legends.
Definition: smallmap_gui.cpp:168
SetSnowLine
void SetSnowLine(byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS])
Set a variable snow line, as loaded from a newgrf file.
Definition: landscape.cpp:625
newgrf_object.h
BridgeSpec::min_length
byte min_length
the minimum length (not counting start and end tile)
Definition: bridge.h:43
IndustryProductionSpriteGroup::add_output
uint16 add_output[INDUSTRY_NUM_OUTPUTS]
Add this much output cargo when successful (unsigned, is indirect in cb version 1+)
Definition: newgrf_spritegroup.h:284
ObjectSpec::name
StringID name
The name for this object.
Definition: newgrf_object.h:62
ChangeGRFBlitter
static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
Callback function for 'INFO'->'BLTR' to set the blitter info.
Definition: newgrf.cpp:7859
FioGetPos
size_t FioGetPos()
Get position in the current file.
Definition: fileio.cpp:59
AirportSpec::size_x
byte size_x
size of airport in x direction
Definition: newgrf_airport.h:105
LoadNextSprite
bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id, byte container_version)
Load a real or recolour sprite.
Definition: spritecache.cpp:535
FinaliseEngineArray
static void FinaliseEngineArray()
Check for invalid engines.
Definition: newgrf.cpp:8897
GRFParameterType
GRFParameterType
The possible types of a newgrf parameter.
Definition: newgrf_config.h:124
ChangeGRFNumUsedParams
static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
Callback function for 'INFO'->'NPAR' to set the number of valid parameters.
Definition: newgrf.cpp:7821
GRFTempEngineData::UNSET
@ UNSET
No properties assigned. Default refit masks shall be activated.
Definition: newgrf.cpp:307
ChangeGRFMinVersion
static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF.
Definition: newgrf.cpp:7894
TileLayoutRegisters::sprite_var10
uint8 sprite_var10
Value for variable 10 when resolving the sprite.
Definition: newgrf_commons.h:102
RAILTYPE_RAIL
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition: rail_type.h:29
_generating_world
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:60
TE_GOODS
@ TE_GOODS
Cargo behaves goods/candy-like.
Definition: cargotype.h:29
GCS_UNKNOWN
@ GCS_UNKNOWN
The status of this grf file is unknown.
Definition: newgrf_config.h:35
ConstructionSettings::max_bridge_length
uint16 max_bridge_length
maximum length of bridges
Definition: settings_type.h:308
ObjectSpec::clear_cost_multiplier
uint8 clear_cost_multiplier
Clear cost multiplier per tile.
Definition: newgrf_object.h:67
FioReadByte
byte FioReadByte()
Read a byte from the file.
Definition: fileio.cpp:107
LanguagePackHeader::GetGenderIndex
uint8 GetGenderIndex(const char *gender_str) const
Get the index for the given gender.
Definition: language.h:67
DeterministicSpriteGroupAdjust
Definition: newgrf_spritegroup.h:150
PriceBaseSpec
Describes properties of price bases.
Definition: economy_type.h:190
IndustryTileSpec::accepts_cargo
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
Cargo accepted by this tile.
Definition: industrytype.h:157
YearMonthDay::year
Year year
Year (0...)
Definition: date_type.h:104
string_func.h
IndustrySpec::enabled
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:140
ObjectSpec::generate_amount
uint8 generate_amount
Number of objects which are attempted to be generated per 256^2 map during world generation.
Definition: newgrf_object.h:75
GRFFile::canal_local_properties
CanalProperties canal_local_properties[CF_END]
Canal properties as set by this NewGRF.
Definition: newgrf.h:138
GRFError
Information about why GRF had problems during initialisation.
Definition: newgrf_config.h:112
RoadTypeInfo::grffile
const GRFFile * grffile[ROTSG_END]
NewGRF providing the Action3 for the roadtype.
Definition: road.h:184
RailtypeInfo::acceleration_type
uint8 acceleration_type
Acceleration type of this rail type.
Definition: rail.h:223
ChangeGRFDescription
static bool ChangeGRFDescription(byte langid, const char *str)
Callback function for 'INFO'->'DESC' to add a translation to the newgrf description.
Definition: newgrf.cpp:7807
GCS_DISABLED
@ GCS_DISABLED
GRF file is disabled.
Definition: newgrf_config.h:36
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
SetUnicodeGlyph
static void SetUnicodeGlyph(FontSize size, WChar key, SpriteID sprite)
Map a SpriteID to the font size and key.
Definition: fontcache.h:173
CIR_DISABLED
@ CIR_DISABLED
GRF was disabled due to error.
Definition: newgrf.cpp:988
GRFParameterInfo::max_value
uint32 max_value
The maximal value of this parameter.
Definition: newgrf_config.h:138
AllocateRailType
RailType AllocateRailType(RailTypeLabel label)
Allocate a new rail type label.
Definition: rail_cmd.cpp:158
ORIGINAL_MAX_YEAR
static const Year ORIGINAL_MAX_YEAR
The maximum year of the original TTD.
Definition: date_type.h:53
vehicle_func.h
rev.h
CURRENCY_END
@ CURRENCY_END
always the last item
Definition: currency.h:65
LanguagePackHeader::GetCaseIndex
uint8 GetCaseIndex(const char *case_str) const
Get the index for the given case.
Definition: language.h:80
PROP_TRAIN_WEIGHT
@ PROP_TRAIN_WEIGHT
Weight in t (if dualheaded: for each single vehicle)
Definition: newgrf_properties.h:25
PROP_VEHICLE_LOAD_AMOUNT
@ PROP_VEHICLE_LOAD_AMOUNT
Loading speed.
Definition: newgrf_properties.h:19
GRFFile::GRFFile
GRFFile(const struct GRFConfig *config)
Constructor for GRFFile.
Definition: newgrf.cpp:8699
RailtypeInfo::flags
RailTypeFlags flags
Bit mask of rail type flags.
Definition: rail.h:208
VehicleSettings::dynamic_engines
bool dynamic_engines
enable dynamic allocation of engine data
Definition: settings_type.h:462
newgrf_sound.h
Clamp
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:77
RoadVehicleInfo::shorten_factor
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:124
Pool::PoolItem<&_engine_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:378
GRFFilePropsBase::spritegroup
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
Definition: newgrf_commons.h:321
GRFP_GRF_WINDOWS
@ GRFP_GRF_WINDOWS
The NewGRF says the Windows palette can be used.
Definition: newgrf_config.h:72
strings_func.h
TLF_VAR10_FLAGS
@ TLF_VAR10_FLAGS
Flags which refer to using multiple action-1-2-3 chains.
Definition: newgrf_commons.h:59
StationSpec
Station specification.
Definition: newgrf_station.h:117
CLEAN_RANDOMSOUNDS
@ CLEAN_RANDOMSOUNDS
Free the dynamically allocated sounds table.
Definition: industrytype.h:24
AirportSpec::enabled
bool enabled
Entity still available (by default true). Newgrf can disable it, though.
Definition: newgrf_airport.h:117
LanguageMap
Mapping of language data between a NewGRF and OpenTTD.
Definition: newgrf_text.h:58
PROP_TRAIN_SHORTEN_FACTOR
@ PROP_TRAIN_SHORTEN_FACTOR
Shorter vehicles.
Definition: newgrf_properties.h:28
IsHouseSpecValid
static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
Check if a given housespec is valid and disable it if it's not.
Definition: newgrf.cpp:8969
IndustrytilesChangeInfo
static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
Define properties for industry tiles.
Definition: newgrf.cpp:3147
RailVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: engine_type.h:47
FioCheckFileExists
bool FioCheckFileExists(const std::string &filename, Subdirectory subdir)
Check whether the given file exists.
Definition: fileio.cpp:266
GRFParameterInfo::value_names
SmallMap< uint32, GRFTextList > value_names
Names for each value.
Definition: newgrf_config.h:143
bridge.h
NEW_AIRPORT_OFFSET
@ NEW_AIRPORT_OFFSET
Number of the first newgrf airport.
Definition: airport.h:39
TileLayoutRegisters::palette
uint8 palette
Register specifying a signed offset for the palette.
Definition: newgrf_commons.h:95
GRFTempEngineData
Temporary engine data used when loading only.
Definition: newgrf.cpp:304
ResetNewGRFErrors
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition: newgrf.cpp:8537
GRFConfig::name
GRFTextWrapper name
NOSAVE: GRF name (Action 0x08)
Definition: newgrf_config.h:160
ResetNewGRF
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition: newgrf.cpp:8526
GRFLoadedFeatures::tram
TramReplacement tram
In which way tram depots were replaced.
Definition: newgrf.h:178
TileLayoutRegisters::max_palette_offset
uint16 max_palette_offset
Maximum offset to add to the palette. (limited by size of the spriteset)
Definition: newgrf_commons.h:97
BridgeSpec::max_length
uint16 max_length
the maximum length (not counting start and end tile)
Definition: bridge.h:44
GRFParameterInfo::desc
GRFTextList desc
The description of this parameter.
Definition: newgrf_config.h:135
AllowedSubtags
Data structure to store the allowed id/type combinations for action 14.
Definition: newgrf.cpp:8013
FinaliseAirportsArray
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition: newgrf.cpp:9201
IndustrySpec::cost_multiplier
uint8 cost_multiplier
Base construction cost multiplier.
Definition: industrytype.h:109
SHORE_REPLACE_ACTION_A
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition: newgrf.h:164
GCF_RESERVED
@ GCF_RESERVED
GRF file passed GLS_RESERVE stage.
Definition: newgrf_config.h:29
BridgeSpec::price
uint16 price
the price multiplier
Definition: bridge.h:45
SanitizeSpriteOffset
static uint16 SanitizeSpriteOffset(uint16 &num, uint16 offset, int max_sprites, const char *name)
Sanitize incoming sprite offsets for Action 5 graphics replacements.
Definition: newgrf.cpp:6061
GRFConfig::min_loadable_version
uint32 min_loadable_version
NOSAVE: Minimum compatible version a NewGRF can define.
Definition: newgrf_config.h:166
ObjectSpec::views
uint8 views
The number of views.
Definition: newgrf_object.h:74
TRAMWAY_REPLACE_DEPOT_WITH_TRACK
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition: newgrf.h:170
IndustryTileSpec::animation
AnimationInfo animation
Information about the animation (is it looping, how many loops etc)
Definition: industrytype.h:169
AirportTileSpec::callback_mask
uint8 callback_mask
Bitmask telling which grf callback is set.
Definition: newgrf_airporttiles.h:69
MapSpriteMappingRecolour
static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
Map the colour modifiers of TTDPatch to those that Open is using.
Definition: newgrf.cpp:711
GetGlobalVariable
bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
Reads a variable common to VarAction2 and Action7/9/D.
Definition: newgrf.cpp:6231
RAILTYPE_END
@ RAILTYPE_END
Used for iterations.
Definition: rail_type.h:33
CanalProperties::flags
uint8 flags
Flags controlling display.
Definition: newgrf.h:41
PaletteID
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:18
CommonVehicleChangeInfo
static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
Define properties common to all vehicles.
Definition: newgrf.cpp:1003
ConstructionSettings::build_on_slopes
bool build_on_slopes
allow building on slopes
Definition: settings_type.h:306
RealSpriteGroup
Definition: newgrf_spritegroup.h:79
AllowedSubtags::subtags
AllowedSubtags * subtags
Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
Definition: newgrf.cpp:8078
HZ_SUBARTC_ABOVE
@ HZ_SUBARTC_ABOVE
11 800 can appear in sub-arctic climate above the snow line
Definition: house.h:79
TextHandler
bool(* TextHandler)(byte, const char *str)
Type of callback function for text nodes.
Definition: newgrf.cpp:8003
Action5Type::block_type
Action5BlockType block_type
How is this Action5 type processed?
Definition: newgrf.cpp:6090
AirportSpec::grf_prop
struct GRFFileProps grf_prop
Properties related to the grf file.
Definition: newgrf_airport.h:118
CargoSpec::quantifier
StringID quantifier
Text for multiple units of cargo of this type.
Definition: cargotype.h:73
SPR_AIRPORT_PREVIEW_BASE
static const SpriteID SPR_AIRPORT_PREVIEW_BASE
Airport preview sprites.
Definition: sprites.h:242
Action5Type::min_sprites
uint16 min_sprites
If the Action5 contains less sprites, the whole block will be ignored.
Definition: newgrf.cpp:6092
GRFConfig::next
struct GRFConfig * next
NOSAVE: Next item in the linked list.
Definition: newgrf_config.h:177
industrytype.h
RAILVEH_MULTIHEAD
@ RAILVEH_MULTIHEAD
indicates a combination of two locomotives
Definition: engine_type.h:28
GetEngineLiveryScheme
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition: vehicle.cpp:1862
InitializeSortedCargoSpecs
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
Definition: cargotype.cpp:169
GrfProcessingState::AddSpriteSets
void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
Records new spritesets.
Definition: newgrf.cpp:135
SPR_OPENTTD_BASE
static const SpriteID SPR_OPENTTD_BASE
Extra graphic spritenumbers.
Definition: sprites.h:56
IndustrySpec::production_down_text
StringID production_down_text
Message appearing when the industry's production is decreasing.
Definition: industrytype.h:131
TRAMWAY_REPLACE_DEPOT_NONE
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
Definition: newgrf.h:169
RailVehicleInfo::user_def_data
byte user_def_data
Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles.
Definition: engine_type.h:61
AlterVehicleListOrder
void AlterVehicleListOrder(EngineID engine, uint target)
Record a vehicle ListOrderChange.
Definition: newgrf_engine.cpp:1257
CargoSpec::classes
uint16 classes
Classes of this cargo type.
Definition: cargotype.h:78
RoadVehicleChangeInfo
static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for road vehicles.
Definition: newgrf.cpp:1340
AirportTileSpec::enabled
bool enabled
entity still available (by default true). newgrf can disable it, though
Definition: newgrf_airporttiles.h:71
IndustrySpec::cleanup_flag
uint8 cleanup_flag
flags indicating which data should be freed upon cleaning up
Definition: industrytype.h:139
IndustrySpec::appear_ingame
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:133
IndustrySpec::grf_prop
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:141
TRAMWAY_REPLACE_DEPOT_NO_TRACK
@ TRAMWAY_REPLACE_DEPOT_NO_TRACK
Electrified depot graphics without tram track were loaded.
Definition: newgrf.h:171
RoadTypeInfo::map_colour
byte map_colour
Colour on mini-map.
Definition: road.h:154
NewGRFSpriteLayout::consistent_max_offset
uint consistent_max_offset
Number of sprites in all referenced spritesets.
Definition: newgrf_commons.h:120
HouseSpec::watched_cargoes
CargoTypes watched_cargoes
Cargo types watched for acceptance.
Definition: house.h:123
NUM_CARGO
@ NUM_CARGO
Maximal number of cargo types in a game.
Definition: cargo_type.h:64
IsSnowLineSet
bool IsSnowLineSet()
Has a snow line table already been loaded.
Definition: landscape.cpp:615
RailTypeFlags
RailTypeFlags
Railtype flags.
Definition: rail.h:25
RailtypeInfo::label
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition: rail.h:233
StationClassID
StationClassID
Definition: newgrf_station.h:83
GetCargoTranslation
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
Definition: newgrf_cargo.cpp:91
IndustrySpec::prospecting_chance
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:111
ConstructionSettings::train_signal_side
byte train_signal_side
show signals on left / driving / right side
Definition: settings_type.h:311
HouseSpec::class_id
HouseClassID class_id
defines the class this house has (not grf file based)
Definition: house.h:119
GRFParameterInfo::name
GRFTextList name
The name of this parameter.
Definition: newgrf_config.h:134
GRFFile::cargo_map
uint8 cargo_map[NUM_CARGO]
Inverse cargo translation table (CargoID -> local ID)
Definition: newgrf.h:127
Pool::PoolItem<&_engine_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition: pool_type.hpp:299
IndustryTileLayoutTile
Definition of one tile in an industry tile layout.
Definition: industrytype.h:96
RailtypeInfo::build_caption
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition: rail.h:176
VehicleSettings::disable_elrails
bool disable_elrails
when true, the elrails are disabled
Definition: settings_type.h:455
InitNewGRFFile
static void InitNewGRFFile(const GRFConfig *config)
Prepare loading a NewGRF file with its config.
Definition: newgrf.cpp:8682
CommitVehicleListOrderChanges
void CommitVehicleListOrderChanges()
Deternine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
Definition: newgrf_engine.cpp:1287
ShipVehicleInfo
Information about a ship vehicle.
Definition: engine_type.h:65
HouseSpec::building_availability
HouseZones building_availability
where can it be built (climates, zones)
Definition: house.h:110
NewGRFClass::name
StringID name
Name of this class.
Definition: newgrf_class.h:39
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:108
IndustryProductionSpriteGroup::version
uint8 version
Production callback version used, or 0xFF if marked invalid.
Definition: newgrf_spritegroup.h:279
AirportSpec::GetWithoutOverride
static AirportSpec * GetWithoutOverride(byte type)
Retrieve airport spec for the given airport.
Definition: newgrf_airport.cpp:119
TileLayoutFlags
TileLayoutFlags
Flags to enable register usage in sprite layouts.
Definition: newgrf_commons.h:33
CargoSpec::name
StringID name
Name of this type of cargo.
Definition: cargotype.h:70
PROP_ROADVEH_CARGO_CAPACITY
@ PROP_ROADVEH_CARGO_CAPACITY
Capacity.
Definition: newgrf_properties.h:33
ResetNewGRFData
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition: newgrf.cpp:8550
AircraftVehicleChangeInfo
static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for aircraft.
Definition: newgrf.cpp:1706
GRFFile::cargo_list
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition: newgrf.h:126
GameCreationSettings::starting_year
Year starting_year
starting date
Definition: settings_type.h:281
PalSpriteID
Combination of a palette sprite and a 'real' sprite.
Definition: gfx_type.h:22
GRFConfig::url
GRFTextWrapper url
NOSAVE: URL belonging to this GRF.
Definition: newgrf_config.h:162
VSG_SCOPE_RELATIVE
@ VSG_SCOPE_RELATIVE
Relative position (vehicles only)
Definition: newgrf_spritegroup.h:105
ActivateOldTramDepot
static void ActivateOldTramDepot()
Replocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition: newgrf.cpp:9495
RailtypeInfo::strings
struct RailtypeInfo::@41 strings
Strings associated with the rail type.
HZ_CLIMALL
@ HZ_CLIMALL
Bitmask of all climate bits.
Definition: house.h:84
RoadVehicleInfo::tractive_effort
uint8 tractive_effort
Coefficient of tractive effort.
Definition: engine_type.h:121
GrfProcessingState::stage
GrfLoadingStage stage
Current loading stage.
Definition: newgrf.cpp:98
ORIGINAL_SAMPLE_COUNT
static const uint ORIGINAL_SAMPLE_COUNT
The number of sounds in the original sample.cat.
Definition: sound_type.h:116
IndustrySpec::callback_mask
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:138
AnimationInfo::triggers
uint16 triggers
The triggers that trigger animation.
Definition: newgrf_animation_type.h:22
IgnoreObjectProperty
static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
Ignore properties for objects.
Definition: newgrf.cpp:3978
CHECK_NOTHING
@ CHECK_NOTHING
Always succeeds.
Definition: industrytype.h:40
AircraftVehicleInfo::mail_capacity
byte mail_capacity
Mail capacity (bags).
Definition: engine_type.h:105
CargoSpec::name_single
StringID name_single
Name of a single entity of this type of cargo.
Definition: cargotype.h:71
PTYPE_END
@ PTYPE_END
Invalid parameter type.
Definition: newgrf_config.h:127
IndustrySpec::random_sounds
const uint8 * random_sounds
array of random sounds.
Definition: industrytype.h:136
GrfProcessingState::GetNumEnts
uint GetNumEnts(byte feature, uint set) const
Returns the number of sprites in a spriteset.
Definition: newgrf.cpp:188
CargoSpec::abbrev
StringID abbrev
Two letter abbreviation for this cargo type.
Definition: cargotype.h:74
_default_refitmasks_rail
static const CargoLabel _default_refitmasks_rail[]
List of what cargo labels are refittable for the given the vehicle-type.
Definition: newgrf.cpp:8750
ReallocT
static T * ReallocT(T *t_ptr, size_t num_elements)
Simplified reallocation function that allocates the specified number of elements of the given type.
Definition: alloc_func.hpp:111
HouseSpec::processing_time
byte processing_time
Periodic refresh multiplier.
Definition: house.h:121
IndustrySpec::life_type
IndustryLifeType life_type
This is also known as Industry production flag, in newgrf specs.
Definition: industrytype.h:123
RoadVehicleInfo::weight
uint8 weight
Weight in 1/4t units.
Definition: engine_type.h:119
_palette_remap_grf
bool _palette_remap_grf[]
Whether the given NewGRFs must get a palette remap from windows to DOS or not.
Definition: gfxinit.cpp:30
Action5Type::name
const char * name
Name for error messages.
Definition: newgrf.cpp:6094
abs
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:21
stredup
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:137
FinaliseHouseArray
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition: newgrf.cpp:9042
GRFConfig::palette
uint8 palette
GRFPalette, bitset.
Definition: newgrf_config.h:173
CargoSpec::multiplier
uint16 multiplier
Capacity multiplier for vehicles. (8 fractional bits)
Definition: cargotype.h:61
IndustryTileSpec::callback_mask
uint8 callback_mask
Bitmask of industry tile callbacks that have to be called.
Definition: industrytype.h:168
_grm_cargoes
static uint32 _grm_cargoes[NUM_CARGO *2]
Contains the GRF ID of the owner of a cargo if it has been reserved.
Definition: newgrf.cpp:346
NewGRFSpriteLayout::Clone
void Clone(const DrawTileSeqStruct *source)
Clone the building sprites of a spritelayout.
Definition: newgrf_commons.cpp:586
error
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:129
StationSpec::cargo_threshold
uint16 cargo_threshold
Cargo threshold for choosing between little and lots of cargo.
Definition: newgrf_station.h:154
network.h
RailVehicleInfo::shorten_factor
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:58
_grfconfig
GRFConfig * _grfconfig
First item in list of current GRF set up.
Definition: newgrf_config.cpp:170
RoadTypeInfo::cost_multiplier
uint16 cost_multiplier
Cost multiplier for building this road type.
Definition: road.h:129
SmallMap::Find
std::vector< Pair >::const_iterator Find(const T &key) const
Finds given key in this map.
Definition: smallmap_type.hpp:41
CurrencySpec::to_euro
Year to_euro
Year of switching to the Euro. May also be CF_NOEURO or CF_ISEURO.
Definition: currency.h:72
DrawTileSprites::seq
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition: sprite.h:60
CIR_UNKNOWN
@ CIR_UNKNOWN
Variable is unknown.
Definition: newgrf.cpp:990
GRFTempEngineData::NONEMPTY
@ NONEMPTY
GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not av...
Definition: newgrf.cpp:309
AllowedSubtags::id
uint32 id
The identifier for this node.
Definition: newgrf.cpp:8070
IndustrySpec::behaviour
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:125
AnimationInfo::status
uint8 status
Status; 0: no looping, 1: looping, 0xFF: no animation.
Definition: newgrf_animation_type.h:20
ResetObjects
void ResetObjects()
This function initialize the spec arrays of objects.
Definition: newgrf_object.cpp:94
SetBit
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: stdafx.h:377
HouseSpec::min_year
Year min_year
introduction year of the house
Definition: house.h:100
YearMonthDay
Data structure to convert between Date and triplet (year, month, and day).
Definition: date_type.h:103
StationSpec::grf_prop
GRFFilePropsBase< NUM_CARGO+3 > grf_prop
Properties related the the grf file.
Definition: newgrf_station.h:124
SPR_FLAGS_BASE
static const SpriteID SPR_FLAGS_BASE
Flags sprites (in same order as enum NetworkLanguage)
Definition: sprites.h:291
NewGRFClass::Get
static NewGRFClass * Get(Tid cls_id)
Get a particular class.
Definition: newgrf_class_func.h:103
RoadTypeInfo::max_speed
uint16 max_speed
Maximum speed for vehicles travelling on this road type.
Definition: road.h:139
InitializeGRFSpecial
static void InitializeGRFSpecial()
Initialize the TTDPatch flags.
Definition: newgrf.cpp:8308
DataHandler
bool(* DataHandler)(size_t, ByteReader *)
Type of callback function for binary nodes.
Definition: newgrf.cpp:8002
RandomizedSpriteGroup::lowest_randbit
byte lowest_randbit
Look for this in the per-object randomized bitmask:
Definition: newgrf_spritegroup.h:206
RailtypeInfo::new_loco
StringID new_loco
Name of an engine for this type of rail in the engine preview GUI.
Definition: rail.h:178
ActivateOldShore
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition: newgrf.cpp:9458
BridgeSpec::material
StringID material
the string that contains the bridge description
Definition: bridge.h:49
RoadVehicleInfo::power
uint8 power
Power in 10hp units.
Definition: engine_type.h:120
TileLayoutRegisters::flags
TileLayoutFlags flags
Flags defining which members are valid and to be used.
Definition: newgrf_commons.h:92
AirportSpec::depot_table
const HangarTileTable * depot_table
gives the position of the depots on the airports
Definition: newgrf_airport.h:103
SkipUnknownInfo
static bool SkipUnknownInfo(ByteReader *buf, byte type)
Try to skip the current node and all subnodes (if it's a branch node).
Definition: newgrf.cpp:8194
RailtypeInfo::compatible_railtypes
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel
Definition: rail.h:188
CT_PURCHASE_OBJECT
static const CargoID CT_PURCHASE_OBJECT
Mapping of purchase for objects.
Definition: newgrf_object.h:159
newgrf_canal.h
TILE_HEIGHT
static const uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:16
IgnoreTownHouseProperty
static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
Ignore a house property.
Definition: newgrf.cpp:2255
RealSpriteGroup::num_loading
byte num_loading
Number of loading groups.
Definition: newgrf_spritegroup.h:91
CargoID
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
MemSetT
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:49
GrfProcessingState::file_index
uint file_index
File index of currently processed GRF file.
Definition: newgrf.cpp:102
VehicleSettings::never_expire_vehicles
bool never_expire_vehicles
never expire vehicles
Definition: settings_type.h:463
HouseSpec
Definition: house.h:98
GetNewgrfCurrencyIdConverted
byte GetNewgrfCurrencyIdConverted(byte grfcurr_id)
Will return the ottd's index correspondence to the ttdpatch's id.
Definition: currency.cpp:111
EF_RAIL_FLIPS
@ EF_RAIL_FLIPS
Rail vehicle can be flipped in the depot.
Definition: engine_type.h:157
GrfProcessingState::SpriteSet::num_sprites
uint num_sprites
Number of sprites in the set.
Definition: newgrf.cpp:90
NEW_AIRPORTTILE_OFFSET
static const uint NEW_AIRPORTTILE_OFFSET
offset of first newgrf airport tile
Definition: airport.h:24
RoadTypeFlags
RoadTypeFlags
Roadtype flags.
Definition: road.h:38
OverrideManagerBase::AddEntityID
virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
Reserves a place in the mapping array for an entity to be installed.
Definition: newgrf_commons.cpp:123
PROP_SHIP_COST_FACTOR
@ PROP_SHIP_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:42
ChangeInfoResult
ChangeInfoResult
Possible return values for the FeatureChangeInfo functions.
Definition: newgrf.cpp:986
engine_base.h
IndustryProductionSpriteGroup::cargo_output
CargoID cargo_output[INDUSTRY_NUM_OUTPUTS]
Which output cargoes to add to (only cb version 2)
Definition: newgrf_spritegroup.h:285
BridgeChangeInfo
static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
Define properties for bridges.
Definition: newgrf.cpp:2145
LiveryScheme
LiveryScheme
List of different livery schemes.
Definition: livery.h:20
fontcache.h
_object_mngr
ObjectOverrideManager _object_mngr
The override manager for our objects.
HouseZones
HouseZones
Definition: house.h:71
VehicleSettings::plane_speed
uint8 plane_speed
divisor for speed of aircraft
Definition: settings_type.h:460
RailtypeInfo::maintenance_multiplier
uint16 maintenance_multiplier
Cost multiplier for maintenance of this rail type.
Definition: rail.h:218
RailTypeChangeInfo
static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for railtypes.
Definition: newgrf.cpp:4155
Engine::grf_prop
GRFFilePropsBase< NUM_CARGO+2 > grf_prop
Properties related the the grf file.
Definition: engine_base.h:58
RAILVEH_SINGLEHEAD
@ RAILVEH_SINGLEHEAD
indicates a "standalone" locomotive
Definition: engine_type.h:27
IndustryTileSpecialFlags
IndustryTileSpecialFlags
Flags for miscellaneous industry tile specialities.
Definition: industrytype.h:88
IndustrySpec::check_proc
byte check_proc
Index to a procedure to check for conflicting circumstances.
Definition: industrytype.h:113
ShipVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:68
GRFTempEngineData::prop27_set
bool prop27_set
Did the NewGRF set property 27 (misc flags)?
Definition: newgrf.cpp:318
RailVehicleInfo::running_cost
byte running_cost
Running cost of engine; For multiheaded engines the sum of both running costs.
Definition: engine_type.h:50
EF_ROAD_TRAM
@ EF_ROAD_TRAM
Road vehicle is a tram/light rail vehicle.
Definition: engine_type.h:154
GetRailTypeByLabel
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition: rail.cpp:311
NEW_INDUSTRYTILEOFFSET
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
Definition: industry_type.h:32
GRFFilePropsBase::local_id
uint16 local_id
id defined by the grf file for this entity
Definition: newgrf_commons.h:319
newgrf_industries.h
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24
EconomySettings::inflation
bool inflation
disable inflation
Definition: settings_type.h:471
FinaliseCargoArray
static void FinaliseCargoArray()
Check for invalid cargoes.
Definition: newgrf.cpp:8946
LoadNewGRF
void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
Load all the NewGRFs.
Definition: newgrf.cpp:9749
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition: settings_type.h:549
GrfProcessingState::IsValidSpriteSet
bool IsValidSpriteSet(byte feature, uint set) const
Check whether a specific set is defined.
Definition: newgrf.cpp:164
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition: settings_type.h:556
FontSize
FontSize
Available font sizes.
Definition: gfx_type.h:206
TLF_PALETTE_REG_FLAGS
@ TLF_PALETTE_REG_FLAGS
Flags which require resolving the action-1-2-3 chain for the palette, even if it is no action-1 palet...
Definition: newgrf_commons.h:65
TLF_SPRITE
@ TLF_SPRITE
Add signed offset to sprite from register TileLayoutRegisters::sprite.
Definition: newgrf_commons.h:37
ClearTemporaryNewGRFData
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition: newgrf.cpp:418
EngineInfo::climates
byte climates
Climates supported by the engine.
Definition: engine_type.h:138
TLF_PALETTE
@ TLF_PALETTE
Add signed offset to palette from register TileLayoutRegisters::palette.
Definition: newgrf_commons.h:38
PTYPE_UINT_ENUM
@ PTYPE_UINT_ENUM
The parameter allows a range of numbers, each of which can have a special name.
Definition: newgrf_config.h:125
AirportSpec::nof_depots
byte nof_depots
the number of hangar tiles in this airport
Definition: newgrf_airport.h:104
PROP_AIRCRAFT_PASSENGER_CAPACITY
@ PROP_AIRCRAFT_PASSENGER_CAPACITY
Passenger Capacity.
Definition: newgrf_properties.h:51
PROP_SHIP_SPEED
@ PROP_SHIP_SPEED
Max. speed: 1 unit = 1/3.2 mph = 0.5 km-ish/h.
Definition: newgrf_properties.h:43
ClearSnowLine
void ClearSnowLine()
Clear the variable snow line table and free the memory.
Definition: landscape.cpp:677
ResetRoadTypes
void ResetRoadTypes()
Reset all road type information to its default values.
Definition: road_cmd.cpp:62
GRFPalette
GRFPalette
Information that can/has to be stored about a GRF's palette.
Definition: newgrf_config.h:59
StationSpec::callback_mask
byte callback_mask
Bitmask of station callbacks that have to be called.
Definition: newgrf_station.h:158
PROP_ROADVEH_POWER
@ PROP_ROADVEH_POWER
Power in 10 HP.
Definition: newgrf_properties.h:35
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
RandomizedSpriteGroup
Definition: newgrf_spritegroup.h:196
RailtypeInfo::group
const SpriteGroup * group[RTSG_END]
Sprite groups for resolving sprites.
Definition: rail.h:278
IndustrySpec::name
StringID name
Displayed name of the industry.
Definition: industrytype.h:127
ChangeGRFParamDefault
static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value.
Definition: newgrf.cpp:7990
IndustryBehaviour
IndustryBehaviour
Various industry behaviours mostly to represent original TTD specialities.
Definition: industrytype.h:61
PROP_TRAIN_COST_FACTOR
@ PROP_TRAIN_COST_FACTOR
Purchase cost (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:26
IndustrySpec::new_industry_text
StringID new_industry_text
Message appearing when the industry is built.
Definition: industrytype.h:128
StationSpec::disallowed_lengths
byte disallowed_lengths
Bitmask of platform lengths available for the station.
Definition: newgrf_station.h:137
_misc_grf_features
byte _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition: newgrf.cpp:74
RailVehicleInfo::capacity
byte capacity
Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine.
Definition: engine_type.h:53
IndustryProductionSpriteGroup::cargo_input
CargoID cargo_input[INDUSTRY_NUM_INPUTS]
Which input cargoes to take from (only cb version 2)
Definition: newgrf_spritegroup.h:282
DefineGotoLabel
static void DefineGotoLabel(ByteReader *buf)
Action 0x10 - Define goto label.
Definition: newgrf.cpp:7507
ByteReader
Class to read from a NewGRF file.
Definition: newgrf.cpp:213
LoadGRFSound
static void LoadGRFSound(size_t offs, SoundEntry *sound)
Load a sound from a file.
Definition: newgrf.cpp:7570
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, BranchHandler handler)
Create a branch node with a callback handler.
Definition: newgrf.cpp:8049
TTDPStringIDToOTTDStringIDMapping
static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
Perform a mapping from TTDPatch's string IDs to OpenTTD's string IDs, but only for the ones we are aw...
Definition: newgrf.cpp:487
GRFFilePropsBase::grffile
const struct GRFFile * grffile
grf file that introduced this entity
Definition: newgrf_commons.h:320
PROP_AIRCRAFT_SPEED
@ PROP_AIRCRAFT_SPEED
Max. speed: 1 unit = 8 mph = 12.8 km-ish/h.
Definition: newgrf_properties.h:49
AirportTileSpec::name
StringID name
Tile Subname string, land information on this tile will give you "AirportName (TileSubname)".
Definition: newgrf_airporttiles.h:68
CanalProperties
Canal properties local to the NewGRF.
Definition: newgrf.h:39
ResetBridges
void ResetBridges()
Reset the data been eventually changed by the grf loaded.
Definition: tunnelbridge_cmd.cpp:83
RailtypeInfo::cost_multiplier
uint16 cost_multiplier
Cost multiplier for building this rail type.
Definition: rail.h:213
DateFract
uint16 DateFract
The fraction of a date we're in, i.e. the number of ticks since the last date changeover.
Definition: date_type.h:15
AllowedSubtags::data
DataHandler data
Callback function for a binary node, only valid if type == 'B'.
Definition: newgrf.cpp:8073
AirportTileTable::ti
TileIndexDiffC ti
Tile offset from the top-most airport tile.
Definition: newgrf_airport.h:24
GRFConfig::filename
char * filename
Filename - either with or without full path.
Definition: newgrf_config.h:159
EngineInfo::string_id
StringID string_id
Default name of engine.
Definition: engine_type.h:145
AircraftVehicleInfo
Information about a aircraft vehicle.
Definition: engine_type.h:97
GetLanguage
const LanguageMetadata * GetLanguage(byte newgrflangid)
Get the language with the given NewGRF language ID.
Definition: strings.cpp:1878
ObjectSpec::climate
uint8 climate
In which climates is this object available?
Definition: newgrf_object.h:64
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:469
AirportSpec::table
const AirportTileTable *const * table
list of the tiles composing the airport
Definition: newgrf_airport.h:100
HangarTileTable
A list of all hangar tiles in an airport.
Definition: newgrf_airport.h:89
CT_INVALID
@ CT_INVALID
Invalid cargo type.
Definition: cargo_type.h:68
MapGRFStringID
StringID MapGRFStringID(uint32 grfid, StringID str)
Used when setting an object's property to map to the GRF's strings while taking in consideration the ...
Definition: newgrf.cpp:551
PROP_TRAIN_POWER
@ PROP_TRAIN_POWER
Power in hp (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:22
AirportTileSpec::Get
static const AirportTileSpec * Get(StationGfx gfx)
Retrieve airport tile spec for the given airport tile.
Definition: newgrf_airporttiles.cpp:36
TownHouseChangeInfo
static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
Define properties for houses.
Definition: newgrf.cpp:2322
IndustryOverrideManager::SetEntitySpec
void SetEntitySpec(IndustrySpec *inds)
Method to install the new industry data in its proper slot The slot assignment is internal of this me...
Definition: newgrf_commons.cpp:260
PROP_TRAIN_CARGO_AGE_PERIOD
@ PROP_TRAIN_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:30
ResetIndustries
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
Definition: industry_cmd.cpp:73
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
VehicleSettings::freight_trains
uint8 freight_trains
value to multiply the weight of cargo by
Definition: settings_type.h:461
ChangeGRFPalette
static bool ChangeGRFPalette(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PALS' to set the number of valid parameters.
Definition: newgrf.cpp:7833
LoadFontGlyph
static void LoadFontGlyph(ByteReader *buf)
Action 0x12.
Definition: newgrf.cpp:7688
PROP_ROADVEH_RUNNING_COST_FACTOR
@ PROP_ROADVEH_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:32
SPR_TRACKS_FOR_SLOPES_BASE
static const SpriteID SPR_TRACKS_FOR_SLOPES_BASE
Sprites for 'highlighting' tracks on sloped land.
Definition: sprites.h:192
ResultSpriteGroup
Definition: newgrf_spritegroup.h:244
IndustryTileSpec::anim_next
byte anim_next
Next frame in an animation.
Definition: industrytype.h:161
IndustryTileSpec
Defines the data structure of each individual tile of an industry.
Definition: industrytype.h:156
GRFLoadedFeatures
Definition: newgrf.h:174
TLF_DRAWING_FLAGS
@ TLF_DRAWING_FLAGS
Flags which are still required after loading the GRF.
Definition: newgrf_commons.h:53
TLF_PALETTE_VAR10
@ TLF_PALETTE_VAR10
Resolve palette with a specific value in variable 10.
Definition: newgrf_commons.h:48
InitRailTypes
void InitRailTypes()
Resolve sprites of custom rail types.
Definition: rail_cmd.cpp:138
HouseSpec::remove_rating_decrease
uint16 remove_rating_decrease
rating decrease if removed
Definition: house.h:105
DisableGrf
static GRFError * DisableGrf(StringID message=STR_NULL, GRFConfig *config=nullptr)
Disable a GRF.
Definition: newgrf.cpp:435
AirportTileSpec::grf_prop
GRFFileProps grf_prop
properties related the the grf file
Definition: newgrf_airporttiles.h:72
TLF_SPRITE_REG_FLAGS
@ TLF_SPRITE_REG_FLAGS
Flags which require resolving the action-1-2-3 chain for the sprite, even if it is no action-1 sprite...
Definition: newgrf_commons.h:62
InitRoadTypes
void InitRoadTypes()
Resolve sprites of custom road types.
Definition: road_cmd.cpp:118
RoadTypeInfo::build_caption
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition: road.h:103
GetFileByFilename
static GRFFile * GetFileByFilename(const char *filename)
Obtain a NewGRF file by its filename.
Definition: newgrf.cpp:409
GrfProcessingState::skip_sprites
int skip_sprites
Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file)
Definition: newgrf.cpp:109
ResetCustomStations
static void ResetCustomStations()
Reset and clear all NewGRF stations.
Definition: newgrf.cpp:8396
HZ_ZON1
@ HZ_ZON1
0..4 1,2,4,8,10 which town zones the building can be built in, Zone1 been the further suburb
Definition: house.h:73
TLF_SPRITE_VAR10
@ TLF_SPRITE_VAR10
Resolve sprite with a specific value in variable 10.
Definition: newgrf_commons.h:47
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: stdafx.h:393
PROP_AIRCRAFT_RANGE
@ PROP_AIRCRAFT_RANGE
Aircraft range.
Definition: newgrf_properties.h:54
EconomySettings::allow_town_roads
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
Definition: settings_type.h:489
MAX_NUM_CASES
static const uint8 MAX_NUM_CASES
Maximum number of supported cases.
Definition: language.h:21
_ttdpatch_flags
static uint32 _ttdpatch_flags[8]
32 * 8 = 256 flags.
Definition: newgrf.cpp:77
BuildLinkStatsLegend
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
Definition: smallmap_gui.cpp:198
ChangeGRFParamDescription
static bool ChangeGRFParamDescription(byte langid, const char *str)
Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter.
Definition: newgrf.cpp:7923
EngineInfo::cargo_age_period
uint16 cargo_age_period
Number of ticks before carried cargo is aged.
Definition: engine_type.h:146
GrfProcessingState::nfo_line
uint32 nfo_line
Currently processed pseudo sprite number in the GRF.
Definition: newgrf.cpp:105
RoadTypeInfo::introduction_required_roadtypes
RoadTypes introduction_required_roadtypes
Bitmask of roadtypes that are required for this roadtype to be introduced at a given introduction_dat...
Definition: road.h:169
ReadSpriteLayout
static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
Read a spritelayout from the GRF.
Definition: newgrf.cpp:853
GetCargoIDByLabel
CargoID GetCargoIDByLabel(CargoLabel cl)
Get the cargo ID by cargo label.
Definition: cargotype.cpp:85
newgrf_cargo.h
SetYearEngineAgingStops
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition: engine.cpp:612
RailtypeInfo::curve_speed
byte curve_speed
Multiplier for curve maximum speed advantage.
Definition: rail.h:203
MapLogY
static uint MapLogY()
Logarithm of the map size along the y side.
Definition: map_func.h:62
GRFFile::railtype_list
std::vector< RailTypeLabel > railtype_list
Railtype translation table.
Definition: newgrf.h:129
AirportSpec::catchment
byte catchment
catchment area of this airport
Definition: newgrf_airport.h:108
ReadSpriteLayoutSprite
static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset=nullptr, uint16 *max_palette_offset=nullptr)
Read a sprite and a palette from the GRF and convert them into a format suitable to OpenTTD.
Definition: newgrf.cpp:742
StationSpec::cargo_triggers
CargoTypes cargo_triggers
Bitmask of cargo types which cause trigger re-randomizing.
Definition: newgrf_station.h:156
FOR_EACH_SET_BIT
#define FOR_EACH_SET_BIT(bitpos_var, bitset_value)
Do an operation for each set set bit in a value.
Definition: bitmath_func.hpp:361
SpriteGroup
Definition: newgrf_spritegroup.h:57
GRFLabel
Definition: newgrf.h:97
SkipAct12
static void SkipAct12(ByteReader *buf)
Action 0x12 (SKIP)
Definition: newgrf.cpp:7719
SPR_ONEWAY_BASE
static const SpriteID SPR_ONEWAY_BASE
One way road sprites.
Definition: sprites.h:287
HouseSpec::grf_prop
GRFFileProps grf_prop
Properties related the the grf file.
Definition: house.h:114
AddStringForMapping
static void AddStringForMapping(StringID source, StringID *target)
Record a static StringID for getting translated later.
Definition: newgrf.cpp:474
GetGRFConfig
GRFConfig * GetGRFConfig(uint32 grfid, uint32 mask)
Retrieve a NewGRF from the current config by its grfid.
Definition: newgrf_config.cpp:827
ResetGenericCallbacks
void ResetGenericCallbacks()
Reset all generic feature callback sprite groups.
Definition: newgrf_generic.cpp:97
Action5Type
Information about a single action 5 type.
Definition: newgrf.cpp:6089
_currency_specs
CurrencySpec _currency_specs[CURRENCY_END]
Array of currencies used by the system.
Definition: currency.cpp:72
NamePart::id
byte id
If probability bit 7 is set.
Definition: newgrf_townname.h:22
LanguageMap::Mapping::newgrf_id
byte newgrf_id
NewGRF's internal ID for a case/gender.
Definition: newgrf_text.h:61
StationSpec::wires
byte wires
Bitmask of base tiles (0 - 7) which should contain elrail wires.
Definition: newgrf_station.h:163
AddGRFTextToList
static void AddGRFTextToList(GRFTextList &list, byte langid, const std::string &text_to_add)
Add a new text to a GRFText list.
Definition: newgrf_text.cpp:494
FindFirstBit
uint8 FindFirstBit(uint32 x)
Search the first set bit in a 32 bit variable.
Definition: bitmath_func.cpp:37
SetEngineGRF
void SetEngineGRF(EngineID engine, const GRFFile *file)
Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters etc during a game.
Definition: newgrf_engine.cpp:103
OrderSettings::gradual_loading
bool gradual_loading
load vehicles gradually
Definition: settings_type.h:440
GCF_STATIC
@ GCF_STATIC
GRF file is used statically (can be used in any MP game)
Definition: newgrf_config.h:25
NewGRFSpriteLayout::Allocate
void Allocate(uint num_sprites)
Allocate a spritelayout for num_sprites building sprites.
Definition: newgrf_commons.cpp:624
Action5Type::max_sprites
uint16 max_sprites
If the Action5 contains more sprites, only the first max_sprites sprites will be used.
Definition: newgrf.cpp:6093
GRFConfig::param_info
std::vector< GRFParameterInfo * > param_info
NOSAVE: extra information about the parameters.
Definition: newgrf_config.h:174
IndustryLifeType
IndustryLifeType
Available types of industry lifetimes.
Definition: industrytype.h:28
GRFFile
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:105
ObjectSpec::cls_id
ObjectClassID cls_id
The class to which this spec belongs.
Definition: newgrf_object.h:61
PROP_TRAIN_USER_DATA
@ PROP_TRAIN_USER_DATA
User defined data for vehicle variable 0x42.
Definition: newgrf_properties.h:29
ShipVehicleInfo::ocean_speed_frac
byte ocean_speed_frac
Fraction of maximum speed for ocean tiles.
Definition: engine_type.h:74
Engine::type
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition: engine_base.h:40
IgnoreIndustryTileProperty
static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
Ignore an industry tile property.
Definition: newgrf.cpp:3107
StationSpec::blocked
byte blocked
Bitmask of base tiles (0 - 7) which are blocked to trains.
Definition: newgrf_station.h:164
debug.h
GRFConfig::param
uint32 param[0x80]
GRF parameters.
Definition: newgrf_config.h:170
DAYS_TILL_ORIGINAL_BASE_YEAR
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the '_date == 0' till 'ConvertYMDToDate(ORIGINAL_BASE_YEAR,...
Definition: date_type.h:80
GRFParameterInfo::min_value
uint32 min_value
The minimal value this parameter can have.
Definition: newgrf_config.h:137
TileLayoutSpriteGroup
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
Definition: newgrf_spritegroup.h:267
GRFConfig::GetName
const char * GetName() const
Get the name of this grf.
Definition: newgrf_config.cpp:104
RoadTypeInfo::maintenance_multiplier
uint16 maintenance_multiplier
Cost multiplier for maintenance of this road type.
Definition: road.h:134
PROP_ROADVEH_WEIGHT
@ PROP_ROADVEH_WEIGHT
Weight in 1/4 t.
Definition: newgrf_properties.h:36
TileLayoutRegisters::max_sprite_offset
uint16 max_sprite_offset
Maximum offset to add to the sprite. (limited by size of the spriteset)
Definition: newgrf_commons.h:96
SPR_TRAMWAY_BASE
static const SpriteID SPR_TRAMWAY_BASE
Tramway sprites.
Definition: sprites.h:266
engine_func.h
AirportTileSpec::animation
AnimationInfo animation
Information about the animation.
Definition: newgrf_airporttiles.h:67
EC_MONORAIL
@ EC_MONORAIL
Mono rail engine.
Definition: engine_type.h:37
WaterFeature::group
const SpriteGroup * group
Sprite group to start resolving.
Definition: newgrf_canal.h:23
INVALID_RAILTYPE
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition: rail_type.h:34
DrawTileSeqStruct
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition: sprite.h:25
ObjectSpec::flags
ObjectFlags flags
Flags/settings related to the object.
Definition: newgrf_object.h:70
RoadTypeChangeInfo
static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
Define properties for roadtypes.
Definition: newgrf.cpp:4373
HouseOverrideManager::SetEntitySpec
void SetEntitySpec(const HouseSpec *hs)
Install the specs into the HouseSpecs array It will find itself the proper slot on which it will go.
Definition: newgrf_commons.cpp:176
RailtypeInfo::introduces_railtypes
RailTypes introduces_railtypes
Bitmask of which other railtypes are introduced when this railtype is introduced.
Definition: rail.h:263
MAX_YEAR
static const Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
Definition: date_type.h:94
AllocaM
#define AllocaM(T, num_elements)
alloca() has to be called in the parent function, so define AllocaM() as a macro
Definition: alloc_func.hpp:132
SNOW_LINE_MONTHS
static const uint SNOW_LINE_MONTHS
Number of months in the snow line table.
Definition: landscape.h:16
CanalFeature
CanalFeature
List of different canal 'features'.
Definition: newgrf.h:25
TileIndexDiffC::x
int16 x
The x value of the coordinate.
Definition: map_type.h:58
ReadSpriteLayoutRegisters
static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
Preprocess the TileLayoutFlags and read register modifiers from the GRF.
Definition: newgrf.cpp:800
GRFP_BLT_MASK
@ GRFP_BLT_MASK
Bitmask to only get the blitter information.
Definition: newgrf_config.h:78