OpenTTD
newgrf_house.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "debug.h"
14 #include "landscape.h"
15 #include "newgrf_house.h"
16 #include "newgrf_spritegroup.h"
17 #include "newgrf_town.h"
18 #include "newgrf_sound.h"
19 #include "company_func.h"
20 #include "company_base.h"
21 #include "town.h"
22 #include "genworld.h"
23 #include "newgrf_animation_base.h"
24 #include "newgrf_cargo.h"
25 #include "station_base.h"
26 
27 #include "safeguards.h"
28 
29 static BuildingCounts<uint32> _building_counts;
30 static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX];
31 
32 HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, NUM_HOUSES, INVALID_HOUSE_ID);
33 
39 static const GRFFile *GetHouseSpecGrf(HouseID house_id)
40 {
41  const HouseSpec *hs = HouseSpec::Get(house_id);
42  return (hs != nullptr) ? hs->grf_prop.grffile : nullptr;
43 }
44 
58  CallbackID callback, uint32 param1, uint32 param2,
59  bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers)
60  : ResolverObject(GetHouseSpecGrf(house_id), callback, param1, param2),
61  house_scope(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers),
62  town_scope(*this, town, not_yet_constructed) // Don't access StorePSA if house is not yet constructed.
63 {
64  this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0];
65 }
66 
67 HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid)
68 {
69  /* Start from 1 because 0 means that no class has been assigned. */
70  for (int i = 1; i != lengthof(_class_mapping); i++) {
71  HouseClassMapping *map = &_class_mapping[i];
72 
73  if (map->class_id == grf_class_id && map->grfid == grfid) return (HouseClassID)i;
74 
75  if (map->class_id == 0 && map->grfid == 0) {
76  map->class_id = grf_class_id;
77  map->grfid = grfid;
78  return (HouseClassID)i;
79  }
80  }
81  return HOUSE_NO_CLASS;
82 }
83 
84 void InitializeBuildingCounts()
85 {
86  memset(&_building_counts, 0, sizeof(_building_counts));
87 
88  Town *t;
89  FOR_ALL_TOWNS(t) {
90  memset(&t->cache.building_counts, 0, sizeof(t->cache.building_counts));
91  }
92 }
93 
101 {
102  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
103 
105 
106  t->cache.building_counts.id_count[house_id]++;
107  _building_counts.id_count[house_id]++;
108 
109  if (class_id == HOUSE_NO_CLASS) return;
110 
111  t->cache.building_counts.class_count[class_id]++;
112  _building_counts.class_count[class_id]++;
113 }
114 
122 {
123  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
124 
126 
127  if (t->cache.building_counts.id_count[house_id] > 0) t->cache.building_counts.id_count[house_id]--;
128  if (_building_counts.id_count[house_id] > 0) _building_counts.id_count[house_id]--;
129 
130  if (class_id == HOUSE_NO_CLASS) return;
131 
132  if (t->cache.building_counts.class_count[class_id] > 0) t->cache.building_counts.class_count[class_id]--;
133  if (_building_counts.class_count[class_id] > 0) _building_counts.class_count[class_id]--;
134 }
135 
136 /* virtual */ uint32 HouseScopeResolver::GetRandomBits() const
137 {
138  /* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
139  assert(IsValidTile(this->tile) && (this->not_yet_constructed || IsTileType(this->tile, MP_HOUSE)));
140  return this->not_yet_constructed ? this->initial_random_bits : GetHouseRandomBits(this->tile);
141 }
142 
143 /* virtual */ uint32 HouseScopeResolver::GetTriggers() 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 ? 0 : GetHouseTriggers(this->tile);
148 }
149 
150 static uint32 GetNumHouses(HouseID house_id, const Town *town)
151 {
152  uint8 map_id_count, town_id_count, map_class_count, town_class_count;
153  HouseClassID class_id = HouseSpec::Get(house_id)->class_id;
154 
155  map_id_count = ClampU(_building_counts.id_count[house_id], 0, 255);
156  map_class_count = ClampU(_building_counts.class_count[class_id], 0, 255);
157  town_id_count = ClampU(town->cache.building_counts.id_count[house_id], 0, 255);
158  town_class_count = ClampU(town->cache.building_counts.class_count[class_id], 0, 255);
159 
160  return map_class_count << 24 | town_class_count << 16 | map_id_count << 8 | town_id_count;
161 }
162 
170 static uint32 GetNearbyTileInformation(byte parameter, TileIndex tile, bool grf_version8)
171 {
172  tile = GetNearbyTile(parameter, tile);
173  return GetNearbyTileInformation(tile, grf_version8);
174 }
175 
178  const HouseSpec *hs;
180 };
181 
188 static bool SearchNearbyHouseID(TileIndex tile, void *user_data)
189 {
190  if (IsTileType(tile, MP_HOUSE)) {
191  HouseID house = GetHouseType(tile); // tile been examined
192  const HouseSpec *hs = HouseSpec::Get(house);
193  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
194  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
195 
196  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
197  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
198 
199  return hs->grf_prop.local_id == nbhd->hs->grf_prop.local_id && // same local id as the one requested
200  hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
201  }
202  }
203  return false;
204 }
205 
212 static bool SearchNearbyHouseClass(TileIndex tile, void *user_data)
213 {
214  if (IsTileType(tile, MP_HOUSE)) {
215  HouseID house = GetHouseType(tile); // tile been examined
216  const HouseSpec *hs = HouseSpec::Get(house);
217  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
218  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
219 
220  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
221  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
222 
223  return hs->class_id == nbhd->hs->class_id && // same classid as the one requested
224  hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
225  }
226  }
227  return false;
228 }
229 
236 static bool SearchNearbyHouseGRFID(TileIndex tile, void *user_data)
237 {
238  if (IsTileType(tile, MP_HOUSE)) {
239  HouseID house = GetHouseType(tile); // tile been examined
240  const HouseSpec *hs = HouseSpec::Get(house);
241  if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file
242  SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data;
243 
244  TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
245  if (north_tile == nbhd->north_tile) return false; // Always ignore origin house
246 
247  return hs->grf_prop.grffile->grfid == nbhd->hs->grf_prop.grffile->grfid; // from the same grf
248  }
249  }
250  return false;
251 }
252 
263 static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseID house)
264 {
265  static TestTileOnSearchProc * const search_procs[3] = {
269  };
270  TileIndex found_tile = tile;
271  uint8 searchtype = GB(parameter, 6, 2);
272  uint8 searchradius = GB(parameter, 0, 6);
273  if (searchtype >= lengthof(search_procs)) return 0; // do not run on ill-defined code
274  if (searchradius < 1) return 0; // do not use a too low radius
275 
277  nbhd.hs = HouseSpec::Get(house);
278  nbhd.north_tile = tile + GetHouseNorthPart(house); // modifies 'house'!
279 
280  /* Use a pointer for the tile to start the search. Will be required for calculating the distance*/
281  if (CircularTileSearch(&found_tile, 2 * searchradius + 1, search_procs[searchtype], &nbhd)) {
282  return DistanceManhattan(found_tile, tile);
283  }
284  return 0;
285 }
286 
290 /* virtual */ uint32 HouseScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
291 {
292  switch (variable) {
293  /* Construction stage. */
294  case 0x40: return (IsTileType(this->tile, MP_HOUSE) ? GetHouseBuildingStage(this->tile) : 0) | TileHash2Bit(TileX(this->tile), TileY(this->tile)) << 2;
295 
296  /* Building age. */
297  case 0x41: return IsTileType(this->tile, MP_HOUSE) ? GetHouseAge(this->tile) : 0;
298 
299  /* Town zone */
300  case 0x42: return GetTownRadiusGroup(this->town, this->tile);
301 
302  /* Terrain type */
303  case 0x43: return GetTerrainType(this->tile);
304 
305  /* Number of this type of building on the map. */
306  case 0x44: return GetNumHouses(this->house_id, this->town);
307 
308  /* Whether the town is being created or just expanded. */
309  case 0x45: return _generating_world ? 1 : 0;
310 
311  /* Current animation frame. */
312  case 0x46: return IsTileType(this->tile, MP_HOUSE) ? GetAnimationFrame(this->tile) : 0;
313 
314  /* Position of the house */
315  case 0x47: return TileY(this->tile) << 16 | TileX(this->tile);
316 
317  /* Building counts for old houses with id = parameter. */
318  case 0x60: return parameter < NEW_HOUSE_OFFSET ? GetNumHouses(parameter, this->town) : 0;
319 
320  /* Building counts for new houses with id = parameter. */
321  case 0x61: {
322  const HouseSpec *hs = HouseSpec::Get(this->house_id);
323  if (hs->grf_prop.grffile == nullptr) return 0;
324 
325  HouseID new_house = _house_mngr.GetID(parameter, hs->grf_prop.grffile->grfid);
326  return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, this->town);
327  }
328 
329  /* Land info for nearby tiles. */
330  case 0x62: return GetNearbyTileInformation(parameter, this->tile, this->ro.grffile->grf_version >= 8);
331 
332  /* Current animation frame of nearby house tiles */
333  case 0x63: {
334  TileIndex testtile = GetNearbyTile(parameter, this->tile);
335  return IsTileType(testtile, MP_HOUSE) ? GetAnimationFrame(testtile) : 0;
336  }
337 
338  /* Cargo acceptance history of nearby stations */
339  case 0x64: {
340  CargoID cid = GetCargoTranslation(parameter, this->ro.grffile);
341  if (cid == CT_INVALID) return 0;
342 
343  /* Extract tile offset. */
344  int8 x_offs = GB(GetRegister(0x100), 0, 8);
345  int8 y_offs = GB(GetRegister(0x100), 8, 8);
346  TileIndex testtile = TILE_MASK(this->tile + TileDiffXY(x_offs, y_offs));
347 
348  StationFinder stations(TileArea(testtile, 1, 1));
349  const StationList *sl = stations.GetStations();
350 
351  /* Collect acceptance stats. */
352  uint32 res = 0;
353  for (Station *st : *sl) {
354  if (HasBit(st->goods[cid].status, GoodsEntry::GES_EVER_ACCEPTED)) SetBit(res, 0);
355  if (HasBit(st->goods[cid].status, GoodsEntry::GES_LAST_MONTH)) SetBit(res, 1);
356  if (HasBit(st->goods[cid].status, GoodsEntry::GES_CURRENT_MONTH)) SetBit(res, 2);
357  if (HasBit(st->goods[cid].status, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(res, 3);
358  }
359 
360  /* Cargo triggered CB 148? */
361  if (HasBit(this->watched_cargo_triggers, cid)) SetBit(res, 4);
362 
363  return res;
364  }
365 
366  /* Distance test for some house types */
367  case 0x65: return GetDistanceFromNearbyHouse(parameter, this->tile, this->house_id);
368 
369  /* Class and ID of nearby house tile */
370  case 0x66: {
371  TileIndex testtile = GetNearbyTile(parameter, this->tile);
372  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
373  HouseID nearby_house_id = GetHouseType(testtile);
374  HouseSpec *hs = HouseSpec::Get(nearby_house_id);
375  /* Information about the grf local classid if the house has a class */
376  uint houseclass = 0;
377  if (hs->class_id != HOUSE_NO_CLASS) {
378  houseclass = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
379  houseclass |= _class_mapping[hs->class_id].class_id;
380  }
381  /* old house type or grf-local houseid */
382  uint local_houseid = 0;
383  if (nearby_house_id < NEW_HOUSE_OFFSET) {
384  local_houseid = nearby_house_id;
385  } else {
386  local_houseid = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
387  local_houseid |= hs->grf_prop.local_id;
388  }
389  return houseclass << 16 | local_houseid;
390  }
391 
392  /* GRFID of nearby house tile */
393  case 0x67: {
394  TileIndex testtile = GetNearbyTile(parameter, this->tile);
395  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
396  HouseID house_id = GetHouseType(testtile);
397  if (house_id < NEW_HOUSE_OFFSET) return 0;
398  /* Checking the grffile information via HouseSpec doesn't work
399  * in case the newgrf was removed. */
400  return _house_mngr.GetGRFID(house_id);
401  }
402  }
403 
404  DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
405 
406  *available = false;
407  return UINT_MAX;
408 }
409 
410 uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile,
411  bool not_yet_constructed, uint8 initial_random_bits, CargoTypes watched_cargo_triggers)
412 {
413  assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
414 
415  HouseResolverObject object(house_id, tile, town, callback, param1, param2,
416  not_yet_constructed, initial_random_bits, watched_cargo_triggers);
417  return object.ResolveCallback();
418 }
419 
420 static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte stage, HouseID house_id)
421 {
422  const DrawTileSprites *dts = group->ProcessRegisters(&stage);
423 
424  const HouseSpec *hs = HouseSpec::Get(house_id);
425  PaletteID palette = hs->random_colour[TileHash2Bit(ti->x, ti->y)] + PALETTE_RECOLOUR_START;
427  uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
428  if (callback != CALLBACK_FAILED) {
429  /* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
430  palette = HasBit(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
431  }
432  }
433 
434  SpriteID image = dts->ground.sprite;
435  PaletteID pal = dts->ground.pal;
436 
437  if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) image += stage;
438  if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += stage;
439 
440  if (GB(image, 0, SPRITE_WIDTH) != 0) {
441  DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
442  }
443 
444  DrawNewGRFTileSeq(ti, dts, TO_HOUSES, stage, palette);
445 }
446 
447 void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
448 {
449  const HouseSpec *hs = HouseSpec::Get(house_id);
450 
451  if (ti->tileh != SLOPE_FLAT) {
452  bool draw_old_one = true;
454  /* Called to determine the type (if any) of foundation to draw for the house tile */
455  uint32 callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
456  if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res);
457  }
458 
459  if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
460  }
461 
462  HouseResolverObject object(house_id, ti->tile, Town::GetByTile(ti->tile));
463 
464  const SpriteGroup *group = object.Resolve();
465  if (group != nullptr && group->type == SGT_TILELAYOUT) {
466  /* Limit the building stage to the number of stages supplied. */
467  const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
468  byte stage = GetHouseBuildingStage(ti->tile);
469  DrawTileLayout(ti, tlgroup, stage, house_id);
470  }
471 }
472 
473 /* Simple wrapper for GetHouseCallback to keep the animation unified. */
474 uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, CargoTypes extra_data)
475 {
476  return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data);
477 }
478 
480 struct HouseAnimationBase : public AnimationBase<HouseAnimationBase, HouseSpec, Town, CargoTypes, GetSimpleHouseCallback> {
481  static const CallbackID cb_animation_speed = CBID_HOUSE_ANIMATION_SPEED;
482  static const CallbackID cb_animation_next_frame = CBID_HOUSE_ANIMATION_NEXT_FRAME;
483 
484  static const HouseCallbackMask cbm_animation_speed = CBM_HOUSE_ANIMATION_SPEED;
485  static const HouseCallbackMask cbm_animation_next_frame = CBM_HOUSE_ANIMATION_NEXT_FRAME;
486 };
487 
488 void AnimateNewHouseTile(TileIndex tile)
489 {
490  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
491  if (hs == nullptr) return;
492 
493  HouseAnimationBase::AnimateTile(hs, Town::GetByTile(tile), tile, HasBit(hs->extra_flags, CALLBACK_1A_RANDOM_BITS));
494 }
495 
496 void AnimateNewHouseConstruction(TileIndex tile)
497 {
498  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
499 
502  }
503 }
504 
505 bool CanDeleteHouse(TileIndex tile)
506 {
507  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
508 
509  /* Humans are always allowed to remove buildings, as is water and disasters and
510  * anyone using the scenario editor. */
512  return true;
513  }
514 
516  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
517  return (callback_res == CALLBACK_FAILED || !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DENY_DESTRUCTION, callback_res));
518  } else {
519  return !(hs->extra_flags & BUILDING_IS_PROTECTED);
520  }
521 }
522 
523 static void AnimationControl(TileIndex tile, uint16 random_bits)
524 {
525  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
526 
528  uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random();
529  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_ANIMATION_START_STOP, hs, Town::GetByTile(tile), tile, param, 0);
530  }
531 }
532 
533 bool NewHouseTileLoop(TileIndex tile)
534 {
535  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
536 
537  if (GetHouseProcessingTime(tile) > 0) {
539  return true;
540  }
541 
542  TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP);
543  if (hs->building_flags & BUILDING_HAS_1_TILE) TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP_TOP);
544 
546  /* If this house is marked as having a synchronised callback, all the
547  * tiles will have the callback called at once, rather than when the
548  * tile loop reaches them. This should only be enabled for the northern
549  * tile, or strange things will happen (here, and in TTDPatch). */
551  uint16 random = GB(Random(), 0, 16);
552 
553  if (hs->building_flags & BUILDING_HAS_1_TILE) AnimationControl(tile, random);
554  if (hs->building_flags & BUILDING_2_TILES_Y) AnimationControl(TILE_ADDXY(tile, 0, 1), random);
555  if (hs->building_flags & BUILDING_2_TILES_X) AnimationControl(TILE_ADDXY(tile, 1, 0), random);
556  if (hs->building_flags & BUILDING_HAS_4_TILES) AnimationControl(TILE_ADDXY(tile, 1, 1), random);
557  } else {
558  AnimationControl(tile, 0);
559  }
560  }
561 
562  /* Check callback 21, which determines if a house should be destroyed. */
564  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
565  if (callback_res != CALLBACK_FAILED && Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DESTRUCTION, callback_res)) {
566  ClearTownHouse(Town::GetByTile(tile), tile);
567  return false;
568  }
569  }
570 
572  MarkTileDirtyByTile(tile);
573  return true;
574 }
575 
576 static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_random, bool first)
577 {
578  /* We can't trigger a non-existent building... */
579  assert(IsTileType(tile, MP_HOUSE));
580 
581  HouseID hid = GetHouseType(tile);
582  HouseSpec *hs = HouseSpec::Get(hid);
583 
584  if (hs->grf_prop.spritegroup[0] == nullptr) return;
585 
586  HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER);
587  object.waiting_triggers = GetHouseTriggers(tile) | trigger;
588  SetHouseTriggers(tile, object.waiting_triggers); // store now for var 5F
589 
590  const SpriteGroup *group = object.Resolve();
591  if (group == nullptr) return;
592 
593  /* Store remaining triggers. */
594  SetHouseTriggers(tile, object.GetRemainingTriggers());
595 
596  /* Rerandomise bits. Scopes other than SELF are invalid for houses. For bug-to-bug-compatibility with TTDP we ignore the scope. */
597  byte new_random_bits = Random();
598  byte random_bits = GetHouseRandomBits(tile);
599  uint32 reseed = object.GetReseedSum();
600  random_bits &= ~reseed;
601  random_bits |= (first ? new_random_bits : base_random) & reseed;
602  SetHouseRandomBits(tile, random_bits);
603 
604  switch (trigger) {
605  case HOUSE_TRIGGER_TILE_LOOP:
606  /* Random value already set. */
607  break;
608 
609  case HOUSE_TRIGGER_TILE_LOOP_TOP:
610  if (!first) {
611  /* The top tile is marked dirty by the usual TileLoop */
612  MarkTileDirtyByTile(tile);
613  break;
614  }
615  /* Random value of first tile already set. */
616  if (hs->building_flags & BUILDING_2_TILES_Y) DoTriggerHouse(TILE_ADDXY(tile, 0, 1), trigger, random_bits, false);
617  if (hs->building_flags & BUILDING_2_TILES_X) DoTriggerHouse(TILE_ADDXY(tile, 1, 0), trigger, random_bits, false);
618  if (hs->building_flags & BUILDING_HAS_4_TILES) DoTriggerHouse(TILE_ADDXY(tile, 1, 1), trigger, random_bits, false);
619  break;
620  }
621 }
622 
623 void TriggerHouse(TileIndex t, HouseTrigger trigger)
624 {
625  DoTriggerHouse(t, trigger, 0, true);
626 }
627 
635 void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, CargoTypes trigger_cargoes, uint16 random)
636 {
637  TileIndexDiffC diff = TileIndexToTileIndexDiffC(origin, tile);
638  uint32 cb_info = random << 16 | (uint8)diff.y << 8 | (uint8)diff.x;
639  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_WATCHED_CARGO_ACCEPTED, HouseSpec::Get(GetHouseType(tile)), Town::GetByTile(tile), tile, 0, cb_info, trigger_cargoes);
640 }
641 
648 void WatchedCargoCallback(TileIndex tile, CargoTypes trigger_cargoes)
649 {
650  assert(IsTileType(tile, MP_HOUSE));
651  HouseID id = GetHouseType(tile);
652  const HouseSpec *hs = HouseSpec::Get(id);
653 
654  trigger_cargoes &= hs->watched_cargoes;
655  /* None of the trigger cargoes is watched? */
656  if (trigger_cargoes == 0) return;
657 
658  /* Same random value for all tiles of a multi-tile house. */
659  uint16 r = Random();
660 
661  /* Do the callback, start at northern tile. */
662  TileIndex north = tile + GetHouseNorthPart(id);
663  hs = HouseSpec::Get(id);
664 
665  DoWatchedCargoCallback(north, tile, trigger_cargoes, r);
666  if (hs->building_flags & BUILDING_2_TILES_Y) DoWatchedCargoCallback(TILE_ADDXY(north, 0, 1), tile, trigger_cargoes, r);
667  if (hs->building_flags & BUILDING_2_TILES_X) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 0), tile, trigger_cargoes, r);
668  if (hs->building_flags & BUILDING_HAS_4_TILES) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 1), tile, trigger_cargoes, r);
669 }
670 
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:2614
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:20
static Year GetHouseAge(TileIndex t)
Get the age of the house.
Definition: town_map.h:251
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:44
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:125
Structure with user-data for SearchNearbyHouseXXX - functions.
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:252
synchronized callback 1B will be performed, on multi tile houses
Definition: house.h:94
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:126
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:47
Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval...
Definition: station_base.h:213
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:207
uint16 HouseClassID
Classes of houses.
Definition: house_type.h:16
Makes class IDs unique to each GRF file.
Definition: newgrf_house.h:84
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:207
static byte GetHouseRandomBits(TileIndex t)
Get the random bits for this house.
Definition: town_map.h:277
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:53
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:117
uint16 HouseID
OpenTTD ID of house types.
Definition: house_type.h:15
decides animation speed
std::set< Station *, StationCompare > StationList
List of stations.
Definition: station_type.h:96
a flat tile
Definition: slope_type.h:51
static const HouseID NUM_HOUSES
Total number of houses.
Definition: house.h:31
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:472
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:184
static bool IsValidHumanID(size_t index)
Is this company a valid company, not controlled by a NoAI program?
Definition: company_base.h:152
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:185
Invalid cargo type.
Definition: cargo_type.h:70
int16 y
The y value of the coordinate.
Definition: map_type.h:61
Set when cargo was delivered for final delivery last month.
Definition: station_base.h:201
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:163
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:27
static uint TileHash2Bit(uint x, uint y)
Get the last two bits of the TileHash from a tile position.
Definition: tile_map.h:336
uint x
X position of the tile in unit coordinates.
Definition: tile_cmd.h:45
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
The tile has no ownership.
Definition: company_type.h:27
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:98
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:152
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:48
The tile is leveled up to a flat slope.
Definition: slope_type.h:97
HouseClassID class_id
defines the class this house has (not grf file based)
Definition: house.h:121
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:60
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:338
byte processing_time
Periodic refresh multiplier.
Definition: house.h:123
#define TILE_ADDXY(tile, x, y)
Adds a given offset to a tile.
Definition: map_func.h:260
A number of safeguards to prevent using unsafe methods.
int16 x
The x value of the coordinate.
Definition: map_type.h:60
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:260
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:264
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:170
uint y
Y position of the tile in unit coordinates.
Definition: tile_cmd.h:46
decide the colour of the building
byte random_colour[4]
4 "random" colours
Definition: house.h:118
static byte GetHouseProcessingTime(TileIndex t)
Get the amount of time remaining before the tile loop processes this tile.
Definition: town_map.h:315
BuildingCounts< uint16 > building_counts
The number of each type of building in the town.
Definition: town.h:51
static void SetHouseProcessingTime(TileIndex t, byte time)
Set the amount of time remaining before the tile loop processes this tile.
Definition: town_map.h:327
TileIndex north_tile
Northern tile of the house.
Set when a sprite originates from an Action 1.
Definition: sprites.h:1526
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:1940
decides next animation frame
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
periodically start/stop the animation
number of bits for the sprite number
Definition: sprites.h:1514
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:2191
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:86
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:111
bool has_newhouses
Set if there are any newhouses loaded.
Definition: newgrf.h:179
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:37
A pair-construct of a TileIndexDiff.
Definition: map_type.h:59
Set when a vehicle ever delivered cargo to the station for final delivery.
Definition: station_base.h:195
The tile/execution is done by "water".
Definition: company_type.h:28
Functions related to companies.
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:61
static const PaletteID PALETTE_RECOLOUR_START
First recolour sprite for company colours.
Definition: sprites.h:1558
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:62
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:303
HouseExtraFlags extra_flags
some more flags
Definition: house.h:120
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:19
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
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:159
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:40
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:61
Called for periodically starting or stopping the animation.
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:217
towns and AI will not remove this house, while human players will be able to
Definition: house.h:93
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:95
TownCache cache
Container for all cacheable data.
Definition: town.h:58
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition: house.h:30
Town data structure.
Definition: town.h:55
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:416
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
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:577
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:181
GRFFileProps grf_prop
Properties related the the grf file.
Definition: house.h:116
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:46
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
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:290
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition: newgrf.cpp:78
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
Structure contains cached list of stations nearby.
Definition: station_type.h:102
Base classes/functions for stations.
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
Station data structure.
Definition: station_base.h:452
#define TILE_MASK(x)
&#39;Wraps&#39; the given tile to it is within the map.
Definition: map_func.h:28
uint32 grfid
The GRF ID of the file this class belongs to.
Definition: newgrf_house.h:85
static TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition: map_func.h:318
static const GRFFile * GetHouseSpecGrf(HouseID house_id)
Retrieve the grf file associated with a house.
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:107
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26
HouseCallbackMask
Callback masks for houses.