OpenTTD Source  1.10.0-RC1
newgrf_house.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 #include "debug.h"
12 #include "landscape.h"
13 #include "newgrf_house.h"
14 #include "newgrf_spritegroup.h"
15 #include "newgrf_town.h"
16 #include "newgrf_sound.h"
17 #include "company_func.h"
18 #include "company_base.h"
19 #include "town.h"
20 #include "genworld.h"
21 #include "newgrf_animation_base.h"
22 #include "newgrf_cargo.h"
23 #include "station_base.h"
24 
25 #include "safeguards.h"
26 
27 static BuildingCounts<uint32> _building_counts;
28 static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX];
29 
30 HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, NUM_HOUSES, INVALID_HOUSE_ID);
31 
37 static const GRFFile *GetHouseSpecGrf(HouseID house_id)
38 {
39  const HouseSpec *hs = HouseSpec::Get(house_id);
40  return (hs != nullptr) ? hs->grf_prop.grffile : nullptr;
41 }
42 
56  CallbackID callback, uint32 param1, uint32 param2,
57  bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers)
58  : ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2),
59  house_scope(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers),
60  town_scope(*this, town, not_yet_constructed) // Don't access StorePSA if house is not yet constructed.
61 {
62  this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0];
63 }
64 
66 {
67  return GSF_HOUSES;
68 }
69 
71 {
72  return HouseSpec::Get(this->house_scope.house_id)->grf_prop.local_id;
73 }
74 
75 HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid)
76 {
77  /* Start from 1 because 0 means that no class has been assigned. */
78  for (int i = 1; i != lengthof(_class_mapping); i++) {
79  HouseClassMapping *map = &_class_mapping[i];
80 
81  if (map->class_id == grf_class_id && map->grfid == grfid) return (HouseClassID)i;
82 
83  if (map->class_id == 0 && map->grfid == 0) {
84  map->class_id = grf_class_id;
85  map->grfid = grfid;
86  return (HouseClassID)i;
87  }
88  }
89  return HOUSE_NO_CLASS;
90 }
91 
92 void InitializeBuildingCounts()
93 {
94  memset(&_building_counts, 0, sizeof(_building_counts));
95 
96  for (Town *t : Town::Iterate()) {
97  memset(&t->cache.building_counts, 0, sizeof(t->cache.building_counts));
98  }
99 }
100 
108 {
109  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
110 
112 
113  t->cache.building_counts.id_count[house_id]++;
114  _building_counts.id_count[house_id]++;
115 
116  if (class_id == HOUSE_NO_CLASS) return;
117 
118  t->cache.building_counts.class_count[class_id]++;
119  _building_counts.class_count[class_id]++;
120 }
121 
129 {
130  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
131 
133 
134  if (t->cache.building_counts.id_count[house_id] > 0) t->cache.building_counts.id_count[house_id]--;
135  if (_building_counts.id_count[house_id] > 0) _building_counts.id_count[house_id]--;
136 
137  if (class_id == HOUSE_NO_CLASS) return;
138 
139  if (t->cache.building_counts.class_count[class_id] > 0) t->cache.building_counts.class_count[class_id]--;
140  if (_building_counts.class_count[class_id] > 0) _building_counts.class_count[class_id]--;
141 }
142 
143 /* virtual */ uint32 HouseScopeResolver::GetRandomBits() const
144 {
145  /* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
146  assert(IsValidTile(this->tile) && (this->not_yet_constructed || IsTileType(this->tile, MP_HOUSE)));
147  return this->not_yet_constructed ? this->initial_random_bits : GetHouseRandomBits(this->tile);
148 }
149 
150 /* virtual */ uint32 HouseScopeResolver::GetTriggers() const
151 {
152  /* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
153  assert(IsValidTile(this->tile) && (this->not_yet_constructed || IsTileType(this->tile, MP_HOUSE)));
154  return this->not_yet_constructed ? 0 : GetHouseTriggers(this->tile);
155 }
156 
157 static uint32 GetNumHouses(HouseID house_id, const Town *town)
158 {
159  uint8 map_id_count, town_id_count, map_class_count, town_class_count;
160  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
161 
162  map_id_count = ClampU(_building_counts.id_count[house_id], 0, 255);
163  map_class_count = ClampU(_building_counts.class_count[class_id], 0, 255);
164  town_id_count = ClampU(town->cache.building_counts.id_count[house_id], 0, 255);
165  town_class_count = ClampU(town->cache.building_counts.class_count[class_id], 0, 255);
166 
167  return map_class_count << 24 | town_class_count << 16 | map_id_count << 8 | town_id_count;
168 }
169 
177 static uint32 GetNearbyTileInformation(byte parameter, TileIndex tile, bool grf_version8)
178 {
179  tile = GetNearbyTile(parameter, tile);
180  return GetNearbyTileInformation(tile, grf_version8);
181 }
182 
185  const HouseSpec *hs;
187 };
188 
195 static bool SearchNearbyHouseID(TileIndex tile, void *user_data)
196 {
197  if (IsTileType(tile, MP_HOUSE)) {
198  HouseID house = GetHouseType(tile); // tile been examined
199  const HouseSpec *hs = HouseSpec::Get(house);
200  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
201  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
202 
203  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
204  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
205 
206  return hs->grf_prop.local_id == nbhd->hs->grf_prop.local_id && // same local id as the one requested
207  hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
208  }
209  }
210  return false;
211 }
212 
219 static bool SearchNearbyHouseClass(TileIndex tile, void *user_data)
220 {
221  if (IsTileType(tile, MP_HOUSE)) {
222  HouseID house = GetHouseType(tile); // tile been examined
223  const HouseSpec *hs = HouseSpec::Get(house);
224  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
225  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
226 
227  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
228  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
229 
230  return hs->class_id == nbhd->hs->class_id && // same classid as the one requested
231  hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
232  }
233  }
234  return false;
235 }
236 
243 static bool SearchNearbyHouseGRFID(TileIndex tile, void *user_data)
244 {
245  if (IsTileType(tile, MP_HOUSE)) {
246  HouseID house = GetHouseType(tile); // tile been examined
247  const HouseSpec *hs = HouseSpec::Get(house);
248  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
249  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
250 
251  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
252  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
253 
254  return hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
255  }
256  }
257  return false;
258 }
259 
270 static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseID house)
271 {
272  static TestTileOnSearchProc * const search_procs[3] = {
276  };
277  TileIndex found_tile = tile;
278  uint8 searchtype = GB(parameter, 6, 2);
279  uint8 searchradius = GB(parameter, 0, 6);
280  if (searchtype >= lengthof(search_procs)) return 0; // do not run on ill-defined code
281  if (searchradius < 1) return 0; // do not use a too low radius
282 
284  nbhd.hs = HouseSpec::Get(house);
285  nbhd.north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
286 
287  /* Use a pointer for the tile to start the search. Will be required for calculating the distance*/
288  if (CircularTileSearch(&found_tile, 2 * searchradius + 1, search_procs[searchtype], &nbhd)) {
289  return DistanceManhattan(found_tile, tile);
290  }
291  return 0;
292 }
293 
297 /* virtual */ uint32 HouseScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
298 {
299  switch (variable) {
300  /* Construction stage. */
301  case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2;
302 
303  /* Building age. */
304  case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0;
305 
306  /* Town zone */
307  case 0x42: return GetTownRadiusGroup(this->town, this->tile);
308 
309  /* Terrain type */
310  case 0x43: return GetTerrainType(this->tile);
311 
312  /* Number of this type of building on the map. */
313  case 0x44: return GetNumHouses(this->house_id, this->town);
314 
315  /* Whether the town is being created or just expanded. */
316  case 0x45: return _generating_world ? 1 : 0;
317 
318  /* Current animation frame. */
319  case 0x46: return IsTileType(this->tile, MP_HOUSE) ? GetAnimationFrame(this->tile) : 0;
320 
321  /* Position of the house */
322  case 0x47: return TileY(this->tile) << 16 | TileX(this->tile);
323 
324  /* Building counts for old houses with id = parameter. */
325  case 0x60: return parameter < NEW_HOUSE_OFFSET ? GetNumHouses(parameter, this->town) : 0;
326 
327  /* Building counts for new houses with id = parameter. */
328  case 0x61: {
329  const HouseSpec *hs = HouseSpec::Get(this->house_id);
330  if (hs->grf_prop.grffile == nullptr) return 0;
331 
332  HouseID new_house = _house_mngr.GetID(parameter, hs->grf_prop.grffile->grfid);
333  return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, this->town);
334  }
335 
336  /* Land info for nearby tiles. */
337  case 0x62: return GetNearbyTileInformation(parameter, this->tile, this->ro.grffile->grf_version >= 8);
338 
339  /* Current animation frame of nearby house tiles */
340  case 0x63: {
341  TileIndex testtile = GetNearbyTile(parameter, this->tile);
342  return IsTileType(testtile, MP_HOUSE) ? GetAnimationFrame(testtile) : 0;
343  }
344 
345  /* Cargo acceptance history of nearby stations */
346  case 0x64: {
347  CargoID cid = GetCargoTranslation(parameter, this->ro.grffile);
348  if (cid == CT_INVALID) return 0;
349 
350  /* Extract tile offset. */
351  int8 x_offs = GB(GetRegister(0x100), 0, 8);
352  int8 y_offs = GB(GetRegister(0x100), 8, 8);
353  TileIndex testtile = TILE_MASK(this->tile + TileDiffXY(x_offs, y_offs));
354 
355  StationFinder stations(TileArea(testtile, 1, 1));
356  const StationList *sl = stations.GetStations();
357 
358  /* Collect acceptance stats. */
359  uint32 res = 0;
360  for (Station *st : *sl) {
361  if (HasBit(st->goods[cid].status, GoodsEntry::GES_EVER_ACCEPTED)) SetBit(res, 0);
362  if (HasBit(st->goods[cid].status, GoodsEntry::GES_LAST_MONTH)) SetBit(res, 1);
363  if (HasBit(st->goods[cid].status, GoodsEntry::GES_CURRENT_MONTH)) SetBit(res, 2);
364  if (HasBit(st->goods[cid].status, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(res, 3);
365  }
366 
367  /* Cargo triggered CB 148? */
368  if (HasBit(this->watched_cargo_triggers, cid)) SetBit(res, 4);
369 
370  return res;
371  }
372 
373  /* Distance test for some house types */
374  case 0x65: return GetDistanceFromNearbyHouse(parameter, this->tile, this->house_id);
375 
376  /* Class and ID of nearby house tile */
377  case 0x66: {
378  TileIndex testtile = GetNearbyTile(parameter, this->tile);
379  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
380  HouseID nearby_house_id = GetHouseType(testtile);
381  HouseSpec *hs = HouseSpec::Get(nearby_house_id);
382  /* Information about the grf local classid if the house has a class */
383  uint houseclass = 0;
384  if (hs->class_id != HOUSE_NO_CLASS) {
385  houseclass = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
386  houseclass |= _class_mapping[hs->class_id].class_id;
387  }
388  /* old house type or grf-local houseid */
389  uint local_houseid = 0;
390  if (nearby_house_id < NEW_HOUSE_OFFSET) {
391  local_houseid = nearby_house_id;
392  } else {
393  local_houseid = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
394  local_houseid |= hs->grf_prop.local_id;
395  }
396  return houseclass << 16 | local_houseid;
397  }
398 
399  /* GRFID of nearby house tile */
400  case 0x67: {
401  TileIndex testtile = GetNearbyTile(parameter, this->tile);
402  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
403  HouseID house_id = GetHouseType(testtile);
404  if (house_id < NEW_HOUSE_OFFSET) return 0;
405  /* Checking the grffile information via HouseSpec doesn't work
406  * in case the newgrf was removed. */
407  return _house_mngr.GetGRFID(house_id);
408  }
409  }
410 
411  DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
412 
413  *available = false;
414  return UINT_MAX;
415 }
416 
417 uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile,
418  bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers)
419 {
420  assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
421 
422  HouseResolverObject object(house_id, tile, town, callback, param1, param2,
423  not_yet_constructed, initial_random_bits, watched_cargo_triggers);
424  return object.ResolveCallback();
425 }
426 
427 static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte stage, HouseID house_id)
428 {
429  const DrawTileSprites *dts = group->ProcessRegisters(&stage);
430 
431  const HouseSpec *hs = HouseSpec::Get(house_id);
432  PaletteID palette = hs->random_colour[TileHash2Bit(ti->x, ti->y)] + PALETTE_RECOLOUR_START;
434  uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
435  if (callback != CALLBACK_FAILED) {
436  /* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
437  palette = HasBit(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
438  }
439  }
440 
441  SpriteID image = dts->ground.sprite;
442  PaletteID pal = dts->ground.pal;
443 
444  if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) image += stage;
445  if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += stage;
446 
447  if (GB(image, 0, SPRITE_WIDTH) != 0) {
448  DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
449  }
450 
451  DrawNewGRFTileSeq(ti, dts, TO_HOUSES, stage, palette);
452 }
453 
454 void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
455 {
456  const HouseSpec *hs = HouseSpec::Get(house_id);
457 
458  if (ti->tileh != SLOPE_FLAT) {
459  bool draw_old_one = true;
461  /* Called to determine the type (if any) of foundation to draw for the house tile */
462  uint32 callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
463  if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res);
464  }
465 
466  if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
467  }
468 
469  HouseResolverObject object(house_id, ti->tile, Town::GetByTile(ti->tile));
470 
471  const SpriteGroup *group = object.Resolve();
472  if (group != nullptr && group->type == SGT_TILELAYOUT) {
473  /* Limit the building stage to the number of stages supplied. */
474  const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
475  byte stage = GetHouseBuildingStage(ti->tile);
476  DrawTileLayout(ti, tlgroup, stage, house_id);
477  }
478 }
479 
480 /* Simple wrapper for GetHouseCallback to keep the animation unified. */
481 uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, CargoTypes extra_data)
482 {
483  return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data);
484 }
485 
487 struct HouseAnimationBase : public AnimationBase<HouseAnimationBase, HouseSpec, Town, CargoTypes, GetSimpleHouseCallback> {
488  static const CallbackID cb_animation_speed = CBID_HOUSE_ANIMATION_SPEED;
489  static const CallbackID cb_animation_next_frame = CBID_HOUSE_ANIMATION_NEXT_FRAME;
490 
491  static const HouseCallbackMask cbm_animation_speed = CBM_HOUSE_ANIMATION_SPEED;
492  static const HouseCallbackMask cbm_animation_next_frame = CBM_HOUSE_ANIMATION_NEXT_FRAME;
493 };
494 
495 void AnimateNewHouseTile(TileIndex tile)
496 {
497  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
498  if (hs == nullptr) return;
499 
500  HouseAnimationBase::AnimateTile(hs, Town::GetByTile(tile), tile, HasBit(hs->extra_flags, CALLBACK_1A_RANDOM_BITS));
501 }
502 
503 void AnimateNewHouseConstruction(TileIndex tile)
504 {
505  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
506 
509  }
510 }
511 
512 bool CanDeleteHouse(TileIndex tile)
513 {
514  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
515 
516  /* Humans are always allowed to remove buildings, as is water and disasters and
517  * anyone using the scenario editor. */
519  return true;
520  }
521 
523  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
524  return (callback_res == CALLBACK_FAILED || !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DENY_DESTRUCTION, callback_res));
525  } else {
526  return !(hs->extra_flags & BUILDING_IS_PROTECTED);
527  }
528 }
529 
530 static void AnimationControl(TileIndex tile, uint16 random_bits)
531 {
532  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
533 
535  uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random();
536  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_ANIMATION_START_STOP, hs, Town::GetByTile(tile), tile, param, 0);
537  }
538 }
539 
540 bool NewHouseTileLoop(TileIndex tile)
541 {
542  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
543 
544  if (GetHouseProcessingTime(tile) > 0) {
546  return true;
547  }
548 
549  TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP);
550  if (hs->building_flags & BUILDING_HAS_1_TILE) TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP_TOP);
551 
553  /* If this house is marked as having a synchronised callback, all the
554  * tiles will have the callback called at once, rather than when the
555  * tile loop reaches them. This should only be enabled for the northern
556  * tile, or strange things will happen (here, and in TTDPatch). */
558  uint16 random = GB(Random(), 0, 16);
559 
560  if (hs->building_flags & BUILDING_HAS_1_TILE) AnimationControl(tile, random);
561  if (hs->building_flags & BUILDING_2_TILES_Y) AnimationControl(TILE_ADDXY(tile, 0, 1), random);
562  if (hs->building_flags & BUILDING_2_TILES_X) AnimationControl(TILE_ADDXY(tile, 1, 0), random);
563  if (hs->building_flags & BUILDING_HAS_4_TILES) AnimationControl(TILE_ADDXY(tile, 1, 1), random);
564  } else {
565  AnimationControl(tile, 0);
566  }
567  }
568 
569  /* Check callback 21, which determines if a house should be destroyed. */
571  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
572  if (callback_res != CALLBACK_FAILED && Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DESTRUCTION, callback_res)) {
573  ClearTownHouse(Town::GetByTile(tile), tile);
574  return false;
575  }
576  }
577 
579  MarkTileDirtyByTile(tile);
580  return true;
581 }
582 
583 static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_random, bool first)
584 {
585  /* We can't trigger a non-existent building... */
586  assert(IsTileType(tile, MP_HOUSE));
587 
588  HouseID hid = GetHouseType(tile);
589  HouseSpec *hs = HouseSpec::Get(hid);
590 
591  if (hs->grf_prop.spritegroup[0] == nullptr) return;
592 
593  HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER);
594  object.waiting_triggers = GetHouseTriggers(tile) | trigger;
595  SetHouseTriggers(tile, object.waiting_triggers); // store now for var 5F
596 
597  const SpriteGroup *group = object.Resolve();
598  if (group == nullptr) return;
599 
600  /* Store remaining triggers. */
601  SetHouseTriggers(tile, object.GetRemainingTriggers());
602 
603  /* Rerandomise bits. Scopes other than SELF are invalid for houses. For bug-to-bug-compatibility with TTDP we ignore the scope. */
604  byte new_random_bits = Random();
605  byte random_bits = GetHouseRandomBits(tile);
606  uint32 reseed = object.GetReseedSum();
607  random_bits &= ~reseed;
608  random_bits |= (first ? new_random_bits : base_random) & reseed;
609  SetHouseRandomBits(tile, random_bits);
610 
611  switch (trigger) {
612  case HOUSE_TRIGGER_TILE_LOOP:
613  /* Random value already set. */
614  break;
615 
616  case HOUSE_TRIGGER_TILE_LOOP_TOP:
617  if (!first) {
618  /* The top tile is marked dirty by the usual TileLoop */
619  MarkTileDirtyByTile(tile);
620  break;
621  }
622  /* Random value of first tile already set. */
623  if (hs->building_flags & BUILDING_2_TILES_Y) DoTriggerHouse(TILE_ADDXY(tile, 0, 1), trigger, random_bits, false);
624  if (hs->building_flags & BUILDING_2_TILES_X) DoTriggerHouse(TILE_ADDXY(tile, 1, 0), trigger, random_bits, false);
625  if (hs->building_flags & BUILDING_HAS_4_TILES) DoTriggerHouse(TILE_ADDXY(tile, 1, 1), trigger, random_bits, false);
626  break;
627  }
628 }
629 
630 void TriggerHouse(TileIndex t, HouseTrigger trigger)
631 {
632  DoTriggerHouse(t, trigger, 0, true);
633 }
634 
642 void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, CargoTypes trigger_cargoes, uint16 random)
643 {
644  TileIndexDiffC diff = TileIndexToTileIndexDiffC(origin, tile);
645  uint32 cb_info = random << 16 | (uint8)diff.y << 8 | (uint8)diff.x;
646  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_WATCHED_CARGO_ACCEPTED, HouseSpec::Get(GetHouseType(tile)), Town::GetByTile(tile), tile, 0, cb_info, trigger_cargoes);
647 }
648 
655 void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes)
656 {
657  assert(IsTileType(tile, MP_HOUSE));
658  HouseID id = GetHouseType(tile);
659  const HouseSpec *hs = HouseSpec::Get(id);
660 
661  trigger_cargoes &= hs->watched_cargoes;
662  /* None of the trigger cargoes is watched? */
663  if (trigger_cargoes == 0) return;
664 
665  /* Same random value for all tiles of a multi-tile house. */
666  uint16 r = Random();
667 
668  /* Do the callback, start at northern tile. */
669  TileIndex north = tile + GetHouseNorthPart(id);
670  hs = HouseSpec::Get(id);
671 
672  DoWatchedCargoCallback(north, tile, trigger_cargoes, r);
673  if (hs->building_flags & BUILDING_2_TILES_Y) DoWatchedCargoCallback(TILE_ADDXY(north, 0, 1), tile, trigger_cargoes, r);
674  if (hs->building_flags & BUILDING_2_TILES_X) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 0), tile, trigger_cargoes, r);
675  if (hs->building_flags & BUILDING_HAS_4_TILES) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 1), tile, trigger_cargoes, r);
676 }
677 
void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, CargoTypes trigger_cargoes, uint16 random)
Run the watched cargo accepted callback for a single house tile.
HouseResolverObject(HouseID house_id, TileIndex tile, Town *town, CallbackID callback=CBID_NO_CALLBACK, uint32 param1=0, uint32 param2=0, bool not_yet_constructed=false, uint8 initial_random_bits=0, CargoTypes watched_cargo_triggers=0)
Construct a resolver for a house.
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
Definition: town_cmd.cpp:2618
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:18
static Year GetHouseAge(TileIndex t)
Get the age of the house.
Definition: town_map.h:249
Definition of stuff that is very close to a company, like the company struct itself.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Tile information, used while rendering the tile.
Definition: tile_cmd.h:42
static uint32 GetNearbyTileInformation(byte parameter, TileIndex tile, bool grf_version8)
Get information about a nearby tile.
CargoTypes watched_cargoes
Cargo types watched for acceptance.
Definition: house.h:123
GrfSpecFeature GetFeature() const override
Get the feature number being resolved for.
Structure with user-data for SearchNearbyHouseXXX - functions.
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:250
synchronized callback 1B will be performed, on multi tile houses
Definition: house.h:92
Functions related to debugging.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
static void DrawNewGRFTileSeq(const struct TileInfo *ti, const DrawTileSprites *dts, TransparencyOption to, uint32 stage, PaletteID default_palette)
Draw NewGRF industrytile or house sprite layout.
Definition: sprite.h:124
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
Interface for SpriteGroup-s to access the gamestate.
uint32 GetTerrainType(TileIndex tile, TileContext context)
Function used by houses (and soon industries) to get information on type of "terrain" the tile it is ...
uint32 GetGRFID(uint16 entity_id) const
Gives the GRFID of the file the entity belongs to.
Slope tileh
Slope of the tile.
Definition: tile_cmd.h:45
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval...
Definition: station_base.h:211
Called periodically to determine if a house should be destroyed.
Called to indicate how long the current animation frame should last.
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override
static bool SearchNearbyHouseGRFID(TileIndex tile, void *user_data)
Callback function to search a house by its grfID.
Set when cargo was delivered for final delivery this month.
Definition: station_base.h:205
uint16 HouseClassID
Classes of houses.
Definition: house_type.h:14
Makes class IDs unique to each GRF file.
Definition: newgrf_house.h:85
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:205
static byte GetHouseRandomBits(TileIndex t)
Get the random bits for this house.
Definition: town_map.h:275
static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, const ObjectSpec *spec)
Draw an group of sprites on the map.
change animation when construction state changes
Resolver object to be used for houses (feature 07 spritegroups).
Definition: newgrf_house.h:51
Called to determine whether a town building can be destroyed.
Functions related to world/map generation.
uint32 reseed[VSG_END]
Collects bits to rerandomise while triggering triggers.
static void ChangeAnimationFrame(CallbackID cb, const HouseSpec *spec, Town *obj, TileIndex tile, uint32 random_bits, uint32 trigger, CargoTypes extra_data=0)
Check a callback to determine what the next animation step is and execute that step.
uint16 callback_mask
Bitmask of house callbacks that have to be called.
Definition: house.h:115
uint16 HouseID
OpenTTD ID of house types.
Definition: house_type.h:13
decides animation speed
std::set< Station *, StationCompare > StationList
List of stations.
Definition: station_type.h:94
a flat tile
Definition: slope_type.h:49
static const HouseID NUM_HOUSES
Total number of houses.
Definition: house.h:29
static void AnimateTile(const HouseSpec *spec, Town *obj, TileIndex tile, bool random_animation, CargoTypes extra_data=0)
Animate a single tile.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition: landscape.cpp:470
const HouseSpec * hs
Specs of the house that started the search.
static uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition: math_func.hpp:182
static bool IsValidHumanID(size_t index)
Is this company a valid company, not controlled by a NoAI program?
Definition: company_base.h:150
Called to determine the type (if any) of foundation to draw for house tile.
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
static byte GetHouseBuildingStage(TileIndex t)
House Construction Scheme.
Definition: town_map.h:183
Invalid cargo type.
Definition: cargo_type.h:68
int16 y
The y value of the coordinate.
Definition: map_type.h:59
Set when cargo was delivered for final delivery last month.
Definition: station_base.h:199
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:161
virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const
Return the ID (if ever available) of a previously inserted entity.
Called to determine the colour of a town building.
town buildings
Definition: transparency.h:25
static uint TileHash2Bit(uint x, uint y)
Get the last two bits of the TileHash from a tile position.
Definition: tile_map.h:334
GrfSpecFeature
Definition: newgrf.h:66
uint x
X position of the tile in unit coordinates.
Definition: tile_cmd.h:43
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
The tile has no ownership.
Definition: company_type.h:25
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:96
Action 2 handling.
TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axis axis)
Get the tile at the given offset.
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
const DrawTileSprites * ProcessRegisters(uint8 *stage) const
Process registers and the construction stage into the sprite layout.
Called when a cargo type specified in property 20 is accepted.
TileIndex tile
Tile index.
Definition: tile_cmd.h:46
The tile is leveled up to a flat slope.
Definition: slope_type.h:95
HouseClassID class_id
defines the class this house has (not grf file based)
Definition: house.h:119
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
static bool SearchNearbyHouseClass(TileIndex tile, void *user_data)
Callback function to search a house by its classID.
HouseID house_id
Type of house being queried.
Definition: newgrf_house.h:21
const StationList * GetStations()
Run a tile loop to find stations around a tile, on demand.
Functions related to NewGRF houses.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
Converts a callback result into a boolean.
trigger destruction of building
Definition of base types and functions in a cross-platform compatible way.
Function implementations related to NewGRF animation.
static void DecHouseProcessingTime(TileIndex t)
Decrease the amount of time remaining before the tile loop processes this tile.
Definition: town_map.h:336
byte processing_time
Periodic refresh multiplier.
Definition: house.h:121
#define TILE_ADDXY(tile, x, y)
Adds a given offset to a tile.
Definition: map_func.h:258
A number of safeguards to prevent using unsafe methods.
int16 x
The x value of the coordinate.
Definition: map_type.h:58
void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes)
Run watched cargo accepted callback for a house.
bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data)
Function performing a search around a center tile and going outward, thus in circle.
Definition: map.cpp:258
uint32 waiting_triggers
Waiting triggers to be used by any rerandomisation. (scope independent)
static void SetHouseRandomBits(TileIndex t, byte random)
Set the random bits for this house.
Definition: town_map.h:262
static PaletteID GroundSpritePaletteTransform(SpriteID image, PaletteID pal, PaletteID default_pal)
Applies PALETTE_MODIFIER_COLOUR to a palette entry of a ground sprite.
Definition: sprite.h:168
uint y
Y position of the tile in unit coordinates.
Definition: tile_cmd.h:44
decide the colour of the building
byte random_colour[4]
4 "random" colours
Definition: house.h:116
static byte GetHouseProcessingTime(TileIndex t)
Get the amount of time remaining before the tile loop processes this tile.
Definition: town_map.h:313
BuildingCounts< uint16 > building_counts
The number of each type of building in the town.
Definition: town.h:49
static void SetHouseProcessingTime(TileIndex t, byte time)
Set the amount of time remaining before the tile loop processes this tile.
Definition: town_map.h:325
TileIndex north_tile
Northern tile of the house.
Set when a sprite originates from an Action 1.
Definition: sprites.h:1524
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1938
decides next animation frame
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
periodically start/stop the animation
number of bits for the sprite number
Definition: sprites.h:1512
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:2195
Called whenever the construction state of a house changes.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
Converts a callback result into a boolean.
uint8 class_id
The class id within the grf file.
Definition: newgrf_house.h:87
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition: house.h:109
bool has_newhouses
Set if there are any newhouses loaded.
Definition: newgrf.h:177
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
A pair-construct of a TileIndexDiff.
Definition: map_type.h:57
Set when a vehicle ever delivered cargo to the station for final delivery.
Definition: station_base.h:193
The tile/execution is done by "water".
Definition: company_type.h:26
Functions related to companies.
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
static const PaletteID PALETTE_RECOLOUR_START
First recolour sprite for company colours.
Definition: sprites.h:1556
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:60
void DecreaseBuildingCount(Town *t, HouseID house_id)
DecreaseBuildingCount() Decrease the number of a building when it is deleted.
static byte GetHouseTriggers(TileIndex t)
Get the already activated triggers bits for this house.
Definition: town_map.h:301
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
uint32 GetRandomBits() const override
Get a few random bits.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
Helper class for a unified approach to NewGRF animation.
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition: map.cpp:157
Cargo support for NewGRFs.
static const uint HOUSE_CLASS_MAX
There can only be as many classes as there are new houses, plus one for NO_CLASS, as the original hou...
Definition: house.h:38
uint32 GetRemainingTriggers() const
Returns the waiting triggers that did not trigger any rerandomisation.
static HouseID GetHouseType(TileIndex t)
Get the type of this house, which is an index into the house spec array.
Definition: town_map.h:59
Called for periodically starting or stopping the animation.
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:215
towns and AI will not remove this house, while human players will be able to
Definition: house.h:91
static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseID house)
This function will activate a search around a central tile, looking for some houses that fit the requ...
CallbackID callback
Callback being resolved.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
callback 1A needs random bits
Definition: house.h:93
TownCache cache
Container for all cacheable data.
Definition: town.h:56
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition: house.h:28
Town data structure.
Definition: town.h:53
Functions related to OTTD&#39;s landscape.
bool TestTileOnSearchProc(TileIndex tile, void *user_data)
A callback function type for searching tiles.
Definition: map_func.h:414
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:45
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition: viewport.cpp:575
uint32 GetTriggers() const override
Get the triggers.
uint16 local_id
id defined by the grf file for this entity
decides if default foundations need to be drawn
conditional protection
static TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:179
GRFFileProps grf_prop
Properties related the the grf file.
Definition: house.h:114
Helper class for animation control.
const struct GRFFile * grffile
grf file that introduced this entity
CallbackID
List of implemented NewGRF callbacks.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Functions related to NewGRF provided sounds.
Set when calling a randomizing trigger (almost undocumented).
Base of the town class.
Functions to handle the town part of NewGRF towns.
A house by a town.
Definition: tile_type.h:44
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
static bool SearchNearbyHouseID(TileIndex tile, void *user_data)
Callback function to search a house by its HouseID.
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town...
Determine the next animation frame for a house.
static void SetHouseTriggers(TileIndex t, byte triggers)
Set the activated triggers bits for this house.
Definition: town_map.h:288
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition: newgrf.cpp:81
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:23
Structure contains cached list of stations nearby.
Definition: station_type.h:100
Base classes/functions for stations.
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
Station data structure.
Definition: station_base.h:450
#define TILE_MASK(x)
&#39;Wraps&#39; the given tile to it is within the map.
Definition: map_func.h:26
uint32 grfid
The GRF ID of the file this class belongs to.
Definition: newgrf_house.h:86
static TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition: map_func.h:316
uint32 GetDebugID() const override
Get an identifier for the item being resolved.
static const GRFFile * GetHouseSpecGrf(HouseID house_id)
Retrieve the grf file associated with a house.
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:105
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24
HouseCallbackMask
Callback masks for houses.