OpenTTD Source  1.10.0-RC1
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 #include <algorithm>
14 
15 #include "debug.h"
16 #include "fileio_func.h"
17 #include "engine_func.h"
18 #include "engine_base.h"
19 #include "bridge.h"
20 #include "town.h"
21 #include "newgrf_engine.h"
22 #include "newgrf_text.h"
23 #include "fontcache.h"
24 #include "currency.h"
25 #include "landscape.h"
26 #include "newgrf_cargo.h"
27 #include "newgrf_house.h"
28 #include "newgrf_sound.h"
29 #include "newgrf_station.h"
30 #include "industrytype.h"
31 #include "newgrf_canal.h"
32 #include "newgrf_townname.h"
33 #include "newgrf_industries.h"
34 #include "newgrf_airporttiles.h"
35 #include "newgrf_airport.h"
36 #include "newgrf_object.h"
37 #include "rev.h"
38 #include "fios.h"
39 #include "strings_func.h"
40 #include "date_func.h"
41 #include "string_func.h"
42 #include "network/network.h"
43 #include <map>
44 #include "smallmap_gui.h"
45 #include "genworld.h"
46 #include "error.h"
47 #include "vehicle_func.h"
48 #include "language.h"
49 #include "vehicle_base.h"
50 #include "road.h"
51 
52 #include "table/strings.h"
53 #include "table/build_industry.h"
54 
55 #include "safeguards.h"
56 
57 /* TTDPatch extended GRF format codec
58  * (c) Petr Baudis 2004 (GPL'd)
59  * Changes by Florian octo Forster are (c) by the OpenTTD development team.
60  *
61  * Contains portions of documentation by TTDPatch team.
62  * Thanks especially to Josef Drexler for the documentation as well as a lot
63  * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
64  * served as subject to the initial testing of this codec. */
65 
67 static std::vector<GRFFile *> _grf_files;
68 
69 const std::vector<GRFFile *> &GetAllGRFFiles()
70 {
71  return _grf_files;
72 }
73 
76 
78 static uint32 _ttdpatch_flags[8];
79 
82 
83 static const uint MAX_SPRITEGROUP = UINT8_MAX;
84 
87 private:
89  struct SpriteSet {
91  uint num_sprites;
92  };
93 
95  std::map<uint, SpriteSet> spritesets[GSF_END];
96 
97 public:
98  /* Global state */
99  GrfLoadingStage stage;
101 
102  /* Local state in the file */
103  uint file_index;
106  uint32 nfo_line;
108 
109  /* Kind of return values when processing certain actions */
111 
112  /* Currently referenceable spritegroups */
113  SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
114 
117  {
118  this->nfo_line = 0;
119  this->skip_sprites = 0;
120 
121  for (uint i = 0; i < GSF_END; i++) {
122  this->spritesets[i].clear();
123  }
124 
125  memset(this->spritegroups, 0, sizeof(this->spritegroups));
126  }
127 
136  void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
137  {
138  assert(feature < GSF_END);
139  for (uint i = 0; i < numsets; i++) {
140  SpriteSet &set = this->spritesets[feature][first_set + i];
141  set.sprite = first_sprite + i * numents;
142  set.num_sprites = numents;
143  }
144  }
145 
152  bool HasValidSpriteSets(byte feature) const
153  {
154  assert(feature < GSF_END);
155  return !this->spritesets[feature].empty();
156  }
157 
165  bool IsValidSpriteSet(byte feature, uint set) const
166  {
167  assert(feature < GSF_END);
168  return this->spritesets[feature].find(set) != this->spritesets[feature].end();
169  }
170 
177  SpriteID GetSprite(byte feature, uint set) const
178  {
179  assert(IsValidSpriteSet(feature, set));
180  return this->spritesets[feature].find(set)->second.sprite;
181  }
182 
189  uint GetNumEnts(byte feature, uint set) const
190  {
191  assert(IsValidSpriteSet(feature, set));
192  return this->spritesets[feature].find(set)->second.num_sprites;
193  }
194 };
195 
196 static GrfProcessingState _cur;
197 
198 
205 template <VehicleType T>
206 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
207 {
208  return image_index == 0xFD || IsValidImageIndex<T>(image_index);
209 }
210 
212 
214 class ByteReader {
215 protected:
216  byte *data;
217  byte *end;
218 
219 public:
220  ByteReader(byte *data, byte *end) : data(data), end(end) { }
221 
222  inline byte ReadByte()
223  {
224  if (data < end) return *(data)++;
225  throw OTTDByteReaderSignal();
226  }
227 
228  uint16 ReadWord()
229  {
230  uint16 val = ReadByte();
231  return val | (ReadByte() << 8);
232  }
233 
234  uint16 ReadExtendedByte()
235  {
236  uint16 val = ReadByte();
237  return val == 0xFF ? ReadWord() : val;
238  }
239 
240  uint32 ReadDWord()
241  {
242  uint32 val = ReadWord();
243  return val | (ReadWord() << 16);
244  }
245 
246  uint32 ReadVarSize(byte size)
247  {
248  switch (size) {
249  case 1: return ReadByte();
250  case 2: return ReadWord();
251  case 4: return ReadDWord();
252  default:
253  NOT_REACHED();
254  return 0;
255  }
256  }
257 
258  const char *ReadString()
259  {
260  char *string = reinterpret_cast<char *>(data);
261  size_t string_length = ttd_strnlen(string, Remaining());
262 
263  if (string_length == Remaining()) {
264  /* String was not NUL terminated, so make sure it is now. */
265  string[string_length - 1] = '\0';
266  grfmsg(7, "String was not terminated with a zero byte.");
267  } else {
268  /* Increase the string length to include the NUL byte. */
269  string_length++;
270  }
271  Skip(string_length);
272 
273  return string;
274  }
275 
276  inline size_t Remaining() const
277  {
278  return end - data;
279  }
280 
281  inline bool HasData(size_t count = 1) const
282  {
283  return data + count <= end;
284  }
285 
286  inline byte *Data()
287  {
288  return data;
289  }
290 
291  inline void Skip(size_t len)
292  {
293  data += len;
294  /* It is valid to move the buffer to exactly the end of the data,
295  * as there may not be any more data read. */
296  if (data > end) throw OTTDByteReaderSignal();
297  }
298 };
299 
300 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
301 
302 static const uint NUM_STATIONS_PER_GRF = 255;
303 
308  UNSET = 0,
311  };
312 
313  uint16 cargo_allowed;
314  uint16 cargo_disallowed;
315  RailTypeLabel railtypelabel;
316  uint8 roadtramtype;
319  bool prop27_set;
320  uint8 rv_max_speed;
321  CargoTypes ctt_include_mask;
322  CargoTypes ctt_exclude_mask;
323 
328  void UpdateRefittability(bool non_empty)
329  {
330  if (non_empty) {
331  this->refittability = NONEMPTY;
332  } else if (this->refittability == UNSET) {
333  this->refittability = EMPTY;
334  }
335  }
336 };
337 
339 
344 static uint32 _grm_engines[256];
345 
347 static uint32 _grm_cargoes[NUM_CARGO * 2];
348 
349 struct GRFLocation {
350  uint32 grfid;
351  uint32 nfoline;
352 
353  GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
354 
355  bool operator<(const GRFLocation &other) const
356  {
357  return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
358  }
359 
360  bool operator == (const GRFLocation &other) const
361  {
362  return this->grfid == other.grfid && this->nfoline == other.nfoline;
363  }
364 };
365 
366 static std::map<GRFLocation, SpriteID> _grm_sprites;
367 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
368 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
369 
380 void CDECL grfmsg(int severity, const char *str, ...)
381 {
382  char buf[1024];
383  va_list va;
384 
385  va_start(va, str);
386  vseprintf(buf, lastof(buf), str, va);
387  va_end(va);
388 
389  DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
390 }
391 
397 static GRFFile *GetFileByGRFID(uint32 grfid)
398 {
399  for (GRFFile * const file : _grf_files) {
400  if (file->grfid == grfid) return file;
401  }
402  return nullptr;
403 }
404 
410 static GRFFile *GetFileByFilename(const char *filename)
411 {
412  for (GRFFile * const file : _grf_files) {
413  if (strcmp(file->filename, filename) == 0) return file;
414  }
415  return nullptr;
416 }
417 
420 {
421  /* Clear the GOTO labels used for GRF processing */
422  for (GRFLabel *l = gf->label; l != nullptr;) {
423  GRFLabel *l2 = l->next;
424  free(l);
425  l = l2;
426  }
427  gf->label = nullptr;
428 }
429 
436 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = nullptr)
437 {
438  GRFFile *file;
439  if (config != nullptr) {
440  file = GetFileByGRFID(config->ident.grfid);
441  } else {
442  config = _cur.grfconfig;
443  file = _cur.grffile;
444  }
445 
446  config->status = GCS_DISABLED;
447  if (file != nullptr) ClearTemporaryNewGRFData(file);
448  if (config == _cur.grfconfig) _cur.skip_sprites = -1;
449 
450  if (message != STR_NULL) {
451  delete config->error;
452  config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
453  if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
454  }
455 
456  return config->error;
457 }
458 
463  uint32 grfid;
466 };
467 typedef std::vector<StringIDMapping> StringIDMappingVector;
468 static StringIDMappingVector _string_to_grf_mapping;
469 
475 static void AddStringForMapping(StringID source, StringID *target)
476 {
477  *target = STR_UNDEFINED;
478  _string_to_grf_mapping.push_back({_cur.grffile->grfid, source, target});
479 }
480 
489 {
490  /* StringID table for TextIDs 0x4E->0x6D */
491  static const StringID units_volume[] = {
492  STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
493  STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
494  STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495  STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
496  STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
497  STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
498  STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
499  STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
500  };
501 
502  /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
503  assert(!IsInsideMM(str, 0xD000, 0xD7FF));
504 
505 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
506  assert_compile(stringend - stringid == end - begin); \
507  if (str >= begin && str <= end) return str + (stringid - begin)
508 
509  /* We have some changes in our cargo strings, resulting in some missing. */
510  TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
511  TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
512  if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
513  TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
514  TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
515  TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
516 
517  /* Map building names according to our lang file changes. There are several
518  * ranges of house ids, all of which need to be remapped to allow newgrfs
519  * to use original house names. */
520  TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
521  TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
522  TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
523 
524  /* Same thing for industries */
525  TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
526  TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
527  TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
528  TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
529  TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
530 
531  switch (str) {
532  case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
533  case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
534  case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
535  }
536 #undef TEXTID_TO_STRINGID
537 
538  if (str == STR_NULL) return STR_EMPTY;
539 
540  DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
541 
542  return STR_EMPTY;
543 }
544 
552 StringID MapGRFStringID(uint32 grfid, StringID str)
553 {
554  if (IsInsideMM(str, 0xD800, 0xE000)) {
555  /* General text provided by NewGRF.
556  * In the specs this is called the 0xDCxx range (misc persistent texts),
557  * but we meanwhile extended the range to 0xD800-0xDFFF.
558  * Note: We are not involved in the "persistent" business, since we do not store
559  * any NewGRF strings in savegames. */
560  return GetGRFStringID(grfid, str);
561  } else if (IsInsideMM(str, 0xD000, 0xD800)) {
562  /* Callback text provided by NewGRF.
563  * In the specs this is called the 0xD0xx range (misc graphics texts).
564  * These texts can be returned by various callbacks.
565  *
566  * Due to how TTDP implements the GRF-local- to global-textid translation
567  * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
568  * We do not care about that difference and just mask out the 0x400 bit.
569  */
570  str &= ~0x400;
571  return GetGRFStringID(grfid, str);
572  } else {
573  /* The NewGRF wants to include/reference an original TTD string.
574  * Try our best to find an equivalent one. */
576  }
577 }
578 
579 static std::map<uint32, uint32> _grf_id_overrides;
580 
586 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
587 {
588  _grf_id_overrides[source_grfid] = target_grfid;
589  grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
590 }
591 
600 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
601 {
602  /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
603  * them use the same engine slots. */
604  uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
606  /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
607  scope_grfid = file->grfid;
608  uint32 override = _grf_id_overrides[file->grfid];
609  if (override != 0) {
610  scope_grfid = override;
611  const GRFFile *grf_match = GetFileByGRFID(override);
612  if (grf_match == nullptr) {
613  grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
614  } else {
615  grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
616  }
617  }
618 
619  /* Check if the engine is registered in the override manager */
620  EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
621  if (engine != INVALID_ENGINE) {
622  Engine *e = Engine::Get(engine);
623  if (e->grf_prop.grffile == nullptr) e->grf_prop.grffile = file;
624  return e;
625  }
626  }
627 
628  /* Check if there is an unreserved slot */
629  EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
630  if (engine != INVALID_ENGINE) {
631  Engine *e = Engine::Get(engine);
632 
633  if (e->grf_prop.grffile == nullptr) {
634  e->grf_prop.grffile = file;
635  grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
636  }
637 
638  /* Reserve the engine slot */
639  if (!static_access) {
640  EngineIDMapping *eid = _engine_mngr.data() + engine;
641  eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
642  }
643 
644  return e;
645  }
646 
647  if (static_access) return nullptr;
648 
649  if (!Engine::CanAllocateItem()) {
650  grfmsg(0, "Can't allocate any more engines");
651  return nullptr;
652  }
653 
654  size_t engine_pool_size = Engine::GetPoolSize();
655 
656  /* ... it's not, so create a new one based off an existing engine */
657  Engine *e = new Engine(type, internal_id);
658  e->grf_prop.grffile = file;
659 
660  /* Reserve the engine slot */
661  assert(_engine_mngr.size() == e->index);
662  _engine_mngr.push_back({
663  scope_grfid, // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
664  internal_id,
665  type,
666  static_cast<uint8>(min(internal_id, _engine_counts[type])) // substitute_id == _engine_counts[subtype] means "no substitute"
667  });
668 
669  if (engine_pool_size != Engine::GetPoolSize()) {
670  /* Resize temporary engine data ... */
671  _gted = ReallocT(_gted, Engine::GetPoolSize());
672 
673  /* and blank the new block. */
674  size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
675  memset(_gted + engine_pool_size, 0, len);
676  }
677  if (type == VEH_TRAIN) {
678  _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
679  }
680 
681  grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
682 
683  return e;
684 }
685 
696 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
697 {
698  uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
700  scope_grfid = file->grfid;
701  uint32 override = _grf_id_overrides[file->grfid];
702  if (override != 0) scope_grfid = override;
703  }
704 
705  return _engine_mngr.GetID(type, internal_id, scope_grfid);
706 }
707 
712 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
713 {
714  if (HasBit(grf_sprite->pal, 14)) {
715  ClrBit(grf_sprite->pal, 14);
716  SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
717  }
718 
719  if (HasBit(grf_sprite->sprite, 14)) {
720  ClrBit(grf_sprite->sprite, 14);
722  }
723 
724  if (HasBit(grf_sprite->sprite, 15)) {
725  ClrBit(grf_sprite->sprite, 15);
726  SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
727  }
728 }
729 
743 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)
744 {
745  grf_sprite->sprite = buf->ReadWord();
746  grf_sprite->pal = buf->ReadWord();
747  TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
748 
749  MapSpriteMappingRecolour(grf_sprite);
750 
751  bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
752  ClrBit(grf_sprite->pal, 15);
753  if (custom_sprite) {
754  /* Use sprite from Action 1 */
755  uint index = GB(grf_sprite->sprite, 0, 14);
756  if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
757  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
758  grf_sprite->sprite = SPR_IMG_QUERY;
759  grf_sprite->pal = PAL_NONE;
760  } else {
761  SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
762  if (max_sprite_offset != nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
763  SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
765  }
766  } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
767  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
768  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
769  return flags;
770  }
771 
772  if (flags & TLF_CUSTOM_PALETTE) {
773  /* Use palette from Action 1 */
774  uint index = GB(grf_sprite->pal, 0, 14);
775  if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
776  grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
777  grf_sprite->pal = PAL_NONE;
778  } else {
779  SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
780  if (max_palette_offset != nullptr) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
781  SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
783  }
784  } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
785  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
786  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
787  return flags;
788  }
789 
790  return flags;
791 }
792 
801 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
802 {
803  if (!(flags & TLF_DRAWING_FLAGS)) return;
804 
805  if (dts->registers == nullptr) dts->AllocateRegisters();
806  TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
807  regs.flags = flags & TLF_DRAWING_FLAGS;
808 
809  if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
810  if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
811  if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
812 
813  if (is_parent) {
814  if (flags & TLF_BB_XY_OFFSET) {
815  regs.delta.parent[0] = buf->ReadByte();
816  regs.delta.parent[1] = buf->ReadByte();
817  }
818  if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
819  } else {
820  if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
821  if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
822  }
823 
824  if (flags & TLF_SPRITE_VAR10) {
825  regs.sprite_var10 = buf->ReadByte();
826  if (regs.sprite_var10 > TLR_MAX_VAR10) {
827  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
828  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
829  return;
830  }
831  }
832 
833  if (flags & TLF_PALETTE_VAR10) {
834  regs.palette_var10 = buf->ReadByte();
835  if (regs.palette_var10 > TLR_MAX_VAR10) {
836  grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
837  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
838  return;
839  }
840  }
841 }
842 
854 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
855 {
856  bool has_flags = HasBit(num_building_sprites, 6);
857  ClrBit(num_building_sprites, 6);
858  TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
859  if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
860  dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
861 
862  uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
863  uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
864  MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
865  MemSetT(max_palette_offset, 0, num_building_sprites + 1);
866 
867  /* Groundsprite */
868  TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
869  if (_cur.skip_sprites < 0) return true;
870 
871  if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
872  grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
873  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
874  return true;
875  }
876 
877  ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
878  if (_cur.skip_sprites < 0) return true;
879 
880  for (uint i = 0; i < num_building_sprites; i++) {
881  DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
882 
883  flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
884  if (_cur.skip_sprites < 0) return true;
885 
886  if (flags & ~valid_flags) {
887  grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
888  DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
889  return true;
890  }
891 
892  seq->delta_x = buf->ReadByte();
893  seq->delta_y = buf->ReadByte();
894 
895  if (!no_z_position) seq->delta_z = buf->ReadByte();
896 
897  if (seq->IsParentSprite()) {
898  seq->size_x = buf->ReadByte();
899  seq->size_y = buf->ReadByte();
900  seq->size_z = buf->ReadByte();
901  }
902 
903  ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
904  if (_cur.skip_sprites < 0) return true;
905  }
906 
907  /* Check if the number of sprites per spriteset is consistent */
908  bool is_consistent = true;
909  dts->consistent_max_offset = 0;
910  for (uint i = 0; i < num_building_sprites + 1; i++) {
911  if (max_sprite_offset[i] > 0) {
912  if (dts->consistent_max_offset == 0) {
913  dts->consistent_max_offset = max_sprite_offset[i];
914  } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
915  is_consistent = false;
916  break;
917  }
918  }
919  if (max_palette_offset[i] > 0) {
920  if (dts->consistent_max_offset == 0) {
921  dts->consistent_max_offset = max_palette_offset[i];
922  } else if (dts->consistent_max_offset != max_palette_offset[i]) {
923  is_consistent = false;
924  break;
925  }
926  }
927  }
928 
929  /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
930  assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
931 
932  if (!is_consistent || dts->registers != nullptr) {
933  dts->consistent_max_offset = 0;
934  if (dts->registers == nullptr) dts->AllocateRegisters();
935 
936  for (uint i = 0; i < num_building_sprites + 1; i++) {
937  TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
938  regs.max_sprite_offset = max_sprite_offset[i];
939  regs.max_palette_offset = max_palette_offset[i];
940  }
941  }
942 
943  return false;
944 }
945 
949 static CargoTypes TranslateRefitMask(uint32 refit_mask)
950 {
951  CargoTypes result = 0;
952  uint8 bit;
953  FOR_EACH_SET_BIT(bit, refit_mask) {
954  CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
955  if (cargo != CT_INVALID) SetBit(result, cargo);
956  }
957  return result;
958 }
959 
967 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
968 {
969  /* Special value for 'none' */
970  if (base_pointer == 0) {
971  *index = INVALID_PRICE;
972  return;
973  }
974 
975  static const uint32 start = 0x4B34;
976  static const uint32 size = 6;
977 
978  if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
979  grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
980  return;
981  }
982 
983  *index = (Price)((base_pointer - start) / size);
984 }
985 
993 };
994 
995 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
996 
1005 {
1006  switch (prop) {
1007  case 0x00: // Introduction date
1008  ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1009  break;
1010 
1011  case 0x02: // Decay speed
1012  ei->decay_speed = buf->ReadByte();
1013  break;
1014 
1015  case 0x03: // Vehicle life
1016  ei->lifelength = buf->ReadByte();
1017  break;
1018 
1019  case 0x04: // Model life
1020  ei->base_life = buf->ReadByte();
1021  break;
1022 
1023  case 0x06: // Climates available
1024  ei->climates = buf->ReadByte();
1025  break;
1026 
1027  case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1028  /* Amount of cargo loaded during a vehicle's "loading tick" */
1029  ei->load_amount = buf->ReadByte();
1030  break;
1031 
1032  default:
1033  return CIR_UNKNOWN;
1034  }
1035 
1036  return CIR_SUCCESS;
1037 }
1038 
1047 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1048 {
1050 
1051  for (int i = 0; i < numinfo; i++) {
1052  Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1053  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1054 
1055  EngineInfo *ei = &e->info;
1056  RailVehicleInfo *rvi = &e->u.rail;
1057 
1058  switch (prop) {
1059  case 0x05: { // Track type
1060  uint8 tracktype = buf->ReadByte();
1061 
1062  if (tracktype < _cur.grffile->railtype_list.size()) {
1063  _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1064  break;
1065  }
1066 
1067  switch (tracktype) {
1068  case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1069  case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1070  case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1071  default:
1072  grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1073  break;
1074  }
1075  break;
1076  }
1077 
1078  case 0x08: // AI passenger service
1079  /* Tells the AI that this engine is designed for
1080  * passenger services and shouldn't be used for freight. */
1081  rvi->ai_passenger_only = buf->ReadByte();
1082  break;
1083 
1084  case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1085  uint16 speed = buf->ReadWord();
1086  if (speed == 0xFFFF) speed = 0;
1087 
1088  rvi->max_speed = speed;
1089  break;
1090  }
1091 
1092  case PROP_TRAIN_POWER: // 0x0B Power
1093  rvi->power = buf->ReadWord();
1094 
1095  /* Set engine / wagon state based on power */
1096  if (rvi->power != 0) {
1097  if (rvi->railveh_type == RAILVEH_WAGON) {
1098  rvi->railveh_type = RAILVEH_SINGLEHEAD;
1099  }
1100  } else {
1101  rvi->railveh_type = RAILVEH_WAGON;
1102  }
1103  break;
1104 
1105  case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1106  rvi->running_cost = buf->ReadByte();
1107  break;
1108 
1109  case 0x0E: // Running cost base
1110  ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1111  break;
1112 
1113  case 0x12: { // Sprite ID
1114  uint8 spriteid = buf->ReadByte();
1115  uint8 orig_spriteid = spriteid;
1116 
1117  /* TTD sprite IDs point to a location in a 16bit array, but we use it
1118  * as an array index, so we need it to be half the original value. */
1119  if (spriteid < 0xFD) spriteid >>= 1;
1120 
1121  if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1122  rvi->image_index = spriteid;
1123  } else {
1124  grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1125  rvi->image_index = 0;
1126  }
1127  break;
1128  }
1129 
1130  case 0x13: { // Dual-headed
1131  uint8 dual = buf->ReadByte();
1132 
1133  if (dual != 0) {
1134  rvi->railveh_type = RAILVEH_MULTIHEAD;
1135  } else {
1136  rvi->railveh_type = rvi->power == 0 ?
1138  }
1139  break;
1140  }
1141 
1142  case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1143  rvi->capacity = buf->ReadByte();
1144  break;
1145 
1146  case 0x15: { // Cargo type
1147  _gted[e->index].defaultcargo_grf = _cur.grffile;
1148  uint8 ctype = buf->ReadByte();
1149 
1150  if (ctype == 0xFF) {
1151  /* 0xFF is specified as 'use first refittable' */
1152  ei->cargo_type = CT_INVALID;
1153  } else if (_cur.grffile->grf_version >= 8) {
1154  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1155  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1156  } else if (ctype < NUM_CARGO) {
1157  /* Use untranslated cargo. */
1158  ei->cargo_type = ctype;
1159  } else {
1160  ei->cargo_type = CT_INVALID;
1161  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1162  }
1163  break;
1164  }
1165 
1166  case PROP_TRAIN_WEIGHT: // 0x16 Weight
1167  SB(rvi->weight, 0, 8, buf->ReadByte());
1168  break;
1169 
1170  case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1171  rvi->cost_factor = buf->ReadByte();
1172  break;
1173 
1174  case 0x18: // AI rank
1175  grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1176  buf->ReadByte();
1177  break;
1178 
1179  case 0x19: { // Engine traction type
1180  /* What do the individual numbers mean?
1181  * 0x00 .. 0x07: Steam
1182  * 0x08 .. 0x27: Diesel
1183  * 0x28 .. 0x31: Electric
1184  * 0x32 .. 0x37: Monorail
1185  * 0x38 .. 0x41: Maglev
1186  */
1187  uint8 traction = buf->ReadByte();
1188  EngineClass engclass;
1189 
1190  if (traction <= 0x07) {
1191  engclass = EC_STEAM;
1192  } else if (traction <= 0x27) {
1193  engclass = EC_DIESEL;
1194  } else if (traction <= 0x31) {
1195  engclass = EC_ELECTRIC;
1196  } else if (traction <= 0x37) {
1197  engclass = EC_MONORAIL;
1198  } else if (traction <= 0x41) {
1199  engclass = EC_MAGLEV;
1200  } else {
1201  break;
1202  }
1203 
1204  if (_cur.grffile->railtype_list.size() == 0) {
1205  /* Use traction type to select between normal and electrified
1206  * rail only when no translation list is in place. */
1207  if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1208  if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1209  }
1210 
1211  rvi->engclass = engclass;
1212  break;
1213  }
1214 
1215  case 0x1A: // Alter purchase list sort order
1216  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1217  break;
1218 
1219  case 0x1B: // Powered wagons power bonus
1220  rvi->pow_wag_power = buf->ReadWord();
1221  break;
1222 
1223  case 0x1C: // Refit cost
1224  ei->refit_cost = buf->ReadByte();
1225  break;
1226 
1227  case 0x1D: { // Refit cargo
1228  uint32 mask = buf->ReadDWord();
1229  _gted[e->index].UpdateRefittability(mask != 0);
1230  ei->refit_mask = TranslateRefitMask(mask);
1231  _gted[e->index].defaultcargo_grf = _cur.grffile;
1232  break;
1233  }
1234 
1235  case 0x1E: // Callback
1236  ei->callback_mask = buf->ReadByte();
1237  break;
1238 
1239  case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1240  rvi->tractive_effort = buf->ReadByte();
1241  break;
1242 
1243  case 0x20: // Air drag
1244  rvi->air_drag = buf->ReadByte();
1245  break;
1246 
1247  case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1248  rvi->shorten_factor = buf->ReadByte();
1249  break;
1250 
1251  case 0x22: // Visual effect
1252  rvi->visual_effect = buf->ReadByte();
1253  /* Avoid accidentally setting visual_effect to the default value
1254  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1255  if (rvi->visual_effect == VE_DEFAULT) {
1256  assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1258  }
1259  break;
1260 
1261  case 0x23: // Powered wagons weight bonus
1262  rvi->pow_wag_weight = buf->ReadByte();
1263  break;
1264 
1265  case 0x24: { // High byte of vehicle weight
1266  byte weight = buf->ReadByte();
1267 
1268  if (weight > 4) {
1269  grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1270  } else {
1271  SB(rvi->weight, 8, 8, weight);
1272  }
1273  break;
1274  }
1275 
1276  case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1277  rvi->user_def_data = buf->ReadByte();
1278  break;
1279 
1280  case 0x26: // Retire vehicle early
1281  ei->retire_early = buf->ReadByte();
1282  break;
1283 
1284  case 0x27: // Miscellaneous flags
1285  ei->misc_flags = buf->ReadByte();
1286  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1287  _gted[e->index].prop27_set = true;
1288  break;
1289 
1290  case 0x28: // Cargo classes allowed
1291  _gted[e->index].cargo_allowed = buf->ReadWord();
1292  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1293  _gted[e->index].defaultcargo_grf = _cur.grffile;
1294  break;
1295 
1296  case 0x29: // Cargo classes disallowed
1297  _gted[e->index].cargo_disallowed = buf->ReadWord();
1298  _gted[e->index].UpdateRefittability(false);
1299  break;
1300 
1301  case 0x2A: // Long format introduction date (days since year 0)
1302  ei->base_intro = buf->ReadDWord();
1303  break;
1304 
1305  case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1306  ei->cargo_age_period = buf->ReadWord();
1307  break;
1308 
1309  case 0x2C: // CTT refit include list
1310  case 0x2D: { // CTT refit exclude list
1311  uint8 count = buf->ReadByte();
1312  _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1313  if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1314  CargoTypes &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1315  ctt = 0;
1316  while (count--) {
1317  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1318  if (ctype == CT_INVALID) continue;
1319  SetBit(ctt, ctype);
1320  }
1321  break;
1322  }
1323 
1324  default:
1325  ret = CommonVehicleChangeInfo(ei, prop, buf);
1326  break;
1327  }
1328  }
1329 
1330  return ret;
1331 }
1332 
1341 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1342 {
1344 
1345  for (int i = 0; i < numinfo; i++) {
1346  Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1347  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1348 
1349  EngineInfo *ei = &e->info;
1350  RoadVehicleInfo *rvi = &e->u.road;
1351 
1352  switch (prop) {
1353  case 0x05: // Road/tram type
1354  /* RoadTypeLabel is looked up later after the engine's road/tram
1355  * flag is set, however 0 means the value has not been set. */
1356  _gted[e->index].roadtramtype = buf->ReadByte() + 1;
1357  break;
1358 
1359  case 0x08: // Speed (1 unit is 0.5 kmh)
1360  rvi->max_speed = buf->ReadByte();
1361  break;
1362 
1363  case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1364  rvi->running_cost = buf->ReadByte();
1365  break;
1366 
1367  case 0x0A: // Running cost base
1368  ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1369  break;
1370 
1371  case 0x0E: { // Sprite ID
1372  uint8 spriteid = buf->ReadByte();
1373  uint8 orig_spriteid = spriteid;
1374 
1375  /* cars have different custom id in the GRF file */
1376  if (spriteid == 0xFF) spriteid = 0xFD;
1377 
1378  if (spriteid < 0xFD) spriteid >>= 1;
1379 
1380  if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1381  rvi->image_index = spriteid;
1382  } else {
1383  grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1384  rvi->image_index = 0;
1385  }
1386  break;
1387  }
1388 
1389  case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1390  rvi->capacity = buf->ReadByte();
1391  break;
1392 
1393  case 0x10: { // Cargo type
1394  _gted[e->index].defaultcargo_grf = _cur.grffile;
1395  uint8 ctype = buf->ReadByte();
1396 
1397  if (ctype == 0xFF) {
1398  /* 0xFF is specified as 'use first refittable' */
1399  ei->cargo_type = CT_INVALID;
1400  } else if (_cur.grffile->grf_version >= 8) {
1401  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1402  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1403  } else if (ctype < NUM_CARGO) {
1404  /* Use untranslated cargo. */
1405  ei->cargo_type = ctype;
1406  } else {
1407  ei->cargo_type = CT_INVALID;
1408  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1409  }
1410  break;
1411  }
1412 
1413  case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1414  rvi->cost_factor = buf->ReadByte();
1415  break;
1416 
1417  case 0x12: // SFX
1418  rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1419  break;
1420 
1421  case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1422  rvi->power = buf->ReadByte();
1423  break;
1424 
1425  case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1426  rvi->weight = buf->ReadByte();
1427  break;
1428 
1429  case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1430  _gted[e->index].rv_max_speed = buf->ReadByte();
1431  break;
1432 
1433  case 0x16: { // Cargoes available for refitting
1434  uint32 mask = buf->ReadDWord();
1435  _gted[e->index].UpdateRefittability(mask != 0);
1436  ei->refit_mask = TranslateRefitMask(mask);
1437  _gted[e->index].defaultcargo_grf = _cur.grffile;
1438  break;
1439  }
1440 
1441  case 0x17: // Callback mask
1442  ei->callback_mask = buf->ReadByte();
1443  break;
1444 
1445  case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1446  rvi->tractive_effort = buf->ReadByte();
1447  break;
1448 
1449  case 0x19: // Air drag
1450  rvi->air_drag = buf->ReadByte();
1451  break;
1452 
1453  case 0x1A: // Refit cost
1454  ei->refit_cost = buf->ReadByte();
1455  break;
1456 
1457  case 0x1B: // Retire vehicle early
1458  ei->retire_early = buf->ReadByte();
1459  break;
1460 
1461  case 0x1C: // Miscellaneous flags
1462  ei->misc_flags = buf->ReadByte();
1463  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1464  break;
1465 
1466  case 0x1D: // Cargo classes allowed
1467  _gted[e->index].cargo_allowed = buf->ReadWord();
1468  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1469  _gted[e->index].defaultcargo_grf = _cur.grffile;
1470  break;
1471 
1472  case 0x1E: // Cargo classes disallowed
1473  _gted[e->index].cargo_disallowed = buf->ReadWord();
1474  _gted[e->index].UpdateRefittability(false);
1475  break;
1476 
1477  case 0x1F: // Long format introduction date (days since year 0)
1478  ei->base_intro = buf->ReadDWord();
1479  break;
1480 
1481  case 0x20: // Alter purchase list sort order
1482  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1483  break;
1484 
1485  case 0x21: // Visual effect
1486  rvi->visual_effect = buf->ReadByte();
1487  /* Avoid accidentally setting visual_effect to the default value
1488  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1489  if (rvi->visual_effect == VE_DEFAULT) {
1490  assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1492  }
1493  break;
1494 
1495  case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1496  ei->cargo_age_period = buf->ReadWord();
1497  break;
1498 
1499  case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1500  rvi->shorten_factor = buf->ReadByte();
1501  break;
1502 
1503  case 0x24: // CTT refit include list
1504  case 0x25: { // CTT refit exclude list
1505  uint8 count = buf->ReadByte();
1506  _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1507  if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1508  CargoTypes &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1509  ctt = 0;
1510  while (count--) {
1511  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1512  if (ctype == CT_INVALID) continue;
1513  SetBit(ctt, ctype);
1514  }
1515  break;
1516  }
1517 
1518  default:
1519  ret = CommonVehicleChangeInfo(ei, prop, buf);
1520  break;
1521  }
1522  }
1523 
1524  return ret;
1525 }
1526 
1535 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1536 {
1538 
1539  for (int i = 0; i < numinfo; i++) {
1540  Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1541  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1542 
1543  EngineInfo *ei = &e->info;
1544  ShipVehicleInfo *svi = &e->u.ship;
1545 
1546  switch (prop) {
1547  case 0x08: { // Sprite ID
1548  uint8 spriteid = buf->ReadByte();
1549  uint8 orig_spriteid = spriteid;
1550 
1551  /* ships have different custom id in the GRF file */
1552  if (spriteid == 0xFF) spriteid = 0xFD;
1553 
1554  if (spriteid < 0xFD) spriteid >>= 1;
1555 
1556  if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1557  svi->image_index = spriteid;
1558  } else {
1559  grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1560  svi->image_index = 0;
1561  }
1562  break;
1563  }
1564 
1565  case 0x09: // Refittable
1566  svi->old_refittable = (buf->ReadByte() != 0);
1567  break;
1568 
1569  case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1570  svi->cost_factor = buf->ReadByte();
1571  break;
1572 
1573  case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1574  svi->max_speed = buf->ReadByte();
1575  break;
1576 
1577  case 0x0C: { // Cargo type
1578  _gted[e->index].defaultcargo_grf = _cur.grffile;
1579  uint8 ctype = buf->ReadByte();
1580 
1581  if (ctype == 0xFF) {
1582  /* 0xFF is specified as 'use first refittable' */
1583  ei->cargo_type = CT_INVALID;
1584  } else if (_cur.grffile->grf_version >= 8) {
1585  /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1586  ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1587  } else if (ctype < NUM_CARGO) {
1588  /* Use untranslated cargo. */
1589  ei->cargo_type = ctype;
1590  } else {
1591  ei->cargo_type = CT_INVALID;
1592  grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1593  }
1594  break;
1595  }
1596 
1597  case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1598  svi->capacity = buf->ReadWord();
1599  break;
1600 
1601  case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1602  svi->running_cost = buf->ReadByte();
1603  break;
1604 
1605  case 0x10: // SFX
1606  svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1607  break;
1608 
1609  case 0x11: { // Cargoes available for refitting
1610  uint32 mask = buf->ReadDWord();
1611  _gted[e->index].UpdateRefittability(mask != 0);
1612  ei->refit_mask = TranslateRefitMask(mask);
1613  _gted[e->index].defaultcargo_grf = _cur.grffile;
1614  break;
1615  }
1616 
1617  case 0x12: // Callback mask
1618  ei->callback_mask = buf->ReadByte();
1619  break;
1620 
1621  case 0x13: // Refit cost
1622  ei->refit_cost = buf->ReadByte();
1623  break;
1624 
1625  case 0x14: // Ocean speed fraction
1626  svi->ocean_speed_frac = buf->ReadByte();
1627  break;
1628 
1629  case 0x15: // Canal speed fraction
1630  svi->canal_speed_frac = buf->ReadByte();
1631  break;
1632 
1633  case 0x16: // Retire vehicle early
1634  ei->retire_early = buf->ReadByte();
1635  break;
1636 
1637  case 0x17: // Miscellaneous flags
1638  ei->misc_flags = buf->ReadByte();
1639  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1640  break;
1641 
1642  case 0x18: // Cargo classes allowed
1643  _gted[e->index].cargo_allowed = buf->ReadWord();
1644  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1645  _gted[e->index].defaultcargo_grf = _cur.grffile;
1646  break;
1647 
1648  case 0x19: // Cargo classes disallowed
1649  _gted[e->index].cargo_disallowed = buf->ReadWord();
1650  _gted[e->index].UpdateRefittability(false);
1651  break;
1652 
1653  case 0x1A: // Long format introduction date (days since year 0)
1654  ei->base_intro = buf->ReadDWord();
1655  break;
1656 
1657  case 0x1B: // Alter purchase list sort order
1658  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1659  break;
1660 
1661  case 0x1C: // Visual effect
1662  svi->visual_effect = buf->ReadByte();
1663  /* Avoid accidentally setting visual_effect to the default value
1664  * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1665  if (svi->visual_effect == VE_DEFAULT) {
1666  assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1668  }
1669  break;
1670 
1671  case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1672  ei->cargo_age_period = buf->ReadWord();
1673  break;
1674 
1675  case 0x1E: // CTT refit include list
1676  case 0x1F: { // CTT refit exclude list
1677  uint8 count = buf->ReadByte();
1678  _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1679  if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1680  CargoTypes &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1681  ctt = 0;
1682  while (count--) {
1683  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1684  if (ctype == CT_INVALID) continue;
1685  SetBit(ctt, ctype);
1686  }
1687  break;
1688  }
1689 
1690  default:
1691  ret = CommonVehicleChangeInfo(ei, prop, buf);
1692  break;
1693  }
1694  }
1695 
1696  return ret;
1697 }
1698 
1707 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1708 {
1710 
1711  for (int i = 0; i < numinfo; i++) {
1712  Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1713  if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1714 
1715  EngineInfo *ei = &e->info;
1716  AircraftVehicleInfo *avi = &e->u.air;
1717 
1718  switch (prop) {
1719  case 0x08: { // Sprite ID
1720  uint8 spriteid = buf->ReadByte();
1721  uint8 orig_spriteid = spriteid;
1722 
1723  /* aircraft have different custom id in the GRF file */
1724  if (spriteid == 0xFF) spriteid = 0xFD;
1725 
1726  if (spriteid < 0xFD) spriteid >>= 1;
1727 
1728  if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1729  avi->image_index = spriteid;
1730  } else {
1731  grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1732  avi->image_index = 0;
1733  }
1734  break;
1735  }
1736 
1737  case 0x09: // Helicopter
1738  if (buf->ReadByte() == 0) {
1739  avi->subtype = AIR_HELI;
1740  } else {
1741  SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1742  }
1743  break;
1744 
1745  case 0x0A: // Large
1746  SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1747  break;
1748 
1749  case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1750  avi->cost_factor = buf->ReadByte();
1751  break;
1752 
1753  case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1754  avi->max_speed = (buf->ReadByte() * 128) / 10;
1755  break;
1756 
1757  case 0x0D: // Acceleration
1758  avi->acceleration = buf->ReadByte();
1759  break;
1760 
1761  case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1762  avi->running_cost = buf->ReadByte();
1763  break;
1764 
1765  case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1766  avi->passenger_capacity = buf->ReadWord();
1767  break;
1768 
1769  case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1770  avi->mail_capacity = buf->ReadByte();
1771  break;
1772 
1773  case 0x12: // SFX
1774  avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1775  break;
1776 
1777  case 0x13: { // Cargoes available for refitting
1778  uint32 mask = buf->ReadDWord();
1779  _gted[e->index].UpdateRefittability(mask != 0);
1780  ei->refit_mask = TranslateRefitMask(mask);
1781  _gted[e->index].defaultcargo_grf = _cur.grffile;
1782  break;
1783  }
1784 
1785  case 0x14: // Callback mask
1786  ei->callback_mask = buf->ReadByte();
1787  break;
1788 
1789  case 0x15: // Refit cost
1790  ei->refit_cost = buf->ReadByte();
1791  break;
1792 
1793  case 0x16: // Retire vehicle early
1794  ei->retire_early = buf->ReadByte();
1795  break;
1796 
1797  case 0x17: // Miscellaneous flags
1798  ei->misc_flags = buf->ReadByte();
1799  _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1800  break;
1801 
1802  case 0x18: // Cargo classes allowed
1803  _gted[e->index].cargo_allowed = buf->ReadWord();
1804  _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1805  _gted[e->index].defaultcargo_grf = _cur.grffile;
1806  break;
1807 
1808  case 0x19: // Cargo classes disallowed
1809  _gted[e->index].cargo_disallowed = buf->ReadWord();
1810  _gted[e->index].UpdateRefittability(false);
1811  break;
1812 
1813  case 0x1A: // Long format introduction date (days since year 0)
1814  ei->base_intro = buf->ReadDWord();
1815  break;
1816 
1817  case 0x1B: // Alter purchase list sort order
1818  AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1819  break;
1820 
1821  case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1822  ei->cargo_age_period = buf->ReadWord();
1823  break;
1824 
1825  case 0x1D: // CTT refit include list
1826  case 0x1E: { // CTT refit exclude list
1827  uint8 count = buf->ReadByte();
1828  _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1829  if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1830  CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1831  ctt = 0;
1832  while (count--) {
1833  CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1834  if (ctype == CT_INVALID) continue;
1835  SetBit(ctt, ctype);
1836  }
1837  break;
1838  }
1839 
1840  case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1841  avi->max_range = buf->ReadWord();
1842  break;
1843 
1844  default:
1845  ret = CommonVehicleChangeInfo(ei, prop, buf);
1846  break;
1847  }
1848  }
1849 
1850  return ret;
1851 }
1852 
1861 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1862 {
1864 
1865  if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1866  grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1867  return CIR_INVALID_ID;
1868  }
1869 
1870  /* Allocate station specs if necessary */
1871  if (_cur.grffile->stations == nullptr) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1872 
1873  for (int i = 0; i < numinfo; i++) {
1874  StationSpec *statspec = _cur.grffile->stations[stid + i];
1875 
1876  /* Check that the station we are modifying is defined. */
1877  if (statspec == nullptr && prop != 0x08) {
1878  grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1879  return CIR_INVALID_ID;
1880  }
1881 
1882  switch (prop) {
1883  case 0x08: { // Class ID
1884  StationSpec **spec = &_cur.grffile->stations[stid + i];
1885 
1886  /* Property 0x08 is special; it is where the station is allocated */
1887  if (*spec == nullptr) *spec = CallocT<StationSpec>(1);
1888 
1889  /* Swap classid because we read it in BE meaning WAYP or DFLT */
1890  uint32 classid = buf->ReadDWord();
1891  (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1892  break;
1893  }
1894 
1895  case 0x09: // Define sprite layout
1896  statspec->tiles = buf->ReadExtendedByte();
1897  delete[] statspec->renderdata; // delete earlier loaded stuff
1898  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1899 
1900  for (uint t = 0; t < statspec->tiles; t++) {
1901  NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1902  dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1903 
1904  if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1905  buf->Skip(4);
1906  extern const DrawTileSprites _station_display_datas_rail[8];
1907  dts->Clone(&_station_display_datas_rail[t % 8]);
1908  continue;
1909  }
1910 
1911  ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1912  /* On error, bail out immediately. Temporary GRF data was already freed */
1913  if (_cur.skip_sprites < 0) return CIR_DISABLED;
1914 
1915  static std::vector<DrawTileSeqStruct> tmp_layout;
1916  tmp_layout.clear();
1917  for (;;) {
1918  /* no relative bounding box support */
1919  /*C++17: DrawTileSeqStruct &dtss = */ tmp_layout.emplace_back();
1920  DrawTileSeqStruct &dtss = tmp_layout.back();
1921  MemSetT(&dtss, 0);
1922 
1923  dtss.delta_x = buf->ReadByte();
1924  if (dtss.IsTerminator()) break;
1925  dtss.delta_y = buf->ReadByte();
1926  dtss.delta_z = buf->ReadByte();
1927  dtss.size_x = buf->ReadByte();
1928  dtss.size_y = buf->ReadByte();
1929  dtss.size_z = buf->ReadByte();
1930 
1931  ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss.image);
1932  /* On error, bail out immediately. Temporary GRF data was already freed */
1933  if (_cur.skip_sprites < 0) return CIR_DISABLED;
1934  }
1935  dts->Clone(tmp_layout.data());
1936  }
1937  break;
1938 
1939  case 0x0A: { // Copy sprite layout
1940  byte srcid = buf->ReadByte();
1941  const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1942 
1943  if (srcstatspec == nullptr) {
1944  grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1945  continue;
1946  }
1947 
1948  delete[] statspec->renderdata; // delete earlier loaded stuff
1949 
1950  statspec->tiles = srcstatspec->tiles;
1951  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1952  for (uint t = 0; t < statspec->tiles; t++) {
1953  statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1954  }
1955  break;
1956  }
1957 
1958  case 0x0B: // Callback mask
1959  statspec->callback_mask = buf->ReadByte();
1960  break;
1961 
1962  case 0x0C: // Disallowed number of platforms
1963  statspec->disallowed_platforms = buf->ReadByte();
1964  break;
1965 
1966  case 0x0D: // Disallowed platform lengths
1967  statspec->disallowed_lengths = buf->ReadByte();
1968  break;
1969 
1970  case 0x0E: // Define custom layout
1971  statspec->copied_layouts = false;
1972 
1973  while (buf->HasData()) {
1974  byte length = buf->ReadByte();
1975  byte number = buf->ReadByte();
1976  StationLayout layout;
1977  uint l, p;
1978 
1979  if (length == 0 || number == 0) break;
1980 
1981  if (length > statspec->lengths) {
1982  byte diff_length = length - statspec->lengths;
1983  statspec->platforms = ReallocT(statspec->platforms, length);
1984  memset(statspec->platforms + statspec->lengths, 0, diff_length);
1985 
1986  statspec->layouts = ReallocT(statspec->layouts, length);
1987  memset(statspec->layouts + statspec->lengths, 0, diff_length * sizeof(*statspec->layouts));
1988 
1989  statspec->lengths = length;
1990  }
1991  l = length - 1; // index is zero-based
1992 
1993  if (number > statspec->platforms[l]) {
1994  statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1995  /* We expect nullptr being 0 here, but C99 guarantees that. */
1996  memset(statspec->layouts[l] + statspec->platforms[l], 0,
1997  (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1998 
1999  statspec->platforms[l] = number;
2000  }
2001 
2002  p = 0;
2003  layout = MallocT<byte>(length * number);
2004  try {
2005  for (l = 0; l < length; l++) {
2006  for (p = 0; p < number; p++) {
2007  layout[l * number + p] = buf->ReadByte();
2008  }
2009  }
2010  } catch (...) {
2011  free(layout);
2012  throw;
2013  }
2014 
2015  l--;
2016  p--;
2017  free(statspec->layouts[l][p]);
2018  statspec->layouts[l][p] = layout;
2019  }
2020  break;
2021 
2022  case 0x0F: { // Copy custom layout
2023  byte srcid = buf->ReadByte();
2024  const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2025 
2026  if (srcstatspec == nullptr) {
2027  grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2028  continue;
2029  }
2030 
2031  statspec->lengths = srcstatspec->lengths;
2032  statspec->platforms = srcstatspec->platforms;
2033  statspec->layouts = srcstatspec->layouts;
2034  statspec->copied_layouts = true;
2035  break;
2036  }
2037 
2038  case 0x10: // Little/lots cargo threshold
2039  statspec->cargo_threshold = buf->ReadWord();
2040  break;
2041 
2042  case 0x11: // Pylon placement
2043  statspec->pylons = buf->ReadByte();
2044  break;
2045 
2046  case 0x12: // Cargo types for random triggers
2047  if (_cur.grffile->grf_version >= 7) {
2048  statspec->cargo_triggers = TranslateRefitMask(buf->ReadDWord());
2049  } else {
2050  statspec->cargo_triggers = (CargoTypes)buf->ReadDWord();
2051  }
2052  break;
2053 
2054  case 0x13: // General flags
2055  statspec->flags = buf->ReadByte();
2056  break;
2057 
2058  case 0x14: // Overhead wire placement
2059  statspec->wires = buf->ReadByte();
2060  break;
2061 
2062  case 0x15: // Blocked tiles
2063  statspec->blocked = buf->ReadByte();
2064  break;
2065 
2066  case 0x16: // Animation info
2067  statspec->animation.frames = buf->ReadByte();
2068  statspec->animation.status = buf->ReadByte();
2069  break;
2070 
2071  case 0x17: // Animation speed
2072  statspec->animation.speed = buf->ReadByte();
2073  break;
2074 
2075  case 0x18: // Animation triggers
2076  statspec->animation.triggers = buf->ReadWord();
2077  break;
2078 
2079  case 0x1A: // Advanced sprite layout
2080  statspec->tiles = buf->ReadExtendedByte();
2081  delete[] statspec->renderdata; // delete earlier loaded stuff
2082  statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2083 
2084  for (uint t = 0; t < statspec->tiles; t++) {
2085  NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2086  uint num_building_sprites = buf->ReadByte();
2087  /* On error, bail out immediately. Temporary GRF data was already freed */
2088  if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2089  }
2090  break;
2091 
2092  default:
2093  ret = CIR_UNKNOWN;
2094  break;
2095  }
2096  }
2097 
2098  return ret;
2099 }
2100 
2109 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2110 {
2112 
2113  if (id + numinfo > CF_END) {
2114  grfmsg(1, "CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring", id + numinfo, CF_END);
2115  return CIR_INVALID_ID;
2116  }
2117 
2118  for (int i = 0; i < numinfo; i++) {
2119  CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2120 
2121  switch (prop) {
2122  case 0x08:
2123  cp->callback_mask = buf->ReadByte();
2124  break;
2125 
2126  case 0x09:
2127  cp->flags = buf->ReadByte();
2128  break;
2129 
2130  default:
2131  ret = CIR_UNKNOWN;
2132  break;
2133  }
2134  }
2135 
2136  return ret;
2137 }
2138 
2147 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2148 {
2150 
2151  if (brid + numinfo > MAX_BRIDGES) {
2152  grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2153  return CIR_INVALID_ID;
2154  }
2155 
2156  for (int i = 0; i < numinfo; i++) {
2157  BridgeSpec *bridge = &_bridge[brid + i];
2158 
2159  switch (prop) {
2160  case 0x08: { // Year of availability
2161  /* We treat '0' as always available */
2162  byte year = buf->ReadByte();
2163  bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2164  break;
2165  }
2166 
2167  case 0x09: // Minimum length
2168  bridge->min_length = buf->ReadByte();
2169  break;
2170 
2171  case 0x0A: // Maximum length
2172  bridge->max_length = buf->ReadByte();
2173  if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2174  break;
2175 
2176  case 0x0B: // Cost factor
2177  bridge->price = buf->ReadByte();
2178  break;
2179 
2180  case 0x0C: // Maximum speed
2181  bridge->speed = buf->ReadWord();
2182  break;
2183 
2184  case 0x0D: { // Bridge sprite tables
2185  byte tableid = buf->ReadByte();
2186  byte numtables = buf->ReadByte();
2187 
2188  if (bridge->sprite_table == nullptr) {
2189  /* Allocate memory for sprite table pointers and zero out */
2190  bridge->sprite_table = CallocT<PalSpriteID*>(7);
2191  }
2192 
2193  for (; numtables-- != 0; tableid++) {
2194  if (tableid >= 7) { // skip invalid data
2195  grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2196  for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2197  continue;
2198  }
2199 
2200  if (bridge->sprite_table[tableid] == nullptr) {
2201  bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2202  }
2203 
2204  for (byte sprite = 0; sprite < 32; sprite++) {
2205  SpriteID image = buf->ReadWord();
2206  PaletteID pal = buf->ReadWord();
2207 
2208  bridge->sprite_table[tableid][sprite].sprite = image;
2209  bridge->sprite_table[tableid][sprite].pal = pal;
2210 
2211  MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2212  }
2213  }
2214  break;
2215  }
2216 
2217  case 0x0E: // Flags; bit 0 - disable far pillars
2218  bridge->flags = buf->ReadByte();
2219  break;
2220 
2221  case 0x0F: // Long format year of availability (year since year 0)
2222  bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2223  break;
2224 
2225  case 0x10: { // purchase string
2226  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2227  if (newone != STR_UNDEFINED) bridge->material = newone;
2228  break;
2229  }
2230 
2231  case 0x11: // description of bridge with rails or roads
2232  case 0x12: {
2233  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2234  if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2235  break;
2236  }
2237 
2238  case 0x13: // 16 bits cost multiplier
2239  bridge->price = buf->ReadWord();
2240  break;
2241 
2242  default:
2243  ret = CIR_UNKNOWN;
2244  break;
2245  }
2246  }
2247 
2248  return ret;
2249 }
2250 
2258 {
2260 
2261  switch (prop) {
2262  case 0x09:
2263  case 0x0B:
2264  case 0x0C:
2265  case 0x0D:
2266  case 0x0E:
2267  case 0x0F:
2268  case 0x11:
2269  case 0x14:
2270  case 0x15:
2271  case 0x16:
2272  case 0x18:
2273  case 0x19:
2274  case 0x1A:
2275  case 0x1B:
2276  case 0x1C:
2277  case 0x1D:
2278  case 0x1F:
2279  buf->ReadByte();
2280  break;
2281 
2282  case 0x0A:
2283  case 0x10:
2284  case 0x12:
2285  case 0x13:
2286  case 0x21:
2287  case 0x22:
2288  buf->ReadWord();
2289  break;
2290 
2291  case 0x1E:
2292  buf->ReadDWord();
2293  break;
2294 
2295  case 0x17:
2296  for (uint j = 0; j < 4; j++) buf->ReadByte();
2297  break;
2298 
2299  case 0x20: {
2300  byte count = buf->ReadByte();
2301  for (byte j = 0; j < count; j++) buf->ReadByte();
2302  break;
2303  }
2304 
2305  case 0x23:
2306  buf->Skip(buf->ReadByte() * 2);
2307  break;
2308 
2309  default:
2310  ret = CIR_UNKNOWN;
2311  break;
2312  }
2313  return ret;
2314 }
2315 
2324 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2325 {
2327 
2328  if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2329  grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2330  return CIR_INVALID_ID;
2331  }
2332 
2333  /* Allocate house specs if they haven't been allocated already. */
2334  if (_cur.grffile->housespec == nullptr) {
2335  _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2336  }
2337 
2338  for (int i = 0; i < numinfo; i++) {
2339  HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2340 
2341  if (prop != 0x08 && housespec == nullptr) {
2342  /* If the house property 08 is not yet set, ignore this property */
2343  ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2344  if (cir > ret) ret = cir;
2345  continue;
2346  }
2347 
2348  switch (prop) {
2349  case 0x08: { // Substitute building type, and definition of a new house
2350  HouseSpec **house = &_cur.grffile->housespec[hid + i];
2351  byte subs_id = buf->ReadByte();
2352 
2353  if (subs_id == 0xFF) {
2354  /* Instead of defining a new house, a substitute house id
2355  * of 0xFF disables the old house with the current id. */
2356  HouseSpec::Get(hid + i)->enabled = false;
2357  continue;
2358  } else if (subs_id >= NEW_HOUSE_OFFSET) {
2359  /* The substitute id must be one of the original houses. */
2360  grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2361  continue;
2362  }
2363 
2364  /* Allocate space for this house. */
2365  if (*house == nullptr) *house = CallocT<HouseSpec>(1);
2366 
2367  housespec = *house;
2368 
2369  MemCpyT(housespec, HouseSpec::Get(subs_id));
2370 
2371  housespec->enabled = true;
2372  housespec->grf_prop.local_id = hid + i;
2373  housespec->grf_prop.subst_id = subs_id;
2374  housespec->grf_prop.grffile = _cur.grffile;
2375  housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2376  housespec->random_colour[1] = 0x08; // for all new houses
2377  housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2378  housespec->random_colour[3] = 0x06;
2379 
2380  /* Make sure that the third cargo type is valid in this
2381  * climate. This can cause problems when copying the properties
2382  * of a house that accepts food, where the new house is valid
2383  * in the temperate climate. */
2384  if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2385  housespec->cargo_acceptance[2] = 0;
2386  }
2387 
2388  _loaded_newgrf_features.has_newhouses = true;
2389  break;
2390  }
2391 
2392  case 0x09: // Building flags
2393  housespec->building_flags = (BuildingFlags)buf->ReadByte();
2394  break;
2395 
2396  case 0x0A: { // Availability years
2397  uint16 years = buf->ReadWord();
2398  housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2399  housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2400  break;
2401  }
2402 
2403  case 0x0B: // Population
2404  housespec->population = buf->ReadByte();
2405  break;
2406 
2407  case 0x0C: // Mail generation multiplier
2408  housespec->mail_generation = buf->ReadByte();
2409  break;
2410 
2411  case 0x0D: // Passenger acceptance
2412  case 0x0E: // Mail acceptance
2413  housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2414  break;
2415 
2416  case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2417  int8 goods = buf->ReadByte();
2418 
2419  /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2420  * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2421  CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2422  ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2423 
2424  /* Make sure the cargo type is valid in this climate. */
2425  if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2426 
2427  housespec->accepts_cargo[2] = cid;
2428  housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2429  break;
2430  }
2431 
2432  case 0x10: // Local authority rating decrease on removal
2433  housespec->remove_rating_decrease = buf->ReadWord();
2434  break;
2435 
2436  case 0x11: // Removal cost multiplier
2437  housespec->removal_cost = buf->ReadByte();
2438  break;
2439 
2440  case 0x12: // Building name ID
2441  AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2442  break;
2443 
2444  case 0x13: // Building availability mask
2445  housespec->building_availability = (HouseZones)buf->ReadWord();
2446  break;
2447 
2448  case 0x14: // House callback mask
2449  housespec->callback_mask |= buf->ReadByte();
2450  break;
2451 
2452  case 0x15: { // House override byte
2453  byte override = buf->ReadByte();
2454 
2455  /* The house being overridden must be an original house. */
2456  if (override >= NEW_HOUSE_OFFSET) {
2457  grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2458  continue;
2459  }
2460 
2461  _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2462  break;
2463  }
2464 
2465  case 0x16: // Periodic refresh multiplier
2466  housespec->processing_time = min(buf->ReadByte(), 63);
2467  break;
2468 
2469  case 0x17: // Four random colours to use
2470  for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2471  break;
2472 
2473  case 0x18: // Relative probability of appearing
2474  housespec->probability = buf->ReadByte();
2475  break;
2476 
2477  case 0x19: // Extra flags
2478  housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2479  break;
2480 
2481  case 0x1A: // Animation frames
2482  housespec->animation.frames = buf->ReadByte();
2483  housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2484  SB(housespec->animation.frames, 7, 1, 0);
2485  break;
2486 
2487  case 0x1B: // Animation speed
2488  housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2489  break;
2490 
2491  case 0x1C: // Class of the building type
2492  housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2493  break;
2494 
2495  case 0x1D: // Callback mask part 2
2496  housespec->callback_mask |= (buf->ReadByte() << 8);
2497  break;
2498 
2499  case 0x1E: { // Accepted cargo types
2500  uint32 cargotypes = buf->ReadDWord();
2501 
2502  /* Check if the cargo types should not be changed */
2503  if (cargotypes == 0xFFFFFFFF) break;
2504 
2505  for (uint j = 0; j < 3; j++) {
2506  /* Get the cargo number from the 'list' */
2507  uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2508  CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2509 
2510  if (cargo == CT_INVALID) {
2511  /* Disable acceptance of invalid cargo type */
2512  housespec->cargo_acceptance[j] = 0;
2513  } else {
2514  housespec->accepts_cargo[j] = cargo;
2515  }
2516  }
2517  break;
2518  }
2519 
2520  case 0x1F: // Minimum life span
2521  housespec->minimum_life = buf->ReadByte();
2522  break;
2523 
2524  case 0x20: { // Cargo acceptance watch list
2525  byte count = buf->ReadByte();
2526  for (byte j = 0; j < count; j++) {
2527  CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2528  if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2529  }
2530  break;
2531  }
2532 
2533  case 0x21: // long introduction year
2534  housespec->min_year = buf->ReadWord();
2535  break;
2536 
2537  case 0x22: // long maximum year
2538  housespec->max_year = buf->ReadWord();
2539  break;
2540 
2541  case 0x23: { // variable length cargo types accepted
2542  uint count = buf->ReadByte();
2543  if (count > lengthof(housespec->accepts_cargo)) {
2544  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
2545  error->param_value[1] = prop;
2546  return CIR_DISABLED;
2547  }
2548  /* Always write the full accepts_cargo array, and check each index for being inside the
2549  * provided data. This ensures all values are properly initialized, and also avoids
2550  * any risks of array overrun. */
2551  for (uint i = 0; i < lengthof(housespec->accepts_cargo); i++) {
2552  if (i < count) {
2553  housespec->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2554  housespec->cargo_acceptance[i] = buf->ReadByte();
2555  } else {
2556  housespec->accepts_cargo[i] = CT_INVALID;
2557  housespec->cargo_acceptance[i] = 0;
2558  }
2559  }
2560  break;
2561  }
2562 
2563  default:
2564  ret = CIR_UNKNOWN;
2565  break;
2566  }
2567  }
2568 
2569  return ret;
2570 }
2571 
2578 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2579 {
2580  /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2581  const GRFFile *grffile = GetFileByGRFID(grfid);
2582  return (grffile != nullptr && grffile->language_map != nullptr && language_id < MAX_LANG) ? &grffile->language_map[language_id] : nullptr;
2583 }
2584 
2594 template <typename T>
2595 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2596 {
2597  if (gvid != 0) {
2598  grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2599  return CIR_INVALID_ID;
2600  }
2601 
2602  translation_table.clear();
2603  for (int i = 0; i < numinfo; i++) {
2604  uint32 item = buf->ReadDWord();
2605  translation_table.push_back(BSWAP32(item));
2606  }
2607 
2608  return CIR_SUCCESS;
2609 }
2610 
2619 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2620 {
2621  /* Properties which are handled as a whole */
2622  switch (prop) {
2623  case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2624  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2625 
2626  case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2627  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2628 
2629  case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2630  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type");
2631 
2632  case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2633  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type");
2634 
2635  default:
2636  break;
2637  }
2638 
2639  /* Properties which are handled per item */
2641  for (int i = 0; i < numinfo; i++) {
2642  switch (prop) {
2643  case 0x08: { // Cost base factor
2644  int factor = buf->ReadByte();
2645  uint price = gvid + i;
2646 
2647  if (price < PR_END) {
2648  _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2649  } else {
2650  grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2651  }
2652  break;
2653  }
2654 
2655  case 0x0A: { // Currency display names
2656  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2657  StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2658 
2659  if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2660  _currency_specs[curidx].name = newone;
2661  }
2662  break;
2663  }
2664 
2665  case 0x0B: { // Currency multipliers
2666  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2667  uint32 rate = buf->ReadDWord();
2668 
2669  if (curidx < CURRENCY_END) {
2670  /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2671  * which OTTD does not. For this reason, divide grf value by 1000,
2672  * to be compatible */
2673  _currency_specs[curidx].rate = rate / 1000;
2674  } else {
2675  grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2676  }
2677  break;
2678  }
2679 
2680  case 0x0C: { // Currency options
2681  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2682  uint16 options = buf->ReadWord();
2683 
2684  if (curidx < CURRENCY_END) {
2685  _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2686  _currency_specs[curidx].separator[1] = '\0';
2687  /* By specifying only one bit, we prevent errors,
2688  * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2689  _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2690  } else {
2691  grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2692  }
2693  break;
2694  }
2695 
2696  case 0x0D: { // Currency prefix symbol
2697  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2698  uint32 tempfix = buf->ReadDWord();
2699 
2700  if (curidx < CURRENCY_END) {
2701  memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2702  _currency_specs[curidx].prefix[4] = 0;
2703  } else {
2704  grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2705  }
2706  break;
2707  }
2708 
2709  case 0x0E: { // Currency suffix symbol
2710  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2711  uint32 tempfix = buf->ReadDWord();
2712 
2713  if (curidx < CURRENCY_END) {
2714  memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2715  _currency_specs[curidx].suffix[4] = 0;
2716  } else {
2717  grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2718  }
2719  break;
2720  }
2721 
2722  case 0x0F: { // Euro introduction dates
2723  uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2724  Year year_euro = buf->ReadWord();
2725 
2726  if (curidx < CURRENCY_END) {
2727  _currency_specs[curidx].to_euro = year_euro;
2728  } else {
2729  grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2730  }
2731  break;
2732  }
2733 
2734  case 0x10: // Snow line height table
2735  if (numinfo > 1 || IsSnowLineSet()) {
2736  grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2737  } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2738  grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2739  } else {
2740  byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2741 
2742  for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2743  for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2744  table[i][j] = buf->ReadByte();
2745  if (_cur.grffile->grf_version >= 8) {
2746  if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2747  } else {
2748  if (table[i][j] >= 128) {
2749  /* no snow */
2750  table[i][j] = 0xFF;
2751  } else {
2752  table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2753  }
2754  }
2755  }
2756  }
2757  SetSnowLine(table);
2758  }
2759  break;
2760 
2761  case 0x11: // GRF match for engine allocation
2762  /* This is loaded during the reservation stage, so just skip it here. */
2763  /* Each entry is 8 bytes. */
2764  buf->Skip(8);
2765  break;
2766 
2767  case 0x13: // Gender translation table
2768  case 0x14: // Case translation table
2769  case 0x15: { // Plural form translation
2770  uint curidx = gvid + i; // The current index, i.e. language.
2771  const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
2772  if (lang == nullptr) {
2773  grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2774  /* Skip over the data. */
2775  if (prop == 0x15) {
2776  buf->ReadByte();
2777  } else {
2778  while (buf->ReadByte() != 0) {
2779  buf->ReadString();
2780  }
2781  }
2782  break;
2783  }
2784 
2785  if (_cur.grffile->language_map == nullptr) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2786 
2787  if (prop == 0x15) {
2788  uint plural_form = buf->ReadByte();
2789  if (plural_form >= LANGUAGE_MAX_PLURAL) {
2790  grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2791  } else {
2792  _cur.grffile->language_map[curidx].plural_form = plural_form;
2793  }
2794  break;
2795  }
2796 
2797  byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2798  while (newgrf_id != 0) {
2799  const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2800 
2801  /* We'll just ignore the UTF8 identifier character. This is (fairly)
2802  * safe as OpenTTD's strings gender/cases are usually in ASCII which
2803  * is just a subset of UTF8, or they need the bigger UTF8 characters
2804  * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2805  WChar c;
2806  size_t len = Utf8Decode(&c, name);
2807  if (c == NFO_UTF8_IDENTIFIER) name += len;
2808 
2810  map.newgrf_id = newgrf_id;
2811  if (prop == 0x13) {
2812  map.openttd_id = lang->GetGenderIndex(name);
2813  if (map.openttd_id >= MAX_NUM_GENDERS) {
2814  grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2815  } else {
2816  _cur.grffile->language_map[curidx].gender_map.push_back(map);
2817  }
2818  } else {
2819  map.openttd_id = lang->GetCaseIndex(name);
2820  if (map.openttd_id >= MAX_NUM_CASES) {
2821  grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2822  } else {
2823  _cur.grffile->language_map[curidx].case_map.push_back(map);
2824  }
2825  }
2826  newgrf_id = buf->ReadByte();
2827  }
2828  break;
2829  }
2830 
2831  default:
2832  ret = CIR_UNKNOWN;
2833  break;
2834  }
2835  }
2836 
2837  return ret;
2838 }
2839 
2840 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2841 {
2842  /* Properties which are handled as a whole */
2843  switch (prop) {
2844  case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2845  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2846 
2847  case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2848  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2849 
2850  case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
2851  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type");
2852 
2853  case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
2854  return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type");
2855 
2856  default:
2857  break;
2858  }
2859 
2860  /* Properties which are handled per item */
2862  for (int i = 0; i < numinfo; i++) {
2863  switch (prop) {
2864  case 0x08: // Cost base factor
2865  case 0x15: // Plural form translation
2866  buf->ReadByte();
2867  break;
2868 
2869  case 0x0A: // Currency display names
2870  case 0x0C: // Currency options
2871  case 0x0F: // Euro introduction dates
2872  buf->ReadWord();
2873  break;
2874 
2875  case 0x0B: // Currency multipliers
2876  case 0x0D: // Currency prefix symbol
2877  case 0x0E: // Currency suffix symbol
2878  buf->ReadDWord();
2879  break;
2880 
2881  case 0x10: // Snow line height table
2882  buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2883  break;
2884 
2885  case 0x11: { // GRF match for engine allocation
2886  uint32 s = buf->ReadDWord();
2887  uint32 t = buf->ReadDWord();
2888  SetNewGRFOverride(s, t);
2889  break;
2890  }
2891 
2892  case 0x13: // Gender translation table
2893  case 0x14: // Case translation table
2894  while (buf->ReadByte() != 0) {
2895  buf->ReadString();
2896  }
2897  break;
2898 
2899  default:
2900  ret = CIR_UNKNOWN;
2901  break;
2902  }
2903  }
2904 
2905  return ret;
2906 }
2907 
2908 
2917 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2918 {
2920 
2921  if (cid + numinfo > NUM_CARGO) {
2922  grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2923  return CIR_INVALID_ID;
2924  }
2925 
2926  for (int i = 0; i < numinfo; i++) {
2927  CargoSpec *cs = CargoSpec::Get(cid + i);
2928 
2929  switch (prop) {
2930  case 0x08: // Bit number of cargo
2931  cs->bitnum = buf->ReadByte();
2932  if (cs->IsValid()) {
2933  cs->grffile = _cur.grffile;
2934  SetBit(_cargo_mask, cid + i);
2935  } else {
2936  ClrBit(_cargo_mask, cid + i);
2937  }
2938  break;
2939 
2940  case 0x09: // String ID for cargo type name
2941  AddStringForMapping(buf->ReadWord(), &cs->name);
2942  break;
2943 
2944  case 0x0A: // String for 1 unit of cargo
2945  AddStringForMapping(buf->ReadWord(), &cs->name_single);
2946  break;
2947 
2948  case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2949  case 0x1B: // String for cargo units
2950  /* String for units of cargo. This is different in OpenTTD
2951  * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2952  * Property 1B is used to set OpenTTD's behaviour. */
2953  AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2954  break;
2955 
2956  case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2957  case 0x1C: // String for any amount of cargo
2958  /* Strings for an amount of cargo. This is different in OpenTTD
2959  * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2960  * Property 1C is used to set OpenTTD's behaviour. */
2961  AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2962  break;
2963 
2964  case 0x0D: // String for two letter cargo abbreviation
2965  AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2966  break;
2967 
2968  case 0x0E: // Sprite ID for cargo icon
2969  cs->sprite = buf->ReadWord();
2970  break;
2971 
2972  case 0x0F: // Weight of one unit of cargo
2973  cs->weight = buf->ReadByte();
2974  break;
2975 
2976  case 0x10: // Used for payment calculation
2977  cs->transit_days[0] = buf->ReadByte();
2978  break;
2979 
2980  case 0x11: // Used for payment calculation
2981  cs->transit_days[1] = buf->ReadByte();
2982  break;
2983 
2984  case 0x12: // Base cargo price
2985  cs->initial_payment = buf->ReadDWord();
2986  break;
2987 
2988  case 0x13: // Colour for station rating bars
2989  cs->rating_colour = buf->ReadByte();
2990  break;
2991 
2992  case 0x14: // Colour for cargo graph
2993  cs->legend_colour = buf->ReadByte();
2994  break;
2995 
2996  case 0x15: // Freight status
2997  cs->is_freight = (buf->ReadByte() != 0);
2998  break;
2999 
3000  case 0x16: // Cargo classes
3001  cs->classes = buf->ReadWord();
3002  break;
3003 
3004  case 0x17: // Cargo label
3005  cs->label = buf->ReadDWord();
3006  cs->label = BSWAP32(cs->label);
3007  break;
3008 
3009  case 0x18: { // Town growth substitute type
3010  uint8 substitute_type = buf->ReadByte();
3011 
3012  switch (substitute_type) {
3013  case 0x00: cs->town_effect = TE_PASSENGERS; break;
3014  case 0x02: cs->town_effect = TE_MAIL; break;
3015  case 0x05: cs->town_effect = TE_GOODS; break;
3016  case 0x09: cs->town_effect = TE_WATER; break;
3017  case 0x0B: cs->town_effect = TE_FOOD; break;
3018  default:
3019  grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3020  FALLTHROUGH;
3021  case 0xFF: cs->town_effect = TE_NONE; break;
3022  }
3023  break;
3024  }
3025 
3026  case 0x19: // Town growth coefficient
3027  cs->multipliertowngrowth = buf->ReadWord();
3028  break;
3029 
3030  case 0x1A: // Bitmask of callbacks to use
3031  cs->callback_mask = buf->ReadByte();
3032  break;
3033 
3034  case 0x1D: // Vehicle capacity muliplier
3035  cs->multiplier = max<uint16>(1u, buf->ReadWord());
3036  break;
3037 
3038  default:
3039  ret = CIR_UNKNOWN;
3040  break;
3041  }
3042  }
3043 
3044  return ret;
3045 }
3046 
3047 
3056 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3057 {
3059 
3060  if (_cur.grffile->sound_offset == 0) {
3061  grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3062  return CIR_INVALID_ID;
3063  }
3064 
3065  if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3066  grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3067  return CIR_INVALID_ID;
3068  }
3069 
3070  for (int i = 0; i < numinfo; i++) {
3071  SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3072 
3073  switch (prop) {
3074  case 0x08: // Relative volume
3075  sound->volume = buf->ReadByte();
3076  break;
3077 
3078  case 0x09: // Priority
3079  sound->priority = buf->ReadByte();
3080  break;
3081 
3082  case 0x0A: { // Override old sound
3083  SoundID orig_sound = buf->ReadByte();
3084 
3085  if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3086  grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3087  } else {
3088  SoundEntry *old_sound = GetSound(orig_sound);
3089 
3090  /* Literally copy the data of the new sound over the original */
3091  *old_sound = *sound;
3092  }
3093  break;
3094  }
3095 
3096  default:
3097  ret = CIR_UNKNOWN;
3098  break;
3099  }
3100  }
3101 
3102  return ret;
3103 }
3104 
3112 {
3114 
3115  switch (prop) {
3116  case 0x09:
3117  case 0x0D:
3118  case 0x0E:
3119  case 0x10:
3120  case 0x11:
3121  case 0x12:
3122  buf->ReadByte();
3123  break;
3124 
3125  case 0x0A:
3126  case 0x0B:
3127  case 0x0C:
3128  case 0x0F:
3129  buf->ReadWord();
3130  break;
3131 
3132  case 0x13:
3133  buf->Skip(buf->ReadByte() * 2);
3134  break;
3135 
3136  default:
3137  ret = CIR_UNKNOWN;
3138  break;
3139  }
3140  return ret;
3141 }
3142 
3151 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3152 {
3154 
3155  if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3156  grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3157  return CIR_INVALID_ID;
3158  }
3159 
3160  /* Allocate industry tile specs if they haven't been allocated already. */
3161  if (_cur.grffile->indtspec == nullptr) {
3162  _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3163  }
3164 
3165  for (int i = 0; i < numinfo; i++) {
3166  IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3167 
3168  if (prop != 0x08 && tsp == nullptr) {
3170  if (cir > ret) ret = cir;
3171  continue;
3172  }
3173 
3174  switch (prop) {
3175  case 0x08: { // Substitute industry tile type
3176  IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3177  byte subs_id = buf->ReadByte();
3178 
3179  if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3180  /* The substitute id must be one of the original industry tile. */
3181  grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3182  continue;
3183  }
3184 
3185  /* Allocate space for this industry. */
3186  if (*tilespec == nullptr) {
3187  *tilespec = CallocT<IndustryTileSpec>(1);
3188  tsp = *tilespec;
3189 
3190  memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3191  tsp->enabled = true;
3192 
3193  /* A copied tile should not have the animation infos copied too.
3194  * The anim_state should be left untouched, though
3195  * It is up to the author to animate them himself */
3196  tsp->anim_production = INDUSTRYTILE_NOANIM;
3197  tsp->anim_next = INDUSTRYTILE_NOANIM;
3198 
3199  tsp->grf_prop.local_id = indtid + i;
3200  tsp->grf_prop.subst_id = subs_id;
3201  tsp->grf_prop.grffile = _cur.grffile;
3202  _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3203  }
3204  break;
3205  }
3206 
3207  case 0x09: { // Industry tile override
3208  byte ovrid = buf->ReadByte();
3209 
3210  /* The industry being overridden must be an original industry. */
3211  if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3212  grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3213  continue;
3214  }
3215 
3216  _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3217  break;
3218  }
3219 
3220  case 0x0A: // Tile acceptance
3221  case 0x0B:
3222  case 0x0C: {
3223  uint16 acctp = buf->ReadWord();
3224  tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3225  tsp->acceptance[prop - 0x0A] = Clamp(GB(acctp, 8, 8), 0, 16);
3226  break;
3227  }
3228 
3229  case 0x0D: // Land shape flags
3230  tsp->slopes_refused = (Slope)buf->ReadByte();
3231  break;
3232 
3233  case 0x0E: // Callback mask
3234  tsp->callback_mask = buf->ReadByte();
3235  break;
3236 
3237  case 0x0F: // Animation information
3238  tsp->animation.frames = buf->ReadByte();
3239  tsp->animation.status = buf->ReadByte();
3240  break;
3241 
3242  case 0x10: // Animation speed
3243  tsp->animation.speed = buf->ReadByte();
3244  break;
3245 
3246  case 0x11: // Triggers for callback 25
3247  tsp->animation.triggers = buf->ReadByte();
3248  break;
3249 
3250  case 0x12: // Special flags
3251  tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3252  break;
3253 
3254  case 0x13: { // variable length cargo acceptance
3255  byte num_cargoes = buf->ReadByte();
3256  if (num_cargoes > lengthof(tsp->acceptance)) {
3257  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3258  error->param_value[1] = prop;
3259  return CIR_DISABLED;
3260  }
3261  for (uint i = 0; i < lengthof(tsp->acceptance); i++) {
3262  if (i < num_cargoes) {
3263  tsp->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3264  /* Tile acceptance can be negative to counteract the INDTILE_SPECIAL_ACCEPTS_ALL_CARGO flag */
3265  tsp->acceptance[i] = (int8)buf->ReadByte();
3266  } else {
3267  tsp->accepts_cargo[i] = CT_INVALID;
3268  tsp->acceptance[i] = 0;
3269  }
3270  }
3271  break;
3272  }
3273 
3274  default:
3275  ret = CIR_UNKNOWN;
3276  break;
3277  }
3278  }
3279 
3280  return ret;
3281 }
3282 
3290 {
3292 
3293  switch (prop) {
3294  case 0x09:
3295  case 0x0B:
3296  case 0x0F:
3297  case 0x12:
3298  case 0x13:
3299  case 0x14:
3300  case 0x17:
3301  case 0x18:
3302  case 0x19:
3303  case 0x21:
3304  case 0x22:
3305  buf->ReadByte();
3306  break;
3307 
3308  case 0x0C:
3309  case 0x0D:
3310  case 0x0E:
3311  case 0x10:
3312  case 0x1B:
3313  case 0x1F:
3314  case 0x24:
3315  buf->ReadWord();
3316  break;
3317 
3318  case 0x11:
3319  case 0x1A:
3320  case 0x1C:
3321  case 0x1D:
3322  case 0x1E:
3323  case 0x20:
3324  case 0x23:
3325  buf->ReadDWord();
3326  break;
3327 
3328  case 0x0A: {
3329  byte num_table = buf->ReadByte();
3330  for (byte j = 0; j < num_table; j++) {
3331  for (uint k = 0;; k++) {
3332  byte x = buf->ReadByte();
3333  if (x == 0xFE && k == 0) {
3334  buf->ReadByte();
3335  buf->ReadByte();
3336  break;
3337  }
3338 
3339  byte y = buf->ReadByte();
3340  if (x == 0 && y == 0x80) break;
3341 
3342  byte gfx = buf->ReadByte();
3343  if (gfx == 0xFE) buf->ReadWord();
3344  }
3345  }
3346  break;
3347  }
3348 
3349  case 0x16:
3350  for (byte j = 0; j < 3; j++) buf->ReadByte();
3351  break;
3352 
3353  case 0x15:
3354  case 0x25:
3355  case 0x26:
3356  case 0x27:
3357  buf->Skip(buf->ReadByte());
3358  break;
3359 
3360  case 0x28: {
3361  int num_inputs = buf->ReadByte();
3362  int num_outputs = buf->ReadByte();
3363  buf->Skip(num_inputs * num_outputs * 2);
3364  break;
3365  }
3366 
3367  default:
3368  ret = CIR_UNKNOWN;
3369  break;
3370  }
3371  return ret;
3372 }
3373 
3379 static bool ValidateIndustryLayout(const IndustryTileLayout &layout)
3380 {
3381  const size_t size = layout.size();
3382  for (size_t i = 0; i < size - 1; i++) {
3383  for (size_t j = i + 1; j < size; j++) {
3384  if (layout[i].ti.x == layout[j].ti.x &&
3385  layout[i].ti.y == layout[j].ti.y) {
3386  return false;
3387  }
3388  }
3389  }
3390  return true;
3391 }
3392 
3401 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3402 {
3404 
3405  if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3406  grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3407  return CIR_INVALID_ID;
3408  }
3409 
3410  /* Allocate industry specs if they haven't been allocated already. */
3411  if (_cur.grffile->industryspec == nullptr) {
3412  _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3413  }
3414 
3415  for (int i = 0; i < numinfo; i++) {
3416  IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3417 
3418  if (prop != 0x08 && indsp == nullptr) {
3419  ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3420  if (cir > ret) ret = cir;
3421  continue;
3422  }
3423 
3424  switch (prop) {
3425  case 0x08: { // Substitute industry type
3426  IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3427  byte subs_id = buf->ReadByte();
3428 
3429  if (subs_id == 0xFF) {
3430  /* Instead of defining a new industry, a substitute industry id
3431  * of 0xFF disables the old industry with the current id. */
3432  _industry_specs[indid + i].enabled = false;
3433  continue;
3434  } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3435  /* The substitute id must be one of the original industry. */
3436  grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3437  continue;
3438  }
3439 
3440  /* Allocate space for this industry.
3441  * Only need to do it once. If ever it is called again, it should not
3442  * do anything */
3443  if (*indspec == nullptr) {
3444  *indspec = new IndustrySpec;
3445  indsp = *indspec;
3446 
3447  *indsp = _origin_industry_specs[subs_id];
3448  indsp->enabled = true;
3449  indsp->grf_prop.local_id = indid + i;
3450  indsp->grf_prop.subst_id = subs_id;
3451  indsp->grf_prop.grffile = _cur.grffile;
3452  /* If the grf industry needs to check its surrounding upon creation, it should
3453  * rely on callbacks, not on the original placement functions */
3454  indsp->check_proc = CHECK_NOTHING;
3455  }
3456  break;
3457  }
3458 
3459  case 0x09: { // Industry type override
3460  byte ovrid = buf->ReadByte();
3461 
3462  /* The industry being overridden must be an original industry. */
3463  if (ovrid >= NEW_INDUSTRYOFFSET) {
3464  grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3465  continue;
3466  }
3467  indsp->grf_prop.override = ovrid;
3468  _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3469  break;
3470  }
3471 
3472  case 0x0A: { // Set industry layout(s)
3473  byte new_num_layouts = buf->ReadByte();
3474  uint32 definition_size = buf->ReadDWord();
3475  uint32 bytes_read = 0;
3476  std::vector<IndustryTileLayout> new_layouts;
3477  IndustryTileLayout layout;
3478 
3479  for (byte j = 0; j < new_num_layouts; j++) {
3480  layout.clear();
3481 
3482  for (uint k = 0;; k++) {
3483  if (bytes_read >= definition_size) {
3484  grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3485  /* Avoid warning twice */
3486  definition_size = UINT32_MAX;
3487  }
3488 
3489  layout.push_back(IndustryTileLayoutTile{});
3490  IndustryTileLayoutTile &it = layout.back();
3491 
3492  it.ti.x = buf->ReadByte(); // Offsets from northermost tile
3493  ++bytes_read;
3494 
3495  if (it.ti.x == 0xFE && k == 0) {
3496  /* This means we have to borrow the layout from an old industry */
3497  IndustryType type = buf->ReadByte();
3498  byte laynbr = buf->ReadByte();
3499  bytes_read += 2;
3500 
3501  if (type >= lengthof(_origin_industry_specs)) {
3502  grfmsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3503  DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
3504  return CIR_DISABLED;
3505  }
3506  if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3507  grfmsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3508  DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
3509  return CIR_DISABLED;
3510  }
3511  layout = _origin_industry_specs[type].layouts[laynbr];
3512  break;
3513  }
3514 
3515  it.ti.y = buf->ReadByte(); // Or table definition finalisation
3516  ++bytes_read;
3517 
3518  if (it.ti.x == 0 && it.ti.y == 0x80) {
3519  /* Terminator, remove and finish up */
3520  layout.pop_back();
3521  break;
3522  }
3523 
3524  it.gfx = buf->ReadByte();
3525  ++bytes_read;
3526 
3527  if (it.gfx == 0xFE) {
3528  /* Use a new tile from this GRF */
3529  int local_tile_id = buf->ReadWord();
3530  bytes_read += 2;
3531 
3532  /* Read the ID from the _industile_mngr. */
3533  int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3534 
3535  if (tempid == INVALID_INDUSTRYTILE) {
3536  grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3537  } else {
3538  /* Declared as been valid, can be used */
3539  it.gfx = tempid;
3540  }
3541  } else if (it.gfx == 0xFF) {
3542  it.ti.x = (int8)GB(it.ti.x, 0, 8);
3543  it.ti.y = (int8)GB(it.ti.y, 0, 8);
3544 
3545  /* When there were only 256x256 maps, TileIndex was a uint16 and
3546  * it.ti was just a TileIndexDiff that was added to it.
3547  * As such negative "x" values were shifted into the "y" position.
3548  * x = -1, y = 1 -> x = 255, y = 0
3549  * Since GRF version 8 the position is interpreted as pair of independent int8.
3550  * For GRF version < 8 we need to emulate the old shifting behaviour.
3551  */
3552  if (_cur.grffile->grf_version < 8 && it.ti.x < 0) it.ti.y += 1;
3553  }
3554  }
3555 
3556  if (!ValidateIndustryLayout(layout)) {
3557  /* The industry layout was not valid, so skip this one. */
3558  grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3559  new_num_layouts--;
3560  j--;
3561  } else {
3562  new_layouts.push_back(layout);
3563  }
3564  }
3565 
3566  /* Install final layout construction in the industry spec */
3567  indsp->layouts = new_layouts;
3568  break;
3569  }
3570 
3571  case 0x0B: // Industry production flags
3572  indsp->life_type = (IndustryLifeType)buf->ReadByte();
3573  break;
3574 
3575  case 0x0C: // Industry closure message
3576  AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3577  break;
3578 
3579  case 0x0D: // Production increase message
3580  AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3581  break;
3582 
3583  case 0x0E: // Production decrease message
3584  AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3585  break;
3586 
3587  case 0x0F: // Fund cost multiplier
3588  indsp->cost_multiplier = buf->ReadByte();
3589  break;
3590 
3591  case 0x10: // Production cargo types
3592  for (byte j = 0; j < 2; j++) {
3593  indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3594  }
3595  break;
3596 
3597  case 0x11: // Acceptance cargo types
3598  for (byte j = 0; j < 3; j++) {
3599  indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3600  }
3601  buf->ReadByte(); // Unnused, eat it up
3602  break;
3603 
3604  case 0x12: // Production multipliers
3605  case 0x13:
3606  indsp->production_rate[prop - 0x12] = buf->ReadByte();
3607  break;
3608 
3609  case 0x14: // Minimal amount of cargo distributed
3610  indsp->minimal_cargo = buf->ReadByte();
3611  break;
3612 
3613  case 0x15: { // Random sound effects
3614  indsp->number_of_sounds = buf->ReadByte();
3615  uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3616 
3617  try {
3618  for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3619  sounds[j] = buf->ReadByte();
3620  }
3621  } catch (...) {
3622  free(sounds);
3623  throw;
3624  }
3625 
3626  if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3627  free(indsp->random_sounds);
3628  }
3629  indsp->random_sounds = sounds;
3631  break;
3632  }
3633 
3634  case 0x16: // Conflicting industry types
3635  for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3636  break;
3637 
3638  case 0x17: // Probability in random game
3639  indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3640  break;
3641 
3642  case 0x18: // Probability during gameplay
3643  indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3644  break;
3645 
3646  case 0x19: // Map colour
3647  indsp->map_colour = buf->ReadByte();
3648  break;
3649 
3650  case 0x1A: // Special industry flags to define special behavior
3651  indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3652  break;
3653 
3654  case 0x1B: // New industry text ID
3655  AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3656  break;
3657 
3658  case 0x1C: // Input cargo multipliers for the three input cargo types
3659  case 0x1D:
3660  case 0x1E: {
3661  uint32 multiples = buf->ReadDWord();
3662  indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3663  indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3664  break;
3665  }
3666 
3667  case 0x1F: // Industry name
3668  AddStringForMapping(buf->ReadWord(), &indsp->name);
3669  break;
3670 
3671  case 0x20: // Prospecting success chance
3672  indsp->prospecting_chance = buf->ReadDWord();
3673  break;
3674 
3675  case 0x21: // Callback mask
3676  case 0x22: { // Callback additional mask
3677  byte aflag = buf->ReadByte();
3678  SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3679  break;
3680  }
3681 
3682  case 0x23: // removal cost multiplier
3683  indsp->removal_cost_multiplier = buf->ReadDWord();
3684  break;
3685 
3686  case 0x24: { // name for nearby station
3687  uint16 str = buf->ReadWord();
3688  if (str == 0) {
3689  indsp->station_name = STR_NULL;
3690  } else {
3691  AddStringForMapping(str, &indsp->station_name);
3692  }
3693  break;
3694  }
3695 
3696  case 0x25: { // variable length produced cargoes
3697  byte num_cargoes = buf->ReadByte();
3698  if (num_cargoes > lengthof(indsp->produced_cargo)) {
3699  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3700  error->param_value[1] = prop;
3701  return CIR_DISABLED;
3702  }
3703  for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) {
3704  if (i < num_cargoes) {
3705  CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3706  indsp->produced_cargo[i] = cargo;
3707  } else {
3708  indsp->produced_cargo[i] = CT_INVALID;
3709  }
3710  }
3711  break;
3712  }
3713 
3714  case 0x26: { // variable length accepted cargoes
3715  byte num_cargoes = buf->ReadByte();
3716  if (num_cargoes > lengthof(indsp->accepts_cargo)) {
3717  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3718  error->param_value[1] = prop;
3719  return CIR_DISABLED;
3720  }
3721  for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
3722  if (i < num_cargoes) {
3723  CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3724  indsp->accepts_cargo[i] = cargo;
3725  } else {
3726  indsp->accepts_cargo[i] = CT_INVALID;
3727  }
3728  }
3729  break;
3730  }
3731 
3732  case 0x27: { // variable length production rates
3733  byte num_cargoes = buf->ReadByte();
3734  if (num_cargoes > lengthof(indsp->production_rate)) {
3735  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3736  error->param_value[1] = prop;
3737  return CIR_DISABLED;
3738  }
3739  for (uint i = 0; i < lengthof(indsp->production_rate); i++) {
3740  if (i < num_cargoes) {
3741  indsp->production_rate[i] = buf->ReadByte();
3742  } else {
3743  indsp->production_rate[i] = 0;
3744  }
3745  }
3746  break;
3747  }
3748 
3749  case 0x28: { // variable size input/output production multiplier table
3750  byte num_inputs = buf->ReadByte();
3751  byte num_outputs = buf->ReadByte();
3752  if (num_inputs > lengthof(indsp->accepts_cargo) || num_outputs > lengthof(indsp->produced_cargo)) {
3753  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3754  error->param_value[1] = prop;
3755  return CIR_DISABLED;
3756  }
3757  for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
3758  for (uint j = 0; j < lengthof(indsp->produced_cargo); j++) {
3759  uint16 mult = 0;
3760  if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3761  indsp->input_cargo_multiplier[i][j] = mult;
3762  }
3763  }
3764  break;
3765  }
3766 
3767  default:
3768  ret = CIR_UNKNOWN;
3769  break;
3770  }
3771  }
3772 
3773  return ret;
3774 }
3775 
3782 {
3783  AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3784  for (int i = 0; i < as->num_table; i++) {
3785  uint num_tiles = 1;
3786  const AirportTileTable *it = as->table[0];
3787  do {
3788  num_tiles++;
3789  } while ((++it)->ti.x != -0x80);
3790  table_list[i] = MallocT<AirportTileTable>(num_tiles);
3791  MemCpyT(table_list[i], as->table[i], num_tiles);
3792  }
3793  as->table = table_list;
3794  HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3795  MemCpyT(depot_table, as->depot_table, as->nof_depots);
3796  as->depot_table = depot_table;
3797  Direction *rotation = MallocT<Direction>(as->num_table);
3798  MemCpyT(rotation, as->rotation, as->num_table);
3799  as->rotation = rotation;
3800 }
3801 
3810 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3811 {
3813 
3814  if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3815  grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3816  return CIR_INVALID_ID;
3817  }
3818 
3819  /* Allocate industry specs if they haven't been allocated already. */
3820  if (_cur.grffile->airportspec == nullptr) {
3821  _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3822  }
3823 
3824  for (int i = 0; i < numinfo; i++) {
3825  AirportSpec *as = _cur.grffile->airportspec[airport + i];
3826 
3827  if (as == nullptr && prop != 0x08 && prop != 0x09) {
3828  grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3829  return CIR_INVALID_ID;
3830  }
3831 
3832  switch (prop) {
3833  case 0x08: { // Modify original airport
3834  byte subs_id = buf->ReadByte();
3835 
3836  if (subs_id == 0xFF) {
3837  /* Instead of defining a new airport, an airport id
3838  * of 0xFF disables the old airport with the current id. */
3839  AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3840  continue;
3841  } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3842  /* The substitute id must be one of the original airports. */
3843  grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3844  continue;
3845  }
3846 
3847  AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3848  /* Allocate space for this airport.
3849  * Only need to do it once. If ever it is called again, it should not
3850  * do anything */
3851  if (*spec == nullptr) {
3852  *spec = MallocT<AirportSpec>(1);
3853  as = *spec;
3854 
3855  memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3856  as->enabled = true;
3857  as->grf_prop.local_id = airport + i;
3858  as->grf_prop.subst_id = subs_id;
3859  as->grf_prop.grffile = _cur.grffile;
3860  /* override the default airport */
3861  _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3862  /* Create a copy of the original tiletable so it can be freed later. */
3863  DuplicateTileTable(as);
3864  }
3865  break;
3866  }
3867 
3868  case 0x0A: { // Set airport layout
3869  free(as->rotation);
3870  as->num_table = buf->ReadByte(); // Number of layaouts
3871  as->rotation = MallocT<Direction>(as->num_table);
3872  uint32 defsize = buf->ReadDWord(); // Total size of the definition
3873  AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3874  AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3875  int size;
3876  const AirportTileTable *copy_from;
3877  try {
3878  for (byte j = 0; j < as->num_table; j++) {
3879  const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
3880  for (int k = 0;; k++) {
3881  att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3882  att[k].ti.y = buf->ReadByte();
3883 
3884  if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3885  /* Not the same terminator. The one we are using is rather
3886  * x = -80, y = 0 . So, adjust it. */
3887  att[k].ti.x = -0x80;
3888  att[k].ti.y = 0;
3889  att[k].gfx = 0;
3890 
3891  size = k + 1;
3892  copy_from = att;
3893  break;
3894  }
3895 
3896  att[k].gfx = buf->ReadByte();
3897 
3898  if (att[k].gfx == 0xFE) {
3899  /* Use a new tile from this GRF */
3900  int local_tile_id = buf->ReadWord();
3901 
3902  /* Read the ID from the _airporttile_mngr. */
3903  uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3904 
3905  if (tempid == INVALID_AIRPORTTILE) {
3906  grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3907  } else {
3908  /* Declared as been valid, can be used */
3909  att[k].gfx = tempid;
3910  }
3911  } else if (att[k].gfx == 0xFF) {
3912  att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3913  att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3914  }
3915 
3916  if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3917  as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3918  as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3919  } else {
3920  as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3921  as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3922  }
3923  }
3924  tile_table[j] = CallocT<AirportTileTable>(size);
3925  memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3926  }
3927  /* Install final layout construction in the airport spec */
3928  as->table = tile_table;
3929  free(att);
3930  } catch (...) {
3931  for (int i = 0; i < as->num_table; i++) {
3932  free(tile_table[i]);
3933  }
3934  free(tile_table);
3935  free(att);
3936  throw;
3937  }
3938  break;
3939  }
3940 
3941  case 0x0C:
3942  as->min_year = buf->ReadWord();
3943  as->max_year = buf->ReadWord();
3944  if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3945  break;
3946 
3947  case 0x0D:
3948  as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3949  break;
3950 
3951  case 0x0E:
3952  as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3953  break;
3954 
3955  case 0x0F:
3956  as->noise_level = buf->ReadByte();
3957  break;
3958 
3959  case 0x10:
3960  AddStringForMapping(buf->ReadWord(), &as->name);
3961  break;
3962 
3963  case 0x11: // Maintenance cost factor
3964  as->maintenance_cost = buf->ReadWord();
3965  break;
3966 
3967  default:
3968  ret = CIR_UNKNOWN;
3969  break;
3970  }
3971  }
3972 
3973  return ret;
3974 }
3975 
3983 {
3985 
3986  switch (prop) {
3987  case 0x0B:
3988  case 0x0C:
3989  case 0x0D:
3990  case 0x12:
3991  case 0x14:
3992  case 0x16:
3993  case 0x17:
3994  buf->ReadByte();
3995  break;
3996 
3997  case 0x09:
3998  case 0x0A:
3999  case 0x10:
4000  case 0x11:
4001  case 0x13:
4002  case 0x15:
4003  buf->ReadWord();
4004  break;
4005 
4006  case 0x08:
4007  case 0x0E:
4008  case 0x0F:
4009  buf->ReadDWord();
4010  break;
4011 
4012  default:
4013  ret = CIR_UNKNOWN;
4014  break;
4015  }
4016 
4017  return ret;
4018 }
4019 
4028 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4029 {
4031 
4032  if (id + numinfo > NUM_OBJECTS_PER_GRF) {
4033  grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
4034  return CIR_INVALID_ID;
4035  }
4036 
4037  /* Allocate object specs if they haven't been allocated already. */
4038  if (_cur.grffile->objectspec == nullptr) {
4039  _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
4040  }
4041 
4042  for (int i = 0; i < numinfo; i++) {
4043  ObjectSpec *spec = _cur.grffile->objectspec[id + i];
4044 
4045  if (prop != 0x08 && spec == nullptr) {
4046  /* If the object property 08 is not yet set, ignore this property */
4047  ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
4048  if (cir > ret) ret = cir;
4049  continue;
4050  }
4051 
4052  switch (prop) {
4053  case 0x08: { // Class ID
4054  ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
4055 
4056  /* Allocate space for this object. */
4057  if (*ospec == nullptr) {
4058  *ospec = CallocT<ObjectSpec>(1);
4059  (*ospec)->views = 1; // Default for NewGRFs that don't set it.
4060  }
4061 
4062  /* Swap classid because we read it in BE. */
4063  uint32 classid = buf->ReadDWord();
4064  (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
4065  (*ospec)->enabled = true;
4066  break;
4067  }
4068 
4069  case 0x09: { // Class name
4070  ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
4071  AddStringForMapping(buf->ReadWord(), &objclass->name);
4072  break;
4073  }
4074 
4075  case 0x0A: // Object name
4076  AddStringForMapping(buf->ReadWord(), &spec->name);
4077  break;
4078 
4079  case 0x0B: // Climate mask
4080  spec->climate = buf->ReadByte();
4081  break;
4082 
4083  case 0x0C: // Size
4084  spec->size = buf->ReadByte();
4085  break;
4086 
4087  case 0x0D: // Build cost multipler
4088  spec->build_cost_multiplier = buf->ReadByte();
4090  break;
4091 
4092  case 0x0E: // Introduction date
4093  spec->introduction_date = buf->ReadDWord();
4094  break;
4095 
4096  case 0x0F: // End of life
4097  spec->end_of_life_date = buf->ReadDWord();
4098  break;
4099 
4100  case 0x10: // Flags
4101  spec->flags = (ObjectFlags)buf->ReadWord();
4102  _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
4103  break;
4104 
4105  case 0x11: // Animation info
4106  spec->animation.frames = buf->ReadByte();
4107  spec->animation.status = buf->ReadByte();
4108  break;
4109 
4110  case 0x12: // Animation speed
4111  spec->animation.speed = buf->ReadByte();
4112  break;
4113 
4114  case 0x13: // Animation triggers
4115  spec->animation.triggers = buf->ReadWord();
4116  break;
4117 
4118  case 0x14: // Removal cost multiplier
4119  spec->clear_cost_multiplier = buf->ReadByte();
4120  break;
4121 
4122  case 0x15: // Callback mask
4123  spec->callback_mask = buf->ReadWord();
4124  break;
4125 
4126  case 0x16: // Building height
4127  spec->height = buf->ReadByte();
4128  break;
4129 
4130  case 0x17: // Views
4131  spec->views = buf->ReadByte();
4132  if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4133  grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4134  spec->views = 1;
4135  }
4136  break;
4137 
4138  case 0x18: // Amount placed on 256^2 map on map creation
4139  spec->generate_amount = buf->ReadByte();
4140  break;
4141 
4142  default:
4143  ret = CIR_UNKNOWN;
4144  break;
4145  }
4146  }
4147 
4148  return ret;
4149 }
4150 
4159 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4160 {
4162 
4163  extern RailtypeInfo _railtypes[RAILTYPE_END];
4164 
4165  if (id + numinfo > RAILTYPE_END) {
4166  grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4167  return CIR_INVALID_ID;
4168  }
4169 
4170  for (int i = 0; i < numinfo; i++) {
4171  RailType rt = _cur.grffile->railtype_map[id + i];
4172  if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4173 
4174  RailtypeInfo *rti = &_railtypes[rt];
4175 
4176  switch (prop) {
4177  case 0x08: // Label of rail type
4178  /* Skipped here as this is loaded during reservation stage. */
4179  buf->ReadDWord();
4180  break;
4181 
4182  case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4183  uint16 str = buf->ReadWord();
4185  if (_cur.grffile->grf_version < 8) {
4186  AddStringForMapping(str, &rti->strings.name);
4187  }
4188  break;
4189  }
4190 
4191  case 0x0A: // Menu text of railtype
4192  AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4193  break;
4194 
4195  case 0x0B: // Build window caption
4196  AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4197  break;
4198 
4199  case 0x0C: // Autoreplace text
4200  AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4201  break;
4202 
4203  case 0x0D: // New locomotive text
4204  AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4205  break;
4206 
4207  case 0x0E: // Compatible railtype list
4208  case 0x0F: // Powered railtype list
4209  case 0x18: // Railtype list required for date introduction
4210  case 0x19: // Introduced railtype list
4211  {
4212  /* Rail type compatibility bits are added to the existing bits
4213  * to allow multiple GRFs to modify compatibility with the
4214  * default rail types. */
4215  int n = buf->ReadByte();
4216  for (int j = 0; j != n; j++) {
4217  RailTypeLabel label = buf->ReadDWord();
4218  RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4219  if (rt != INVALID_RAILTYPE) {
4220  switch (prop) {
4221  case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4222  case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4223  case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4224  case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4225  }
4226  }
4227  }
4228  break;
4229  }
4230 
4231  case 0x10: // Rail Type flags
4232  rti->flags = (RailTypeFlags)buf->ReadByte();
4233  break;
4234 
4235  case 0x11: // Curve speed advantage
4236  rti->curve_speed = buf->ReadByte();
4237  break;
4238 
4239  case 0x12: // Station graphic
4240  rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4241  break;
4242 
4243  case 0x13: // Construction cost factor
4244  rti->cost_multiplier = buf->ReadWord();
4245  break;
4246 
4247  case 0x14: // Speed limit
4248  rti->max_speed = buf->ReadWord();
4249  break;
4250 
4251  case 0x15: // Acceleration model
4252  rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4253  break;
4254 
4255  case 0x16: // Map colour
4256  rti->map_colour = buf->ReadByte();
4257  break;
4258 
4259  case 0x17: // Introduction date
4260  rti->introduction_date = buf->ReadDWord();
4261  break;
4262 
4263  case 0x1A: // Sort order
4264  rti->sorting_order = buf->ReadByte();
4265  break;
4266 
4267  case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4268  AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4269  break;
4270 
4271  case 0x1C: // Maintenance cost factor
4272  rti->maintenance_multiplier = buf->ReadWord();
4273  break;
4274 
4275  case 0x1D: // Alternate rail type label list
4276  /* Skipped here as this is loaded during reservation stage. */
4277  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4278  break;
4279 
4280  default:
4281  ret = CIR_UNKNOWN;
4282  break;
4283  }
4284  }
4285 
4286  return ret;
4287 }
4288 
4289 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4290 {
4292 
4293  extern RailtypeInfo _railtypes[RAILTYPE_END];
4294 
4295  if (id + numinfo > RAILTYPE_END) {
4296  grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4297  return CIR_INVALID_ID;
4298  }
4299 
4300  for (int i = 0; i < numinfo; i++) {
4301  switch (prop) {
4302  case 0x08: // Label of rail type
4303  {
4304  RailTypeLabel rtl = buf->ReadDWord();
4305  rtl = BSWAP32(rtl);
4306 
4307  RailType rt = GetRailTypeByLabel(rtl, false);
4308  if (rt == INVALID_RAILTYPE) {
4309  /* Set up new rail type */
4310  rt = AllocateRailType(rtl);
4311  }
4312 
4313  _cur.grffile->railtype_map[id + i] = rt;
4314  break;
4315  }
4316 
4317  case 0x09: // Toolbar caption of railtype
4318  case 0x0A: // Menu text
4319  case 0x0B: // Build window caption
4320  case 0x0C: // Autoreplace text
4321  case 0x0D: // New loco
4322  case 0x13: // Construction cost
4323  case 0x14: // Speed limit
4324  case 0x1B: // Name of railtype
4325  case 0x1C: // Maintenance cost factor
4326  buf->ReadWord();
4327  break;
4328 
4329  case 0x1D: // Alternate rail type label list
4330  if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4331  int n = buf->ReadByte();
4332  for (int j = 0; j != n; j++) {
4333  _railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord()));
4334  }
4335  break;
4336  }
4337  grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4338  FALLTHROUGH;
4339 
4340  case 0x0E: // Compatible railtype list
4341  case 0x0F: // Powered railtype list
4342  case 0x18: // Railtype list required for date introduction
4343  case 0x19: // Introduced railtype list
4344  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4345  break;
4346 
4347  case 0x10: // Rail Type flags
4348  case 0x11: // Curve speed advantage
4349  case 0x12: // Station graphic
4350  case 0x15: // Acceleration model
4351  case 0x16: // Map colour
4352  case 0x1A: // Sort order
4353  buf->ReadByte();
4354  break;
4355 
4356  case 0x17: // Introduction date
4357  buf->ReadDWord();
4358  break;
4359 
4360  default:
4361  ret = CIR_UNKNOWN;
4362  break;
4363  }
4364  }
4365 
4366  return ret;
4367 }
4368 
4377 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
4378 {
4380 
4381  extern RoadTypeInfo _roadtypes[ROADTYPE_END];
4382  RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
4383 
4384  if (id + numinfo > ROADTYPE_END) {
4385  grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
4386  return CIR_INVALID_ID;
4387  }
4388 
4389  for (int i = 0; i < numinfo; i++) {
4390  RoadType rt = type_map[id + i];
4391  if (rt == INVALID_ROADTYPE) return CIR_INVALID_ID;
4392 
4393  RoadTypeInfo *rti = &_roadtypes[rt];
4394 
4395  switch (prop) {
4396  case 0x08: // Label of road type
4397  /* Skipped here as this is loaded during reservation stage. */
4398  buf->ReadDWord();
4399  break;
4400 
4401  case 0x09: { // Toolbar caption of roadtype (sets name as well for backwards compatibility for grf ver < 8)
4402  uint16 str = buf->ReadWord();
4404  break;
4405  }
4406 
4407  case 0x0A: // Menu text of roadtype
4408  AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4409  break;
4410 
4411  case 0x0B: // Build window caption
4412  AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4413  break;
4414 
4415  case 0x0C: // Autoreplace text
4416  AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4417  break;
4418 
4419  case 0x0D: // New engine text
4420  AddStringForMapping(buf->ReadWord(), &rti->strings.new_engine);
4421  break;
4422 
4423  case 0x0F: // Powered roadtype list
4424  case 0x18: // Roadtype list required for date introduction
4425  case 0x19: { // Introduced roadtype list
4426  /* Road type compatibility bits are added to the existing bits
4427  * to allow multiple GRFs to modify compatibility with the
4428  * default road types. */
4429  int n = buf->ReadByte();
4430  for (int j = 0; j != n; j++) {
4431  RoadTypeLabel label = buf->ReadDWord();
4432  RoadType rt = GetRoadTypeByLabel(BSWAP32(label), false);
4433  if (rt != INVALID_ROADTYPE) {
4434  switch (prop) {
4435  case 0x0F: SetBit(rti->powered_roadtypes, rt); break;
4436  case 0x18: SetBit(rti->introduction_required_roadtypes, rt); break;
4437  case 0x19: SetBit(rti->introduces_roadtypes, rt); break;
4438  }
4439  }
4440  }
4441  break;
4442  }
4443 
4444  case 0x10: // Road Type flags
4445  rti->flags = (RoadTypeFlags)buf->ReadByte();
4446  break;
4447 
4448  case 0x13: // Construction cost factor
4449  rti->cost_multiplier = buf->ReadWord();
4450  break;
4451 
4452  case 0x14: // Speed limit
4453  rti->max_speed = buf->ReadWord();
4454  break;
4455 
4456  case 0x16: // Map colour
4457  rti->map_colour = buf->ReadByte();
4458  break;
4459 
4460  case 0x17: // Introduction date
4461  rti->introduction_date = buf->ReadDWord();
4462  break;
4463 
4464  case 0x1A: // Sort order
4465  rti->sorting_order = buf->ReadByte();
4466  break;
4467 
4468  case 0x1B: // Name of roadtype
4469  AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4470  break;
4471 
4472  case 0x1C: // Maintenance cost factor
4473  rti->maintenance_multiplier = buf->ReadWord();
4474  break;
4475 
4476  case 0x1D: // Alternate road type label list
4477  /* Skipped here as this is loaded during reservation stage. */
4478  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4479  break;
4480 
4481  default:
4482  ret = CIR_UNKNOWN;
4483  break;
4484  }
4485  }
4486 
4487  return ret;
4488 }
4489 
4490 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4491 {
4492  return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_ROAD);
4493 }
4494 
4495 static ChangeInfoResult TramTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4496 {
4497  return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_TRAM);
4498 }
4499 
4500 
4501 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
4502 {
4504 
4505  extern RoadTypeInfo _roadtypes[ROADTYPE_END];
4506  RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
4507 
4508  if (id + numinfo > ROADTYPE_END) {
4509  grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
4510  return CIR_INVALID_ID;
4511  }
4512 
4513  for (int i = 0; i < numinfo; i++) {
4514  switch (prop) {
4515  case 0x08: { // Label of road type
4516  RoadTypeLabel rtl = buf->ReadDWord();
4517  rtl = BSWAP32(rtl);
4518 
4519  RoadType rt = GetRoadTypeByLabel(rtl, false);
4520  if (rt == INVALID_ROADTYPE) {
4521  /* Set up new road type */
4522  rt = AllocateRoadType(rtl, rtt);
4523  } else if (GetRoadTramType(rt) != rtt) {
4524  grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring", id + numinfo);
4525  return CIR_INVALID_ID;
4526  }
4527 
4528  type_map[id + i] = rt;
4529  break;
4530  }
4531  case 0x09: // Toolbar caption of roadtype
4532  case 0x0A: // Menu text
4533  case 0x0B: // Build window caption
4534  case 0x0C: // Autoreplace text
4535  case 0x0D: // New loco
4536  case 0x13: // Construction cost
4537  case 0x14: // Speed limit
4538  case 0x1B: // Name of roadtype
4539  case 0x1C: // Maintenance cost factor
4540  buf->ReadWord();
4541  break;
4542 
4543  case 0x1D: // Alternate road type label list
4544  if (type_map[id + i] != INVALID_ROADTYPE) {
4545  int n = buf->ReadByte();
4546  for (int j = 0; j != n; j++) {
4547  _roadtypes[type_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord()));
4548  }
4549  break;
4550  }
4551  grfmsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set", id + i);
4552  /* FALL THROUGH */
4553 
4554  case 0x0F: // Powered roadtype list
4555  case 0x18: // Roadtype list required for date introduction
4556  case 0x19: // Introduced roadtype list
4557  for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4558  break;
4559 
4560  case 0x10: // Road Type flags
4561  case 0x16: // Map colour
4562  case 0x1A: // Sort order
4563  buf->ReadByte();
4564  break;
4565 
4566  case 0x17: // Introduction date
4567  buf->ReadDWord();
4568  break;
4569 
4570  default:
4571  ret = CIR_UNKNOWN;
4572  break;
4573  }
4574  }
4575 
4576  return ret;
4577 }
4578 
4579 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4580 {
4581  return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_ROAD);
4582 }
4583 
4584 static ChangeInfoResult TramTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4585 {
4586  return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_TRAM);
4587 }
4588 
4589 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4590 {
4592 
4593  if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4594  grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4595  return CIR_INVALID_ID;
4596  }
4597 
4598  /* Allocate airport tile specs if they haven't been allocated already. */
4599  if (_cur.grffile->airtspec == nullptr) {
4600  _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4601  }
4602 
4603  for (int i = 0; i < numinfo; i++) {
4604  AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4605 
4606  if (prop != 0x08 && tsp == nullptr) {
4607  grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4608  return CIR_INVALID_ID;
4609  }
4610 
4611  switch (prop) {
4612  case 0x08: { // Substitute airport tile type
4613  AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4614  byte subs_id = buf->ReadByte();
4615 
4616  if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4617  /* The substitute id must be one of the original airport tiles. */
4618  grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4619  continue;
4620  }
4621 
4622  /* Allocate space for this airport tile. */
4623  if (*tilespec == nullptr) {
4624  *tilespec = CallocT<AirportTileSpec>(1);
4625  tsp = *tilespec;
4626 
4627  memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4628  tsp->enabled = true;
4629 
4630  tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4631 
4632  tsp->grf_prop.local_id = airtid + i;
4633  tsp->grf_prop.subst_id = subs_id;
4634  tsp->grf_prop.grffile = _cur.grffile;
4635  _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4636  }
4637  break;
4638  }
4639 
4640  case 0x09: { // Airport tile override
4641  byte override = buf->ReadByte();
4642 
4643  /* The airport tile being overridden must be an original airport tile. */
4644  if (override >= NEW_AIRPORTTILE_OFFSET) {
4645  grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4646  continue;
4647  }
4648 
4649  _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4650  break;
4651  }
4652 
4653  case 0x0E: // Callback mask
4654  tsp->callback_mask = buf->ReadByte();
4655  break;
4656 
4657  case 0x0F: // Animation information
4658  tsp->animation.frames = buf->ReadByte();
4659  tsp->animation.status = buf->ReadByte();
4660  break;
4661 
4662  case 0x10: // Animation speed
4663  tsp->animation.speed = buf->ReadByte();
4664  break;
4665 
4666  case 0x11: // Animation triggers
4667  tsp->animation.triggers = buf->ReadByte();
4668  break;
4669 
4670  default:
4671  ret = CIR_UNKNOWN;
4672  break;
4673  }
4674  }
4675 
4676  return ret;
4677 }
4678 
4679 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4680 {
4681  switch (cir) {
4682  default: NOT_REACHED();
4683 
4684  case CIR_DISABLED:
4685  /* Error has already been printed; just stop parsing */
4686  return true;
4687 
4688  case CIR_SUCCESS:
4689  return false;
4690 
4691  case CIR_UNHANDLED:
4692  grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4693  return false;
4694 
4695  case CIR_UNKNOWN:
4696  grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4697  FALLTHROUGH;
4698 
4699  case CIR_INVALID_ID: {
4700  /* No debug message for an invalid ID, as it has already been output */
4701  GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4702  if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4703  return true;
4704  }
4705  }
4706 }
4707 
4708 /* Action 0x00 */
4709 static void FeatureChangeInfo(ByteReader *buf)
4710 {
4711  /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4712  *
4713  * B feature
4714  * B num-props how many properties to change per vehicle/station
4715  * B num-info how many vehicles/stations to change
4716  * E id ID of first vehicle/station to change, if num-info is
4717  * greater than one, this one and the following
4718  * vehicles/stations will be changed
4719  * B property what property to change, depends on the feature
4720  * V new-info new bytes of info (variable size; depends on properties) */
4721 
4722  static const VCI_Handler handler[] = {
4723  /* GSF_TRAINS */ RailVehicleChangeInfo,
4724  /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4725  /* GSF_SHIPS */ ShipVehicleChangeInfo,
4726  /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4727  /* GSF_STATIONS */ StationChangeInfo,
4728  /* GSF_CANALS */ CanalChangeInfo,
4729  /* GSF_BRIDGES */ BridgeChangeInfo,
4730  /* GSF_HOUSES */ TownHouseChangeInfo,
4731  /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4732  /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4733  /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4734  /* GSF_CARGOES */ nullptr, // Cargo is handled during reservation
4735  /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4736  /* GSF_AIRPORTS */ AirportChangeInfo,
4737  /* GSF_SIGNALS */ nullptr,
4738  /* GSF_OBJECTS */ ObjectChangeInfo,
4739  /* GSF_RAILTYPES */ RailTypeChangeInfo,
4740  /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4741  /* GSF_ROADTYPES */ RoadTypeChangeInfo,
4742  /* GSF_TRAMTYPES */ TramTypeChangeInfo,
4743  };
4744 
4745  uint8 feature = buf->ReadByte();
4746  uint8 numprops = buf->ReadByte();
4747  uint numinfo = buf->ReadByte();
4748  uint engine = buf->ReadExtendedByte();
4749 
4750  if (feature >= GSF_END) {
4751  grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4752  return;
4753  }
4754 
4755  grfmsg(6, "FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4756  feature, numprops, engine, numinfo);
4757 
4758  if (feature >= lengthof(handler) || handler[feature] == nullptr) {
4759  if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4760  return;
4761  }
4762 
4763  /* Mark the feature as used by the grf */
4764  SetBit(_cur.grffile->grf_features, feature);
4765 
4766  while (numprops-- && buf->HasData()) {
4767  uint8 prop = buf->ReadByte();
4768 
4769  ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4770  if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4771  }
4772 }
4773 
4774 /* Action 0x00 (GLS_SAFETYSCAN) */
4775 static void SafeChangeInfo(ByteReader *buf)
4776 {
4777  uint8 feature = buf->ReadByte();
4778  uint8 numprops = buf->ReadByte();
4779  uint numinfo = buf->ReadByte();
4780  buf->ReadExtendedByte(); // id
4781 
4782  if (feature == GSF_BRIDGES && numprops == 1) {
4783  uint8 prop = buf->ReadByte();
4784  /* Bridge property 0x0D is redefinition of sprite layout tables, which
4785  * is considered safe. */
4786  if (prop == 0x0D) return;
4787  } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4788  uint8 prop = buf->ReadByte();
4789  /* Engine ID Mappings are safe, if the source is static */
4790  if (prop == 0x11) {
4791  bool is_safe = true;
4792  for (uint i = 0; i < numinfo; i++) {
4793  uint32 s = buf->ReadDWord();
4794  buf->ReadDWord(); // dest
4795  const GRFConfig *grfconfig = GetGRFConfig(s);
4796  if (grfconfig != nullptr && !HasBit(grfconfig->flags, GCF_STATIC)) {
4797  is_safe = false;
4798  break;
4799  }
4800  }
4801  if (is_safe) return;
4802  }
4803  }
4804 
4805  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4806 
4807  /* Skip remainder of GRF */
4808  _cur.skip_sprites = -1;
4809 }
4810 
4811 /* Action 0x00 (GLS_RESERVE) */
4812 static void ReserveChangeInfo(ByteReader *buf)
4813 {
4814  uint8 feature = buf->ReadByte();
4815 
4816  if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES) return;
4817 
4818  uint8 numprops = buf->ReadByte();
4819  uint8 numinfo = buf->ReadByte();
4820  uint8 index = buf->ReadExtendedByte();
4821 
4822  while (numprops-- && buf->HasData()) {
4823  uint8 prop = buf->ReadByte();
4825 
4826  switch (feature) {
4827  default: NOT_REACHED();
4828  case GSF_CARGOES:
4829  cir = CargoChangeInfo(index, numinfo, prop, buf);
4830  break;
4831 
4832  case GSF_GLOBALVAR:
4833  cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4834  break;
4835 
4836  case GSF_RAILTYPES:
4837  cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4838  break;
4839 
4840  case GSF_ROADTYPES:
4841  cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4842  break;
4843 
4844  case GSF_TRAMTYPES:
4845  cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4846  break;
4847  }
4848 
4849  if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4850  }
4851 }
4852 
4853 /* Action 0x01 */
4854 static void NewSpriteSet(ByteReader *buf)
4855 {
4856  /* Basic format: <01> <feature> <num-sets> <num-ent>
4857  * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4858  *
4859  * B feature feature to define sprites for
4860  * 0, 1, 2, 3: veh-type, 4: train stations
4861  * E first-set first sprite set to define
4862  * B num-sets number of sprite sets (extended byte in extended format)
4863  * E num-ent how many entries per sprite set
4864  * For vehicles, this is the number of different
4865  * vehicle directions in each sprite set
4866  * Set num-dirs=8, unless your sprites are symmetric.
4867  * In that case, use num-dirs=4.
4868  */
4869 
4870  uint8 feature = buf->ReadByte();
4871  uint16 num_sets = buf->ReadByte();
4872  uint16 first_set = 0;
4873 
4874  if (num_sets == 0 && buf->HasData(3)) {
4875  /* Extended Action1 format.
4876  * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4877  first_set = buf->ReadExtendedByte();
4878  num_sets = buf->ReadExtendedByte();
4879  }
4880  uint16 num_ents = buf->ReadExtendedByte();
4881 
4882  if (feature >= GSF_END) {
4883  _cur.skip_sprites = num_sets * num_ents;
4884  grfmsg(1, "NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.skip_sprites);
4885  return;
4886  }
4887 
4888  _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4889 
4890  grfmsg(7, "New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4891  _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4892  );
4893 
4894  for (int i = 0; i < num_sets * num_ents; i++) {
4895  _cur.nfo_line++;
4896  LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4897  }
4898 }
4899 
4900 /* Action 0x01 (SKIP) */
4901 static void SkipAct1(ByteReader *buf)
4902 {
4903  buf->ReadByte();
4904  uint16 num_sets = buf->ReadByte();
4905 
4906  if (num_sets == 0 && buf->HasData(3)) {
4907  /* Extended Action1 format.
4908  * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4909  buf->ReadExtendedByte(); // first_set
4910  num_sets = buf->ReadExtendedByte();
4911  }
4912  uint16 num_ents = buf->ReadExtendedByte();
4913 
4914  _cur.skip_sprites = num_sets * num_ents;
4915 
4916  grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4917 }
4918 
4919 /* Helper function to either create a callback or link to a previously
4920  * defined spritegroup. */
4921 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4922 {
4923  if (HasBit(groupid, 15)) {
4925  return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4926  }
4927 
4928  if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
4929  grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4930  return nullptr;
4931  }
4932 
4933  return _cur.spritegroups[groupid];
4934 }
4935 
4944 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4945 {
4946  if (HasBit(spriteid, 15)) {
4948  return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4949  }
4950 
4951  if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4952  grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4953  return nullptr;
4954  }
4955 
4956  SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4957  uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4958 
4959  /* Ensure that the sprites are loeded */
4960  assert(spriteset_start + num_sprites <= _cur.spriteid);
4961 
4963  return new ResultSpriteGroup(spriteset_start, num_sprites);
4964 }
4965 
4966 /* Action 0x02 */
4967 static void NewSpriteGroup(ByteReader *buf)
4968 {
4969  /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4970  *
4971  * B feature see action 1
4972  * B set-id ID of this particular definition
4973  * B type/num-entries
4974  * if 80 or greater, this is a randomized or variational
4975  * list definition, see below
4976  * otherwise it specifies a number of entries, the exact
4977  * meaning depends on the feature
4978  * V feature-specific-data (huge mess, don't even look it up --pasky) */
4979  SpriteGroup *act_group = nullptr;
4980 
4981  uint8 feature = buf->ReadByte();
4982  if (feature >= GSF_END) {
4983  grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
4984  return;
4985  }
4986 
4987  uint8 setid = buf->ReadByte();
4988  uint8 type = buf->ReadByte();
4989 
4990  /* Sprite Groups are created here but they are allocated from a pool, so
4991  * we do not need to delete anything if there is an exception from the
4992  * ByteReader. */
4993 
4994  switch (type) {
4995  /* Deterministic Sprite Group */
4996  case 0x81: // Self scope, byte
4997  case 0x82: // Parent scope, byte
4998  case 0x85: // Self scope, word
4999  case 0x86: // Parent scope, word
5000  case 0x89: // Self scope, dword
5001  case 0x8A: // Parent scope, dword
5002  {
5003  byte varadjust;
5004  byte varsize;
5005 
5008  group->nfo_line = _cur.nfo_line;
5009  act_group = group;
5010  group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
5011 
5012  switch (GB(type, 2, 2)) {
5013  default: NOT_REACHED();
5014  case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
5015  case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
5016  case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
5017  }
5018 
5019  static std::vector<DeterministicSpriteGroupAdjust> adjusts;
5020  adjusts.clear();
5021 
5022  /* Loop through the var adjusts. Unfortunately we don't know how many we have
5023  * from the outset, so we shall have to keep reallocing. */
5024  do {
5025  /*C++17: DeterministicSpriteGroupAdjust &adjust = */ adjusts.emplace_back();
5026  DeterministicSpriteGroupAdjust &adjust = adjusts.back();
5027 
5028  /* The first var adjust doesn't have an operation specified, so we set it to add. */
5029  adjust.operation = adjusts.size() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
5030  adjust.variable = buf->ReadByte();
5031  if (adjust.variable == 0x7E) {
5032  /* Link subroutine group */
5033  adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5034  } else {
5035  adjust.parameter = IsInsideMM(adjust.variable, 0x60, 0x80) ? buf->ReadByte() : 0;
5036  }
5037 
5038  varadjust = buf->ReadByte();
5039  adjust.shift_num = GB(varadjust, 0, 5);
5040  adjust.type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
5041  adjust.and_mask = buf->ReadVarSize(varsize);
5042 
5043  if (adjust.type != DSGA_TYPE_NONE) {
5044  adjust.add_val = buf->ReadVarSize(varsize);
5045  adjust.divmod_val = buf->ReadVarSize(varsize);
5046  } else {
5047  adjust.add_val = 0;
5048  adjust.divmod_val = 0;
5049  }
5050 
5051  /* Continue reading var adjusts while bit 5 is set. */
5052  } while (HasBit(varadjust, 5));
5053 
5054  group->num_adjusts = (uint)adjusts.size();
5055  group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
5056  MemCpyT(group->adjusts, adjusts.data(), group->num_adjusts);
5057 
5058  std::vector<DeterministicSpriteGroupRange> ranges;
5059  ranges.resize(buf->ReadByte());
5060  for (uint i = 0; i < ranges.size(); i++) {
5061  ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5062  ranges[i].low = buf->ReadVarSize(varsize);
5063  ranges[i].high = buf->ReadVarSize(varsize);
5064  }
5065 
5066  group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5067  group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5068  /* nvar == 0 is a special case -- we turn our value into a callback result */
5069  group->calculated_result = ranges.size() == 0;
5070 
5071  /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
5072  std::vector<uint32> bounds;
5073  for (uint i = 0; i < ranges.size(); i++) {
5074  bounds.push_back(ranges[i].low);
5075  if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5076  }
5077  std::sort(bounds.begin(), bounds.end());
5078  bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5079 
5080  std::vector<const SpriteGroup *> target;
5081  for (uint j = 0; j < bounds.size(); ++j) {
5082  uint32 v = bounds[j];
5083  const SpriteGroup *t = group->default_group;
5084  for (uint i = 0; i < ranges.size(); i++) {
5085  if (ranges[i].low <= v && v <= ranges[i].high) {
5086  t = ranges[i].group;
5087  break;
5088  }
5089  }
5090  target.push_back(t);
5091  }
5092  assert(target.size() == bounds.size());
5093 
5094  std::vector<DeterministicSpriteGroupRange> optimised;
5095  for (uint j = 0; j < bounds.size(); ) {
5096  if (target[j] != group->default_group) {
5098  r.group = target[j];
5099  r.low = bounds[j];
5100  while (j < bounds.size() && target[j] == r.group) {
5101  j++;
5102  }
5103  r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5104  optimised.push_back(r);
5105  } else {
5106  j++;
5107  }
5108  }
5109 
5110  group->num_ranges = (uint)optimised.size(); // cast is safe, there should never be 2**31 elements here
5111  if (group->num_ranges > 0) {
5112  group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
5113  MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
5114  }
5115  break;
5116  }
5117 
5118  /* Randomized Sprite Group */
5119  case 0x80: // Self scope
5120  case 0x83: // Parent scope
5121  case 0x84: // Relative scope
5122  {
5125  group->nfo_line = _cur.nfo_line;
5126  act_group = group;
5127  group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
5128 
5129  if (HasBit(type, 2)) {
5130  if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
5131  group->count = buf->ReadByte();
5132  }
5133 
5134  uint8 triggers = buf->ReadByte();
5135  group->triggers = GB(triggers, 0, 7);
5136  group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5137  group->lowest_randbit = buf->ReadByte();
5138  group->num_groups = buf->ReadByte();
5139  group->groups = CallocT<const SpriteGroup*>(group->num_groups);
5140 
5141  for (uint i = 0; i < group->num_groups; i++) {
5142  group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
5143  }
5144 
5145  break;
5146  }
5147 
5148  /* Neither a variable or randomized sprite group... must be a real group */
5149  default:
5150  {
5151  switch (feature) {
5152  case GSF_TRAINS:
5153  case GSF_ROADVEHICLES:
5154  case GSF_SHIPS:
5155  case GSF_AIRCRAFT:
5156  case GSF_STATIONS:
5157  case GSF_CANALS:
5158  case GSF_CARGOES:
5159  case GSF_AIRPORTS:
5160  case GSF_RAILTYPES:
5161  case GSF_ROADTYPES:
5162  case GSF_TRAMTYPES:
5163  {
5164  byte num_loaded = type;
5165  byte num_loading = buf->ReadByte();
5166 
5167  if (!_cur.HasValidSpriteSets(feature)) {
5168  grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
5169  return;
5170  }
5171 
5173  RealSpriteGroup *group = new RealSpriteGroup();
5174  group->nfo_line = _cur.nfo_line;
5175  act_group = group;
5176 
5177  group->num_loaded = num_loaded;
5178  group->num_loading = num_loading;
5179  if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
5180  if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
5181 
5182  grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5183  setid, num_loaded, num_loading);
5184 
5185  for (uint i = 0; i < num_loaded; i++) {
5186  uint16 spriteid = buf->ReadWord();
5187  group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5188  grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
5189  }
5190 
5191  for (uint i = 0; i < num_loading; i++) {
5192  uint16 spriteid = buf->ReadWord();
5193  group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5194  grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
5195  }
5196 
5197  break;
5198  }
5199 
5200  case GSF_HOUSES:
5201  case GSF_AIRPORTTILES:
5202  case GSF_OBJECTS:
5203  case GSF_INDUSTRYTILES: {
5204  byte num_building_sprites = max((uint8)1, type);
5205 
5208  group->nfo_line = _cur.nfo_line;
5209  act_group = group;
5210 
5211  /* On error, bail out immediately. Temporary GRF data was already freed */
5212  if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
5213  break;
5214  }
5215 
5216  case GSF_INDUSTRIES: {
5217  if (type > 2) {
5218  grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5219  break;
5220  }
5221 
5224  group->nfo_line = _cur.nfo_line;
5225  act_group = group;
5226  group->version = type;
5227  if (type == 0) {
5228  group->num_input = 3;
5229  for (uint i = 0; i < 3; i++) {
5230  group->subtract_input[i] = (int16)buf->ReadWord(); // signed
5231  }
5232  group->num_output = 2;
5233  for (uint i = 0; i < 2; i++) {
5234  group->add_output[i] = buf->ReadWord(); // unsigned
5235  }
5236  group->again = buf->ReadByte();
5237  } else if (type == 1) {
5238  group->num_input = 3;
5239  for (uint i = 0; i < 3; i++) {
5240  group->subtract_input[i] = buf->ReadByte();
5241  }
5242  group->num_output = 2;
5243  for (uint i = 0; i < 2; i++) {
5244  group->add_output[i] = buf->ReadByte();
5245  }
5246  group->again = buf->ReadByte();
5247  } else if (type == 2) {
5248  group->num_input = buf->ReadByte();
5249  if (group->num_input > lengthof(group->subtract_input)) {
5250  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5251  error->data = stredup("too many inputs (max 16)");
5252  return;
5253  }
5254  for (uint i = 0; i < group->num_input; i++) {
5255  byte rawcargo = buf->ReadByte();
5256  CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
5257  if (cargo == CT_INVALID) {
5258  /* The mapped cargo is invalid. This is permitted at this point,
5259  * as long as the result is not used. Mark it invalid so this
5260  * can be tested later. */
5261  group->version = 0xFF;
5262  } else if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) {
5263  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5264  error->data = stredup("duplicate input cargo");
5265  return;
5266  }
5267  group->cargo_input[i] = cargo;
5268  group->subtract_input[i] = buf->ReadByte();
5269  }
5270  group->num_output = buf->ReadByte();
5271  if (group->num_output > lengthof(group->add_output)) {
5272  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5273  error->data = stredup("too many outputs (max 16)");
5274  return;
5275  }
5276  for (uint i = 0; i < group->num_output; i++) {
5277  byte rawcargo = buf->ReadByte();
5278  CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
5279  if (cargo == CT_INVALID) {
5280  /* Mark this result as invalid to use */
5281  group->version = 0xFF;
5282  } else if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) {
5283  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5284  error->data = stredup("duplicate output cargo");
5285  return;
5286  }
5287  group->cargo_output[i] = cargo;
5288  group->add_output[i] = buf->ReadByte();
5289  }
5290  group->again = buf->ReadByte();
5291  } else {
5292  NOT_REACHED();
5293  }
5294  break;
5295  }
5296 
5297  /* Loading of Tile Layout and Production Callback groups would happen here */
5298  default: grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5299  }
5300  }
5301  }
5302 
5303  _cur.spritegroups[setid] = act_group;
5304 }
5305 
5306 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5307 {
5308  if (feature == GSF_OBJECTS) {
5309  switch (ctype) {
5310  case 0: return 0;
5311  case 0xFF: return CT_PURCHASE_OBJECT;
5312  default:
5313  grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5314  return CT_INVALID;
5315  }
5316  }
5317  /* Special cargo types for purchase list and stations */
5318  if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
5319  if (ctype == 0xFF) return CT_PURCHASE;
5320 
5321  if (_cur.grffile->cargo_list.size() == 0) {
5322  /* No cargo table, so use bitnum values */
5323  if (ctype >= 32) {
5324  grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5325  return CT_INVALID;
5326  }
5327 
5328  const CargoSpec *cs;
5329  FOR_ALL_CARGOSPECS(cs) {
5330  if (cs->bitnum == ctype) {
5331  grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5332  return cs->Index();
5333  }
5334  }
5335 
5336  grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5337  return CT_INVALID;
5338  }
5339 
5340  /* Check if the cargo type is out of bounds of the cargo translation table */
5341  if (ctype >= _cur.grffile->cargo_list.size()) {
5342  grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (unsigned int)_cur.grffile->cargo_list.size() - 1);
5343  return CT_INVALID;
5344  }
5345 
5346  /* Look up the cargo label from the translation table */
5347  CargoLabel cl = _cur.grffile->cargo_list[ctype];
5348  if (cl == 0) {
5349  grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5350  return CT_INVALID;
5351  }
5352 
5353  ctype = GetCargoIDByLabel(cl);
5354  if (ctype == CT_INVALID) {
5355  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));
5356  return CT_INVALID;
5357  }
5358 
5359  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);
5360  return ctype;
5361 }
5362 
5363 
5364 static bool IsValidGroupID(uint16 groupid, const char *function)
5365 {
5366  if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
5367  grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
5368  return false;
5369  }
5370 
5371  return true;
5372 }
5373 
5374 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
5375 {
5376  static EngineID *last_engines;
5377  static uint last_engines_count;
5378  bool wagover = false;
5379 
5380  /* Test for 'wagon override' flag */
5381  if (HasBit(idcount, 7)) {
5382  wagover = true;
5383  /* Strip off the flag */
5384  idcount = GB(idcount, 0, 7);
5385 
5386  if (last_engines_count == 0) {
5387  grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5388  return;
5389  }
5390 
5391  grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5392  last_engines_count, idcount);
5393  } else {
5394  if (last_engines_count != idcount) {
5395  last_engines = ReallocT(last_engines, idcount);
5396  last_engines_count = idcount;
5397  }
5398  }
5399 
5400  EngineID *engines = AllocaM(EngineID, idcount);
5401  for (uint i = 0; i < idcount; i++) {
5402  Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
5403  if (e == nullptr) {
5404  /* No engine could be allocated?!? Deal with it. Okay,
5405  * this might look bad. Also make sure this NewGRF
5406  * gets disabled, as a half loaded one is bad. */
5407  HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
5408  return;
5409  }
5410 
5411  engines[i] = e->index;
5412  if (!wagover) last_engines[i] = engines[i];
5413  }
5414 
5415  uint8 cidcount = buf->ReadByte();
5416  for (uint c = 0; c < cidcount; c++) {
5417  uint8 ctype = buf->ReadByte();
5418  uint16 groupid = buf->ReadWord();
5419  if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
5420 
5421  grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5422 
5423  ctype = TranslateCargo(feature, ctype);
5424  if (ctype == CT_INVALID) continue;
5425 
5426  for (uint i = 0; i < idcount; i++) {
5427  EngineID engine = engines[i];
5428 
5429  grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5430 
5431  if (wagover) {
5432  SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5433  } else {
5434  SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5435  }
5436  }
5437  }
5438 
5439  uint16 groupid = buf->ReadWord();
5440  if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5441 
5442  grfmsg(8, "-- Default group id 0x%04X", groupid);
5443 
5444  for (uint i = 0; i < idcount; i++) {
5445  EngineID engine = engines[i];
5446 
5447  if (wagover) {
5448  SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5449  } else {
5450  SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5451  SetEngineGRF(engine, _cur.grffile);
5452  }
5453  }
5454 }
5455 
5456 
5457 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5458 {
5459  CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5460  for (uint i = 0; i < idcount; i++) {
5461  cfs[i] = (CanalFeature)buf->ReadByte();
5462  }
5463 
5464  uint8 cidcount = buf->ReadByte();
5465  buf->Skip(cidcount * 3);
5466 
5467  uint16 groupid = buf->ReadWord();
5468  if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5469 
5470  for (uint i = 0; i < idcount; i++) {
5471  CanalFeature cf = cfs[i];
5472 
5473  if (cf >= CF_END) {
5474  grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5475  continue;
5476  }
5477 
5478  _water_feature[cf].grffile = _cur.grffile;
5479  _water_feature[cf].group = _cur.spritegroups[groupid];
5480  }
5481 }
5482 
5483 
5484 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5485 {
5486  uint8 *stations = AllocaM(uint8, idcount);
5487  for (uint i = 0; i < idcount; i++) {
5488  stations[i] = buf->ReadByte();
5489  }
5490 
5491  uint8 cidcount = buf->ReadByte();
5492  for (uint c = 0; c < cidcount; c++) {
5493  uint8 ctype = buf->ReadByte();
5494  uint16 groupid = buf->ReadWord();
5495  if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5496 
5497  ctype = TranslateCargo(GSF_STATIONS, ctype);
5498  if (ctype == CT_INVALID) continue;
5499 
5500  for (uint i = 0; i < idcount; i++) {
5501  StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5502 
5503  if (statspec == nullptr) {
5504  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5505  continue;
5506  }
5507 
5508  statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5509  }
5510  }
5511 
5512  uint16 groupid = buf->ReadWord();
5513  if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5514 
5515  for (uint i = 0; i < idcount; i++) {
5516  StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5517 
5518  if (statspec == nullptr) {
5519  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5520  continue;
5521  }
5522 
5523  if (statspec->grf_prop.grffile != nullptr) {
5524  grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5525  continue;
5526  }
5527 
5528  statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5529  statspec->grf_prop.grffile = _cur.grffile;
5530  statspec->grf_prop.local_id = stations[i];
5531  StationClass::Assign(statspec);
5532  }
5533 }
5534 
5535 
5536 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5537 {
5538  uint8 *houses = AllocaM(uint8, idcount);
5539  for (uint i = 0; i < idcount; i++) {
5540  houses[i] = buf->ReadByte();
5541  }
5542 
5543  /* Skip the cargo type section, we only care about the default group */
5544  uint8 cidcount = buf->ReadByte();
5545  buf->Skip(cidcount * 3);
5546 
5547  uint16 groupid = buf->ReadWord();
5548  if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5549 
5550  if (_cur.grffile->housespec == nullptr) {
5551  grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5552  return;
5553  }
5554 
5555  for (uint i = 0; i < idcount; i++) {
5556  HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5557 
5558  if (hs == nullptr) {
5559  grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5560  continue;
5561  }
5562 
5563  hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5564  }
5565 }
5566 
5567 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5568 {
5569  uint8 *industries = AllocaM(uint8, idcount);
5570  for (uint i = 0; i < idcount; i++) {
5571  industries[i] = buf->ReadByte();
5572  }
5573 
5574  /* Skip the cargo type section, we only care about the default group */
5575  uint8 cidcount = buf->ReadByte();
5576  buf->Skip(cidcount * 3);
5577 
5578  uint16 groupid = buf->ReadWord();
5579  if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5580 
5581  if (_cur.grffile->industryspec == nullptr) {
5582  grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5583  return;
5584  }
5585 
5586  for (uint i = 0; i < idcount; i++) {
5587  IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5588 
5589  if (indsp == nullptr) {
5590  grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5591  continue;
5592  }
5593 
5594  indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5595  }
5596 }
5597 
5598 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5599 {
5600  uint8 *indtiles = AllocaM(uint8, idcount);
5601  for (uint i = 0; i < idcount; i++) {
5602  indtiles[i] = buf->ReadByte();
5603  }
5604 
5605  /* Skip the cargo type section, we only care about the default group */
5606  uint8 cidcount = buf->ReadByte();
5607  buf->Skip(cidcount * 3);
5608 
5609  uint16 groupid = buf->ReadWord();
5610  if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5611 
5612  if (_cur.grffile->indtspec == nullptr) {
5613  grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5614  return;
5615  }
5616 
5617  for (uint i = 0; i < idcount; i++) {
5618  IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5619 
5620  if (indtsp == nullptr) {
5621  grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5622  continue;
5623  }
5624 
5625  indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5626  }
5627 }
5628 
5629 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5630 {
5631  CargoID *cargoes = AllocaM(CargoID, idcount);
5632  for (uint i = 0; i < idcount; i++) {
5633  cargoes[i] = buf->ReadByte();
5634  }
5635 
5636  /* Skip the cargo type section, we only care about the default group */
5637  uint8 cidcount = buf->ReadByte();
5638  buf->Skip(cidcount * 3);
5639 
5640  uint16 groupid = buf->ReadWord();
5641  if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5642 
5643  for (uint i = 0; i < idcount; i++) {
5644  CargoID cid = cargoes[i];
5645 
5646  if (cid >= NUM_CARGO) {
5647  grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5648  continue;
5649  }
5650 
5651  CargoSpec *cs = CargoSpec::Get(cid);
5652  cs->grffile = _cur.grffile;
5653  cs->group = _cur.spritegroups[groupid];
5654  }
5655 }
5656 
5657 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5658 {
5659  if (_cur.grffile->objectspec == nullptr) {
5660  grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5661  return;
5662  }
5663 
5664  uint8 *objects = AllocaM(uint8, idcount);
5665  for (uint i = 0; i < idcount; i++) {
5666  objects[i] = buf->ReadByte();
5667  }
5668 
5669  uint8 cidcount = buf->ReadByte();
5670  for (uint c = 0; c < cidcount; c++) {
5671  uint8 ctype = buf->ReadByte();
5672  uint16 groupid = buf->ReadWord();
5673  if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5674 
5675  ctype = TranslateCargo(GSF_OBJECTS, ctype);
5676  if (ctype == CT_INVALID) continue;
5677 
5678  for (uint i = 0; i < idcount; i++) {
5679  ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5680 
5681  if (spec == nullptr) {
5682  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5683  continue;
5684  }
5685 
5686  spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5687  }
5688  }
5689 
5690  uint16 groupid = buf->ReadWord();
5691  if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5692 
5693  for (uint i = 0; i < idcount; i++) {
5694  ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5695 
5696  if (spec == nullptr) {
5697  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5698  continue;
5699  }
5700 
5701  if (spec->grf_prop.grffile != nullptr) {
5702  grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5703  continue;
5704  }
5705 
5706  spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5707  spec->grf_prop.grffile = _cur.grffile;
5708  spec->grf_prop.local_id = objects[i];
5709  }
5710 }
5711 
5712 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5713 {
5714  uint8 *railtypes = AllocaM(uint8, idcount);
5715  for (uint i = 0; i < idcount; i++) {
5716  uint8 id = buf->ReadByte();
5717  railtypes[i] = id < RAILTYPE_END ? _cur.grffile->railtype_map[id] : INVALID_RAILTYPE;
5718  }
5719 
5720  uint8 cidcount = buf->ReadByte();
5721  for (uint c = 0; c < cidcount; c++) {
5722  uint8 ctype = buf->ReadByte();
5723  uint16 groupid = buf->ReadWord();
5724  if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5725 
5726  if (ctype >= RTSG_END) continue;
5727 
5728  extern RailtypeInfo _railtypes[RAILTYPE_END];
5729  for (uint i = 0; i < idcount; i++) {
5730  if (railtypes[i] != INVALID_RAILTYPE) {
5731  RailtypeInfo *rti = &_railtypes[railtypes[i]];
5732 
5733  rti->grffile[ctype] = _cur.grffile;
5734  rti->group[ctype] = _cur.spritegroups[groupid];
5735  }
5736  }
5737  }
5738 
5739  /* Railtypes do not use the default group. */
5740  buf->ReadWord();
5741 }
5742 
5743 static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadTramType rtt)
5744 {
5745  RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
5746 
5747  uint8 *roadtypes = AllocaM(uint8, idcount);
5748  for (uint i = 0; i < idcount; i++) {
5749  uint8 id = buf->ReadByte();
5750  roadtypes[i] = id < ROADTYPE_END ? type_map[id] : INVALID_ROADTYPE;
5751  }
5752 
5753  uint8 cidcount = buf->ReadByte();
5754  for (uint c = 0; c < cidcount; c++) {
5755  uint8 ctype = buf->ReadByte();
5756  uint16 groupid = buf->ReadWord();
5757  if (!IsValidGroupID(groupid, "RoadTypeMapSpriteGroup")) continue;
5758 
5759  if (ctype >= ROTSG_END) continue;
5760 
5761  extern RoadTypeInfo _roadtypes[ROADTYPE_END];
5762  for (uint i = 0; i < idcount; i++) {
5763  if (roadtypes[i] != INVALID_ROADTYPE) {
5764  RoadTypeInfo *rti = &_roadtypes[roadtypes[i]];
5765 
5766  rti->grffile[ctype] = _cur.grffile;
5767  rti->group[ctype] = _cur.spritegroups[groupid];
5768  }
5769  }
5770  }
5771 
5772  /* Roadtypes do not use the default group. */
5773  buf->ReadWord();
5774 }
5775 
5776 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5777 {
5778  uint8 *airports = AllocaM(uint8, idcount);
5779  for (uint i = 0; i < idcount; i++) {
5780  airports[i] = buf->ReadByte();
5781  }
5782 
5783  /* Skip the cargo type section, we only care about the default group */
5784  uint8 cidcount = buf->ReadByte();
5785  buf->Skip(cidcount * 3);
5786 
5787  uint16 groupid = buf->ReadWord();
5788  if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5789 
5790  if (_cur.grffile->airportspec == nullptr) {
5791  grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5792  return;
5793  }
5794 
5795  for (uint i = 0; i < idcount; i++) {
5796  AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5797 
5798  if (as == nullptr) {
5799  grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5800  continue;
5801  }
5802 
5803  as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5804  }
5805 }
5806 
5807 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5808 {
5809  uint8 *airptiles = AllocaM(uint8, idcount);
5810  for (uint i = 0; i < idcount; i++) {
5811  airptiles[i] = buf->ReadByte();
5812  }
5813 
5814  /* Skip the cargo type section, we only care about the default group */
5815  uint8 cidcount = buf->ReadByte();
5816  buf->Skip(cidcount * 3);
5817 
5818  uint16 groupid = buf->ReadWord();
5819  if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5820 
5821  if (_cur.grffile->airtspec == nullptr) {
5822  grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5823  return;
5824  }
5825 
5826  for (uint i = 0; i < idcount; i++) {
5827  AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5828 
5829  if (airtsp == nullptr) {
5830  grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5831  continue;
5832  }
5833 
5834  airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5835  }
5836 }
5837 
5838 
5839 /* Action 0x03 */
5840 static void FeatureMapSpriteGroup(ByteReader *buf)
5841 {
5842  /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5843  * id-list := [<id>] [id-list]
5844  * cargo-list := <cargo-type> <cid> [cargo-list]
5845  *
5846  * B feature see action 0
5847  * B n-id bits 0-6: how many IDs this definition applies to
5848  * bit 7: if set, this is a wagon override definition (see below)
5849  * B ids the IDs for which this definition applies
5850  * B num-cid number of cargo IDs (sprite group IDs) in this definition
5851  * can be zero, in that case the def-cid is used always
5852  * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5853  * W cid cargo ID (sprite group ID) for this type of cargo
5854  * W def-cid default cargo ID (sprite group ID) */
5855 
5856  uint8 feature = buf->ReadByte();
5857  uint8 idcount = buf->ReadByte();
5858 
5859  if (feature >= GSF_END) {
5860  grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5861  return;
5862  }
5863 
5864  /* If idcount is zero, this is a feature callback */
5865  if (idcount == 0) {
5866  /* Skip number of cargo ids? */
5867  buf->ReadByte();
5868  uint16 groupid = buf->ReadWord();
5869  if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5870 
5871  grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5872 
5873  AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5874  return;
5875  }
5876 
5877  /* Mark the feature as used by the grf (generic callbacks do not count) */
5878  SetBit(_cur.grffile->grf_features, feature);
5879 
5880  grfmsg(6, "FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5881 
5882  switch (feature) {
5883  case GSF_TRAINS:
5884  case GSF_ROADVEHICLES:
5885  case GSF_SHIPS:
5886  case GSF_AIRCRAFT:
5887  VehicleMapSpriteGroup(buf, feature, idcount);
5888  return;
5889 
5890  case GSF_CANALS:
5891  CanalMapSpriteGroup(buf, idcount);
5892  return;
5893 
5894  case GSF_STATIONS:
5895  StationMapSpriteGroup(buf, idcount);
5896  return;
5897 
5898  case GSF_HOUSES:
5899  TownHouseMapSpriteGroup(buf, idcount);
5900  return;
5901 
5902  case GSF_INDUSTRIES:
5903  IndustryMapSpriteGroup(buf, idcount);
5904  return;
5905 
5906  case GSF_INDUSTRYTILES:
5907  IndustrytileMapSpriteGroup(buf, idcount);
5908  return;
5909 
5910  case GSF_CARGOES:
5911  CargoMapSpriteGroup(buf, idcount);
5912  return;
5913 
5914  case GSF_AIRPORTS:
5915  AirportMapSpriteGroup(buf, idcount);
5916  return;
5917 
5918  case GSF_OBJECTS:
5919  ObjectMapSpriteGroup(buf, idcount);
5920  break;
5921 
5922  case GSF_RAILTYPES:
5923  RailTypeMapSpriteGroup(buf, idcount);
5924  break;
5925 
5926  case GSF_ROADTYPES:
5927  RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5928  break;
5929 
5930  case GSF_TRAMTYPES:
5931  RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5932  break;
5933 
5934  case GSF_AIRPORTTILES:
5935  AirportTileMapSpriteGroup(buf, idcount);
5936  return;
5937 
5938  default:
5939  grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5940  return;
5941  }
5942 }
5943 
5944 /* Action 0x04 */
5945 static void FeatureNewName(ByteReader *buf)
5946 {
5947  /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5948  *
5949  * B veh-type see action 0 (as 00..07, + 0A
5950  * But IF veh-type = 48, then generic text
5951  * B language-id If bit 6 is set, This is the extended language scheme,
5952  * with up to 64 language.
5953  * Otherwise, it is a mapping where set bits have meaning
5954  * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5955  * Bit 7 set means this is a generic text, not a vehicle one (or else)
5956  * B num-veh number of vehicles which are getting a new name
5957  * B/W offset number of the first vehicle that gets a new name
5958  * Byte : ID of vehicle to change
5959  * Word : ID of string to change/add
5960  * S data new texts, each of them zero-terminated, after
5961  * which the next name begins. */
5962 
5963  bool new_scheme = _cur.grffile->grf_version >= 7;
5964 
5965  uint8 feature = buf->ReadByte();
5966  if (feature >= GSF_END && feature != 0x48) {
5967  grfmsg(1, "FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
5968  return;
5969  }
5970 
5971  uint8 lang = buf->ReadByte();
5972  uint8 num = buf->ReadByte();
5973  bool generic = HasBit(lang, 7);
5974  uint16 id;
5975  if (generic) {
5976  id = buf->ReadWord();
5977  } else if (feature <= GSF_AIRCRAFT) {
5978  id = buf->ReadExtendedByte();
5979  } else {
5980  id = buf->ReadByte();
5981  }
5982 
5983  ClrBit(lang, 7);
5984 
5985  uint16 endid = id + num;
5986 
5987  grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
5988  id, endid, feature, lang);
5989 
5990  for (; id < endid && buf->HasData(); id++) {
5991  const char *name = buf->ReadString();
5992  grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5993 
5994  switch (feature) {
5995  case GSF_TRAINS:
5996  case GSF_ROADVEHICLES:
5997  case GSF_SHIPS:
5998  case GSF_AIRCRAFT:
5999  if (!generic) {
6000  Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
6001  if (e == nullptr) break;
6002  StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
6003  e->info.string_id = string;
6004  } else {
6005  AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
6006  }
6007  break;
6008 
6009  default:
6010  if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
6011  AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
6012  break;
6013  }
6014 
6015  switch (GB(id, 8, 8)) {
6016  case 0xC4: // Station class name
6017  if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
6018  grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
6019  } else {
6020  StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
6021  StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6022  }
6023  break;
6024 
6025  case 0xC5: // Station name
6026  if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
6027  grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
6028  } else {
6029  _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6030  }
6031  break;
6032 
6033  case 0xC7: // Airporttile name
6034  if (_cur.grffile->airtspec == nullptr || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) {
6035  grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
6036  } else {
6037  _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6038  }
6039  break;
6040 
6041  case 0xC9: // House name
6042  if (_cur.grffile->housespec == nullptr || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) {
6043  grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
6044  } else {
6045  _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6046  }
6047  break;
6048 
6049  default:
6050  grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
6051  break;
6052  }
6053  break;
6054  }
6055  }
6056 }
6057 
6066 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
6067 {
6068 
6069  if (offset >= max_sprites) {
6070  grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6071  uint orig_num = num;
6072  num = 0;
6073  return orig_num;
6074  }
6075 
6076  if (offset + num > max_sprites) {
6077  grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
6078  uint orig_num = num;
6079  num = max(max_sprites - offset, 0);
6080  return orig_num - num;
6081  }
6082 
6083  return 0;
6084 }
6085 
6086 
6092 };
6094 struct Action5Type {
6097  uint16 min_sprites;
6098  uint16 max_sprites;
6099  const char *name;
6100 };
6101 
6103 static const Action5Type _action5_types[] = {
6104  /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
6105  /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
6106  /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
6107  /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
6108  /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
6109  /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
6110  /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
6111  /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
6112  /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
6113  /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
6114  /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
6115  /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
6116  /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
6117  /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
6118  /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
6119  /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
6120  /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
6121  /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
6122  /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
6123  /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
6124  /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
6125  /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
6126  /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
6127  /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
6128  /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
6129  /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
6130 };
6131 
6132 /* Action 0x05 */
6133 static void GraphicsNew(ByteReader *buf)
6134 {
6135  /* <05> <graphics-type> <num-sprites> <other data...>
6136  *
6137  * B graphics-type What set of graphics the sprites define.
6138  * E num-sprites How many sprites are in this set?
6139  * V other data Graphics type specific data. Currently unused. */
6140 
6141  uint8 type = buf->ReadByte();
6142  uint16 num = buf->ReadExtendedByte();
6143  uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6144  ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
6145 
6146  if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
6147  /* Special not-TTDP-compatible case used in openttd.grf
6148  * Missing shore sprites and initialisation of SPR_SHORE_BASE */
6149  grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6150  LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
6151  LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
6152  LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
6153  LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
6154  LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
6155  LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
6156  LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
6157  LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
6158  LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
6159  LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
6160  if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
6161  return;
6162  }
6163 
6164  /* Supported type? */
6165  if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
6166  grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6167  _cur.skip_sprites = num;
6168  return;
6169  }
6170 
6171  const Action5Type *action5_type = &_action5_types[type];
6172 
6173  /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
6174  * except for the long version of the shore type:
6175  * Ignore offset if not allowed */
6176  if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
6177  grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
6178  offset = 0;
6179  }
6180 
6181  /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
6182  * This does not make sense, if <offset> is allowed */
6183  if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
6184  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);
6185  _cur.skip_sprites = num;
6186  return;
6187  }
6188 
6189  /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extensions) */
6190  uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
6191  SpriteID replace = action5_type->sprite_base + offset;
6192 
6193  /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
6194  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);
6195 
6196  if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
6197 
6198  if (type == 0x0B) {
6199  static const SpriteID depot_with_track_offset = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_TRAMWAY_BASE;
6200  static const SpriteID depot_no_track_offset = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_TRAMWAY_BASE;
6201  if (offset <= depot_with_track_offset && offset + num > depot_with_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_WITH_TRACK;
6202  if (offset <= depot_no_track_offset && offset + num > depot_no_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NO_TRACK;
6203  }
6204 
6205  for (; num > 0; num--) {
6206  _cur.nfo_line++;
6207  LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
6208  }
6209 
6210  _cur.skip_sprites = skip_num;
6211 }
6212 
6213 /* Action 0x05 (SKIP) */
6214 static void SkipAct5(ByteReader *buf)
6215 {
6216  /* Ignore type byte */
6217  buf->ReadByte();
6218 
6219  /* Skip the sprites of this action */
6220  _cur.skip_sprites = buf->ReadExtendedByte();
6221 
6222  grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
6223 }
6224 
6236 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
6237 {
6238  switch (param) {
6239  case 0x00: // current date
6240  *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
6241  return true;
6242 
6243  case 0x01: // current year
6245  return true;
6246 
6247  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)
6248  YearMonthDay ymd;
6249  ConvertDateToYMD(_date, &ymd);
6250  Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
6251  *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
6252  return true;
6253  }
6254 
6255  case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
6257  return true;
6258 
6259  case 0x06: // road traffic side, bit 4 clear=left, set=right
6260  *value = _settings_game.vehicle.road_side << 4;
6261  return true;
6262 
6263  case 0x09: // date fraction
6264  *value = _date_fract * 885;
6265  return true;
6266 
6267  case 0x0A: // animation counter
6268  *value = _tick_counter;
6269  return true;
6270 
6271  case 0x0B: { // TTDPatch version
6272  uint major = 2;
6273  uint minor = 6;
6274  uint revision = 1; // special case: 2.0.1 is 2.0.10
6275  uint build = 1382;
6276  *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6277  return true;
6278  }
6279 
6280  case 0x0D: // TTD Version, 00=DOS, 01=Windows
6281  *value = _cur.grfconfig->palette & GRFP_USE_MASK;
6282  return true;
6283 
6284  case 0x0E: // Y-offset for train sprites
6285  *value = _cur.grffile->traininfo_vehicle_pitch;
6286  return true;
6287 
6288  case 0x0F: // Rail track type cost factors
6289  *value = 0;
6290  SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
6292  /* skip elrail multiplier - disabled */
6293  SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
6294  } else {
6295  SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
6296  /* Skip monorail multiplier - no space in result */
6297  }
6298  SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
6299  return true;
6300 
6301  case 0x11: // current rail tool type
6302  *value = 0; // constant fake value to avoid desync
6303  return true;
6304 
6305  case 0x12: // Game mode
6306  *value = _game_mode;
6307  return true;
6308 
6309  /* case 0x13: // Tile refresh offset to left not implemented */
6310  /* case 0x14: // Tile refresh offset to right not implemented */
6311  /* case 0x15: // Tile refresh offset upwards not implemented */
6312  /* case 0x16: // Tile refresh offset downwards not implemented */
6313  /* case 0x17: // temperate snow line not implemented */
6314 
6315  case 0x1A: // Always -1
6316  *value = UINT_MAX;
6317  return true;
6318 
6319  case 0x1B: // Display options
6320  *value = 0x3F; // constant fake value to avoid desync
6321  return true;
6322 
6323  case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
6324  *value = 1;
6325  return true;
6326 
6327  case 0x1E: // Miscellaneous GRF features
6328  *value = _misc_grf_features;
6329 
6330  /* Add the local flags */
6331  assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
6332  if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
6333  return true;
6334 
6335  /* case 0x1F: // locale dependent settings not implemented to avoid desync */
6336 
6337  case 0x20: { // snow line height
6338  byte snowline = GetSnowLine();
6340  *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
6341  } else {
6342  /* No snow */
6343  *value = 0xFF;
6344  }
6345  return true;
6346  }
6347 
6348  case 0x21: // OpenTTD version
6349  *value = _openttd_newgrf_version;
6350  return true;
6351 
6352  case 0x22: // difficulty level
6353  *value = SP_CUSTOM;
6354  return true;
6355 
6356  case 0x23: // long format date
6357  *value = _date;
6358  return true;
6359 
6360  case 0x24: // long format year
6361  *value = _cur_year;
6362  return true;
6363 
6364  default: return false;
6365  }
6366 }
6367 
6368 static uint32 GetParamVal(byte param, uint32 *cond_val)
6369 {
6370  /* First handle variable common with VarAction2 */
6371  uint32 value;
6372  if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
6373 
6374  /* Non-common variable */
6375  switch (param) {
6376  case 0x84: { // GRF loading stage
6377  uint32 res = 0;
6378 
6379  if (_cur.stage > GLS_INIT) SetBit(res, 0);
6380  if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
6381  if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
6382  return res;
6383  }
6384 
6385  case 0x85: // TTDPatch flags, only for bit tests
6386  if (cond_val == nullptr) {
6387  /* Supported in Action 0x07 and 0x09, not 0x0D */
6388  return 0;
6389  } else {
6390  uint32 index = *cond_val / 0x20;
6391  uint32 param_val = index < lengthof(_ttdpatch_flags) ? _ttdpatch_flags[index] : 0;
6392  *cond_val %= 0x20;
6393  return param_val;
6394  }
6395 
6396  case 0x88: // GRF ID check
6397  return 0;
6398 
6399  /* case 0x99: Global ID offset not implemented */
6400 
6401  default:
6402  /* GRF Parameter */
6403  if (param < 0x80) return _cur.grffile->GetParam(param);
6404 
6405  /* In-game variable. */
6406  grfmsg(1, "Unsupported in-game variable 0x%02X", param);
6407  return UINT_MAX;
6408  }
6409 }
6410 
6411 /* Action 0x06 */
6412 static void CfgApply(ByteReader *buf)
6413 {
6414  /* <06> <param-num> <param-size> <offset> ... <FF>
6415  *
6416  * B param-num Number of parameter to substitute (First = "zero")
6417  * Ignored if that parameter was not specified in newgrf.cfg
6418  * B param-size How many bytes to replace. If larger than 4, the
6419  * bytes of the following parameter are used. In that
6420  * case, nothing is applied unless *all* parameters
6421  * were specified.
6422  * B offset Offset into data from beginning of next sprite
6423  * to place where parameter is to be stored. */
6424 
6425  /* Preload the next sprite */
6426  size_t pos = FioGetPos();
6427  uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
6428  uint8 type = FioReadByte();
6429  byte *preload_sprite = nullptr;
6430 
6431  /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
6432  if (type == 0xFF) {
6433  preload_sprite = MallocT<byte>(num);
6434  FioReadBlock(preload_sprite, num);
6435  }
6436 
6437  /* Reset the file position to the start of the next sprite */
6438  FioSeekTo(pos, SEEK_SET);
6439 
6440  if (type != 0xFF) {
6441  grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
6442  free(preload_sprite);
6443  return;
6444  }
6445 
6446  GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
6447  GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6448  if (it != _grf_line_to_action6_sprite_override.end()) {
6449  free(preload_sprite);
6450  preload_sprite = _grf_line_to_action6_sprite_override[location];
6451  } else {
6452  _grf_line_to_action6_sprite_override[location] = preload_sprite;
6453  }
6454 
6455  /* Now perform the Action 0x06 on our data. */
6456 
6457  for (;;) {
6458  uint i;
6459  uint param_num;
6460  uint param_size;
6461  uint offset;
6462  bool add_value;
6463 
6464  /* Read the parameter to apply. 0xFF indicates no more data to change. */
6465  param_num = buf->ReadByte();
6466  if (param_num == 0xFF) break;
6467 
6468  /* Get the size of the parameter to use. If the size covers multiple
6469  * double words, sequential parameter values are used. */
6470  param_size = buf->ReadByte();
6471 
6472  /* Bit 7 of param_size indicates we should add to the original value
6473  * instead of replacing it. */
6474  add_value = HasBit(param_size, 7);
6475  param_size = GB(param_size, 0, 7);
6476 
6477  /* Where to apply the data to within the pseudo sprite data. */
6478  offset = buf->ReadExtendedByte();
6479 
6480  /* If the parameter is a GRF parameter (not an internal variable) check
6481  * if it (and all further sequential parameters) has been defined. */
6482  if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6483  grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6484  break;
6485  }
6486 
6487  grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6488 
6489  bool carry = false;
6490  for (i = 0; i < param_size && offset + i < num; i++) {
6491  uint32 value = GetParamVal(param_num + i / 4, nullptr);
6492  /* Reset carry flag for each iteration of the variable (only really
6493  * matters if param_size is greater than 4) */
6494  if (i % 4 == 0) carry = false;
6495 
6496  if (add_value) {
6497  uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6498  preload_sprite[offset + i] = GB(new_value, 0, 8);
6499  /* Check if the addition overflowed */
6500  carry = new_value >= 256;
6501  } else {
6502  preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6503  }
6504  }
6505  }
6506 }
6507 
6518 {
6519  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6520  error->data = stredup(_cur.grfconfig->GetName());
6521 }
6522 
6523 /* Action 0x07
6524  * Action 0x09 */
6525 static void SkipIf(ByteReader *buf)
6526 {
6527  /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6528  *
6529  * B param-num
6530  * B param-size
6531  * B condition-type
6532  * V value
6533  * B num-sprites */
6534  uint32 cond_val = 0;
6535  uint32 mask = 0;
6536  bool result;
6537 
6538  uint8 param = buf->ReadByte();
6539  uint8 paramsize = buf->ReadByte();
6540  uint8 condtype = buf->ReadByte();
6541 
6542  if (condtype < 2) {
6543  /* Always 1 for bit tests, the given value should be ignored. */
6544  paramsize = 1;
6545  }
6546 
6547  switch (paramsize) {
6548  case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6549  case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6550  case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6551  case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6552  default: break;
6553  }
6554 
6555  if (param < 0x80 && _cur.grffile->param_end <= param) {
6556  grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6557  return;
6558  }
6559 
6560  uint32 param_val = GetParamVal(param, &cond_val);
6561 
6562  grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6563 
6564  /*
6565  * Parameter (variable in specs) 0x88 can only have GRF ID checking
6566  * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6567  * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6568  * So, when the condition type is one of those, the specific variable
6569  * 0x88 code is skipped, so the "general" code for the cargo
6570  * availability conditions kicks in.
6571  */
6572  if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6573  /* GRF ID checks */
6574 
6575  GRFConfig *c = GetGRFConfig(cond_val, mask);
6576 
6577  if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6579  c = nullptr;
6580  }
6581 
6582  if (condtype != 10 && c == nullptr) {
6583  grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6584  return;
6585  }
6586 
6587  switch (condtype) {
6588  /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6589  case 0x06: // Is GRFID active?
6590  result = c->status == GCS_ACTIVATED;
6591  break;
6592 
6593  case 0x07: // Is GRFID non-active?
6594  result = c->status != GCS_ACTIVATED;
6595  break;
6596 
6597  case 0x08: // GRFID is not but will be active?
6598  result = c->status == GCS_INITIALISED;
6599  break;
6600 
6601  case 0x09: // GRFID is or will be active?
6602  result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6603  break;
6604 
6605  case 0x0A: // GRFID is not nor will be active
6606  /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6607  result = c == nullptr || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6608  break;
6609 
6610  default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6611  }
6612  } else {
6613  /* Parameter or variable tests */
6614  switch (condtype) {
6615  case 0x00: result = !!(param_val & (1 << cond_val));
6616  break;
6617  case 0x01: result = !(param_val & (1 << cond_val));
6618  break;
6619  case 0x02: result = (param_val & mask) == cond_val;
6620  break;
6621  case 0x03: result = (param_val & mask) != cond_val;
6622  break;
6623  case 0x04: result = (param_val & mask) < cond_val;
6624  break;
6625  case 0x05: result = (param_val & mask) > cond_val;
6626  break;
6627  case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6628  break;
6629  case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6630  break;
6631  case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6632  break;
6633  case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6634  break;
6635  case 0x0F: {
6636  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6637  result = rt == INVALID_ROADTYPE || !RoadTypeIsRoad(rt);
6638  break;
6639  }
6640  case 0x10: {
6641  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6642  result = rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt);
6643  break;
6644  }
6645  case 0x11: {
6646  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6647  result = rt == INVALID_ROADTYPE || !RoadTypeIsTram(rt);
6648  break;
6649  }
6650  case 0x12: {
6651  RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6652  result = rt != INVALID_ROADTYPE && RoadTypeIsTram(rt);
6653  break;
6654  }
6655  default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6656  }
6657  }
6658 
6659  if (!result) {
6660  grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6661  return;
6662  }
6663 
6664  uint8 numsprites = buf->ReadByte();
6665 
6666  /* numsprites can be a GOTO label if it has been defined in the GRF
6667  * file. The jump will always be the first matching label that follows
6668  * the current nfo_line. If no matching label is found, the first matching
6669  * label in the file is used. */
6670  GRFLabel *choice = nullptr;
6671  for (GRFLabel *label = _cur.grffile->label; label != nullptr; label = label->next) {
6672  if (label->label != numsprites) continue;
6673 
6674  /* Remember a goto before the current line */
6675  if (choice == nullptr) choice = label;
6676  /* If we find a label here, this is definitely good */
6677  if (label->nfo_line > _cur.nfo_line) {
6678  choice = label;
6679  break;
6680  }
6681  }
6682 
6683  if (choice != nullptr) {
6684  grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6685  FioSeekTo(choice->pos, SEEK_SET);
6686  _cur.nfo_line = choice->nfo_line;
6687  return;
6688  }
6689 
6690  grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6691  _cur.skip_sprites = numsprites;
6692  if (_cur.skip_sprites == 0) {
6693  /* Zero means there are no sprites to skip, so
6694  * we use -1 to indicate that all further
6695  * sprites should be skipped. */
6696  _cur.skip_sprites = -1;
6697 
6698  /* If an action 8 hasn't been encountered yet, disable the grf. */
6699  if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6700  DisableGrf();
6701  }
6702  }
6703 }
6704 
6705 
6706 /* Action 0x08 (GLS_FILESCAN) */
6707 static void ScanInfo(ByteReader *buf)
6708 {
6709  uint8 grf_version = buf->ReadByte();
6710  uint32 grfid = buf->ReadDWord();
6711  const char *name = buf->ReadString();
6712 
6713  _cur.grfconfig->ident.grfid = grfid;
6714 
6715  if (grf_version < 2 || grf_version > 8) {
6717  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);
6718  }
6719 
6720  /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6721  if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6722 
6723  AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6724 
6725  if (buf->HasData()) {
6726  const char *info = buf->ReadString();
6727  AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6728  }
6729 
6730  /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6731  _cur.skip_sprites = -1;
6732 }
6733 
6734 /* Action 0x08 */
6735 static void GRFInfo(ByteReader *buf)
6736 {
6737  /* <08> <version> <grf-id> <name> <info>
6738  *
6739  * B version newgrf version, currently 06
6740  * 4*B grf-id globally unique ID of this .grf file
6741  * S name name of this .grf set
6742  * S info string describing the set, and e.g. author and copyright */
6743 
6744  uint8 version = buf->ReadByte();
6745  uint32 grfid = buf->ReadDWord();
6746  const char *name = buf->ReadString();
6747 
6748  if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6749  DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6750  return;
6751  }
6752 
6753  if (_cur.grffile->grfid != grfid) {
6754  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));
6755  _cur.grffile->grfid = grfid;
6756  }
6757 
6758  _cur.grffile->grf_version = version;
6759  _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6760 
6761  /* Do swap the GRFID for displaying purposes since people expect that */
6762  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);
6763 }
6764 
6765 /* Action 0x0A */
6766 static void SpriteReplace(ByteReader *buf)
6767 {
6768  /* <0A> <num-sets> <set1> [<set2> ...]
6769  * <set>: <num-sprites> <first-sprite>
6770  *
6771  * B num-sets How many sets of sprites to replace.
6772  * Each set:
6773  * B num-sprites How many sprites are in this set
6774  * W first-sprite First sprite number to replace */
6775 
6776  uint8 num_sets = buf->ReadByte();
6777 
6778  for (uint i = 0; i < num_sets; i++) {
6779  uint8 num_sprites = buf->ReadByte();
6780  uint16 first_sprite = buf->ReadWord();
6781 
6782  grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6783  i, num_sprites, first_sprite
6784  );
6785 
6786  for (uint j = 0; j < num_sprites; j++) {
6787  int load_index = first_sprite + j;
6788  _cur.nfo_line++;
6789  LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6790 
6791  /* Shore sprites now located at different addresses.
6792  * So detect when the old ones get replaced. */
6793  if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6794  if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6795  }
6796  }
6797  }
6798 }
6799 
6800 /* Action 0x0A (SKIP) */
6801 static void SkipActA(ByteReader *buf)
6802 {
6803  uint8 num_sets = buf->ReadByte();
6804 
6805  for (uint i = 0; i < num_sets; i++) {
6806  /* Skip the sprites this replaces */
6807  _cur.skip_sprites += buf->ReadByte();
6808  /* But ignore where they go */
6809  buf->ReadWord();
6810  }
6811 
6812  grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6813 }
6814 
6815 /* Action 0x0B */
6816 static void GRFLoadError(ByteReader *buf)
6817 {
6818  /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6819  *
6820  * B severity 00: notice, continue loading grf file
6821  * 01: warning, continue loading grf file
6822  * 02: error, but continue loading grf file, and attempt
6823  * loading grf again when loading or starting next game
6824  * 03: error, abort loading and prevent loading again in
6825  * the future (only when restarting the patch)
6826  * B language-id see action 4, use 1F for built-in error messages
6827  * B message-id message to show, see below
6828  * S message for custom messages (message-id FF), text of the message
6829  * not present for built-in messages.
6830  * V data additional data for built-in (or custom) messages
6831  * B parnum parameter numbers to be shown in the message (maximum of 2) */
6832 
6833  static const StringID msgstr[] = {
6834  STR_NEWGRF_ERROR_VERSION_NUMBER,
6835  STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6836  STR_NEWGRF_ERROR_UNSET_SWITCH,
6837  STR_NEWGRF_ERROR_INVALID_PARAMETER,
6838  STR_NEWGRF_ERROR_LOAD_BEFORE,
6839  STR_NEWGRF_ERROR_LOAD_AFTER,
6840  STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6841  };
6842 
6843  static const StringID sevstr[] = {
6844  STR_NEWGRF_ERROR_MSG_INFO,
6845  STR_NEWGRF_ERROR_MSG_WARNING,
6846  STR_NEWGRF_ERROR_MSG_ERROR,
6847  STR_NEWGRF_ERROR_MSG_FATAL
6848  };
6849 
6850  byte severity = buf->ReadByte();
6851  byte lang = buf->ReadByte();
6852  byte message_id = buf->ReadByte();
6853 
6854  /* Skip the error if it isn't valid for the current language. */
6855  if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6856 
6857  /* Skip the error until the activation stage unless bit 7 of the severity
6858  * is set. */
6859  if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6860  grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6861  return;
6862  }
6863  ClrBit(severity, 7);
6864 
6865  if (severity >= lengthof(sevstr)) {
6866  grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6867  severity = 2;
6868  } else if (severity == 3) {
6869  /* This is a fatal error, so make sure the GRF is deactivated and no
6870  * more of it gets loaded. */
6871  DisableGrf();
6872 
6873  /* Make sure we show fatal errors, instead of silly infos from before */
6874  delete _cur.grfconfig->error;
6875  _cur.grfconfig->error = nullptr;
6876  }
6877 
6878  if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6879  grfmsg(7, "GRFLoadError: Invalid message id.");
6880  return;
6881  }
6882 
6883  if (buf->Remaining() <= 1) {
6884  grfmsg(7, "GRFLoadError: No message data supplied.");
6885  return;
6886  }
6887 
6888  /* For now we can only show one message per newgrf file. */
6889  if (_cur.grfconfig->error != nullptr) return;
6890 
6891  GRFError *error = new GRFError(sevstr[severity]);
6892 
6893  if (message_id == 0xFF) {
6894  /* This is a custom error message. */
6895  if (buf->HasData()) {
6896  const char *message = buf->ReadString();
6897 
6898  error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, nullptr, SCC_RAW_STRING_POINTER);
6899  } else {
6900  grfmsg(7, "GRFLoadError: No custom message supplied.");
6901  error->custom_message = stredup("");
6902  }
6903  } else {
6904  error->message = msgstr[message_id];
6905  }
6906 
6907  if (buf->HasData()) {
6908  const char *data = buf->ReadString();
6909 
6910  error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6911  } else {
6912  grfmsg(7, "GRFLoadError: No message data supplied.");
6913  error->data = stredup("");
6914  }
6915 
6916  /* Only two parameter numbers can be used in the string. */
6917  for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6918  uint param_number = buf->ReadByte();
6919  error->param_value[i] = _cur.grffile->GetParam(param_number);
6920  }
6921 
6922  _cur.grfconfig->error = error;
6923 }
6924 
6925 /* Action 0x0C */
6926 static void GRFComment(ByteReader *buf)
6927 {
6928  /* <0C> [<ignored...>]
6929  *
6930  * V ignored Anything following the 0C is ignored */
6931 
6932  if (!buf->HasData()) return;
6933 
6934  const char *text = buf->ReadString();
6935  grfmsg(2, "GRFComment: %s", text);
6936 }
6937 
6938 /* Action 0x0D (GLS_SAFETYSCAN) */
6939 static void SafeParamSet(ByteReader *buf)
6940 {
6941  uint8 target = buf->ReadByte();
6942 
6943  /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6944  if (target < 0x80 || target == 0x9E) return;
6945 
6946  /* GRM could be unsafe, but as here it can only happen after other GRFs
6947  * are loaded, it should be okay. If the GRF tried to use the slots it
6948  * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6949  * sprites is considered safe. */
6950 
6951  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6952 
6953  /* Skip remainder of GRF */
6954  _cur.skip_sprites = -1;
6955 }
6956 
6957 
6958 static uint32 GetPatchVariable(uint8 param)
6959 {
6960  switch (param) {
6961  /* start year - 1920 */
6963 
6964  /* freight trains weight factor */
6965  case 0x0E: return _settings_game.vehicle.freight_trains;
6966 
6967  /* empty wagon speed increase */
6968  case 0x0F: return 0;
6969 
6970  /* plane speed factor; our patch option is reversed from TTDPatch's,
6971  * the following is good for 1x, 2x and 4x (most common?) and...
6972  * well not really for 3x. */
6973  case 0x10:
6975  default:
6976  case 4: return 1;
6977  case 3: return 2;
6978  case 2: return 2;
6979  case 1: return 4;
6980  }
6981 
6982 
6983  /* 2CC colourmap base sprite */
6984  case 0x11: return SPR_2CCMAP_BASE;
6985 
6986  /* map size: format = -MABXYSS
6987  * M : the type of map
6988  * bit 0 : set : squared map. Bit 1 is now not relevant
6989  * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6990  * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6991  * clear : X is the bigger edge.
6992  * A : minimum edge(log2) of the map
6993  * B : maximum edge(log2) of the map
6994  * XY : edges(log2) of each side of the map.
6995  * SS : combination of both X and Y, thus giving the size(log2) of the map
6996  */
6997  case 0x13: {
6998  byte map_bits = 0;
6999  byte log_X = MapLogX() - 6; // subtraction is required to make the minimal size (64) zero based
7000  byte log_Y = MapLogY() - 6;
7001  byte max_edge = max(log_X, log_Y);
7002 
7003  if (log_X == log_Y) { // we have a squared map, since both edges are identical
7004  SetBit(map_bits, 0);
7005  } else {
7006  if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
7007  }
7008 
7009  return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
7010  (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7011  }
7012 
7013  /* The maximum height of the map. */
7014  case 0x14:
7016 
7017  /* Extra foundations base sprite */
7018  case 0x15:
7019  return SPR_SLOPES_BASE;
7020 
7021  /* Shore base sprite */
7022  case 0x16:
7023  return SPR_SHORE_BASE;
7024 
7025  default:
7026  grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
7027  return 0;
7028  }
7029 }
7030 
7031 
7032 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
7033 {
7034  uint start = 0;
7035  uint size = 0;
7036 
7037  if (op == 6) {
7038  /* Return GRFID of set that reserved ID */
7039  return grm[_cur.grffile->GetParam(target)];
7040  }
7041 
7042  /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
7043  if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
7044 
7045  for (uint i = start; i < num_ids; i++) {
7046  if (grm[i] == 0) {
7047  size++;
7048  } else {
7049  if (op == 2 || op == 3) break;
7050  start = i + 1;
7051  size = 0;
7052  }
7053 
7054  if (size == count) break;
7055  }
7056 
7057  if (size == count) {
7058  /* Got the slot... */
7059  if (op == 0 || op == 3) {
7060  grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7061  for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
7062  }
7063  return start;
7064  }
7065 
7066  /* Unable to allocate */
7067  if (op != 4 && op != 5) {
7068  /* Deactivate GRF */
7069  grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7070  DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
7071  return UINT_MAX;
7072  }
7073 
7074  grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
7075  return UINT_MAX;
7076 }
7077 
7078 
7080 static void ParamSet(ByteReader *buf)
7081 {
7082  /* <0D> <target> <operation> <source1> <source2> [<data>]
7083  *
7084  * B target parameter number where result is stored
7085  * B operation operation to perform, see below
7086  * B source1 first source operand
7087  * B source2 second source operand
7088  * D data data to use in the calculation, not necessary
7089  * if both source1 and source2 refer to actual parameters
7090  *
7091  * Operations
7092  * 00 Set parameter equal to source1
7093  * 01 Addition, source1 + source2
7094  * 02 Subtraction, source1 - source2
7095  * 03 Unsigned multiplication, source1 * source2 (both unsigned)
7096  * 04 Signed multiplication, source1 * source2 (both signed)
7097  * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
7098  * signed quantity; left shift if positive and right shift if
7099  * negative, source1 is unsigned)
7100  * 06 Signed bit shift, source1 by source2
7101  * (source2 like in 05, and source1 as well)
7102  */
7103 
7104  uint8 target = buf->ReadByte();
7105  uint8 oper = buf->ReadByte();
7106  uint32 src1 = buf->ReadByte();
7107  uint32 src2 = buf->ReadByte();
7108 
7109  uint32 data = 0;
7110  if (buf->Remaining() >= 4) data = buf->ReadDWord();
7111 
7112  /* You can add 80 to the operation to make it apply only if the target
7113  * is not defined yet. In this respect, a parameter is taken to be
7114  * defined if any of the following applies:
7115  * - it has been set to any value in the newgrf(w).cfg parameter list
7116  * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
7117  * an earlier action D */
7118  if (HasBit(oper, 7)) {
7119  if (target < 0x80 && target < _cur.grffile->param_end) {
7120  grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
7121  return;
7122  }
7123 
7124  oper = GB(oper, 0, 7);
7125  }
7126 
7127  if (src2 == 0xFE) {
7128  if (GB(data, 0, 8) == 0xFF) {
7129  if (data == 0x0000FFFF) {
7130  /* Patch variables */
7131  src1 = GetPatchVariable(src1);
7132  } else {
7133  /* GRF Resource Management */
7134  uint8 op = src1;
7135  uint8 feature = GB(data, 8, 8);
7136  uint16 count = GB(data, 16, 16);
7137 
7138  if (_cur.stage == GLS_RESERVE) {
7139  if (feature == 0x08) {
7140  /* General sprites */
7141  if (op == 0) {
7142  /* Check if the allocated sprites will fit below the original sprite limit */
7143  if (_cur.spriteid + count >= 16384) {
7144  grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7145  DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
7146  return;
7147  }
7148 
7149  /* Reserve space at the current sprite ID */
7150  grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
7151  _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
7152  _cur.spriteid += count;
7153  }
7154  }
7155  /* Ignore GRM result during reservation */
7156  src1 = 0;
7157  } else if (_cur.stage == GLS_ACTIVATION) {
7158  switch (feature) {
7159  case 0x00: // Trains
7160  case 0x01: // Road Vehicles
7161  case 0x02: // Ships
7162  case 0x03: // Aircraft
7164  src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
7165  if (_cur.skip_sprites == -1) return;
7166  } else {
7167  /* GRM does not apply for dynamic engine allocation. */
7168  switch (op) {
7169  case 2:
7170  case 3:
7171  src1 = _cur.grffile->GetParam(target);
7172  break;
7173 
7174  default:
7175  src1 = 0;
7176  break;
7177  }
7178  }
7179  break;
7180 
7181  case 0x08: // General sprites
7182  switch (op) {
7183  case 0:
7184  /* Return space reserved during reservation stage */
7185  src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
7186  grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7187  break;
7188 
7189  case 1:
7190  src1 = _cur.spriteid;
7191  break;
7192 
7193  default:
7194  grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
7195  return;
7196  }
7197  break;
7198 
7199  case 0x0B: // Cargo
7200  /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
7201  src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
7202  if (_cur.skip_sprites == -1) return;
7203  break;
7204 
7205  default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
7206  }
7207  } else {
7208  /* Ignore GRM during initialization */
7209  src1 = 0;
7210  }
7211  }
7212  } else {
7213  /* Read another GRF File's parameter */
7214  const GRFFile *file = GetFileByGRFID(data);
7215  GRFConfig *c = GetGRFConfig(data);
7216  if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
7217  /* Disable the read GRF if it is a static NewGRF. */
7219  src1 = 0;
7220  } else if (file == nullptr || c == nullptr || c->status == GCS_DISABLED) {
7221  src1 = 0;
7222  } else if (src1 == 0xFE) {
7223  src1 = c->version;
7224  } else {
7225  src1 = file->GetParam(src1);
7226  }
7227  }
7228  } else {
7229  /* The source1 and source2 operands refer to the grf parameter number
7230  * like in action 6 and 7. In addition, they can refer to the special
7231  * variables available in action 7, or they can be FF to use the value
7232  * of <data>. If referring to parameters that are undefined, a value
7233  * of 0 is used instead. */
7234  src1 = (src1 == 0xFF) ? data : GetParamVal(src1, nullptr);
7235  src2 = (src2 == 0xFF) ? data : GetParamVal(src2, nullptr);
7236  }
7237 
7238  uint32 res;
7239  switch (oper) {
7240  case 0x00:
7241  res = src1;
7242  break;
7243 
7244  case 0x01:
7245  res = src1 + src2;
7246  break;
7247 
7248  case 0x02:
7249  res = src1 - src2;
7250  break;
7251 
7252  case 0x03:
7253  res = src1 * src2;
7254  break;
7255 
7256  case 0x04:
7257  res = (int32)src1 * (int32)src2;
7258  break;
7259 
7260  case 0x05:
7261  if ((int32)src2 < 0) {
7262  res = src1 >> -(int32)src2;
7263  } else {
7264  res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7265  }
7266  break;
7267 
7268  case 0x06:
7269  if ((int32)src2 < 0) {
7270  res = (int32)src1 >> -(int32)src2;
7271  } else {
7272  res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7273  }
7274  break;
7275 
7276  case 0x07: // Bitwise AND
7277  res = src1 & src2;
7278  break;
7279 
7280  case 0x08: // Bitwise OR
7281  res = src1 | src2;
7282  break;
7283 
7284  case 0x09: // Unsigned division
7285  if (src2 == 0) {
7286  res = src1;
7287  } else {
7288  res = src1 / src2;
7289  }
7290  break;
7291 
7292  case 0x0A: // Signed division
7293  if (src2 == 0) {
7294  res = src1;
7295  } else {
7296  res = (int32)src1 / (int32)src2;
7297  }
7298  break;
7299 
7300  case 0x0B: // Unsigned modulo
7301  if (src2 == 0) {
7302  res = src1;
7303  } else {
7304  res = src1 % src2;
7305  }
7306  break;
7307 
7308  case 0x0C: // Signed modulo
7309  if (src2 == 0) {
7310  res = src1;
7311  } else {
7312  res = (int32)src1 % (int32)src2;
7313  }
7314  break;
7315 
7316  default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
7317  }
7318 
7319  switch (target) {
7320  case 0x8E: // Y-Offset for train sprites
7321  _cur.grffile->traininfo_vehicle_pitch = res;
7322  break;
7323 
7324  case 0x8F: { // Rail track type cost factors
7325  extern RailtypeInfo _railtypes[RAILTYPE_END];
7326  _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
7328  _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
7329  _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
7330  } else {
7331  _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
7332  _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
7333  }
7334  _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
7335  break;
7336  }
7337 
7338  /* not implemented */
7339  case 0x93: // Tile refresh offset to left -- Intended to allow support for larger sprites, not necessary for OTTD
7340  case 0x94: // Tile refresh offset to right
7341  case 0x95: // Tile refresh offset upwards
7342  case 0x96: // Tile refresh offset downwards
7343  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
7344  case 0x99: // Global ID offset -- Not necessary since IDs are remapped automatically
7345  grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7346  break;
7347 
7348  case 0x9E: // Miscellaneous GRF features
7349  /* Set train list engine width */
7350  _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
7351  /* Remove the local flags from the global flags */
7353 
7354  /* Only copy safe bits for static grfs */
7355  if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
7356  uint32 safe_bits = 0;
7357  SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7358 
7359  _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
7360  } else {
7361  _misc_grf_features = res;
7362  }
7363  break;
7364 
7365  case 0x9F: // locale-dependent settings
7366  grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7367  break;
7368 
7369  default:
7370  if (target < 0x80) {
7371  _cur.grffile->param[target] = res;
7372  /* param is zeroed by default */
7373  if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
7374  } else {
7375  grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
7376  }
7377  break;
7378  }
7379 }
7380 
7381 /* Action 0x0E (GLS_SAFETYSCAN) */
7382 static void SafeGRFInhibit(ByteReader *buf)
7383 {
7384  /* <0E> <num> <grfids...>
7385  *
7386  * B num Number of GRFIDs that follow
7387  * D grfids GRFIDs of the files to deactivate */
7388 
7389  uint8 num = buf->ReadByte();
7390 
7391  for (uint i = 0; i < num; i++) {
7392  uint32 grfid = buf->ReadDWord();
7393 
7394  /* GRF is unsafe it if tries to deactivate other GRFs */
7395  if (grfid != _cur.grfconfig->ident.grfid) {
7396  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7397 
7398  /* Skip remainder of GRF */
7399  _cur.skip_sprites = -1;
7400 
7401  return;
7402  }
7403  }
7404 }
7405 
7406 /* Action 0x0E */
7407 static void GRFInhibit(ByteReader *buf)
7408 {
7409  /* <0E> <num> <grfids...>
7410  *
7411  * B num Number of GRFIDs that follow
7412  * D grfids GRFIDs of the files to deactivate */
7413 
7414  uint8 num = buf->ReadByte();
7415 
7416  for (uint i = 0; i < num; i++) {
7417  uint32 grfid = buf->ReadDWord();
7418  GRFConfig *file = GetGRFConfig(grfid);
7419 
7420  /* Unset activation flag */
7421  if (file != nullptr && file != _cur.grfconfig) {
7422  grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
7423  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
7424  error->data = stredup(_cur.grfconfig->GetName());
7425  }
7426  }
7427 }
7428 
7430 static void FeatureTownName(ByteReader *buf)
7431 {
7432  /* <0F> <id> <style-name> <num-parts> <parts>
7433  *
7434  * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
7435  * V style-name Name of the style (only for final definition)
7436  * B num-parts Number of parts in this definition
7437  * V parts The parts */
7438 
7439  uint32 grfid = _cur.grffile->grfid;
7440 
7441  GRFTownName *townname = AddGRFTownName(grfid);
7442 
7443  byte id = buf->ReadByte();
7444  grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
7445 
7446  if (HasBit(id, 7)) {
7447  /* Final definition */
7448  ClrBit(id, 7);
7449  bool new_scheme = _cur.grffile->grf_version >= 7;
7450 
7451  byte lang = buf->ReadByte();
7452 
7453  byte nb_gen = townname->nb_gen;
7454  do {
7455  ClrBit(lang, 7);
7456 
7457  const char *name = buf->ReadString();
7458 
7459  char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
7460  grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
7461  free(lang_name);
7462 
7463  townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
7464 
7465  lang = buf->ReadByte();
7466  } while (lang != 0);
7467  townname->id[nb_gen] = id;
7468  townname->nb_gen++;
7469  }
7470 
7471  byte nb = buf->ReadByte();
7472  grfmsg(6, "FeatureTownName: %u parts", nb);
7473 
7474  townname->nbparts[id] = nb;
7475  townname->partlist[id] = CallocT<NamePartList>(nb);
7476 
7477  for (int i = 0; i < nb; i++) {
7478  byte nbtext = buf->ReadByte();
7479  townname->partlist[id][i].bitstart = buf->ReadByte();
7480  townname->partlist[id][i].bitcount = buf->ReadByte();
7481  townname->partlist[id][i].maxprob = 0;
7482  townname->partlist[id][i].partcount = nbtext;
7483  townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7484  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);
7485 
7486  for (int j = 0; j < nbtext; j++) {
7487  byte prob = buf->ReadByte();
7488 
7489  if (HasBit(prob, 7)) {
7490  byte ref_id = buf->ReadByte();
7491 
7492  if (townname->nbparts[ref_id] == 0) {
7493  grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7494  DelGRFTownName(grfid);
7495  DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
7496  return;
7497  }
7498 
7499  grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7500  townname->partlist[id][i].parts[j].data.id = ref_id;
7501  } else {
7502  const char *text = buf->ReadString();
7503  townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7504  grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7505  }
7506  townname->partlist[id][i].parts[j].prob = prob;
7507  townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7508  }
7509  grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7510  }
7511 }
7512 
7514 static void DefineGotoLabel(ByteReader *buf)
7515 {
7516  /* <10> <label> [<comment>]
7517  *
7518  * B label The label to define
7519  * V comment Optional comment - ignored */
7520 
7521  byte nfo_label = buf->ReadByte();
7522 
7523  GRFLabel *label = MallocT<GRFLabel>(1);
7524  label->label = nfo_label;
7525  label->nfo_line = _cur.nfo_line;
7526  label->pos = FioGetPos();
7527  label->next = nullptr;
7528 
7529  /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7530  if (_cur.grffile->label == nullptr) {
7531  _cur.grffile->label = label;
7532  } else {
7533  /* Attach the label to the end of the list */
7534  GRFLabel *l;
7535  for (l = _cur.grffile->label; l->next != nullptr; l = l->next) {}
7536  l->next = label;
7537  }
7538 
7539  grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7540 }
7541 
7546 static void ImportGRFSound(SoundEntry *sound)
7547 {
7548  const GRFFile *file;
7549  uint32 grfid = FioReadDword();
7550  SoundID sound_id = FioReadWord();
7551 
7552  file = GetFileByGRFID(grfid);
7553  if (file == nullptr || file->sound_offset == 0) {
7554  grfmsg(1, "ImportGRFSound: Source file not available");
7555  return;
7556  }
7557 
7558  if (sound_id >= file->num_sounds) {
7559  grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7560  return;
7561  }
7562 
7563  grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7564 
7565  *sound = *GetSound(file->sound_offset + sound_id);
7566 
7567  /* Reset volume and priority, which TTDPatch doesn't copy */
7568  sound->volume = 128;
7569  sound->priority = 0;
7570 }
7571 
7577 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7578 {
7579  /* Set default volume and priority */
7580  sound->volume = 0x80;
7581  sound->priority = 0;
7582 
7583  if (offs != SIZE_MAX) {
7584  /* Sound is present in the NewGRF. */
7585  sound->file_slot = _cur.file_index;
7586  sound->file_offset = offs;
7587  sound->grf_container_ver = _cur.grf_container_ver;
7588  }
7589 }
7590 
7591 /* Action 0x11 */
7592 static void GRFSound(ByteReader *buf)
7593 {
7594  /* <11> <num>
7595  *
7596  * W num Number of sound files that follow */
7597 
7598  uint16 num = buf->ReadWord();
7599  if (num == 0) return;
7600 
7601  SoundEntry *sound;
7602  if (_cur.grffile->sound_offset == 0) {
7603  _cur.grffile->sound_offset = GetNumSounds();
7604  _cur.grffile->num_sounds = num;
7605  sound = AllocateSound(num);
7606  } else {
7607  sound = GetSound(_cur.grffile->sound_offset);
7608  }
7609 
7610  for (int i = 0; i < num; i++) {
7611  _cur.nfo_line++;
7612 
7613  /* Check whether the index is in range. This might happen if multiple action 11 are present.
7614  * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7615  bool invalid = i >= _cur.grffile->num_sounds;
7616 
7617  size_t offs = FioGetPos();
7618 
7619  uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7620  byte type = FioReadByte();
7621 
7622  if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7623  /* Reference to sprite section. */
7624  if (invalid) {
7625  grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7626  FioSkipBytes(len);
7627  } else if (len != 4) {
7628  grfmsg(1, "GRFSound: Invalid sprite section import");
7629  FioSkipBytes(len);
7630  } else {
7631  uint32 id = FioReadDword();
7632  if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7633  }
7634  continue;
7635  }
7636 
7637  if (type != 0xFF) {
7638  grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7639  FioSkipBytes(7);
7640  SkipSpriteData(type, len - 8);
7641  continue;
7642  }
7643 
7644  if (invalid) {
7645  grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7646  FioSkipBytes(len);
7647  }
7648 
7649  byte action = FioReadByte();
7650  switch (action) {
7651  case 0xFF:
7652  /* Allocate sound only in init stage. */
7653  if (_cur.stage == GLS_INIT) {
7654  if (_cur.grf_container_ver >= 2) {
7655  grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7656  } else {
7657  LoadGRFSound(offs, sound + i);
7658  }
7659  }
7660  FioSkipBytes(len - 1); // already read <action>
7661  break;
7662 
7663  case 0xFE:
7664  if (_cur.stage == GLS_ACTIVATION) {
7665  /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7666  * importing sounds, so this is probably all wrong... */
7667  if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7668  ImportGRFSound(sound + i);
7669  } else {
7670  FioSkipBytes(len - 1); // already read <action>
7671  }
7672  break;
7673 
7674  default:
7675  grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7676  FioSkipBytes(len - 1); // already read <action>
7677  break;
7678  }
7679  }
7680 }
7681 
7682 /* Action 0x11 (SKIP) */
7683 static void SkipAct11(ByteReader *buf)
7684 {
7685  /* <11> <num>
7686  *
7687  * W num Number of sound files that follow */
7688 
7689  _cur.skip_sprites = buf->ReadWord();
7690 
7691  grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7692 }
7693 
7695 static void LoadFontGlyph(ByteReader *buf)
7696 {
7697  /* <12> <num_def> <font_size> <num_char> <base_char>
7698  *
7699  * B num_def Number of definitions
7700  * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7701  * B num_char Number of consecutive glyphs
7702  * W base_char First character index */
7703 
7704  uint8 num_def = buf->ReadByte();
7705 
7706  for (uint i = 0; i < num_def; i++) {
7707  FontSize size = (FontSize)buf->ReadByte();
7708  uint8 num_char = buf->ReadByte();
7709  uint16 base_char = buf->ReadWord();
7710 
7711  if (size >= FS_END) {
7712  grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7713  }
7714 
7715  grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7716 
7717  for (uint c = 0; c < num_char; c++) {
7718  if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7719  _cur.nfo_line++;
7720  LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7721  }
7722  }
7723 }
7724 
7726 static void SkipAct12(ByteReader *buf)
7727 {
7728  /* <12> <num_def> <font_size> <num_char> <base_char>
7729  *
7730  * B num_def Number of definitions
7731  * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7732  * B num_char Number of consecutive glyphs
7733  * W base_char First character index */
7734 
7735  uint8 num_def = buf->ReadByte();
7736 
7737  for (uint i = 0; i < num_def; i++) {
7738  /* Ignore 'size' byte */
7739  buf->ReadByte();
7740 
7741  /* Sum up number of characters */
7742  _cur.skip_sprites += buf->ReadByte();
7743 
7744  /* Ignore 'base_char' word */
7745  buf->ReadWord();
7746  }
7747 
7748  grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7749 }
7750 
7753 {
7754  /* <13> <grfid> <num-ent> <offset> <text...>
7755  *
7756  * 4*B grfid The GRFID of the file whose texts are to be translated
7757  * B num-ent Number of strings
7758  * W offset First text ID
7759  * S text... Zero-terminated strings */
7760 
7761  uint32 grfid = buf->ReadDWord();
7762  const GRFConfig *c = GetGRFConfig(grfid);
7763  if (c == nullptr || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7764  grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7765  return;
7766  }
7767 
7768  if (c->status == GCS_INITIALISED) {
7769  /* If the file is not active but will be activated later, give an error
7770  * and disable this file. */
7771  GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7772 
7773  char tmp[256];
7774  GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7775  error->data = stredup(tmp);
7776 
7777  return;
7778  }
7779 
7780  /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7781  * to be added as a generic string, thus the language id of 0x7F. For this to work
7782  * new_scheme has to be true as well, which will also be implicitly the case for version 8
7783  * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7784  * not change anything if a string has been provided specifically for this language. */
7785  byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7786  byte num_strings = buf->ReadByte();
7787  uint16 first_id = buf->ReadWord();
7788 
7789  if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7790  grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7791  return;
7792  }
7793 
7794  for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7795  const char *string = buf->ReadString();
7796 
7797  if (StrEmpty(string)) {
7798  grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7799  continue;
7800  }
7801 
7802  AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7803  }
7804 }
7805 
7807 static bool ChangeGRFName(byte langid, const char *str)
7808 {
7809  AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7810  return true;
7811 }
7812 
7814 static bool ChangeGRFDescription(byte langid, const char *str)
7815 {
7816  AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7817  return true;
7818 }
7819 
7821 static bool ChangeGRFURL(byte langid, const char *str)
7822 {
7823  AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7824  return true;
7825 }
7826 
7828 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7829 {
7830  if (len != 1) {
7831  grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7832  buf->Skip(len);
7833  } else {
7834  _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7835  }
7836  return true;
7837 }
7838 
7840 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7841 {
7842  if (len != 1) {
7843  grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7844  buf->Skip(len);
7845  } else {
7846  char data = buf->ReadByte();
7847  GRFPalette pal = GRFP_GRF_UNSET;
7848  switch (data) {
7849  case '*':
7850  case 'A': pal = GRFP_GRF_ANY; break;
7851  case 'W': pal = GRFP_GRF_WINDOWS; break;
7852  case 'D': pal = GRFP_GRF_DOS; break;
7853  default:
7854  grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7855  break;
7856  }
7857  if (pal != GRFP_GRF_UNSET) {
7858  _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7859  _cur.grfconfig->palette |= pal;
7860  }
7861  }
7862  return true;
7863 }
7864 
7866 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7867 {
7868  if (len != 1) {
7869  grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7870  buf->Skip(len);
7871  } else {
7872  char data = buf->ReadByte();
7873  GRFPalette pal = GRFP_BLT_UNSET;
7874  switch (data) {
7875  case '8': pal = GRFP_BLT_UNSET; break;
7876  case '3': pal = GRFP_BLT_32BPP; break;
7877  default:
7878  grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7879  return true;
7880  }
7881  _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7882  _cur.grfconfig->palette |= pal;
7883  }
7884  return true;
7885 }
7886 
7888 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7889 {
7890  if (len != 4) {
7891  grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7892  buf->Skip(len);
7893  } else {
7894  /* Set min_loadable_version as well (default to minimal compatibility) */
7895  _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7896  }
7897  return true;
7898 }
7899 
7901 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7902 {
7903  if (len != 4) {
7904  grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7905  buf->Skip(len);
7906  } else {
7907  _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7908  if (_cur.grfconfig->version == 0) {
7909  grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7910  _cur.grfconfig->min_loadable_version = 0;
7911  }
7912  if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7913  grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7915  }
7916  }
7917  return true;
7918 }
7919 
7921 
7923 static bool ChangeGRFParamName(byte langid, const char *str)
7924 {
7925  AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7926  return true;
7927 }
7928 
7930 static bool ChangeGRFParamDescription(byte langid, const char *str)
7931 {
7932  AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7933  return true;
7934 }
7935 
7937 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7938 {
7939  if (len != 1) {
7940  grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7941  buf->Skip(len);
7942  } else {
7943  GRFParameterType type = (GRFParameterType)buf->ReadByte();
7944  if (type < PTYPE_END) {
7945  _cur_parameter->type = type;
7946  } else {
7947  grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7948  }
7949  }
7950  return true;
7951 }
7952 
7954 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7955 {
7956  if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7957  grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7958  buf->Skip(len);
7959  } else if (len != 8) {
7960  grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7961  buf->Skip(len);
7962  } else {
7963  uint32 min_value = buf->ReadDWord();
7964  uint32 max_value = buf->ReadDWord();
7965  if (min_value <= max_value) {
7966  _cur_parameter->min_value = min_value;
7967  _cur_parameter->max_value = max_value;
7968  } else {
7969  grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7970  }
7971  }
7972  return true;
7973 }
7974 
7976 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7977 {
7978  if (len < 1 || len > 3) {
7979  grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7980  buf->Skip(len);
7981  } else {
7982  byte param_nr = buf->ReadByte();
7983  if (param_nr >= lengthof(_cur.grfconfig->param)) {
7984  grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7985  buf->Skip(len - 1);
7986  } else {
7987  _cur_parameter->param_nr = param_nr;
7988  if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7989  if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7990  }
7991  }
7992 
7993  return true;
7994 }
7995 
7997 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7998 {
7999  if (len != 4) {
8000  grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
8001  buf->Skip(len);
8002  } else {
8003  _cur_parameter->def_value = buf->ReadDWord();
8004  }
8005  _cur.grfconfig->has_param_defaults = true;
8006  return true;
8007 }
8008 
8009 typedef bool (*DataHandler)(size_t, ByteReader *);
8010 typedef bool (*TextHandler)(byte, const char *str);
8011 typedef bool (*BranchHandler)(ByteReader *);
8012 
8023  id(0),
8024  type(0)
8025  {}
8026 
8032  AllowedSubtags(uint32 id, DataHandler handler) :
8033  id(id),
8034  type('B')
8035  {
8036  this->handler.data = handler;
8037  }
8038 
8044  AllowedSubtags(uint32 id, TextHandler handler) :
8045  id(id),
8046  type('T')
8047  {
8048  this->handler.text = handler;
8049  }
8050 
8056  AllowedSubtags(uint32 id, BranchHandler handler) :
8057  id(id),
8058  type('C')
8059  {
8060  this->handler.call_handler = true;
8061  this->handler.u.branch = handler;
8062  }
8063 
8069  AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
8070  id(id),
8071  type('C')
8072  {
8073  this->handler.call_handler = false;
8074  this->handler.u.subtags = subtags;
8075  }
8076 
8077  uint32 id;
8078  byte type;
8079  union {
8082  struct {
8083  union {
8086  } u;
8088  };
8089  } handler;
8090 };
8091 
8092 static bool SkipUnknownInfo(ByteReader *buf, byte type);
8093 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
8094 
8102 {
8103  byte type = buf->ReadByte();
8104  while (type != 0) {
8105  uint32 id = buf->ReadDWord();
8106  if (type != 'T' || id > _cur_parameter->max_value) {
8107  grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8108  if (!SkipUnknownInfo(buf, type)) return false;
8109  type = buf->ReadByte();
8110  continue;
8111  }
8112 
8113  byte langid = buf->ReadByte();
8114  const char *name_string = buf->ReadString();
8115 
8116  SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
8117  if (val_name != _cur_parameter->value_names.End()) {
8118  AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
8119  } else {
8120  GRFText *list = nullptr;
8121  AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
8122  _cur_parameter->value_names.Insert(id, list);
8123  }
8124 
8125  type = buf->ReadByte();
8126  }
8127  return true;
8128 }
8129 
8139  AllowedSubtags()
8140 };
8141 
8149 {
8150  byte type = buf->ReadByte();
8151  while (type != 0) {
8152  uint32 id = buf->ReadDWord();
8153  if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
8154  grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8155  if (!SkipUnknownInfo(buf, type)) return false;
8156  type = buf->ReadByte();
8157  continue;
8158  }
8159 
8160  if (id >= _cur.grfconfig->param_info.size()) {
8161  _cur.grfconfig->param_info.resize(id + 1);
8162  }
8163  if (_cur.grfconfig->param_info[id] == nullptr) {
8164  _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
8165  }
8166  _cur_parameter = _cur.grfconfig->param_info[id];
8167  /* Read all parameter-data and process each node. */
8168  if (!HandleNodes(buf, _tags_parameters)) return false;
8169  type = buf->ReadByte();
8170  }
8171  return true;
8172 }
8173 
8176  AllowedSubtags('NAME', ChangeGRFName),
8178  AllowedSubtags('URL_', ChangeGRFURL),
8185  AllowedSubtags()
8186 };
8187 
8190  AllowedSubtags('INFO', _tags_info),
8191  AllowedSubtags()
8192 };
8193 
8194 
8201 static bool SkipUnknownInfo(ByteReader *buf, byte type)
8202 {
8203  /* type and id are already read */
8204  switch (type) {
8205  case 'C': {
8206  byte new_type = buf->ReadByte();
8207  while (new_type != 0) {
8208  buf->ReadDWord(); // skip the id
8209  if (!SkipUnknownInfo(buf, new_type)) return false;
8210  new_type = buf->ReadByte();
8211  }
8212  break;
8213  }
8214 
8215  case 'T':
8216  buf->ReadByte(); // lang
8217  buf->ReadString(); // actual text
8218  break;
8219 
8220  case 'B': {
8221  uint16 size = buf->ReadWord();
8222  buf->Skip(size);
8223  break;
8224  }
8225 
8226  default:
8227  return false;
8228  }
8229 
8230  return true;
8231 }
8232 
8241 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
8242 {
8243  uint i = 0;
8244  AllowedSubtags *tag;
8245  while ((tag = &subtags[i++])->type != 0) {
8246  if (tag->id != BSWAP32(id) || tag->type != type) continue;
8247  switch (type) {
8248  default: NOT_REACHED();
8249 
8250  case 'T': {
8251  byte langid = buf->ReadByte();
8252  return tag->handler.text(langid, buf->ReadString());
8253  }
8254 
8255  case 'B': {
8256  size_t len = buf->ReadWord();
8257  if (buf->Remaining() < len) return false;
8258  return tag->handler.data(len, buf);
8259  }
8260 
8261  case 'C': {
8262  if (tag->handler.call_handler) {
8263  return tag->handler.u.branch(buf);
8264  }
8265  return HandleNodes(buf, tag->handler.u.subtags);
8266  }
8267  }
8268  }
8269  grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
8270  return SkipUnknownInfo(buf, type);
8271 }
8272 
8279 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
8280 {
8281  byte type = buf->ReadByte();
8282  while (type != 0) {
8283  uint32 id = buf->ReadDWord();
8284  if (!HandleNode(type, id, buf, subtags)) return false;
8285  type = buf->ReadByte();
8286  }
8287  return true;
8288 }
8289 
8294 static void StaticGRFInfo(ByteReader *buf)
8295 {
8296  /* <14> <type> <id> <text/data...> */
8297  HandleNodes(buf, _tags_root);
8298 }
8299 
8305 static void GRFUnsafe(ByteReader *buf)
8306 {
8307  SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
8308 
8309  /* Skip remainder of GRF */
8310  _cur.skip_sprites = -1;
8311 }
8312 
8313 
8316 {
8317  _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
8318  | (1 << 0x0D) // newairports
8319  | (1 << 0x0E) // largestations
8320  | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
8321  | (0 << 0x10) // loadtime
8322  | (1 << 0x12) // presignals
8323  | (1 << 0x13) // extpresignals
8324  | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
8325  | (1 << 0x1B) // multihead
8326  | (1 << 0x1D) // lowmemory
8327  | (1 << 0x1E); // generalfixes
8328 
8329  _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
8330  | (1 << 0x08) // mammothtrains
8331  | (1 << 0x09) // trainrefit
8332  | (0 << 0x0B) // subsidiaries
8333  | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
8334  | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
8335  | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
8336  | (1 << 0x14) // bridgespeedlimits
8337  | (1 << 0x16) // eternalgame
8338  | (1 << 0x17) // newtrains
8339  | (1 << 0x18) // newrvs
8340  | (1 << 0x19) // newships
8341  | (1 << 0x1A) // newplanes
8342  | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
8343  | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
8344 
8345  _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
8346  | (1 << 0x03) // semaphores
8347  | (1 << 0x0A) // newobjects
8348  | (0 << 0x0B) // enhancedgui
8349  | (0 << 0x0C) // newagerating
8350  | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
8351  | (1 << 0x0E) // fullloadany
8352  | (1 << 0x0F) // planespeed
8353  | (0 << 0x10) // moreindustriesperclimate - obsolete
8354  | (0 << 0x11) // moretoylandfeatures
8355  | (1 << 0x12) // newstations
8356  | (1 << 0x13) // tracktypecostdiff
8357  | (1 << 0x14) // manualconvert
8358  | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
8359  | (1 << 0x16) // canals
8360  | (1 << 0x17) // newstartyear
8361  | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
8362  | (1 << 0x19) // newhouses
8363  | (1 << 0x1A) // newbridges
8364  | (1 << 0x1B) // newtownnames
8365  | (1 << 0x1C) // moreanimation
8366  | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
8367  | (1 << 0x1E) // newshistory
8368  | (0 << 0x1F); // custombridgeheads
8369 
8370  _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
8371  | (1 << 0x01) // windowsnap
8372  | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
8373  | (1 << 0x03) // pathbasedsignalling
8374  | (0 << 0x04) // aichoosechance
8375  | (1 << 0x05) // resolutionwidth
8376  | (1 << 0x06) // resolutionheight
8377  | (1 << 0x07) // newindustries
8378  | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
8379  | (0 << 0x09) // townroadbranchprob
8380  | (0 << 0x0A) // tempsnowline
8381  | (1 << 0x0B) // newcargo
8382  | (1 << 0x0C) // enhancemultiplayer
8383  | (1 << 0x0D) // onewayroads
8384  | (1 << 0x0E) // irregularstations
8385  | (1 << 0x0F) // statistics
8386  | (1 << 0x10) // newsounds
8387  | (1 << 0x11) // autoreplace
8388  | (1 << 0x12) // autoslope
8389  | (0 << 0x13) // followvehicle
8390  | (1 << 0x14) // trams
8391  | (0 << 0x15) // enhancetunnels
8392  | (1 << 0x16) // shortrvs
8393  | (1 << 0x17) // articulatedrvs
8394  | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
8395  | (1 << 0x1E) // variablerunningcosts
8396  | (1 << 0x1F); // any switch is on
8397 
8398  _ttdpatch_flags[4] = (1 << 0x00); // larger persistent storage
8399 }
8400 
8402 static void ResetCustomStations()
8403 {
8404  for (GRFFile * const file : _grf_files) {
8405  StationSpec **&stations = file->stations;
8406  if (stations == nullptr) continue;
8407  for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
8408  if (stations[i] == nullptr) continue;
8409  StationSpec *statspec = stations[i];
8410 
8411  delete[] statspec->renderdata;
8412 
8413  /* Release platforms and layouts */
8414  if (!statspec->copied_layouts) {
8415  for (uint l = 0; l < statspec->lengths; l++) {
8416  for (uint p = 0; p < statspec->platforms[l]; p++) {
8417  free(statspec->layouts[l][p]);
8418  }
8419  free(statspec->layouts[l]);
8420  }
8421  free(statspec->layouts);
8422  free(statspec->platforms);
8423  }
8424 
8425  /* Release this station */
8426  free(statspec);
8427  }
8428 
8429  /* Free and reset the station data */
8430  free(stations);
8431  stations = nullptr;
8432  }
8433 }
8434 
8436 static void ResetCustomHouses()
8437 {
8438  for (GRFFile * const file : _grf_files) {
8439  HouseSpec **&housespec = file->housespec;
8440  if (housespec == nullptr) continue;
8441  for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8442  free(housespec[i]);
8443  }
8444 
8445  free(housespec);
8446  housespec = nullptr;
8447  }
8448 }
8449 
8451 static void ResetCustomAirports()
8452 {
8453  for (GRFFile * const file : _grf_files) {
8454  AirportSpec **aslist = file->airportspec;
8455  if (aslist != nullptr) {
8456  for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8457  AirportSpec *as = aslist[i];
8458 
8459  if (as != nullptr) {
8460  /* We need to remove the tiles layouts */
8461  for (int j = 0; j < as->num_table; j++) {
8462  /* remove the individual layouts */
8463  free(as->table[j]);
8464  }
8465  free(as->table);
8466  free(as->depot_table);
8467  free(as->rotation);
8468 
8469  free(as);
8470  }
8471  }
8472  free(aslist);
8473  file->airportspec = nullptr;
8474  }
8475 
8476  AirportTileSpec **&airporttilespec = file->airtspec;
8477  if (airporttilespec != nullptr) {
8478  for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8479  free(airporttilespec[i]);
8480  }
8481  free(airporttilespec);
8482  airporttilespec = nullptr;
8483  }
8484  }
8485 }
8486 
8489 {
8490  for (GRFFile * const file : _grf_files) {
8491  IndustrySpec **&industryspec = file->industryspec;
8492  IndustryTileSpec **&indtspec = file->indtspec;
8493 
8494  /* We are verifiying both tiles and industries specs loaded from the grf file
8495  * First, let's deal with industryspec */
8496  if (industryspec != nullptr) {
8497  for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8498  IndustrySpec *ind = industryspec[i];
8499  delete ind;
8500  }
8501 
8502  free(industryspec);
8503  industryspec = nullptr;
8504  }
8505 
8506  if (indtspec == nullptr) continue;
8507  for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8508  free(indtspec[i]);
8509  }
8510 
8511  free(indtspec);
8512  indtspec = nullptr;
8513  }
8514 }
8515 
8517 static void ResetCustomObjects()
8518 {
8519  for (GRFFile * const file : _grf_files) {
8520  ObjectSpec **&objectspec = file->objectspec;
8521  if (objectspec == nullptr) continue;
8522  for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8523  free(objectspec[i]);
8524  }
8525 
8526  free(objectspec);
8527  objectspec = nullptr;
8528  }
8529 }
8530 
8532 static void ResetNewGRF()
8533 {
8534  for (GRFFile * const file : _grf_files) {
8535  delete file;
8536  }
8537 
8538  _grf_files.clear();
8539  _cur.grffile = nullptr;
8540 }
8541 
8543 static void ResetNewGRFErrors()
8544 {
8545  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
8546  if (!HasBit(c->flags, GCF_COPY) && c->error != nullptr) {
8547  delete c->error;
8548  c->error = nullptr;
8549  }
8550  }
8551 }
8552 
8557 {
8558  CleanUpStrings();
8559  CleanUpGRFTownNames();
8560 
8561  /* Copy/reset original engine info data */
8562  SetupEngines();
8563 
8564  /* Copy/reset original bridge info data */
8565  ResetBridges();
8566 
8567  /* Reset rail type information */
8568  ResetRailTypes();
8569 
8570  /* Copy/reset original road type info data */
8571  ResetRoadTypes();
8572 
8573  /* Allocate temporary refit/cargo class data */
8574  _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8575 
8576  /* Fill rail type label temporary data for default trains */
8577  for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
8578  _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8579  }
8580 
8581  /* Reset GRM reservations */
8582  memset(&_grm_engines, 0, sizeof(_grm_engines));
8583  memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8584 
8585  /* Reset generic feature callback lists */
8587 
8588  /* Reset price base data */
8590 
8591  /* Reset the curencies array */
8592  ResetCurrencies();
8593 
8594  /* Reset the house array */
8596  ResetHouses();
8597 
8598  /* Reset the industries structures*/
8600  ResetIndustries();
8601 
8602  /* Reset the objects. */
8603  ObjectClass::Reset();
8605  ResetObjects();
8606 
8607  /* Reset station classes */
8608  StationClass::Reset();
8610 
8611  /* Reset airport-related structures */
8612  AirportClass::Reset();
8616 
8617  /* Reset canal sprite groups and flags */
8618  memset(_water_feature, 0, sizeof(_water_feature));
8619 
8620  /* Reset the snowline table. */
8621  ClearSnowLine();
8622 
8623  /* Reset NewGRF files */
8624  ResetNewGRF();
8625 
8626  /* Reset NewGRF errors. */
8628 
8629  /* Set up the default cargo types */
8631 
8632  /* Reset misc GRF features and train list display variables */
8633  _misc_grf_features = 0;
8634 
8635  _loaded_newgrf_features.has_2CC = false;
8636  _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8637  _loaded_newgrf_features.has_newhouses = false;
8638  _loaded_newgrf_features.has_newindustries = false;
8639  _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8640  _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NONE;
8641 
8642  /* Clear all GRF overrides */
8643  _grf_id_overrides.clear();
8644 
8645  InitializeSoundPool();
8646  _spritegroup_pool.CleanPool();
8647 }
8648 
8653 {
8654  /* Reset override managers */
8655  _engine_mngr.ResetToDefaultMapping();
8656  _house_mngr.ResetMapping();
8657  _industry_mngr.ResetMapping();
8658  _industile_mngr.ResetMapping();
8659  _airport_mngr.ResetMapping();
8660  _airporttile_mngr.ResetMapping();
8661 }
8662 
8668 {
8669  memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8670 
8671  for (CargoID c = 0; c < NUM_CARGO; c++) {
8672  const CargoSpec *cs = CargoSpec::Get(c);
8673  if (!cs->IsValid()) continue;
8674 
8675  if (_cur.grffile->cargo_list.size() == 0) {
8676  /* Default translation table, so just a straight mapping to bitnum */
8677  _cur.grffile->cargo_map[c] = cs->bitnum;
8678  } else {
8679  /* Check the translation table for this cargo's label */
8680  int idx = find_index(_cur.grffile->cargo_list, {cs->label});
8681  if (idx >= 0) _cur.grffile->cargo_map[c] = idx;
8682  }
8683  }
8684 }
8685 
8690 static void InitNewGRFFile(const GRFConfig *config)
8691 {
8692  GRFFile *newfile = GetFileByFilename(config->filename);
8693  if (newfile != nullptr) {
8694  /* We already loaded it once. */
8695  _cur.grffile = newfile;
8696  return;
8697  }
8698 
8699  newfile = new GRFFile(config);
8700  _grf_files.push_back(_cur.grffile = newfile);
8701 }
8702 
8708 {
8709  this->filename = stredup(config->filename);
8710  this->grfid = config->ident.grfid;
8711 
8712  /* Initialise local settings to defaults */
8713  this->traininfo_vehicle_pitch = 0;
8714  this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8715 
8716  /* Mark price_base_multipliers as 'not set' */
8717  for (Price i = PR_BEGIN; i < PR_END; i++) {
8718  this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8719  }
8720 
8721  /* Initialise rail type map with default rail types */
8722  memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8723  this->railtype_map[0] = RAILTYPE_RAIL;
8724  this->railtype_map[1] = RAILTYPE_ELECTRIC;
8725  this->railtype_map[2] = RAILTYPE_MONO;
8726  this->railtype_map[3] = RAILTYPE_MAGLEV;
8727 
8728  /* Initialise road type map with default road types */
8729  memset(this->roadtype_map, INVALID_ROADTYPE, sizeof(this->roadtype_map));
8730  this->roadtype_map[0] = ROADTYPE_ROAD;
8731 
8732  /* Initialise tram type map with default tram types */
8733  memset(this->tramtype_map, INVALID_ROADTYPE, sizeof(this->tramtype_map));
8734  this->tramtype_map[0] = ROADTYPE_TRAM;
8735 
8736  /* Copy the initial parameter list
8737  * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8738  assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8739 
8740  assert(config->num_params <= lengthof(config->param));
8741  this->param_end = config->num_params;
8742  if (this->param_end > 0) {
8743  MemCpyT(this->param, config->param, this->param_end);
8744  }
8745 }
8746 
8747 GRFFile::~GRFFile()
8748 {
8749  free(this->filename);
8750  delete[] this->language_map;
8751 }
8752 
8753 
8759  'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8760  'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8761  'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8762  'PLST', 'FZDR',
8763  0 };
8764 
8765 static const CargoLabel _default_refitmasks_road[] = {
8766  0 };
8767 
8768 static const CargoLabel _default_refitmasks_ships[] = {
8769  'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8770  'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8771  'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8772  'PLST', 'FZDR',
8773  0 };
8774 
8775 static const CargoLabel _default_refitmasks_aircraft[] = {
8776  'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8777  'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8778  0 };
8779 
8780 static const CargoLabel * const _default_refitmasks[] = {
8782  _default_refitmasks_road,
8783  _default_refitmasks_ships,
8784  _default_refitmasks_aircraft,
8785 };
8786 
8787 
8791 static void CalculateRefitMasks()
8792 {
8793  for (Engine *e : Engine::Iterate()) {
8794  EngineID engine = e->index;
8795  EngineInfo *ei = &e->info;
8796  bool only_defaultcargo;
8797 
8798  /* Did the newgrf specify any refitting? If not, use defaults. */
8799  if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8800  CargoTypes mask = 0;
8801  CargoTypes not_mask = 0;
8802  CargoTypes xor_mask = ei->refit_mask;
8803 
8804  /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8805  * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8806  only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8807 
8808  if (_gted[engine].cargo_allowed != 0) {
8809  /* Build up the list of cargo types from the set cargo classes. */
8810  const CargoSpec *cs;
8811  FOR_ALL_CARGOSPECS(cs) {
8812  if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8813  if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8814  }
8815  }
8816 
8817  ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8818 
8819  /* Apply explicit refit includes/excludes. */
8820  ei->refit_mask |= _gted[engine].ctt_include_mask;
8821  ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8822  } else {
8823  CargoTypes xor_mask = 0;
8824 
8825  /* Don't apply default refit mask to wagons nor engines with no capacity */
8826  if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8827  const CargoLabel *cl = _default_refitmasks[e->type];
8828  for (uint i = 0;; i++) {
8829  if (cl[i] == 0) break;
8830 
8831  CargoID cargo = GetCargoIDByLabel(cl[i]);
8832  if (cargo == CT_INVALID) continue;
8833 
8834  SetBit(xor_mask, cargo);
8835  }
8836  }
8837 
8838  ei->refit_mask = xor_mask & _cargo_mask;
8839 
8840  /* If the mask is zero, the vehicle shall only carry the default cargo */
8841  only_defaultcargo = (ei->refit_mask == 0);
8842  }
8843 
8844  /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8845  if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8846 
8847  /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8848  * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8849  if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8850  ei->cargo_type = CT_INVALID;
8851  }
8852 
8853  /* Check if this engine's cargo type is valid. If not, set to the first refittable
8854  * cargo type. Finally disable the vehicle, if there is still no cargo. */
8855  if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8856  /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8857  const uint8 *cargo_map_for_first_refittable = nullptr;
8858  {
8859  const GRFFile *file = _gted[engine].defaultcargo_grf;
8860  if (file == nullptr) file = e->GetGRF();
8861  if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) {
8862  cargo_map_for_first_refittable = file->cargo_map;
8863  }
8864  }
8865 
8866  if (cargo_map_for_first_refittable != nullptr) {
8867  /* Use first refittable cargo from cargo translation table */
8868  byte best_local_slot = 0xFF;
8869  CargoID cargo_type;
8870  FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8871  byte local_slot = cargo_map_for_first_refittable[cargo_type];
8872  if (local_slot < best_local_slot) {
8873  best_local_slot = local_slot;
8874  ei->cargo_type = cargo_type;
8875  }
8876  }
8877  }
8878 
8879  if (ei->cargo_type == CT_INVALID) {
8880  /* Use first refittable cargo slot */
8881  ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8882  }
8883  }
8884  if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8885 
8886  /* Clear refit_mask for not refittable ships */
8887  if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8888  ei->refit_mask = 0;
8889  }
8890  }
8891 }
8892 
8894 static void FinaliseCanals()
8895 {
8896  for (uint i = 0; i < CF_END; i++) {
8897  if (_water_feature[i].grffile != nullptr) {
8900  }
8901  }
8902 }
8903 
8905 static void FinaliseEngineArray()
8906 {
8907  for (Engine *e : Engine::Iterate()) {
8908  if (e->GetGRF() == nullptr) {
8909  const EngineIDMapping &eid = _engine_mngr[e->index];
8910  if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8911  e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8912  }
8913  }
8914 
8915  if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
8916 
8917  /* When the train does not set property 27 (misc flags), but it
8918  * is overridden by a NewGRF graphically we want to disable the
8919  * flipping possibility. */
8920  if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) {
8921  ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8922  }
8923 
8924  /* Skip wagons, there livery is defined via the engine */
8925  if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8926  LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, nullptr);
8927  SetBit(_loaded_newgrf_features.used_liveries, ls);
8928  /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8929 
8930  if (e->type == VEH_TRAIN) {
8931  SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8932  switch (ls) {
8933  case LS_STEAM:
8934  case LS_DIESEL:
8935  case LS_ELECTRIC:
8936  case LS_MONORAIL:
8937  case LS_MAGLEV:
8938  SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8939  break;
8940 
8941  case LS_DMU:
8942  case LS_EMU:
8943  SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8944  break;
8945 
8946  default: NOT_REACHED();
8947  }
8948  }
8949  }
8950  }
8951 }
8952 
8954 static void FinaliseCargoArray()
8955 {
8956  for (CargoID c = 0; c < NUM_CARGO; c++) {
8957  CargoSpec *cs = CargoSpec::Get(c);
8958  if (!cs->IsValid()) {
8959  cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8960  cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8961  cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8962  }
8963  }
8964 }
8965 
8977 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8978 {
8979  if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8980  (next1 == nullptr || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8981  ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8982  (next2 == nullptr || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8983  next3 == nullptr || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8984  hs->enabled = false;
8985  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);
8986  return false;
8987  }
8988 
8989  /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8990  * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8991  * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8992  if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8993  ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8994  hs->enabled = false;
8995  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);
8996  return false;
8997  }
8998 
8999  /* Substitute type is also used for override, and having an override with a different size causes crashes.
9000  * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
9001  if (filename != nullptr && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
9002  hs->enabled = false;
9003  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);
9004  return false;
9005  }
9006 
9007  /* Make sure that additional parts of multitile houses are not available. */
9008  if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
9009  hs->enabled = false;
9010  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);
9011  return false;
9012  }
9013 
9014  return true;
9015 }
9016 
9023 static void EnsureEarlyHouse(HouseZones bitmask)
9024 {
9025  Year min_year = MAX_YEAR;
9026 
9027  for (int i = 0; i < NUM_HOUSES; i++) {
9028  HouseSpec *hs = HouseSpec::Get(i);
9029  if (hs == nullptr || !hs->enabled) continue;
9030  if ((hs->building_availability & bitmask) != bitmask) continue;
9031  if (hs->min_year < min_year) min_year = hs->min_year;
9032  }
9033 
9034  if (min_year == 0) return;
9035 
9036  for (int i = 0; i < NUM_HOUSES; i++) {
9037  HouseSpec *hs = HouseSpec::Get(i);
9038  if (hs == nullptr || !hs->enabled) continue;
9039  if ((hs->building_availability & bitmask) != bitmask) continue;
9040  if (hs->min_year == min_year) hs->min_year = 0;
9041  }
9042 }
9043 
9050 static void FinaliseHouseArray()
9051 {
9052  /* If there are no houses with start dates before 1930, then all houses
9053  * with start dates of 1930 have them reset to 0. This is in order to be
9054  * compatible with TTDPatch, where if no houses have start dates before
9055  * 1930 and the date is before 1930, the game pretends that this is 1930.
9056  * If there have been any houses defined with start dates before 1930 then
9057  * the dates are left alone.
9058  * On the other hand, why 1930? Just 'fix' the houses with the lowest
9059  * minimum introduction date to 0.
9060  */
9061  for (GRFFile * const file : _grf_files) {
9062  HouseSpec **&housespec = file->housespec;
9063  if (housespec == nullptr) continue;
9064 
9065  for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
9066  HouseSpec *hs = housespec[i];
9067 
9068  if (hs == nullptr) continue;
9069 
9070  const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : nullptr);
9071  const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : nullptr);
9072  const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : nullptr);
9073 
9074  if (!IsHouseSpecValid(hs, next1, next2, next3, file->filename)) continue;
9075 
9076  _house_mngr.SetEntitySpec(hs);
9077  }
9078  }
9079 
9080  for (int i = 0; i < NUM_HOUSES; i++) {
9081  HouseSpec *hs = HouseSpec::Get(i);
9082  const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
9083  const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
9084  const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
9085 
9086  /* We need to check all houses again to we are sure that multitile houses
9087  * did get consecutive IDs and none of the parts are missing. */
9088  if (!IsHouseSpecValid(hs, next1, next2, next3, nullptr)) {
9089  /* GetHouseNorthPart checks 3 houses that are directly before
9090  * it in the house pool. If any of those houses have multi-tile
9091  * flags set it assumes it's part of a multitile house. Since
9092  * we can have invalid houses in the pool marked as disabled, we
9093  * don't want to have them influencing valid tiles. As such set
9094  * building_flags to zero here to make sure any house following
9095  * this one in the pool is properly handled as 1x1 house. */
9096  hs->building_flags = TILE_NO_FLAG;
9097  }
9098  }
9099 
9100  HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
9101  EnsureEarlyHouse(HZ_ZON1 | climate_mask);
9102  EnsureEarlyHouse(HZ_ZON2 | climate_mask);
9103  EnsureEarlyHouse(HZ_ZON3 | climate_mask);
9104  EnsureEarlyHouse(HZ_ZON4 | climate_mask);
9105  EnsureEarlyHouse(HZ_ZON5 | climate_mask);
9106 
9107  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
9113  }
9114 }
9115 
9122 {
9123  for (GRFFile * const file : _grf_files) {
9124  IndustrySpec **&industryspec = file->industryspec;
9125  IndustryTileSpec **&indtspec = file->indtspec;
9126  if (industryspec != nullptr) {
9127  for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
9128  IndustrySpec *indsp = industryspec[i];
9129 
9130  if (indsp != nullptr && indsp->enabled) {
9131  StringID strid;
9132  /* process the conversion of text at the end, so to be sure everything will be fine
9133  * and available. Check if it does not return undefind marker, which is a very good sign of a
9134  * substitute industry who has not changed the string been examined, thus using it as such */
9135  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
9136  if (strid != STR_UNDEFINED) indsp->name = strid;
9137 
9138  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
9139  if (strid != STR_UNDEFINED) indsp->closure_text = strid;
9140 
9141  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
9142  if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
9143 
9144  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
9145  if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
9146 
9147  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
9148  if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
9149 
9150  if (indsp->station_name != STR_NULL) {
9151  /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
9152  * station's name. Don't want to lose the value, therefore, do not process. */
9153  strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
9154  if (strid != STR_UNDEFINED) indsp->station_name = strid;
9155  }
9156 
9157  _industry_mngr.SetEntitySpec(indsp);
9158  _loaded_newgrf_features.has_newindustries = true;
9159  }
9160  }
9161  }
9162 
9163  if (indtspec != nullptr) {
9164  for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
9165  IndustryTileSpec *indtsp = indtspec[i];
9166  if (indtsp != nullptr) {
9167  _industile_mngr.SetEntitySpec(indtsp);
9168  }
9169  }
9170  }
9171  }
9172 
9173  for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
9174  IndustrySpec *indsp = &_industry_specs[j];
9175  if (indsp->enabled && indsp->grf_prop.grffile != nullptr) {
9176  for (uint i = 0; i < 3; i++) {
9177  indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
9178  }
9179  }
9180  if (!indsp->enabled) {
9181  indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9182  }
9183  }
9184 }
9185 
9192 {
9193  for (GRFFile * const file : _grf_files) {
9194  ObjectSpec **&objectspec = file->objectspec;
9195  if (objectspec != nullptr) {
9196  for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
9197  if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->enabled) {
9198  _object_mngr.SetEntitySpec(objectspec[i]);
9199  }
9200  }
9201  }
9202  }
9203 }
9204 
9211 {
9212  for (GRFFile * const file : _grf_files) {
9213  AirportSpec **&airportspec = file->airportspec;
9214  if (airportspec != nullptr) {
9215  for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
9216  if (airportspec[i] != nullptr && airportspec[i]->enabled) {
9217  _airport_mngr.SetEntitySpec(airportspec[i]);
9218  }
9219  }
9220  }
9221 
9222  AirportTileSpec **&airporttilespec = file->airtspec;
9223  if (airporttilespec != nullptr) {
9224  for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
9225  if (airporttilespec[i] != nullptr && airporttilespec[i]->enabled) {
9226  _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9227  }
9228  }
9229  }
9230  }
9231 }
9232 
9233 /* Here we perform initial decoding of some special sprites (as are they
9234  * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
9235  * partial implementation yet).
9236  * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
9237  * a crafted invalid GRF file. We should tell that to the user somehow, or
9238  * better make this more robust in the future. */
9239 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
9240 {
9241  /* XXX: There is a difference between staged loading in TTDPatch and
9242  * here. In TTDPatch, for some reason actions 1 and 2 are carried out
9243  * during stage 1, whilst action 3 is carried out during stage 2 (to
9244  * "resolve" cargo IDs... wtf). This is a little problem, because cargo
9245  * IDs are valid only within a given set (action 1) block, and may be
9246  * overwritten after action 3 associates them. But overwriting happens
9247  * in an earlier stage than associating, so... We just process actions
9248  * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
9249  * --pasky
9250  * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
9251  * is not in memory and scanning the file every time would be too expensive.
9252  * In other stages we skip action 0x10 since it's already dealt with. */
9253  static const SpecialSpriteHandler handlers[][GLS_END] = {
9254  /* 0x00 */ { nullptr, SafeChangeInfo, nullptr, nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9255  /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9256  /* 0x02 */ { nullptr, nullptr, nullptr, nullptr, nullptr, NewSpriteGroup, },
9257  /* 0x03 */ { nullptr, GRFUnsafe, nullptr, nullptr, nullptr, FeatureMapSpriteGroup, },
9258  /* 0x04 */ { nullptr, nullptr, nullptr, nullptr, nullptr, FeatureNewName, },
9259  /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9260  /* 0x06 */ { nullptr, nullptr, nullptr, CfgApply, CfgApply, CfgApply, },
9261  /* 0x07 */ { nullptr, nullptr, nullptr, nullptr, SkipIf, SkipIf, },
9262  /* 0x08 */ { ScanInfo, nullptr, nullptr, GRFInfo, GRFInfo, GRFInfo, },
9263  /* 0x09 */ { nullptr, nullptr, nullptr, SkipIf, SkipIf, SkipIf, },
9264  /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9265  /* 0x0B */ { nullptr, nullptr, nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9266  /* 0x0C */ { nullptr, nullptr, nullptr, GRFComment, nullptr, GRFComment, },
9267  /* 0x0D */ { nullptr, SafeParamSet, nullptr, ParamSet, ParamSet, ParamSet, },
9268  /* 0x0E */ { nullptr, SafeGRFInhibit, nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9269  /* 0x0F */ { nullptr, GRFUnsafe, nullptr, FeatureTownName, nullptr, nullptr, },
9270  /* 0x10 */ { nullptr, nullptr, DefineGotoLabel, nullptr, nullptr, nullptr, },
9271  /* 0x11 */ { SkipAct11, GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9273  /* 0x13 */ { nullptr, nullptr, nullptr, nullptr, nullptr, TranslateGRFStrings, },
9274  /* 0x14 */ { StaticGRFInfo, nullptr, nullptr, nullptr, nullptr, nullptr, },
9275  };
9276 
9277  GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
9278 
9279  GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9280  if (it == _grf_line_to_action6_sprite_override.end()) {
9281  /* No preloaded sprite to work with; read the
9282  * pseudo sprite content. */
9283  FioReadBlock(buf, num);
9284  } else {
9285  /* Use the preloaded sprite data. */
9286  buf = _grf_line_to_action6_sprite_override[location];
9287  grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
9288 
9289  /* Skip the real (original) content of this action. */
9290  FioSeekTo(num, SEEK_CUR);
9291  }
9292 
9293  ByteReader br(buf, buf + num);
9294  ByteReader *bufp = &br;
9295 
9296  try {
9297  byte action = bufp->ReadByte();
9298 
9299  if (action == 0xFF) {
9300  grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
9301  } else if (action == 0xFE) {
9302  grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
9303  } else if (action >= lengthof(handlers)) {
9304  grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9305  } else if (handlers[action][stage] == nullptr) {
9306  grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9307  } else {
9308  grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9309  handlers[action][stage](bufp);
9310  }
9311  } catch (...) {
9312  grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9313  DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
9314  }
9315 }
9316 
9317 
9319 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9320 
9326 {
9327  size_t pos = FioGetPos();
9328 
9329  if (FioReadWord() == 0) {
9330  /* Check for GRF container version 2, which is identified by the bytes
9331  * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
9332  for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
9333  if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
9334  }
9335 
9336  return 2;
9337  }
9338 
9339  /* Container version 1 has no header, rewind to start. */
9340  FioSeekTo(pos, SEEK_SET);
9341  return 1;
9342 }
9343 
9351 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
9352 {
9353  const char *filename = config->filename;
9354 
9355  /* A .grf file is activated only if it was active when the game was
9356  * started. If a game is loaded, only its active .grfs will be
9357  * reactivated, unless "loadallgraphics on" is used. A .grf file is
9358  * considered active if its action 8 has been processed, i.e. its
9359  * action 8 hasn't been skipped using an action 7.
9360  *
9361  * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
9362  * carried out. All others are ignored, because they only need to be
9363  * processed once at initialization. */
9364  if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9365  _cur.grffile = GetFileByFilename(filename);
9366  if (_cur.grffile == nullptr) usererror("File '%s' lost in cache.\n", filename);
9367  if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
9368  if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
9369  }
9370 
9371  if (file_index >= MAX_FILE_SLOTS) {
9372  DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
9373  config->status = GCS_DISABLED;
9374  config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9375  return;
9376  }
9377 
9378  FioOpenFile(file_index, filename, subdir);
9379  _cur.file_index = file_index; // XXX
9380  _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
9381 
9382  _cur.grfconfig = config;
9383 
9384  DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
9385 
9387  if (_cur.grf_container_ver == 0) {
9388  DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9389  return;
9390  }
9391 
9392  if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9393  /* We need the sprite offsets in the init stage for NewGRF sounds
9394  * and in the activation stage for real sprites. */
9396  } else {
9397  /* Skip sprite section offset if present. */
9398  if (_cur.grf_container_ver >= 2) FioReadDword();
9399  }
9400 
9401  if (_cur.grf_container_ver >= 2) {
9402  /* Read compression value. */
9403  byte compression = FioReadByte();
9404  if (compression != 0) {
9405  DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
9406  return;
9407  }
9408  }
9409 
9410  /* Skip the first sprite; we don't care about how many sprites this
9411  * does contain; newest TTDPatches and George's longvehicles don't
9412  * neither, apparently. */
9413  uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
9414  if (num == 4 && FioReadByte() == 0xFF) {
9415  FioReadDword();
9416  } else {
9417  DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9418  return;
9419  }
9420 
9421  _cur.ClearDataForNextFile();
9422 
9424 
9425  while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
9426  byte type = FioReadByte();
9427  _cur.nfo_line++;
9428 
9429  if (type == 0xFF) {
9430  if (_cur.skip_sprites == 0) {
9431  DecodeSpecialSprite(buf.Allocate(num), num, stage);
9432 
9433  /* Stop all processing if we are to skip the remaining sprites */
9434  if (_cur.skip_sprites == -1) break;
9435 
9436  continue;
9437  } else {
9438  FioSkipBytes(num);
9439  }
9440  } else {
9441  if (_cur.skip_sprites == 0) {
9442  grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
9443  DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9444  break;
9445  }
9446 
9447  if (_cur.grf_container_ver >= 2 && type == 0xFD) {
9448  /* Reference to data section. Container version >= 2 only. */
9449  FioSkipBytes(num);
9450  } else {
9451  FioSkipBytes(7);
9452  SkipSpriteData(type, num - 8);
9453  }
9454  }
9455 
9456  if (_cur.skip_sprites > 0) _cur.skip_sprites--;
9457  }
9458 }
9459 
9467 static void ActivateOldShore()
9468 {
9469  /* Use default graphics, if no shore sprites were loaded.
9470  * Should not happen, as the base set's extra grf should include some. */
9471  if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
9472 
9473  if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
9474  DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
9475  DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
9476  DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
9477  DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
9478  DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
9479  DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
9480  DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
9481  DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
9482  }
9483 
9484  if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
9485  DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
9486  DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
9487  DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
9488  DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
9489  DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
9490  DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
9491  DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
9492  DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
9493 
9494  /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9495  * If they would be used somewhen, then these grass tiles will most like not look as needed */
9496  DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
9497  DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
9498  }
9499 }
9500 
9505 {
9506  if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK) {
9507  DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
9508  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9509  DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
9510  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9511  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9512  DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9513  }
9514 }
9515 
9520 {
9521  extern const PriceBaseSpec _price_base_specs[];
9523  static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9524 
9525  /* Evaluate grf overrides */
9526  int num_grfs = (uint)_grf_files.size();
9527  int *grf_overrides = AllocaM(int, num_grfs);
9528  for (int i = 0; i < num_grfs; i++) {
9529  grf_overrides[i] = -1;
9530 
9531  GRFFile *source = _grf_files[i];
9532  uint32 override = _grf_id_overrides[source->grfid];
9533  if (override == 0) continue;
9534 
9535  GRFFile *dest = GetFileByGRFID(override);
9536  if (dest == nullptr) continue;
9537 
9538  grf_overrides[i] = find_index(_grf_files, dest);
9539  assert(grf_overrides[i] >= 0);
9540  }
9541 
9542  /* Override features and price base multipliers of earlier loaded grfs */
9543  for (int i = 0; i < num_grfs; i++) {
9544  if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9545  GRFFile *source = _grf_files[i];
9546  GRFFile *dest = _grf_files[grf_overrides[i]];
9547 
9548  uint32 features = (source->grf_features | dest->grf_features) & override_features;
9549  source->grf_features |= features;
9550  dest->grf_features |= features;
9551 
9552  for (Price p = PR_BEGIN; p < PR_END; p++) {
9553  /* No price defined -> nothing to do */
9554  if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9555  DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9556  dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9557  }
9558  }
9559 
9560  /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9561  for (int i = num_grfs - 1; i >= 0; i--) {
9562  if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9563  GRFFile *source = _grf_files[i];
9564  GRFFile *dest = _grf_files[grf_overrides[i]];
9565 
9566  uint32 features = (source->grf_features | dest->grf_features) & override_features;
9567  source->grf_features |= features;
9568  dest->grf_features |= features;
9569 
9570  for (Price p = PR_BEGIN; p < PR_END; p++) {
9571  /* Already a price defined -> nothing to do */
9572  if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9573  DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9574  dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9575  }
9576  }
9577 
9578  /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9579  for (int i = 0; i < num_grfs; i++) {
9580  if (grf_overrides[i] < 0) continue;
9581  GRFFile *source = _grf_files[i];
9582  GRFFile *dest = _grf_files[grf_overrides[i]];
9583 
9584  uint32 features = (source->grf_features | dest->grf_features) & override_features;
9585  source->grf_features |= features;
9586  dest->grf_features |= features;
9587 
9588  for (Price p = PR_BEGIN; p < PR_END; p++) {
9589  if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9590  if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9591  DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9592  }
9593  source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9594  }
9595  }
9596 
9597  /* Apply fallback prices for grf version < 8 */
9598  for (GRFFile * const file : _grf_files) {
9599  if (file->grf_version >= 8) continue;
9600  PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9601  for (Price p = PR_BEGIN; p < PR_END; p++) {
9602  Price fallback_price = _price_base_specs[p].fallback_price;
9603  if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9604  /* No price multiplier has been set.
9605  * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9606  price_base_multipliers[p] = price_base_multipliers[fallback_price];
9607  }
9608  }
9609  }
9610 
9611  /* Decide local/global scope of price base multipliers */
9612  for (GRFFile * const file : _grf_files) {
9613  PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9614  for (Price p = PR_BEGIN; p < PR_END; p++) {
9615  if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9616  /* No multiplier was set; set it to a neutral value */
9617  price_base_multipliers[p] = 0;
9618  } else {
9619  if (!HasBit(file->grf_features, _price_base_specs[p].grf_feature)) {
9620  /* The grf does not define any objects of the feature,
9621  * so it must be a difficulty setting. Apply it globally */
9622  DEBUG(grf, 3, "'%s' sets global price base multiplier %d", file->filename, p);
9623  SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9624  price_base_multipliers[p] = 0;
9625  } else {
9626  DEBUG(grf, 3, "'%s' sets local price base multiplier %d", file->filename, p);
9627  }
9628  }
9629  }
9630  }
9631 }
9632 
9633 extern void InitGRFTownGeneratorNames();
9634 
9636 static void AfterLoadGRFs()
9637 {
9638  for (StringIDMapping &it : _string_to_grf_mapping) {
9639  *it.target = MapGRFStringID(it.grfid, it.source);
9640  }
9641  _string_to_grf_mapping.clear();
9642 
9643  /* Free the action 6 override sprites. */
9644  for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9645  free((*it).second);
9646  }
9647  _grf_line_to_action6_sprite_override.clear();
9648 
9649  /* Polish cargoes */
9651 
9652  /* Pre-calculate all refit masks after loading GRF files. */
9654 
9655  /* Polish engines */
9657 
9658  /* Set the actually used Canal properties */
9659  FinaliseCanals();
9660 
9661  /* Add all new houses to the house array. */
9663 
9664  /* Add all new industries to the industry array. */
9666 
9667  /* Add all new objects to the object array. */
9669 
9671 
9672  /* Sort the list of industry types. */
9674 
9675  /* Create dynamic list of industry legends for smallmap_gui.cpp */
9677 
9678  /* Build the routemap legend, based on the available cargos */
9680 
9681  /* Add all new airports to the airports array. */
9683  BindAirportSpecs();
9684 
9685  /* Update the townname generators list */
9687 
9688  /* Run all queued vehicle list order changes */
9690 
9691  /* Load old shore sprites in new position, if they were replaced by ActionA */
9692  ActivateOldShore();
9693 
9694  /* Load old tram depot sprites in new position, if no new ones are present */
9696 
9697  /* Set up custom rail types */
9698  InitRailTypes();
9699  InitRoadTypes();
9700 
9701  for (Engine *e : Engine::IterateType(VEH_ROAD)) {
9702  if (_gted[e->index].rv_max_speed != 0) {
9703  /* Set RV maximum speed from the mph/0.8 unit value */
9704  e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9705  }
9706 
9707  RoadTramType rtt = HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? RTT_TRAM : RTT_ROAD;
9708 
9709  const GRFFile *file = e->GetGRF();
9710  if (file == nullptr || _gted[e->index].roadtramtype == 0) {
9711  e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
9712  continue;
9713  }
9714 
9715  /* Remove +1 offset. */
9716  _gted[e->index].roadtramtype--;
9717 
9718  const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
9719  if (_gted[e->index].roadtramtype < list->size())
9720  {
9721  RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
9722  RoadType rt = GetRoadTypeByLabel(rtl);
9723  if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
9724  e->u.road.roadtype = rt;
9725  continue;
9726  }
9727  }
9728 
9729  /* Road type is not available, so disable this engine */
9730  e->info.climates = 0;
9731  }
9732 
9733  for (Engine *e : Engine::IterateType(VEH_TRAIN)) {
9734  RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9735  if (railtype == INVALID_RAILTYPE) {
9736  /* Rail type is not available, so disable this engine */
9737  e->info.climates = 0;
9738  } else {
9739  e->u.rail.railtype = railtype;
9740  }
9741  }
9742 
9744 
9746 
9747  /* Deallocate temporary loading data */
9748  free(_gted);
9749  _grm_sprites.clear();
9750 }
9751 
9758 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9759 {
9760  /* In case of networking we need to "sync" the start values
9761  * so all NewGRFs are loaded equally. For this we use the
9762  * start date of the game and we set the counters, etc. to
9763  * 0 so they're the same too. */
9764  Date date = _date;
9765  Year year = _cur_year;
9766  DateFract date_fract = _date_fract;
9767  uint16 tick_counter = _tick_counter;
9768  byte display_opt = _display_opt;
9769 
9770  if (_networking) {
9772  _date = ConvertYMDToDate(_cur_year, 0, 1);
9773  _date_fract = 0;
9774  _tick_counter = 0;
9775  _display_opt = 0;
9776  }
9777 
9779 
9780  ResetNewGRFData();
9781 
9782  /*
9783  * Reset the status of all files, so we can 'retry' to load them.
9784  * This is needed when one for example rearranges the NewGRFs in-game
9785  * and a previously disabled NewGRF becomes usable. If it would not
9786  * be reset, the NewGRF would remain disabled even though it should
9787  * have been enabled.
9788  */
9789  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9790  if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9791  }
9792 
9793  _cur.spriteid = load_index;
9794 
9795  /* Load newgrf sprites
9796  * in each loading stage, (try to) open each file specified in the config
9797  * and load information from it. */
9798  for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9799  /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9800  * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9801  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9802  if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9803  }
9804 
9805  if (stage == GLS_RESERVE) {
9806  static const uint32 overrides[][2] = {
9807  { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9808  { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9809  { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9810  };
9811  for (size_t i = 0; i < lengthof(overrides); i++) {
9812  SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9813  }
9814  }
9815 
9816  uint slot = file_index;
9817  uint num_non_static = 0;
9818 
9819  _cur.stage = stage;
9820  for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9821  if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9822  if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9823 
9824  Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9825  if (!FioCheckFileExists(c->filename, subdir)) {
9826  DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9827  c->status = GCS_NOT_FOUND;
9828  continue;
9829  }
9830 
9831  if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9832 
9833  if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9834  if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9835  DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9836  c->status = GCS_DISABLED;
9837  c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9838  continue;
9839  }
9840  num_non_static++;
9841  }
9842  LoadNewGRFFile(c, slot++, stage, subdir);
9843  if (stage == GLS_RESERVE) {
9844  SetBit(c->flags, GCF_RESERVED);
9845  } else if (stage == GLS_ACTIVATION) {
9846  ClrBit(c->flags, GCF_RESERVED);
9847  assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9850  DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9851  } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9852  /* We're not going to activate this, so free whatever data we allocated */
9854  }
9855  }
9856  }
9857 
9858  /* Pseudo sprite processing is finished; free temporary stuff */
9859  _cur.ClearDataForNextFile();
9860 
9861  /* Call any functions that should be run after GRFs have been loaded. */
9862  AfterLoadGRFs();
9863 
9864  /* Now revert back to the original situation */
9865  _cur_year = year;
9866  _date = date;
9867  _date_fract = date_fract;
9868  _tick_counter = tick_counter;
9869  _display_opt = display_opt;
9870 }
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 accepted cargoes.
Definition: industrytype.h:120
void ResetBridges()
Reset the data been eventually changed by the grf loaded.
bool disable_elrails
when true, the elrails are disabled
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition: house.h:111
const struct GRFFile * grffile
NewGRF where #group belongs to.
Definition: cargotype.h:79
Information about a ship vehicle.
Definition: engine_type.h:65
TextHandler text
Callback function for a text node, only valid if type == &#39;T&#39;.
Definition: newgrf.cpp:8081
Functions related to OTTD&#39;s strings.
Monorail.
Definition: rail_type.h:31
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition: newgrf.h:132
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition: road.cpp:243
VehicleSettings vehicle
options for vehicles
static void FinaliseEngineArray()
Check for invalid engines.
Definition: newgrf.cpp:8905
TTDPAirportType ttd_airport_type
ttdpatch airport type (Small/Large/Helipad/Oilrig)
void ResetRoadTypes()
Reset all road type information to its default values.
Definition: road_cmd.cpp:62
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:18
void ClearDataForNextFile()
Clear temporary data before processing the next file in the current loading stage.
Definition: newgrf.cpp:116
Class to read from a NewGRF file.
Definition: newgrf.cpp:214
static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
Ignore an industry tile property.
Definition: newgrf.cpp:3111
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition: sprites.h:216
const SpriteGroup * group[RTSG_END]
Sprite groups for resolving sprites.
Definition: rail.h:278
uint8 max_heightlevel
maximum allowed heightlevel
RailTypeFlags
Railtype flags.
Definition: rail.h:25
byte probability
Relative probability of appearing (16 is the standard value)
Definition: house.h:117
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:80
GRF was disabled due to error.
Definition: newgrf.cpp:989
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
SmallMap< uint32, struct GRFText * > value_names
Names for each value.
const SpriteGroup ** groups
Take the group with appropriate index:
bool _networking
are we in networking mode?
Definition: network.cpp:52
std::vector< Mapping > case_map
Mapping of NewGRF and OpenTTD IDs for cases.
Definition: newgrf_text.h:59
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:302
void SetEntitySpec(ObjectSpec *spec)
Method to install the new object data in its proper slot The slot assignment is internal of this meth...
CargoID cargo_output[INDUSTRY_NUM_OUTPUTS]
Which output cargoes to add to (only cb version 2)
Functions for NewGRF engines.
uint8 GetCaseIndex(const char *case_str) const
Get the index for the given case.
Definition: language.h:80
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:139
ObjectFlags
Various object behaviours.
Definition: newgrf_object.h:24
Object wants 2CC colour mapping.
Definition: newgrf_object.h:34
void SortIndustryTypes()
Initialize the list of sorted industry types.
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:304
Year avail_year
the year where it becomes available
Definition: bridge.h:42
static void ResetCustomObjects()
Reset and clear all NewObjects.
Definition: newgrf.cpp:8517
const GRFFile * grffile[RTSG_END]
NewGRF providing the Action3 for the railtype.
Definition: rail.h:273
ObjectFlags flags
Flags/settings related to the object.
Definition: newgrf_object.h:70
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition: newgrf.cpp:9121
struct LanguageMap * language_map
Mappings related to the languages.
Definition: newgrf.h:140
Add signed offset to child sprite Y positions from register TileLayoutRegisters::delta.child[1].
int16 subtract_input[INDUSTRY_NUM_INPUTS]
Take this much of the input cargo (can be negative, is indirect in cb version 1+) ...
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition: newgrf.cpp:9636
static const SpriteID SPR_TRACKS_FOR_SLOPES_BASE
Sprites for &#39;highlighting&#39; tracks on sloped land.
Definition: sprites.h:190
uint32 param_value[2]
Values of GRF parameters to show for message and custom_message.
uint8 weight
Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
Definition: cargotype.h:60
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition: cargotype.cpp:29
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.
Electrified depot graphics without tram track were loaded.
Definition: newgrf.h:171
void AlterVehicleListOrder(EngineID engine, uint target)
Record a vehicle ListOrderChange.
static void ResetCustomAirports()
Reset and clear all NewGRF airports.
Definition: newgrf.cpp:8451
AllowedSubtags(uint32 id, DataHandler handler)
Create a binary leaf node.
Definition: newgrf.cpp:8032
LiveryScheme
List of different livery schemes.
Definition: livery.h:20
The parameter allows a range of numbers, each of which can have a special name.
GRFConfig * _grfconfig
First item in list of current GRF set up.
byte landscape
the landscape we&#39;re currently in
void ResetCurrencies(bool preserve_custom)
Will fill _currency_specs array with default values from origin_currency_specs Called only from newgr...
Definition: currency.cpp:154
byte size_y
size of airport in y direction
Aircraft range.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:108
RoadType tramtype_map[ROADTYPE_END]
, Roadtype translation table (tram)
Definition: newgrf.h:136
byte map_colour
colour used for the small map
Definition: industrytype.h:125
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition: newgrf.cpp:8532
int plural_form
The plural form used for this language.
Definition: newgrf_text.h:60
static AirportSpec * GetWithoutOverride(byte type)
Retrieve airport spec for the given airport.
uint16 triggers
The triggers that trigger animation.
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition: rail.h:174
GRF file is processed up to GLS_INIT.
Definition: newgrf_config.h:27
uint32 grfid
The GRF ID of the file the entity belongs to.
Definition: engine_base.h:164
byte newgrf_id
NewGRF&#39;s internal ID for a case/gender.
Definition: newgrf_text.h:48
Action5BlockType block_type
How is this Action5 type processed?
Definition: newgrf.cpp:6095
byte _display_opt
What do we want to draw/do?
CargoTypes watched_cargoes
Cargo types watched for acceptance.
Definition: house.h:123
EconomySettings economy
settings to change the economy
byte map_colour
Colour on mini-map.
Definition: road.h:154
uint8 build_cost_multiplier
Build cost multiplier per tile.
Definition: newgrf_object.h:66
bool is_freight
Cargo type is considered to be freight (affects train freight multiplier).
Definition: cargotype.h:65
uint32 nfo_line
Currently processed pseudo sprite number in the GRF.
Definition: newgrf.cpp:106
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the &#39;_date == 0&#39; till &#39;ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)&#39;.
Definition: date_type.h:80
void Allocate(uint num_sprites)
Allocate a spritelayout for num_sprites building sprites.
TileLayoutFlags
Flags to enable register usage in sprite layouts.
byte curve_speed
Multiplier for curve maximum speed advantage.
Definition: rail.h:203
uint16 max_sprites
If the Action5 contains more sprites, only the first max_sprites sprites will be used.
Definition: newgrf.cpp:6098
Train vehicle type.
Definition: vehicle_type.h:24
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition: newgrf.cpp:9191
Max. speed: 1 unit = 1/1.6 mph = 1 km-ish/h.
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:329
const GRFFile * grffile
NewGRF where &#39;group&#39; belongs to.
Definition: newgrf_canal.h:24
AllowedSubtags(uint32 id, AllowedSubtags *subtags)
Create a branch node with a list of sub-nodes.
Definition: newgrf.cpp:8069
static const SpriteID SPR_ONEWAY_BASE
One way road sprites.
Definition: sprites.h:285
byte ocean_speed_frac
Fraction of maximum speed for ocean tiles.
Definition: engine_type.h:74
Functions related to dates.
Power in hp (if dualheaded: sum of both vehicles)
Day day
Day (1..31)
Definition: date_type.h:106
CargoID GetCargoIDByLabel(CargoLabel cl)
Get the cargo ID by cargo label.
Definition: cargotype.cpp:86
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:2595
static const Year ORIGINAL_MAX_YEAR
The maximum year of the original TTD.
Definition: date_type.h:53
CurrencySpec _currency_specs[CURRENCY_END]
Array of currencies used by the system.
Definition: currency.cpp:71
Functions for NewGRF industries.
Functions to handle different currencies.
const uint8 _engine_offsets[4]
Offset of the first engine of each vehicle type in original engine data.
Definition: engine.cpp:58
Basic road type.
Definition: road_type.h:24
SpriteID sprite
SpriteID of the first sprite of the set.
Definition: newgrf.cpp:90
GRFParameterType type
The type of this parameter.
West.
void UpdateRefittability(bool non_empty)
Update the summary refittability on setting a refittability property.
Definition: newgrf.cpp:328
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
static uint MapLogX()
Logarithm of the map size along the X side.
Definition: map_func.h:51
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:110
PalSpriteID ** sprite_table
table of sprites for drawing the bridge
Definition: bridge.h:51
static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for ships.
Definition: newgrf.cpp:1535
RailTypeFlags flags
Bit mask of rail type flags.
Definition: rail.h:208
const byte _grf_cont_v2_sig[8]
Signature of a container version 2 GRF.
static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;MASK&#39; to set the parameter and bits to use...
Definition: newgrf.cpp:7976
static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
Ignore properties for objects.
Definition: newgrf.cpp:3982
Free the dynamically allocated sounds table.
Definition: industrytype.h:24
Functions related to debugging.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
uint32 grfid
Source NewGRF.
Definition: newgrf.cpp:463
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.
GRFConfig * grfconfig
Config of the currently processed GRF file.
Definition: newgrf.cpp:105
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:600
char * text
If probability bit 7 is clear.
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
Definition: industry_type.h:34
RoadTypeFlags flags
Bit mask of road type flags.
Definition: road.h:124
Add signed offset to bounding box X and Y positions from register TileLayoutRegisters::delta.parent[0..1].
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
static void ImportGRFSound(SoundEntry *sound)
Process a sound import from another GRF file.
Definition: newgrf.cpp:7546
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition: newgrf.cpp:8894
GRFPalette
Information that can/has to be stored about a GRF&#39;s palette.
Definition: newgrf_config.h:58
byte flags
bit 0 set: disable drawing of far pillars.
Definition: bridge.h:52
Ship vehicle type.
Definition: vehicle_type.h:26
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition: road.h:101
char * TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const char *str, int *olen, StringControlCode byte80)
Translate TTDPatch string codes into something OpenTTD can handle (better).
uint16 FioReadWord()
Read a word (16 bits) from the file (in low endian format).
Definition: fileio.cpp:164
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...
GRFFilePropsBase< NUM_CARGO+2 > grf_prop
Properties related the the grf file.
Definition: engine_base.h:58
GRFFilePropsBase< 2 > grf_prop
Properties related the the grf file.
Definition: newgrf_object.h:60
Maximal number of cargo types in a game.
Definition: cargo_type.h:64
Rail vehicle can be flipped in the depot.
Definition: engine_type.h:157
The NewGRF prefers a 32 bpp blitter.
Definition: newgrf_config.h:76
static std::vector< GRFFile * > _grf_files
List of all loaded GRF files.
Definition: newgrf.cpp:67
byte cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition: house.h:107
GRFFile(const struct GRFConfig *config)
Constructor for GRFFile.
Definition: newgrf.cpp:8707
static const uint ORIGINAL_SAMPLE_COUNT
The number of sounds in the original sample.cat.
Definition: sound_type.h:116
Flag for invalid railtype.
Definition: rail_type.h:34
RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
Allocate a new road type label.
Definition: road_cmd.cpp:138
GRF file has been initialised.
Definition: newgrf_config.h:37
Used for iterations.
Definition: road_type.h:26
Specification of a cargo type.
Definition: cargotype.h:55
std::vector< Pair >::const_iterator Find(const T &key) const
Finds given key in this map.
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
Station specification.
Road specific functions.
static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;LIMI&#39; to set the min/max value of a parameter...
Definition: newgrf.cpp:7954
CanalFeature
List of different canal &#39;features&#39;.
Definition: newgrf.h:25
static void GRFUnsafe(ByteReader *buf)
Set the current NewGRF as unsafe for static use.
Definition: newgrf.cpp:8305
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
uint32 def_value
Default value of this parameter.
Yearly runningcost (if dualheaded: sum of both vehicles)
IndustryLifeType life_type
This is also known as Industry production flag, in newgrf specs.
Definition: industrytype.h:122
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:123
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:60
bool IsSnowLineSet()
Has a snow line table already been loaded.
Definition: landscape.cpp:615
GRFStatus status
NOSAVE: GRFStatus, enum.
uint16 max_palette_offset
Maximum offset to add to the palette. (limited by size of the spriteset)
Functions related to vehicles.
struct GRFText * text
The actual text.
Resolve sprite with a specific value in variable 10.
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition: newgrf.cpp:8667
const HangarTileTable * depot_table
gives the position of the depots on the airports
CargoID accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition: house.h:108
static const uint INVALID_AIRPORTTILE
id for an invalid airport tile
Definition: airport.h:25
Flags which require resolving the action-1-2-3 chain for the sprite, even if it is no action-1 sprite...
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:137
Allow replacing any subset by specifiing an offset.
Definition: newgrf.cpp:6090
uint32 grf_features
Bitset of GrfSpecFeature the grf uses.
Definition: newgrf.h:145
Always succeeds.
Definition: industrytype.h:40
StringID new_engine
Name of an engine for this type of road in the engine preview GUI.
Definition: road.h:105
Price
Enumeration of all base prices for use with Prices.
Definition: economy_type.h:65
Combination of a palette sprite and a &#39;real&#39; sprite.
Definition: gfx_type.h:22
No profile, special "custom" highscore.
Definition: settings_type.h:33
byte removal_cost
cost multiplier for removing it
Definition: house.h:103
bool HasValidSpriteSets(byte feature) const
Check whether there are any valid spritesets for a feature.
Definition: newgrf.cpp:152
uint32 removal_cost_multiplier
Base removal cost multiplier.
Definition: industrytype.h:109
Purchase cost (if dualheaded: sum of both vehicles)
GRF file is used statically (can be used in any MP game)
Definition: newgrf_config.h:24
Header of Action 0F "universal holder" structure and functions.
bool never_expire_airports
never expire airports
uint8 flags
Flags controlling display.
Definition: newgrf_canal.h:26
uint GetNumEnts(byte feature, uint set) const
Returns the number of sprites in a spriteset.
Definition: newgrf.cpp:189
AllowedSubtags _tags_info[]
Action14 tags for the INFO node.
Definition: newgrf.cpp:8175
uint8 num_valid_params
NOSAVE: Number of valid parameters (action 0x14)
char * custom_message
Custom message (if present)
Add signed offset to palette from register TileLayoutRegisters::palette.
Flags which do not work for the (first) ground sprite.
RailTypeLabelList alternate_labels
Rail type labels this type provides in addition to the main label.
Definition: rail.h:238
Maximum number of slots.
Definition: fios.h:99
std::vector< Mapping > gender_map
Mapping of NewGRF and OpenTTD IDs for genders.
Definition: newgrf_text.h:58
Tindex index
Index of this pool item.
Definition: pool_type.hpp:227
static void FinaliseCargoArray()
Check for invalid cargoes.
Definition: newgrf.cpp:8954
int8 acceptance[INDUSTRY_NUM_INPUTS]
Level of acceptance per cargo type (signed, may be negative!)
Definition: industrytype.h:157
flag for invalid roadtype
Definition: road_type.h:27
EngineID GetID(VehicleType type, uint16 grf_local_id, uint32 grfid)
Looks up an EngineID in the EngineOverrideManager.
Definition: engine.cpp:510
EngineClass
Type of rail engine.
Definition: engine_type.h:33
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.net/tiki-index.php?page=BaseCosts.
Definition: newgrf.cpp:967
void CommitVehicleListOrderChanges()
Deternine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition: newgrf.cpp:8652
StringID name_single
Name of a single entity of this type of cargo.
Definition: cargotype.h:71
GRFError * error
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
static const uint SNOW_LINE_MONTHS
Number of months in the snow line table.
Definition: landscape.h:16
uint16 speed
maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: bridge.h:46
Add signed offset to sprite from register TileLayoutRegisters::sprite.
RoadTypeFlags
Roadtype flags.
Definition: road.h:38
Allow incrementing of ObjectClassID variables.
Definition: newgrf_object.h:58
Functions for Standard In/Out file operations.
Date end_of_life_date
When can&#39;t this object be built anymore.
Definition: newgrf_object.h:69
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition: newgrf.cpp:9467
A list of all hangar tiles in an airport.
Industry type specs.
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition: string.cpp:446
The NewGRF provided no information.
Definition: newgrf_config.h:69
static const CargoID CT_PURCHASE_OBJECT
Mapping of purchase for objects.
byte param_nr
GRF parameter to store content in.
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition: road.h:103
Cargo behaves water-like.
Definition: cargotype.h:30
StringID abbrev
Two letter abbreviation for this cargo type.
Definition: cargotype.h:74
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:121
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:48
static bool ChangeGRFParamName(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;NAME&#39; to set the name of a parameter.
Definition: newgrf.cpp:7923
static const SpriteID SPR_AQUEDUCT_BASE
Sprites for the Aqueduct.
Definition: sprites.h:178
StringID GetGRFStringID(uint32 grfid, StringID stringid)
Returns the index for this stringid associated with its grfID.
ChangeInfoResult
Possible return values for the FeatureChangeInfo functions.
Definition: newgrf.cpp:987
GRF file was not found in the local cache.
Definition: newgrf_config.h:36
Functions related to world/map generation.
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel ...
Definition: rail.h:188
No properties assigned. Default refit masks shall be activated.
Definition: newgrf.cpp:308
Number of ticks before carried cargo is aged.
Cargo behaves goods/candy-like.
Definition: cargotype.h:29
StringID quantifier
Text for multiple units of cargo of this type.
Definition: cargotype.h:73
static uint MapLogY()
Logarithm of the map size along the y side.
Definition: map_func.h:62
Relative position (vehicles only)
static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for railtypes.
Definition: newgrf.cpp:4159
Date introduction_date
From when can this object be built.
Definition: newgrf_object.h:68
void AllocateRegisters()
Allocate memory for register modifiers.
uint8 flags
Flags controlling display.
Definition: newgrf.h:41
byte num_loaded
Number of loaded groups.
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition: vehicle.cpp:1803
#define FOR_EACH_SET_BIT(bitpos_var, bitset_value)
Do an operation for each set set bit in a value.
#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
TramReplacement tram
In which way tram depots were replaced.
Definition: newgrf.h:180
Tractive effort coefficient in 1/256.
Refittability refittability
Did the newgrf set any refittability property? If not, default refittability will be applied...
Definition: newgrf.cpp:318
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
Define properties for airports.
Definition: newgrf.cpp:3810
void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
Load all the NewGRFs.
Definition: newgrf.cpp:9758
byte pow_wag_weight
Extra weight applied to consist if wagon should be powered.
Definition: engine_type.h:56
int32 Year
Type for the year, note: 0 based, i.e. starts at the year 0.
Definition: date_type.h:18
uint16 callback_mask
Bitmask of house callbacks that have to be called.
Definition: house.h:115
RoadType
The different roadtypes we support.
Definition: road_type.h:22
StringID source
Source StringID (GRF local).
Definition: newgrf.cpp:464
Subdirectory for all base data (base sets, intro game)
Definition: fileio_type.h:116
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:6066
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:24
uint16 classes
Classes of this cargo type.
Definition: cargotype.h:78
static bool ChangeGRFPalette(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PALS&#39; to set the number of valid parameters.
Definition: newgrf.cpp:7840
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
static bool ChangeGRFDescription(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;DESC&#39; to add a translation to the newgrf description.
Definition: newgrf.cpp:7814
byte FioReadByte()
Read a byte from the file.
Definition: fileio.cpp:131
std::vector< IndustryTileLayout > layouts
List of possible tile layouts for the industry.
Definition: industrytype.h:107
GRFLabel * label
Pointer to the first label. This is a linked list, not an array.
Definition: newgrf.h:124
uint8 status
Status; 0: no looping, 1: looping, 0xFF: no animation.
bool never_expire_vehicles
never expire vehicles
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:25
Struct containing information about a single bridge type.
Definition: bridge.h:41
uint32 GetParam(uint number) const
Get GRF Parameter with range checking.
Definition: newgrf.h:152
struct RailtypeInfo::@39 strings
Strings associated with the rail type.
uint tiles
Number of tile layouts.
bool improved_load
improved loading algorithm
static void DefineGotoLabel(ByteReader *buf)
Action 0x10 - Define goto label.
Definition: newgrf.cpp:7514
const SpriteGroup * group[ROTSG_END]
Sprite groups for resolving sprites.
Definition: road.h:189
GRF file is disabled.
Definition: newgrf_config.h:35
Year min_year
first year the airport is available
static void LoadGRFSound(size_t offs, SoundEntry *sound)
Load a sound from a file.
Definition: newgrf.cpp:7577
Date base_intro
Basic date of engine introduction (without random parts).
Definition: engine_type.h:133
static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
Perform a mapping from TTDPatch&#39;s string IDs to OpenTTD&#39;s string IDs, but only for the ones we are aw...
Definition: newgrf.cpp:488
GRFParameterType
The possible types of a newgrf parameter.
byte nof_depots
the number of hangar tiles in this airport
Tables with default industry layouts and behaviours.
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition: rail.h:175
StationSettings station
settings related to station management
void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group)
Add a generic feature callback sprite group to the appropriate feature list.
StringID production_down_text
Message appearing when the industry&#39;s production is decreasing.
Definition: industrytype.h:130
StringID new_loco
Name of an engine for this type of rail in the engine preview GUI.
Definition: rail.h:178
struct GRFConfig * next
NOSAVE: Next item in the linked list.
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
StringID name
Name of this type of cargo.
Definition: cargotype.h:70
uint16 maintenance_cost
maintenance cost multiplier
Year lifelength
Lifetime of a single vehicle.
Definition: engine_type.h:134
static const HouseID NUM_HOUSES
Total number of houses.
Definition: house.h:29
Metadata about a single language.
Definition: language.h:92
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
Definition of a single Action1 spriteset.
Definition: newgrf.cpp:89
byte grf_container_ver
NewGRF container version if the sound is from a NewGRF.
Definition: sound_type.h:22
StringID name
Displayed name of the industry.
Definition: industrytype.h:126
Maglev engine.
Definition: engine_type.h:38
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.
HouseZones
Definition: house.h:71
uint num_sprites
Number of sprites in the set.
Definition: newgrf.cpp:91
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition: sprite.h:60
const AirportTileTable *const * table
list of the tiles composing the airport
uint16 max_speed
Maximum speed (1 unit = 8 mph = 12.8 km-ish/h)
Definition: engine_type.h:104
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:68
No shore sprites were replaced.
Definition: newgrf.h:162
byte lowest_randbit
Look for this in the per-object randomized bitmask:
Temporary data during loading of GRFs.
Definition: newgrf.cpp:86
BridgeSpec _bridge[MAX_BRIDGES]
The specification of all bridges.
CargoTypes cargo_triggers
Bitmask of cargo types which cause trigger re-randomizing.
size_t GetGRFSpriteOffset(uint32 id)
Get the file offset for a specific sprite in the sprite section of a GRF.
IndustryTileSpecialFlags special_flags
Bitmask of extra flags used by the tile.
Definition: industrytype.h:169
SpriteID sprite_base
Load the sprites starting from this sprite.
Definition: newgrf.cpp:6096
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition: rail.h:176
This struct contains all the info that is needed to draw and construct tracks.
Definition: rail.h:124
Mono rail engine.
Definition: engine_type.h:37
const LanguageMetadata * GetLanguage(byte newgrflangid)
Get the language with the given NewGRF language ID.
Definition: strings.cpp:1880
NewGRF handling of airports.
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition: newgrf.cpp:9210
HouseZones building_availability
where can it be built (climates, zones)
Definition: house.h:110
static const LanguageMap * GetLanguageMap(uint32 grfid, uint8 language_id)
Get the language map associated with a given NewGRF and language.
Definition: newgrf.cpp:2578
IndustryLifeType
Available types of industry lifetimes.
Definition: industrytype.h:28
Diesel rail engine.
Definition: engine_type.h:35
GRFFile * grffile
Currently processed GRF file.
Definition: newgrf.cpp:104
byte population
population (Zero on other tiles in multi tile house.)
Definition: house.h:102
uint8 size
The size of this objects; low nibble for X, high nibble for Y.
Definition: newgrf_object.h:65
Functions related to NewGRF objects.
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
uint16 multiplier
Capacity multiplier for vehicles. (8 fractional bits)
Definition: cargotype.h:61
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition: newgrf.h:146
StringID replace_text
Text used in the autoreplace GUI.
Definition: road.h:104
Invalid cargo type.
Definition: cargo_type.h:68
int16 y
The y value of the coordinate.
Definition: map_type.h:59
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
uint8 cleanup_flag
flags indicating which data should be freed upon cleaning up
Definition: industrytype.h:138
virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const
Return the ID (if ever available) of a previously inserted entity.
byte grf_container_ver
Container format of the current GRF file.
Definition: newgrf.cpp:107
Slope slopes_refused
slope pattern on which this tile cannot be built
Definition: industrytype.h:158
static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
Define properties common to all vehicles.
Definition: newgrf.cpp:1004
Functions to read fonts from files and cache them.
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:264
const uint8 * random_sounds
array of random sounds.
Definition: industrytype.h:135
StringID * target
Destination for mapping result.
Definition: newgrf.cpp:465
static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for aircraft.
Definition: newgrf.cpp:1707
Only draw sprite if value of register TileLayoutRegisters::dodraw is non-zero.
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition: economy.cpp:883
byte symbol_pos
The currency symbol is represented by two possible values, prefix and suffix Usage of one or the othe...
Definition: currency.h:83
uint16 add_output[INDUSTRY_NUM_OUTPUTS]
Add this much output cargo when successful (unsigned, is indirect in cb version 1+) ...
struct GRFText * desc
The description of this parameter.
Mapping between NewGRF and OpenTTD IDs.
Definition: newgrf_text.h:47
byte catchment
catchment area of this airport
Header of Action 04 "universal holder" structure and functions.
uint8 height
The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
Definition: newgrf_object.h:73
GrfLoadingStage stage
Current loading stage.
Definition: newgrf.cpp:99
void ResetObjects()
This function initialize the spec arrays of objects.
void ReadGRFSpriteOffsets(byte container_version)
Parse the sprite section of GRFs.
User defined data for vehicle variable 0x42.
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:743
StringID name
Name of this rail type.
Definition: road.h:100
byte noise_level
noise that this airport generates
Struct containing information relating to NewGRF classes for stations and airports.
Definition: newgrf_class.h:19
ShoreReplacement shore
In which way shore sprites were replaced.
Definition: newgrf.h:179
Functions related to low-level strings.
byte pylons
Bitmask of base tiles (0 - 7) which should contain elrail pylons.
uint8 freight_trains
value to multiply the weight of cargo by
bool prop27_set
Did the NewGRF set property 27 (misc flags)?
Definition: newgrf.cpp:319
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:801
uint8 num_output
How many add_output values are valid.
uint8 palette_var10
Value for variable 10 when resolving the palette.
uint param_end
one more than the highest set parameter
Definition: newgrf.h:122
Electric rails.
Definition: rail_type.h:30
void Clone(const DrawTileSeqStruct *source)
Clone the building sprites of a spritelayout.
First bit used for the type of effect.
Definition: vehicle_base.h:81
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition: newgrf.h:142
bool enabled
Is this spec enabled?
Definition: newgrf_object.h:76
Information about a vehicle.
Definition: engine_type.h:132
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition: newgrf.cpp:9050
uint16 internal_id
The internal ID within the GRF file.
Definition: engine_base.h:165
uint8 num_params
Number of used parameters.
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition: newgrf.cpp:8791
byte mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition: house.h:106
bool(* BranchHandler)(ByteReader *)
Type of callback function for branch nodes.
Definition: newgrf.cpp:8011
Functions related to errors.
RailType AllocateRailType(RailTypeLabel label)
Allocate a new rail type label.
Definition: rail_cmd.cpp:158
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power ...
Definition: road.h:119
bool IsTerminator() const
Check whether this is a sequence terminator.
Definition: sprite.h:41
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
byte subtype
Type of aircraft.
Definition: engine_type.h:101
uint16 max_sprite_offset
Maximum offset to add to the sprite. (limited by size of the spriteset)
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition: engine.cpp:543
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:28
static uint32 _grm_engines[256]
Contains the GRF ID of the owner of a vehicle if it has been reserved.
Definition: newgrf.cpp:344
byte train_signal_side
show signals on left / driving / right side
The NewGRF says any palette can be used.
Definition: newgrf_config.h:72
Shore sprites were replaced by Action5.
Definition: newgrf.h:163
GRF file is an openttd-internal system grf.
Definition: newgrf_config.h:22
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:350
HouseClassID class_id
defines the class this house has (not grf file based)
Definition: house.h:119
Information about GRF, used in the game and (part of it) in savegames.
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition: engine.cpp:615
int8 retire_early
Number of years early to retire vehicle.
Definition: engine_type.h:144
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
byte ReadByte(LoadgameState *ls)
Reads a byte from the buffer and decompress if needed.
Definition: oldloader.cpp:75
Number of the first newgrf airport.
Definition: airport.h:39
void AddGRFTextToList(GRFText **list, GRFText *text_to_add)
Add a GRFText to a GRFText list.
Simple pair of data.
No tram depot graphics were loaded.
Definition: newgrf.h:169
Functions related to engines.
uint16 maintenance_multiplier
Cost multiplier for maintenance of this road type.
Definition: road.h:134
byte road_side
the side of the road vehicles drive on
uint32 id
The identifier for this node.
Definition: newgrf.cpp:8077
static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
Define properties for stations.
Definition: newgrf.cpp:1861
static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
Define properties for bridges.
Definition: newgrf.cpp:2147
EngineClass engclass
Class of engine for this vehicle.
Definition: engine_type.h:52
uint consistent_max_offset
Number of sprites in all referenced spritesets.
static bool ChangeGRFURL(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;URL_&#39; to set the newgrf url.
Definition: newgrf.cpp:7821
East.
const Direction * rotation
the rotation of each tiletable
static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for objects.
Definition: newgrf.cpp:4028
uint16 pow_wag_power
Extra power applied to consist if wagon should be powered.
Definition: engine_type.h:55
uint16 max_speed
Maximum speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: engine_type.h:47
Functions related to NewGRF houses.
Bitmask to get only the use palette use states.
Definition: newgrf_config.h:67
bool has_param_defaults
NOSAVE: did this newgrf specify any defaults for it&#39;s parameters.
static void DuplicateTileTable(AirportSpec *as)
Create a copy of the tile table so it can be freed later without problems.
Definition: newgrf.cpp:3781
void ClearSnowLine()
Clear the variable snow line table and free the memory.
Definition: landscape.cpp:677
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:143
simple wagon, not motorized
Definition: engine_type.h:29
GRFFilePropsBase< NUM_CARGO+3 > grf_prop
Properties related the the grf file.
DeterministicSpriteGroupAdjustOperation
Standard non-electric rails.
Definition: rail_type.h:29
SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id)
Resolve NewGRF sound ID.
byte num_bit
Number of bits to use for this parameter.
static void ResetAirports()
This function initializes the airportspec array.
AnimationInfo animation
Information about the animation.
Definition: newgrf_object.h:71
Capacity (if dualheaded: for each single vehicle)
static void StaticGRFInfo(ByteReader *buf)
Handle Action 0x14.
Definition: newgrf.cpp:8294
Mapping of language data between a NewGRF and OpenTTD.
Definition: newgrf_text.h:45
Definition of base types and functions in a cross-platform compatible way.
static void ResetAirportTiles()
This function initializes the tile array of AirportTileSpec.
static void ResetCustomIndustries()
Reset and clear all NewGRF industries.
Definition: newgrf.cpp:8488
The data is copied from a grf in _all_grfs.
Definition: newgrf_config.h:26
Weight in 1/4 t.
Data structure to convert between Date and triplet (year, month, and day).
Definition: date_type.h:103
bool IsValidSpriteSet(byte feature, uint set) const
Check whether a specific set is defined.
Definition: newgrf.cpp:165
byte processing_time
Periodic refresh multiplier.
Definition: house.h:121
void SetEntitySpec(const HouseSpec *hs)
Install the specs into the HouseSpecs array It will find itself the proper slot on which it will go...
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
Definition: openttd.cpp:92
A number of safeguards to prevent using unsafe methods.
Trams.
Definition: road_type.h:25
int16 x
The x value of the coordinate.
Definition: map_type.h:58
static void FeatureTownName(ByteReader *buf)
Action 0x0F - Define Town names.
Definition: newgrf.cpp:7430
static bool ValidateIndustryLayout(const IndustryTileLayout &layout)
Validate the industry layout; e.g.
Definition: newgrf.cpp:3379
uint16 callback_mask
Bitmask of requested/allowed callbacks.
Definition: newgrf_object.h:72
uint8 acceleration_type
Acceleration type of this rail type.
Definition: rail.h:223
void FioSeekTo(size_t pos, int mode)
Seek in the current file.
Definition: fileio.cpp:86
Information about why GRF had problems during initialisation.
uint32 max_value
The maximal value of this parameter.
Direction
Defines the 8 directions on the map.
Cargo has no effect.
Definition: cargotype.h:26
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id)
Map the GRF local type to an industry type.
RailTypes introduces_railtypes
Bitmask of which other railtypes are introduced when this railtype is introduced. ...
Definition: rail.h:263
Vehicle uses two company colours.
Definition: engine_type.h:155
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
Definition: industry_type.h:32
StringID new_industry_text
Message appearing when the industry is built.
Definition: industrytype.h:127
Max. speed: 1 unit = 1/0.8 mph = 2 km-ish/h.
const SpriteGroup * group
Sprite group to start resolving.
Definition: newgrf_canal.h:23
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
Load a particular NewGRF.
Definition: newgrf.cpp:9351
bool dynamic_engines
enable dynamic allocation of engine data
T * Allocate(size_t count)
Get buffer of at least count times T.
Definition: alloc_type.hpp:42
static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for rail vehicles.
Definition: newgrf.cpp:1047
StringID MapGRFStringID(uint32 grfid, StringID str)
Used when setting an object&#39;s property to map to the GRF&#39;s strings while taking in consideration the ...
Definition: newgrf.cpp:552
byte random_colour[4]
4 "random" colours
Definition: house.h:116
static const Action5Type _action5_types[]
The information about action 5 types.
Definition: newgrf.cpp:6103
uint8 callback_mask
Bitmask of cargo callbacks that have to be called.
Definition: cargotype.h:68
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:73
int skip_sprites
Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file) ...
Definition: newgrf.cpp:110
byte sorting_order
The sorting order of this railtype for the toolbar dropdown.
Definition: rail.h:268
Refittability
Summary state of refittability properties.
Definition: newgrf.cpp:307
CargoLabel label
Unique label of the cargo type.
Definition: cargotype.h:57
byte num_table
number of elements in the table
static bool ChangeGRFParamValueNames(ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARA&#39;->param_num->&#39;VALU&#39; to set the names of some parameter values (ty...
Definition: newgrf.cpp:8101
static void LoadFontGlyph(ByteReader *buf)
Action 0x12.
Definition: newgrf.cpp:7695
uint8 views
The number of views.
Definition: newgrf_object.h:74
bool operator==(const MultiMapIterator< Tmap_iter1, Tlist_iter1, Tkey, Tvalue1, Tcompare > &iter1, const MultiMapIterator< Tmap_iter2, Tlist_iter2, Tkey, Tvalue2, Tcompare > &iter2)
Compare two MultiMap iterators.
Definition: multimap.hpp:203
void CleanUpStrings()
House cleaning.
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition: road.h:102
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
Information about languages and their files.
static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
Define properties for cargoes.
Definition: newgrf.cpp:2917
byte capacity
Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine.
Definition: engine_type.h:53
uint8 flags
NOSAVE: GCF_Flags, bitset.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:136
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
uint8 tractive_effort
Coefficient of tractive effort.
Definition: engine_type.h:121
static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;DFLT&#39; to set the default value.
Definition: newgrf.cpp:7997
Number of ticks before carried cargo is aged.
uint8 sprite_var10
Value for variable 10 when resolving the sprite.
uint16 DateFract
The fraction of a date we&#39;re in, i.e. the number of ticks since the last date changeover.
Definition: date_type.h:15
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
GRF is unusable with this version of OpenTTD.
Definition: newgrf_config.h:29
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition: newgrf.h:143
byte cost_factor
Purchase cost factor; For multiheaded engines the sum of both engine prices.
Definition: engine_type.h:45
AllowedSubtags(uint32 id, TextHandler handler)
Create a text leaf node.
Definition: newgrf.cpp:8044
StringID name
Tile Subname string, land information on this tile will give you "AirportName (TileSubname)".
static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for water features.
Definition: newgrf.cpp:2109
uint16 max_bridge_length
maximum length of bridges
The NewGRF provided no information or doesn&#39;t care about a 32 bpp blitter.
Definition: newgrf_config.h:75
uint16 max_speed
Maximum speed for vehicles travelling on this rail type.
Definition: rail.h:228
static bool IsValidNewGRFImageIndex(uint8 image_index)
Helper to check whether an image index is valid for a particular NewGRF vehicle.
Definition: newgrf.cpp:206
byte min_length
the minimum length (not counting start and end tile)
Definition: bridge.h:43
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:142
Set when a sprite originates from an Action 1.
Definition: sprites.h:1524
uint16 max_speed
Maximum speed for vehicles travelling on this road type.
Definition: road.h:139
static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
Define properties for industries.
Definition: newgrf.cpp:3401
Defines the data structure for constructing industry.
Definition: industrytype.h:106
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:58
uint8 sprite
Register specifying a signed offset for the sprite.
Add signed offset to bounding box Z positions from register TileLayoutRegisters::delta.parent[2].
static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
Handle the nodes of an Action14.
Definition: newgrf.cpp:8241
bool call_handler
True if there is a callback function for this node, false if there is a list of subnodes.
Definition: newgrf.cpp:8087
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
Year year
Year (0...)
Definition: date_type.h:104
static const uint8 MAX_NUM_GENDERS
Maximum number of supported genders.
Definition: language.h:20
Power in 10 HP.
byte air_drag
Coefficient of air drag.
Definition: engine_type.h:60
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:171
static void AddStringForMapping(StringID source, StringID *target)
Record a static StringID for getting translated later.
Definition: newgrf.cpp:475
static const AirportTileSpec * Get(StationGfx gfx)
Retrieve airport tile spec for the given airport tile.
void FioReadBlock(void *ptr, size_t size)
Read a block.
Definition: fileio.cpp:185
static bool ChangeGRFVersion(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;VRSN&#39; to the version of the NewGRF.
Definition: newgrf.cpp:7888
bool _palette_remap_grf[]
Whether the given NewGRFs must get a palette remap from windows to DOS or not.
Definition: gfxinit.cpp:30
StationGfx gfx
AirportTile to use for this tile.
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
Return the ID of a new engine.
Definition: newgrf.cpp:696
uint8 weight
Weight in 1/4t units.
Definition: engine_type.h:119
byte wires
Bitmask of base tiles (0 - 7) which should contain elrail wires.
bool IsParentSprite() const
Check whether this is a parent sprite with a boundingbox.
Definition: sprite.h:47
StringID building_name
building name
Definition: house.h:104
Basic functions/variables used all over the place.
const SpriteGroup ** loading
List of loading groups (can be SpriteIDs or Callback results)
struct RoadTypeInfo::@42 strings
Strings associated with the rail type.
bool Insert(const T &key, const U &data)
Adds new item to this map.
unknown/not-implemented type
Definition: newgrf.cpp:6091
byte openttd_id
OpenTTD&#39;s internal ID for a case/gender.
Definition: newgrf_text.h:49
Flags which are still required after loading the GRF.
static const uint8 ANIM_STATUS_NO_ANIMATION
There is no animation.
static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;MINV&#39; to the minimum compatible version of the NewGRF.
Definition: newgrf.cpp:7901
SpriteID GetSprite(byte feature, uint set) const
Returns the first sprite of a spriteset.
Definition: newgrf.cpp:177
AllowedSubtags()
Create empty subtags object used to identify the end of a list.
Definition: newgrf.cpp:8022
uint8 cargo_map[NUM_CARGO]
Inverse cargo translation table (CargoID -> local ID)
Definition: newgrf.h:127
static CargoTypes TranslateRefitMask(uint32 refit_mask)
Translate the refit mask.
Definition: newgrf.cpp:949
static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
Set the override for a NewGRF.
Definition: newgrf.cpp:586
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:124
static const uint8 MAX_NUM_CASES
Maximum number of supported cases.
Definition: language.h:21
always the last item
Definition: currency.h:64
static uint32 _ttdpatch_flags[8]
32 * 8 = 256 flags.
Definition: newgrf.cpp:78
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:132
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:140
StringID message
Default message.
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
byte GetNewgrfCurrencyIdConverted(byte grfcurr_id)
Will return the ottd&#39;s index correspondence to the ttdpatch&#39;s id.
Definition: currency.cpp:110
number of bits for the sprite number
Definition: sprites.h:1512
Resolved object itself.
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition: rail.h:233
Element of the linked list.
Definition: newgrf_text.cpp:68
uint8 plane_speed
divisor for speed of aircraft
bool FioCheckFileExists(const char *filename, Subdirectory subdir)
Check whether the given file exists.
Definition: fileio.cpp:310
Year max_year
last year it can be built
Definition: house.h:101
NewGRF supplied spritelayout.
StringID transport_name[2]
description of the bridge, when built for road or rail
Definition: bridge.h:50
static const Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
Definition: date_type.h:49
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
Bitmask of all climate bits.
Definition: house.h:84
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
const uint8 _engine_counts[4]
Number of engines of each vehicle type in original engine data.
Definition: engine.cpp:50
bool build_on_slopes
allow building on slopes
bool SkipSpriteData(byte type, uint16 num)
Skip the given amount of sprite graphics data.
Definition: spritecache.cpp:94
uint16 power
Power of engine (hp); For multiheaded engines the sum of both engine powers.
Definition: engine_type.h:48
Month month
Month (0..11)
Definition: date_type.h:105
Flags which require resolving the action-1-2-3 chain for the palette, even if it is no action-1 palet...
Known flags. Any unknown set flag will disable the GRF.
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;BLTR&#39; to set the blitter info.
Definition: newgrf.cpp:7866
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition: house.h:109
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:4944
static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
Define properties for industry tiles.
Definition: newgrf.cpp:3151
SpriteID spriteid
First available SpriteID for loading realsprites.
Definition: newgrf.cpp:100
byte sorting_order
The sorting order of this roadtype for the toolbar dropdown.
Definition: road.h:179
Price fallback_price
Fallback price multiplier for new prices but old grfs.
Definition: economy_type.h:185
Year to_euro
Year of switching to the Euro. May also be CF_NOEURO or CF_ISEURO.
Definition: currency.h:71
bool has_newhouses
Set if there are any newhouses loaded.
Definition: newgrf.h:177
WaterFeature _water_feature[CF_END]
Table of canal &#39;feature&#39; sprite groups.
NewGRF handling of airport tiles.
SoundEntry * AllocateSound(uint num)
Allocate sound slots.
Subdirectory for all NewGRFs.
Definition: fileio_type.h:117
AllowedSubtags _tags_parameters[]
Action14 parameter tags.
Definition: newgrf.cpp:8131
uint8 GetGenderIndex(const char *gender_str) const
Get the index for the given gender.
Definition: language.h:67
uint16 price
the price multiplier
Definition: bridge.h:45
Information about a rail vehicle.
Definition: engine_type.h:42
static bool IsLeapYear(Year yr)
Checks whether the given year is a leap year or not.
Definition: date_func.h:30
The status of this grf file is unknown.
Definition: newgrf_config.h:34
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores). ...
Definition: newgrf.h:164
static const SpriteID SPR_RAILTYPE_TUNNEL_BASE
Tunnel sprites with grass only for custom railtype tunnel.
Definition: sprites.h:293
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:137
StringID replace_text
Text used in the autoreplace GUI.
Definition: rail.h:177
uint32 version
NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown.
static void MemCpyT(T *destination, const T *source, size_t num=1)
Type-safe version of memcpy().
Definition: mem_func.hpp:23
StringID name
The name for this object.
Definition: newgrf_object.h:62
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition: newgrf.cpp:9519
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
uint8 FindFirstBit(uint32 x)
Search the first set bit in a 32 bit variable.
static const uint MAX_LANG
Maximum number of languages supported by the game, and the NewGRF specs.
Definition: strings_type.h:19
uint8 callback_mask
Bitmask of industry tile callbacks that have to be called.
Definition: industrytype.h:167
uint16 override
id of the entity been replaced by
HouseExtraFlags
Definition: house.h:88
void FioOpenFile(int slot, const char *filename, Subdirectory subdir)
Open a slotted file.
Definition: fileio.cpp:248
Variable is unknown.
Definition: newgrf.cpp:991
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf.h:40
byte flags
Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size...
GRFTextWrapper * url
NOSAVE: URL belonging to this GRF.
void BindAirportSpecs()
Tie all airportspecs to their class.
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:29
GRF file passed GLS_RESERVE stage.
Definition: newgrf_config.h:28
static void ResetCustomHouses()
Reset and clear all NewGRF houses.
Definition: newgrf.cpp:8436
static void ParamSet(ByteReader *buf)
Action 0x0D: Set parameter.
Definition: newgrf.cpp:7080
AllowedSubtags * subtags
Pointer to a list of subtags, only valid if type == &#39;C&#39; && !call_handler.
Definition: newgrf.cpp:8085
Resolve palette with a specific value in variable 10.
byte num_loading
Number of loading groups.
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&#39;s not.
Definition: newgrf.cpp:8977
Cargo behaves passenger-like.
Definition: cargotype.h:27
Additional modifiers for items in sprite layouts.
static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;NPAR&#39; to set the number of valid parameters.
Definition: newgrf.cpp:7828
The NewGRF says the Windows palette can be used.
Definition: newgrf_config.h:71
Handling of NewGRF canals.
Describes properties of price bases.
Definition: economy_type.h:181
uint32 FioReadDword()
Read a double word (32 bits) from the file (in low endian format).
Definition: fileio.cpp:174
Flag to disable visual effect.
Definition: vehicle_base.h:88
Cargo behaves mail-like.
Definition: cargotype.h:28
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:174
void InitRoadTypes()
Resolve sprites of custom road types.
Definition: road_cmd.cpp:118
byte first_bit
First bit to use in the GRF parameter.
StringID material
the string that contains the bridge description
Definition: bridge.h:49
uint grf_feature
GRF Feature that decides whether price multipliers apply locally or globally, #GSF_END if none...
Definition: economy_type.h:184
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
Cargo accepted by this tile.
Definition: industrytype.h:156
Smallmap GUI functions.
uint8 clear_cost_multiplier
Clear cost multiplier per tile.
Definition: newgrf_object.h:67
bool old_refittable
Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask.
Definition: engine_type.h:72
std::vector< IndustryTileLayoutTile > IndustryTileLayout
A complete tile layout for an industry is a list of tiles.
Definition: industrytype.h:101
IndustryTileSpecialFlags
Flags for miscellaneous industry tile specialities.
Definition: industrytype.h:87
Date introduction_date
Introduction date.
Definition: rail.h:252
uint16 cost_multiplier
Cost multiplier for building this rail type.
Definition: rail.h:213
static GRFFile * GetFileByGRFID(uint32 grfid)
Obtain a NewGRF file by its grfID.
Definition: newgrf.cpp:397
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
GRFConfig * GetGRFConfig(uint32 grfid, uint32 mask)
Retrieve a NewGRF from the current config by its grfid.
uint8 child[2]
Registers for signed offsets for the position of child sprites.
TownEffect town_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies...
Definition: cargotype.h:66
this bit is set when a recolouring process is in action
Definition: sprites.h:1527
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:60
1F This is just to englobe all above types at once
Definition: house.h:78
Base class for engines.
Information about a road vehicle.
Definition: engine_type.h:111
Header file for NewGRF stations.
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf_canal.h:25
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:117
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:27
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
AllowedSubtags(uint32 id, BranchHandler handler)
Create a branch node with a callback handler.
Definition: newgrf.cpp:8056
Variable was parsed but unread.
Definition: newgrf.cpp:990
static const WChar NFO_UTF8_IDENTIFIER
This character, the thorn (&#39;þ&#39;), indicates a unicode string to NFO.
Definition: newgrf_text.h:19
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:378
HouseExtraFlags extra_flags
some more flags
Definition: house.h:118
bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
Reads a variable common to VarAction2 and Action7/9/D.
Definition: newgrf.cpp:6236
byte minimal_cargo
minimum amount of cargo transported to the stations.
Definition: industrytype.h:119
byte prob
The relative probability of the following name to appear in the bottom 7 bits.
uint8 cost_multiplier
Base construction cost multiplier.
Definition: industrytype.h:108
Information about one grf parameter.
bool station_noise_level
build new airports when the town noise level is still within accepted limits
Base class for all vehicles.
indicates a "standalone" locomotive
Definition: engine_type.h:27
StationClassID
byte appear_creation[NUM_LANDSCAPE]
Probability of appearance during map creation.
Definition: industrytype.h:133
bool(* TextHandler)(byte, const char *str)
Type of callback function for text nodes.
Definition: newgrf.cpp:8010
void ResetMapping()
Resets the mapping, which is used while initializing game.
uint16 max_length
the maximum length (not counting start and end tile)
Definition: bridge.h:44
Maximal number of airports per NewGRF.
Definition: airport.h:40
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:69
Temporary engine data used when loading only.
Definition: newgrf.cpp:305
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:57
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition: newgrf.cpp:8556
Declarations for savegames operations.
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:21
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:117
bool gradual_loading
load vehicles gradually
Number of bits used for the effect type.
Definition: vehicle_base.h:82
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:6517
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition: newgrf.cpp:8543
RandomizedSpriteGroupCompareMode cmp_mode
Check for these triggers:
uint16 cost_multiplier
Cost multiplier for building this road type.
Definition: road.h:129
AnimationInfo animation
Information about the animation (is it looping, how many loops etc)
Definition: industrytype.h:168
Max. speed: 1 unit = 1/3.2 mph = 0.5 km-ish/h.
byte tractive_effort
Tractive effort coefficient.
Definition: engine_type.h:59
Cargo support for NewGRFs.
uint8 palette
GRFPalette, bitset.
static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for road vehicles.
Definition: newgrf.cpp:1341
Number of ticks before carried cargo is aged.
byte minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition: house.h:122
StringID name
name of this airport
Canal properties local to the NewGRF.
Definition: newgrf.h:39
Information about a aircraft vehicle.
Definition: engine_type.h:97
uint16 remove_rating_decrease
rating decrease if removed
Definition: house.h:105
bool has_newindustries
Set if there are any newindustries loaded.
Definition: newgrf.h:178
GRF file is unsafe for static usage.
Definition: newgrf_config.h:23
byte fallback_railtype
Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations...
Definition: rail.h:198
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
OrderSettings order
settings related to orders
AnimationInfo animation
Information about the animation.
bool wagon_speed_limits
enable wagon speed limits
static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
Map the colour modifiers of TTDPatch to those that Open is using.
Definition: newgrf.cpp:712
static void InitNewGRFFile(const GRFConfig *config)
Prepare loading a NewGRF file with its config.
Definition: newgrf.cpp:8690
Add signed offset to child sprite X positions from register TileLayoutRegisters::delta.child[0].
StringID closure_text
Message appearing when the industry closes.
Definition: industrytype.h:128
Related object of the resolved one.
GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not av...
Definition: newgrf.cpp:310
void FioSkipBytes(int n)
Skip n bytes ahead in the file.
Definition: fileio.cpp:148
Date introduction_date
Introduction date.
Definition: road.h:163
Year min_year
introduction year of the house
Definition: house.h:100
byte map_colour
Colour on mini-map.
Definition: rail.h:243
when a sprite is to be displayed transparently, this bit needs to be set.
Definition: sprites.h:1526
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:112
Action5BlockType
The type of action 5 type.
Definition: newgrf.cpp:6088
int8 delta_z
0x80 identifies child sprites
Definition: sprite.h:28
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:380
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:81
byte size_x
size of airport in x direction
indicates a combination of two locomotives
Definition: engine_type.h:28
uint8 power
Power in 10hp units.
Definition: engine_type.h:120
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
Definition: cargotype.cpp:170
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
uint8 rv_max_speed
Temporary storage of RV prop 15, maximum speed in mph/0.8.
Definition: newgrf.cpp:320
void InitRailTypes()
Resolve sprites of custom rail types.
Definition: rail_cmd.cpp:138
static void ActivateOldTramDepot()
Replocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition: newgrf.cpp:9504
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition: bridge.h:34
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
uint16 max_range
Maximum range of this aircraft.
Definition: engine_type.h:107
Tile-offset / AirportTileID pair.
static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
Handle the contents of a &#39;C&#39; choice of an Action14.
Definition: newgrf.cpp:8279
StringID string_id
Default name of engine.
Definition: engine_type.h:145
CanalProperties canal_local_properties[CF_END]
Canal properties as set by this NewGRF.
Definition: newgrf.h:138
bool(* DataHandler)(size_t, ByteReader *)
Type of callback function for binary nodes.
Definition: newgrf.cpp:8009
FontSize
Available font sizes.
Definition: gfx_type.h:201
static const SpriteID SPR_AIRPORT_PREVIEW_BASE
Airport preview sprites.
Definition: sprites.h:240
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
static GRFTempEngineData * _gted
Temporary engine data used during NewGRF loading.
Definition: newgrf.cpp:338
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition: economy.cpp:871
char * filename
Filename - either with or without full path.
static const CargoLabel _default_refitmasks_rail[]
List of what cargo labels are refittable for the given the vehicle-type.
Definition: newgrf.cpp:8758
uint32 CargoLabel
Globally unique label of a cargo type.
Definition: cargotype.h:21
uint8 version
Production callback version used, or 0xFF if marked invalid.
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition: house.h:28
Only corner-shores were loaded by Action5 (openttd(w/d).grf only).
Definition: newgrf.h:165
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
Bitmask to only get the blitter information.
Definition: newgrf_config.h:77
bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id, byte container_version)
Load a real or recolour sprite.
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
Definition: industry_type.h:25
static const SpriteID SPR_OPENTTD_BASE
Extra graphic spritenumbers.
Definition: sprites.h:56
uint16 weight
Weight of vehicle (tons); For multiheaded engines the weight of each single engine.
Definition: engine_type.h:49
uint16 cargo_threshold
Cargo threshold for choosing between little and lots of cargo.
byte type
The type of the node, must be one of &#39;C&#39;, &#39;B&#39; or &#39;T&#39;.
Definition: newgrf.cpp:8078
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
Definition: newgrf.h:175
uint8 generate_amount
Number of objects which are attempted to be generated per 256^2 map during world generation.
Definition: newgrf_object.h:75
static NewGRFClass * Get(Tid cls_id)
Get a particular class.
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
Number of ticks before carried cargo is aged.
RailTypes powered_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype generates power ...
Definition: rail.h:185
Functions related to OTTD&#39;s landscape.
Default value to indicate that visual effect should be based on engine class.
Definition: vehicle_base.h:92
void ResetRailTypes()
Reset all rail type information to its default values.
Definition: rail_cmd.cpp:63
GRFTextWrapper * name
NOSAVE: GRF name (Action 0x08)
void ResetGenericCallbacks()
Reset all generic feature callback sprite groups.
Data structure to store the allowed id/type combinations for action 14.
Definition: newgrf.cpp:8020
std::vector< RailTypeLabel > railtype_list
Railtype translation table.
Definition: newgrf.h:129
uint8 substitute_id
The (original) entity ID to use if this GRF is not available (currently not used) ...
Definition: engine_base.h:167
Attempt to modify an invalid ID.
Definition: newgrf.cpp:992
Defines the data structure of each individual tile of an airport.
const GRFFile * defaultcargo_grf
GRF defining the cargo translation table to use if the default cargo is the &#39;first refittable&#39;...
Definition: newgrf.cpp:317
IndustryBehaviour
Various industry behaviours mostly to represent original TTD specialities.
Definition: industrytype.h:61
static void InitializeGRFSpecial()
Initialize the TTDPatch flags.
Definition: newgrf.cpp:8315
The NewGRF says the DOS palette can be used.
Definition: newgrf_config.h:70
AnimationInfo animation
information about the animation.
Definition: house.h:120
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition: newgrf.cpp:419
CargoID Index() const
Determines index of this cargospec.
Definition: cargotype.h:88
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:9023
byte GetGRFContainerVersion()
Get the container version of the currently opened GRF file.
Definition: newgrf.cpp:9325
uint8 callback_mask
Bitmask telling which grf callback is set.
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:111
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:644
uint16 local_id
id defined by the grf file for this entity
uint32 min_loadable_version
NOSAVE: Minimum compatible version a NewGRF can define.
static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
Ignore a house property.
Definition: newgrf.cpp:2257
static bool SkipUnknownInfo(ByteReader *buf, byte type)
Try to skip the current node and all subnodes (if it&#39;s a branch node).
Definition: newgrf.cpp:8201
uint64 used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition: newgrf.h:176
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:124
std::vector< GRFParameterInfo * > param_info
NOSAVE: extra information about the parameters.
static const SpriteID SPR_TRAMWAY_BASE
Tramway sprites.
Definition: sprites.h:264
Cargo behaves food/fizzy-drinks-like.
Definition: cargotype.h:31
static const uint TLR_MAX_VAR10
Maximum value for var 10.
Max. speed: 1 unit = 8 mph = 12.8 km-ish/h.
ConstructionSettings construction
construction of things in-game
static const uint SNOW_LINE_DAYS
Number of days in each month in the snow line table.
Definition: landscape.h:17
Variable was parsed and read.
Definition: newgrf.cpp:988
Steam rail engine.
Definition: engine_type.h:34
DataHandler data
Callback function for a binary node, only valid if type == &#39;B&#39;.
Definition: newgrf.cpp:8080
static const Year MIN_YEAR
The absolute minimum & maximum years in OTTD.
Definition: date_type.h:83
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:347
static const uint MAX_SPRITEGROUP
Maximum GRF-local ID for a spritegroup.
Definition: newgrf.cpp:83
uint8 air_drag
Coefficient of air drag.
Definition: engine_type.h:122
uint32 min_value
The minimal value this parameter can have.
const char * GetName() const
Get the name of this grf.
int32 Date
The type to store our dates in.
Definition: date_type.h:14
uint32 grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:83
char * data
Additional data for message and custom_message.
Tractive effort coefficient in 1/256.
struct GRFText * name
The name of this parameter.
Aircraft vehicle type.
Definition: vehicle_type.h:27
VarSpriteGroupScope var_scope
Take this object:
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:129
GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
Definition: newgrf.cpp:309
GRFFileProps grf_prop
Properties related the the grf file.
Definition: house.h:114
StringID name
Name of this rail type.
Definition: rail.h:173
uint file_index
File index of currently processed GRF file.
Definition: newgrf.cpp:103
declaration of OTTD revision dependent variables
const struct GRFFile * grffile
grf file that introduced this entity
uint8 number_of_sounds
Number of sounds available in the sounds array.
Definition: industrytype.h:134
uint8 bitnum
Cargo bit number, is INVALID_CARGO for a non-used spec.
Definition: cargotype.h:56
bool enabled
Entity still available (by default true). Newgrf can disable it, though.
StringID station_name
Default name for nearby station.
Definition: industrytype.h:131
Used for iterations.
Definition: rail_type.h:33
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition: newgrf.h:126
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
uint32 param[0x80]
GRF parameters.
GRF file has been activated.
Definition: newgrf_config.h:38
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
StringID units_volume
Name of a single unit of cargo of this type.
Definition: cargotype.h:72
bool IsValid() const
Tests for validity of this cargospec.
Definition: cargotype.h:98
StringID production_up_text
Message appearing when the industry&#39;s production is increasing.
Definition: industrytype.h:129
Functions related to NewGRF provided sounds.
byte callback_mask
Bitmask of station callbacks that have to be called.
byte num_groups
must be power of 2
AllowedSubtags _tags_root[]
Action14 root tags.
Definition: newgrf.cpp:8189
byte disallowed_lengths
Bitmask of platform lengths available for the station.
byte _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition: newgrf.cpp:75
Base of the town class.
byte check_proc
Index to a procedure to check for conflicting circumstances.
Definition: industrytype.h:112
Definition of one tile in an industry tile layout.
Definition: industrytype.h:95
static GRFFile * GetFileByFilename(const char *filename)
Obtain a NewGRF file by its filename.
Definition: newgrf.cpp:410
byte id
If probability bit 7 is set.
BranchHandler branch
Callback function for a branch node, only valid if type == &#39;C&#39; && call_handler.
Definition: newgrf.cpp:8084
static GRFParameterInfo * _cur_parameter
The parameter which info is currently changed by the newgrf.
Definition: newgrf.cpp:7920
static void ResetCustomStations()
Reset and clear all NewGRF stations.
Definition: newgrf.cpp:8402
GameCreationSettings game_creation
settings used during the creation of a game (map)
static const uint NEW_AIRPORTTILE_OFFSET
offset of first newgrf airport tile
Definition: airport.h:24
static bool ChangeGRFParamType(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;TYPE&#39; to set the typeof a parameter.
Definition: newgrf.cpp:7937
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
uint16 cargo_age_period
Number of ticks before carried cargo is aged.
Definition: engine_type.h:146
Defines the data structure of each individual tile of an industry.
Definition: industrytype.h:155
static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
Define properties for global variables.
Definition: newgrf.cpp:2619
Bitmask to get only the NewGRF supplied information.
Definition: newgrf_config.h:73
Weight in t (if dualheaded: for each single vehicle)
Year base_life
Basic duration of engine availability (without random parts). 0xFF means infinite life...
Definition: engine_type.h:135
Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition: date.cpp:150
Road vehicle is a tram/light rail vehicle.
Definition: engine_type.h:154
NewGRFSpriteLayout * renderdata
Array of tile layouts.
size_t FioGetPos()
Get position in the current file.
Definition: fileio.cpp:66
int8 delta_x
0x80 is sequence terminator
Definition: sprite.h:26
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
static void SkipAct12(ByteReader *buf)
Action 0x12 (SKIP)
Definition: newgrf.cpp:7726
static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
Define properties for sound effects.
Definition: newgrf.cpp:3056
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced. ...
Definition: road.h:174
StringID name
Name of this station.
Maximum catchment for airports with "modified catchment" enabled.
Definition: station_type.h:84
Defines the data structure for an airport.
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition: newgrf.cpp:81
Use 32 pixels per train vehicle in depot gui and vehicle details. Never set in the global variable;...
Definition: newgrf.h:60
static void TranslateGRFStrings(ByteReader *buf)
Action 0x13.
Definition: newgrf.cpp:7752
static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
Define properties for houses.
Definition: newgrf.cpp:2324
RoadTypeLabelList alternate_labels
Road type labels this type provides in addition to the main label.
Definition: road.h:149
uint16 multipliertowngrowth
Size of the effect.
Definition: cargotype.h:67
const GRFFile * grffile[ROTSG_END]
NewGRF providing the Action3 for the roadtype.
Definition: road.h:184
byte parameter
Used for variables between 0x60 and 0x7F inclusive.
CargoTypes ctt_include_mask
Cargo types always included in the refit mask.
Definition: newgrf.cpp:321
byte ai_passenger_only
Bit value to tell AI that this engine is for passenger use only.
Definition: engine_type.h:54
uint8 num_input
How many subtract_input values are valid.
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition: rail.cpp:311
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:23
uint8 parent[3]
Registers for signed offsets for the bounding box position of parent sprites.
byte disallowed_platforms
Bitmask of number of platforms available for the station.
Header file for bridges.
uint8 speed
The speed, i.e. the amount of time between frames.
byte running_cost
Running cost of engine; For multiheaded engines the sum of both running costs.
Definition: engine_type.h:50
static GRFError * DisableGrf(StringID message=STR_NULL, GRFConfig *config=nullptr)
Disable a GRF.
Definition: newgrf.cpp:436
ObjectClassID cls_id
The class to which this spec belongs.
Definition: newgrf_object.h:61
StationClassID cls_id
The class to which this spec belongs.
uint8 dodraw
Register deciding whether the sprite shall be drawn at all. Non-zero means drawing.
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
static bool ChangeGRFParamDescription(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;DESC&#39; to set the description of a parameter...
Definition: newgrf.cpp:7930
byte climates
Climates supported by the engine.
Definition: engine_type.h:138
static void SetUnicodeGlyph(FontSize size, WChar key, SpriteID sprite)
Map a SpriteID to the font size and key.
Definition: fontcache.h:173
Date _date
Current date in days (day counter)
Definition: date.cpp:27
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition: sprite.h:25
static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
Ignore an industry property.
Definition: newgrf.cpp:3289
SpriteID sprite
Icon to display this cargo type, may be 0xFFF (which means to resolve an action123 chain)...
Definition: cargotype.h:76
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:854
uint32 WChar
Type for wide characters, i.e.
Definition: string_type.h:35
TTDPAirportType
Allow incrementing of AirportClassID variables.
Year max_year
last year the airport is available
void ConvertDateToYMD(Date date, YearMonthDay *ymd)
Converts a Date to a Year, Month & Day.
Definition: date.cpp:95
Set when a sprite must not ever be displayed transparently.
Definition: sprites.h:1525
Palette is from Action 1 (moved to SPRITE_MODIFIER_CUSTOM_SPRITE in palette during loading)...
uint8 climate
In which climates is this object available?
Definition: newgrf_object.h:64
GRFFileProps grf_prop
properties related the the grf file
CargoID cargo_input[INDUSTRY_NUM_INPUTS]
Which input cargoes to take from (only cb version 2)
byte canal_speed_frac
Fraction of maximum speed for canal/river tiles.
Definition: engine_type.h:75
static const IndustryGfx INDUSTRYTILE_NOANIM
flag to mark industry tiles as having no animation
Definition: industry_type.h:31
void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
Records new spritesets.
Definition: newgrf.cpp:136
byte user_def_data
Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles.
Definition: engine_type.h:61
uint8 frames
The number of frames.
const char * name
Name for error messages.
Definition: newgrf.cpp:6099
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
void SetEntitySpec(IndustrySpec *inds)
Method to install the new industry data in its proper slot The slot assignment is internal of this me...
std::map< uint, SpriteSet > spritesets[GSF_END]
Currently referenceable spritesets.
Definition: newgrf.cpp:95
Year starting_year
starting date
static bool ChangeGRFName(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;NAME&#39; to add a translation to the newgrf name.
Definition: newgrf.cpp:7807
struct GRFFileProps grf_prop
Properties related to the grf file.
ObjectOverrideManager _object_mngr
The override manager for our objects.
Road vehicle type.
Definition: vehicle_type.h:25
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_...
center of town
Definition: house.h:77
Only allow replacing a whole block of sprites. (TTDP compatible)
Definition: newgrf.cpp:6089
CargoTypes ctt_exclude_mask
Cargo types always excluded from the refit mask.
Definition: newgrf.cpp:322
byte blocked
Bitmask of base tiles (0 - 7) which are blocked to trains.
uint8 palette
Register specifying a signed offset for the palette.
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition: config.h:58
TileLayoutFlags flags
Flags defining which members are valid and to be used.
static const SpriteID SPR_FLAGS_BASE
Flags sprites (in same order as enum NetworkLanguage)
Definition: sprites.h:289
uint16 passenger_capacity
Passenger capacity (persons).
Definition: engine_type.h:106
byte mail_capacity
Mail capacity (bags).
Definition: engine_type.h:105
uint16 min_sprites
If the Action5 contains less sprites, the whole block will be ignored.
Definition: newgrf.cpp:6097
virtual void CleanPool()
Virtual method that deletes all items in the pool.
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:49
void ResetToDefaultMapping()
Initializes the EngineOverrideManager with the default engines.
Definition: engine.cpp:486
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:57
Invalid parameter type.
Electric rail engine.
Definition: engine_type.h:36
Electrified depot graphics with tram track were loaded.
Definition: newgrf.h:170
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:105
11 800 can appear in sub-arctic climate above the snow line
Definition: house.h:79
uint16 maintenance_multiplier
Cost multiplier for maintenance of this rail type.
Definition: rail.h:218
Maglev.
Definition: rail_type.h:32
Information about a single action 5 type.
Definition: newgrf.cpp:6094
Information for mapping static StringIDs.
Definition: newgrf.cpp:462
static bool HandleParameterInfo(ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARA&#39; to set extra information about the parameters.
Definition: newgrf.cpp:8148
GRFTextWrapper * info
NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
void SetupCargoForClimate(LandscapeID l)
Set up the default cargo types for the given landscape type.
Definition: cargotype.cpp:40
static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
Define properties for roadtypes.
Definition: newgrf.cpp:4377
Flags which refer to using multiple action-1-2-3 chains.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24
StringID name
Name of this class.
Definition: newgrf_class.h:39
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...
void BuildIndustriesLegend()
Fills an array for the industries legends.