OpenTTD
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 
65 HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid)
66 {
67  /* Start from 1 because 0 means that no class has been assigned. */
68  for (int i = 1; i != lengthof(_class_mapping); i++) {
69  HouseClassMapping *map = &_class_mapping[i];
70 
71  if (map->class_id == grf_class_id && map->grfid == grfid) return (HouseClassID)i;
72 
73  if (map->class_id == 0 && map->grfid == 0) {
74  map->class_id = grf_class_id;
75  map->grfid = grfid;
76  return (HouseClassID)i;
77  }
78  }
79  return HOUSE_NO_CLASS;
80 }
81 
82 void InitializeBuildingCounts()
83 {
84  memset(&_building_counts, 0, sizeof(_building_counts));
85 
86  for (Town *t : Town::Iterate()) {
87  memset(&t->cache.building_counts, 0, sizeof(t->cache.building_counts));
88  }
89 }
90 
98 {
99  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
100 
102 
103  t->cache.building_counts.id_count[house_id]++;
104  _building_counts.id_count[house_id]++;
105 
106  if (class_id == HOUSE_NO_CLASS) return;
107 
108  t->cache.building_counts.class_count[class_id]++;
109  _building_counts.class_count[class_id]++;
110 }
111 
119 {
120  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
121 
123 
124  if (t->cache.building_counts.id_count[house_id] > 0) t->cache.building_counts.id_count[house_id]--;
125  if (_building_counts.id_count[house_id] > 0) _building_counts.id_count[house_id]--;
126 
127  if (class_id == HOUSE_NO_CLASS) return;
128 
129  if (t->cache.building_counts.class_count[class_id] > 0) t->cache.building_counts.class_count[class_id]--;
130  if (_building_counts.class_count[class_id] > 0) _building_counts.class_count[class_id]--;
131 }
132 
133 /* virtual */ uint32 HouseScopeResolver::GetRandomBits() const
134 {
135  /* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
136  assert(IsValidTile(this->tile) && (this->not_yet_constructed || IsTileType(this->tile, MP_HOUSE)));
137  return this->not_yet_constructed ? this->initial_random_bits : GetHouseRandomBits(this->tile);
138 }
139 
140 /* virtual */ uint32 HouseScopeResolver::GetTriggers() const
141 {
142  /* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
143  assert(IsValidTile(this->tile) && (this->not_yet_constructed || IsTileType(this->tile, MP_HOUSE)));
144  return this->not_yet_constructed ? 0 : GetHouseTriggers(this->tile);
145 }
146 
147 static uint32 GetNumHouses(HouseID house_id, const Town *town)
148 {
149  uint8 map_id_count, town_id_count, map_class_count, town_class_count;
150  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
151 
152  map_id_count = ClampU(_building_counts.id_count[house_id], 0, 255);
153  map_class_count = ClampU(_building_counts.class_count[class_id], 0, 255);
154  town_id_count = ClampU(town->cache.building_counts.id_count[house_id], 0, 255);
155  town_class_count = ClampU(town->cache.building_counts.class_count[class_id], 0, 255);
156 
157  return map_class_count << 24 | town_class_count << 16 | map_id_count << 8 | town_id_count;
158 }
159 
167 static uint32 GetNearbyTileInformation(byte parameter, TileIndex tile, bool grf_version8)
168 {
169  tile = GetNearbyTile(parameter, tile);
170  return GetNearbyTileInformation(tile, grf_version8);
171 }
172 
175  const HouseSpec *hs;
177 };
178 
185 static bool SearchNearbyHouseID(TileIndex tile, void *user_data)
186 {
187  if (IsTileType(tile, MP_HOUSE)) {
188  HouseID house = GetHouseType(tile); // tile been examined
189  const HouseSpec *hs = HouseSpec::Get(house);
190  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
191  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
192 
193  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
194  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
195 
196  return hs->grf_prop.local_id == nbhd->hs->grf_prop.local_id && // same local id as the one requested
197  hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
198  }
199  }
200  return false;
201 }
202 
209 static bool SearchNearbyHouseClass(TileIndex tile, void *user_data)
210 {
211  if (IsTileType(tile, MP_HOUSE)) {
212  HouseID house = GetHouseType(tile); // tile been examined
213  const HouseSpec *hs = HouseSpec::Get(house);
214  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
215  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
216 
217  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
218  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
219 
220  return hs->class_id == nbhd->hs->class_id && // same classid as the one requested
221  hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
222  }
223  }
224  return false;
225 }
226 
233 static bool SearchNearbyHouseGRFID(TileIndex tile, void *user_data)
234 {
235  if (IsTileType(tile, MP_HOUSE)) {
236  HouseID house = GetHouseType(tile); // tile been examined
237  const HouseSpec *hs = HouseSpec::Get(house);
238  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
239  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
240 
241  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
242  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
243 
244  return hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
245  }
246  }
247  return false;
248 }
249 
260 static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseID house)
261 {
262  static TestTileOnSearchProc * const search_procs[3] = {
266  };
267  TileIndex found_tile = tile;
268  uint8 searchtype = GB(parameter, 6, 2);
269  uint8 searchradius = GB(parameter, 0, 6);
270  if (searchtype >= lengthof(search_procs)) return 0; // do not run on ill-defined code
271  if (searchradius < 1) return 0; // do not use a too low radius
272 
274  nbhd.hs = HouseSpec::Get(house);
275  nbhd.north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
276 
277  /* Use a pointer for the tile to start the search. Will be required for calculating the distance*/
278  if (CircularTileSearch(&found_tile, 2 * searchradius + 1, search_procs[searchtype], &nbhd)) {
279  return DistanceManhattan(found_tile, tile);
280  }
281  return 0;
282 }
283 
287 /* virtual */ uint32 HouseScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
288 {
289  switch (variable) {
290  /* Construction stage. */
291  case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2;
292 
293  /* Building age. */
294  case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0;
295 
296  /* Town zone */
297  case 0x42: return GetTownRadiusGroup(this->town, this->tile);
298 
299  /* Terrain type */
300  case 0x43: return GetTerrainType(this->tile);
301 
302  /* Number of this type of building on the map. */
303  case 0x44: return GetNumHouses(this->house_id, this->town);
304 
305  /* Whether the town is being created or just expanded. */
306  case 0x45: return _generating_world ? 1 : 0;
307 
308  /* Current animation frame. */
309  case 0x46: return IsTileType(this->tile, MP_HOUSE) ? GetAnimationFrame(this->tile) : 0;
310 
311  /* Position of the house */
312  case 0x47: return TileY(this->tile) << 16 | TileX(this->tile);
313 
314  /* Building counts for old houses with id = parameter. */
315  case 0x60: return parameter < NEW_HOUSE_OFFSET ? GetNumHouses(parameter, this->town) : 0;
316 
317  /* Building counts for new houses with id = parameter. */
318  case 0x61: {
319  const HouseSpec *hs = HouseSpec::Get(this->house_id);
320  if (hs->grf_prop.grffile == nullptr) return 0;
321 
322  HouseID new_house = _house_mngr.GetID(parameter, hs->grf_prop.grffile->grfid);
323  return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, this->town);
324  }
325 
326  /* Land info for nearby tiles. */
327  case 0x62: return GetNearbyTileInformation(parameter, this->tile, this->ro.grffile->grf_version >= 8);
328 
329  /* Current animation frame of nearby house tiles */
330  case 0x63: {
331  TileIndex testtile = GetNearbyTile(parameter, this->tile);
332  return IsTileType(testtile, MP_HOUSE) ? GetAnimationFrame(testtile) : 0;
333  }
334 
335  /* Cargo acceptance history of nearby stations */
336  case 0x64: {
337  CargoID cid = GetCargoTranslation(parameter, this->ro.grffile);
338  if (cid == CT_INVALID) return 0;
339 
340  /* Extract tile offset. */
341  int8 x_offs = GB(GetRegister(0x100), 0, 8);
342  int8 y_offs = GB(GetRegister(0x100), 8, 8);
343  TileIndex testtile = TILE_MASK(this->tile + TileDiffXY(x_offs, y_offs));
344 
345  StationFinder stations(TileArea(testtile, 1, 1));
346  const StationList *sl = stations.GetStations();
347 
348  /* Collect acceptance stats. */
349  uint32 res = 0;
350  for (Station *st : *sl) {
351  if (HasBit(st->goods[cid].status, GoodsEntry::GES_EVER_ACCEPTED)) SetBit(res, 0);
352  if (HasBit(st->goods[cid].status, GoodsEntry::GES_LAST_MONTH)) SetBit(res, 1);
353  if (HasBit(st->goods[cid].status, GoodsEntry::GES_CURRENT_MONTH)) SetBit(res, 2);
354  if (HasBit(st->goods[cid].status, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(res, 3);
355  }
356 
357  /* Cargo triggered CB 148? */
358  if (HasBit(this->watched_cargo_triggers, cid)) SetBit(res, 4);
359 
360  return res;
361  }
362 
363  /* Distance test for some house types */
364  case 0x65: return GetDistanceFromNearbyHouse(parameter, this->tile, this->house_id);
365 
366  /* Class and ID of nearby house tile */
367  case 0x66: {
368  TileIndex testtile = GetNearbyTile(parameter, this->tile);
369  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
370  HouseID nearby_house_id = GetHouseType(testtile);
371  HouseSpec *hs = HouseSpec::Get(nearby_house_id);
372  /* Information about the grf local classid if the house has a class */
373  uint houseclass = 0;
374  if (hs->class_id != HOUSE_NO_CLASS) {
375  houseclass = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
376  houseclass |= _class_mapping[hs->class_id].class_id;
377  }
378  /* old house type or grf-local houseid */
379  uint local_houseid = 0;
380  if (nearby_house_id < NEW_HOUSE_OFFSET) {
381  local_houseid = nearby_house_id;
382  } else {
383  local_houseid = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
384  local_houseid |= hs->grf_prop.local_id;
385  }
386  return houseclass << 16 | local_houseid;
387  }
388 
389  /* GRFID of nearby house tile */
390  case 0x67: {
391  TileIndex testtile = GetNearbyTile(parameter, this->tile);
392  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
393  HouseID house_id = GetHouseType(testtile);
394  if (house_id < NEW_HOUSE_OFFSET) return 0;
395  /* Checking the grffile information via HouseSpec doesn't work
396  * in case the newgrf was removed. */
397  return _house_mngr.GetGRFID(house_id);
398  }
399  }
400 
401  DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
402 
403  *available = false;
404  return UINT_MAX;
405 }
406 
407 uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile,
408  bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers)
409 {
410  assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
411 
412  HouseResolverObject object(house_id, tile, town, callback, param1, param2,
413  not_yet_constructed, initial_random_bits, watched_cargo_triggers);
414  return object.ResolveCallback();
415 }
416 
417 static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte stage, HouseID house_id)
418 {
419  const DrawTileSprites *dts = group->ProcessRegisters(&stage);
420 
421  const HouseSpec *hs = HouseSpec::Get(house_id);
422  PaletteID palette = hs->random_colour[TileHash2Bit(ti->x, ti->y)] + PALETTE_RECOLOUR_START;
424  uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
425  if (callback != CALLBACK_FAILED) {
426  /* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
427  palette = HasBit(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
428  }
429  }
430 
431  SpriteID image = dts->ground.sprite;
432  PaletteID pal = dts->ground.pal;
433 
434  if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) image += stage;
435  if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += stage;
436 
437  if (GB(image, 0, SPRITE_WIDTH) != 0) {
438  DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
439  }
440 
441  DrawNewGRFTileSeq(ti, dts, TO_HOUSES, stage, palette);
442 }
443 
444 void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
445 {
446  const HouseSpec *hs = HouseSpec::Get(house_id);
447 
448  if (ti->tileh != SLOPE_FLAT) {
449  bool draw_old_one = true;
451  /* Called to determine the type (if any) of foundation to draw for the house tile */
452  uint32 callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
453  if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res);
454  }
455 
456  if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
457  }
458 
459  HouseResolverObject object(house_id, ti->tile, Town::GetByTile(ti->tile));
460 
461  const SpriteGroup *group = object.Resolve();
462  if (group != nullptr && group->type == SGT_TILELAYOUT) {
463  /* Limit the building stage to the number of stages supplied. */
464  const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
465  byte stage = GetHouseBuildingStage(ti->tile);
466  DrawTileLayout(ti, tlgroup, stage, house_id);
467  }
468 }
469 
470 /* Simple wrapper for GetHouseCallback to keep the animation unified. */
471 uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, CargoTypes extra_data)
472 {
473  return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data);
474 }
475 
477 struct HouseAnimationBase : public AnimationBase<HouseAnimationBase, HouseSpec, Town, CargoTypes, GetSimpleHouseCallback> {
478  static const CallbackID cb_animation_speed = CBID_HOUSE_ANIMATION_SPEED;
479  static const CallbackID cb_animation_next_frame = CBID_HOUSE_ANIMATION_NEXT_FRAME;
480 
481  static const HouseCallbackMask cbm_animation_speed = CBM_HOUSE_ANIMATION_SPEED;
482  static const HouseCallbackMask cbm_animation_next_frame = CBM_HOUSE_ANIMATION_NEXT_FRAME;
483 };
484 
485 void AnimateNewHouseTile(TileIndex tile)
486 {
487  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
488  if (hs == nullptr) return;
489 
490  HouseAnimationBase::AnimateTile(hs, Town::GetByTile(tile), tile, HasBit(hs->extra_flags, CALLBACK_1A_RANDOM_BITS));
491 }
492 
493 void AnimateNewHouseConstruction(TileIndex tile)
494 {
495  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
496 
499  }
500 }
501 
502 bool CanDeleteHouse(TileIndex tile)
503 {
504  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
505 
506  /* Humans are always allowed to remove buildings, as is water and disasters and
507  * anyone using the scenario editor. */
509  return true;
510  }
511 
513  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
514  return (callback_res == CALLBACK_FAILED || !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DENY_DESTRUCTION, callback_res));
515  } else {
516  return !(hs->extra_flags & BUILDING_IS_PROTECTED);
517  }
518 }
519 
520 static void AnimationControl(TileIndex tile, uint16 random_bits)
521 {
522  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
523 
525  uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random();
526  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_ANIMATION_START_STOP, hs, Town::GetByTile(tile), tile, param, 0);
527  }
528 }
529 
530 bool NewHouseTileLoop(TileIndex tile)
531 {
532  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
533 
534  if (GetHouseProcessingTime(tile) > 0) {
536  return true;
537  }
538 
539  TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP);
540  if (hs->building_flags & BUILDING_HAS_1_TILE) TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP_TOP);
541 
543  /* If this house is marked as having a synchronised callback, all the
544  * tiles will have the callback called at once, rather than when the
545  * tile loop reaches them. This should only be enabled for the northern
546  * tile, or strange things will happen (here, and in TTDPatch). */
548  uint16 random = GB(Random(), 0, 16);
549 
550  if (hs->building_flags & BUILDING_HAS_1_TILE) AnimationControl(tile, random);
551  if (hs->building_flags & BUILDING_2_TILES_Y) AnimationControl(TILE_ADDXY(tile, 0, 1), random);
552  if (hs->building_flags & BUILDING_2_TILES_X) AnimationControl(TILE_ADDXY(tile, 1, 0), random);
553  if (hs->building_flags & BUILDING_HAS_4_TILES) AnimationControl(TILE_ADDXY(tile, 1, 1), random);
554  } else {
555  AnimationControl(tile, 0);
556  }
557  }
558 
559  /* Check callback 21, which determines if a house should be destroyed. */
561  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
562  if (callback_res != CALLBACK_FAILED && Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DESTRUCTION, callback_res)) {
563  ClearTownHouse(Town::GetByTile(tile), tile);
564  return false;
565  }
566  }
567 
569  MarkTileDirtyByTile(tile);
570  return true;
571 }
572 
573 static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_random, bool first)
574 {
575  /* We can't trigger a non-existent building... */
576  assert(IsTileType(tile, MP_HOUSE));
577 
578  HouseID hid = GetHouseType(tile);
579  HouseSpec *hs = HouseSpec::Get(hid);
580 
581  if (hs->grf_prop.spritegroup[0] == nullptr) return;
582 
583  HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER);
584  object.waiting_triggers = GetHouseTriggers(tile) | trigger;
585  SetHouseTriggers(tile, object.waiting_triggers); // store now for var 5F
586 
587  const SpriteGroup *group = object.Resolve();
588  if (group == nullptr) return;
589 
590  /* Store remaining triggers. */
591  SetHouseTriggers(tile, object.GetRemainingTriggers());
592 
593  /* Rerandomise bits. Scopes other than SELF are invalid for houses. For bug-to-bug-compatibility with TTDP we ignore the scope. */
594  byte new_random_bits = Random();
595  byte random_bits = GetHouseRandomBits(tile);
596  uint32 reseed = object.GetReseedSum();
597  random_bits &= ~reseed;
598  random_bits |= (first ? new_random_bits : base_random) & reseed;
599  SetHouseRandomBits(tile, random_bits);
600 
601  switch (trigger) {
602  case HOUSE_TRIGGER_TILE_LOOP:
603  /* Random value already set. */
604  break;
605 
606  case HOUSE_TRIGGER_TILE_LOOP_TOP:
607  if (!first) {
608  /* The top tile is marked dirty by the usual TileLoop */
609  MarkTileDirtyByTile(tile);
610  break;
611  }
612  /* Random value of first tile already set. */
613  if (hs->building_flags & BUILDING_2_TILES_Y) DoTriggerHouse(TILE_ADDXY(tile, 0, 1), trigger, random_bits, false);
614  if (hs->building_flags & BUILDING_2_TILES_X) DoTriggerHouse(TILE_ADDXY(tile, 1, 0), trigger, random_bits, false);
615  if (hs->building_flags & BUILDING_HAS_4_TILES) DoTriggerHouse(TILE_ADDXY(tile, 1, 1), trigger, random_bits, false);
616  break;
617  }
618 }
619 
620 void TriggerHouse(TileIndex t, HouseTrigger trigger)
621 {
622  DoTriggerHouse(t, trigger, 0, true);
623 }
624 
632 void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, CargoTypes trigger_cargoes, uint16 random)
633 {
634  TileIndexDiffC diff = TileIndexToTileIndexDiffC(origin, tile);
635  uint32 cb_info = random << 16 | (uint8)diff.y << 8 | (uint8)diff.x;
636  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_WATCHED_CARGO_ACCEPTED, HouseSpec::Get(GetHouseType(tile)), Town::GetByTile(tile), tile, 0, cb_info, trigger_cargoes);
637 }
638 
645 void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes)
646 {
647  assert(IsTileType(tile, MP_HOUSE));
648  HouseID id = GetHouseType(tile);
649  const HouseSpec *hs = HouseSpec::Get(id);
650 
651  trigger_cargoes &= hs->watched_cargoes;
652  /* None of the trigger cargoes is watched? */
653  if (trigger_cargoes == 0) return;
654 
655  /* Same random value for all tiles of a multi-tile house. */
656  uint16 r = Random();
657 
658  /* Do the callback, start at northern tile. */
659  TileIndex north = tile + GetHouseNorthPart(id);
660  hs = HouseSpec::Get(id);
661 
662  DoWatchedCargoCallback(north, tile, trigger_cargoes, r);
663  if (hs->building_flags & BUILDING_2_TILES_Y) DoWatchedCargoCallback(TILE_ADDXY(north, 0, 1), tile, trigger_cargoes, r);
664  if (hs->building_flags & BUILDING_2_TILES_X) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 0), tile, trigger_cargoes, r);
665  if (hs->building_flags & BUILDING_HAS_4_TILES) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 1), tile, trigger_cargoes, r);
666 }
667 
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:2604
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
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:82
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
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.
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:2181
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:84
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:340
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:76
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:83
static TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition: map_func.h:316
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.