OpenTTD
newgrf_house.cpp
Go to the documentation of this file.
1 /* $Id: newgrf_house.cpp 27984 2018-03-11 13:19:41Z frosch $ */
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 != NULL) ? hs->grf_prop.grffile : NULL;
43 }
44 
58  CallbackID callback, uint32 param1, uint32 param2,
59  bool not_yet_constructed, uint8 initial_random_bits, uint32 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 != NULL) { // 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 != NULL) { // 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 != NULL) { // 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 == NULL) 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 * const * st_iter = sl->Begin(); st_iter != sl->End(); st_iter++) {
354  const Station *st = *st_iter;
355  if (HasBit(st->goods[cid].status, GoodsEntry::GES_EVER_ACCEPTED)) SetBit(res, 0);
356  if (HasBit(st->goods[cid].status, GoodsEntry::GES_LAST_MONTH)) SetBit(res, 1);
357  if (HasBit(st->goods[cid].status, GoodsEntry::GES_CURRENT_MONTH)) SetBit(res, 2);
359  }
360 
361  /* Cargo triggered CB 148? */
362  if (HasBit(this->watched_cargo_triggers, cid)) SetBit(res, 4);
363 
364  return res;
365  }
366 
367  /* Distance test for some house types */
368  case 0x65: return GetDistanceFromNearbyHouse(parameter, this->tile, this->house_id);
369 
370  /* Class and ID of nearby house tile */
371  case 0x66: {
372  TileIndex testtile = GetNearbyTile(parameter, this->tile);
373  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
374  HouseID nearby_house_id = GetHouseType(testtile);
375  HouseSpec *hs = HouseSpec::Get(nearby_house_id);
376  /* Information about the grf local classid if the house has a class */
377  uint houseclass = 0;
378  if (hs->class_id != HOUSE_NO_CLASS) {
379  houseclass = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
380  houseclass |= _class_mapping[hs->class_id].class_id;
381  }
382  /* old house type or grf-local houseid */
383  uint local_houseid = 0;
384  if (nearby_house_id < NEW_HOUSE_OFFSET) {
385  local_houseid = nearby_house_id;
386  } else {
387  local_houseid = (hs->grf_prop.grffile == this->ro.grffile ? 1 : 2) << 8;
388  local_houseid |= hs->grf_prop.local_id;
389  }
390  return houseclass << 16 | local_houseid;
391  }
392 
393  /* GRFID of nearby house tile */
394  case 0x67: {
395  TileIndex testtile = GetNearbyTile(parameter, this->tile);
396  if (!IsTileType(testtile, MP_HOUSE)) return 0xFFFFFFFF;
397  HouseID house_id = GetHouseType(testtile);
398  if (house_id < NEW_HOUSE_OFFSET) return 0;
399  /* Checking the grffile information via HouseSpec doesn't work
400  * in case the newgrf was removed. */
401  return _house_mngr.GetGRFID(house_id);
402  }
403  }
404 
405  DEBUG(grf, 1, "Unhandled house variable 0x%X", variable);
406 
407  *available = false;
408  return UINT_MAX;
409 }
410 
411 uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile,
412  bool not_yet_constructed, uint8 initial_random_bits, uint32 watched_cargo_triggers)
413 {
414  assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
415 
416  HouseResolverObject object(house_id, tile, town, callback, param1, param2,
417  not_yet_constructed, initial_random_bits, watched_cargo_triggers);
418  return object.ResolveCallback();
419 }
420 
421 static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte stage, HouseID house_id)
422 {
423  const DrawTileSprites *dts = group->ProcessRegisters(&stage);
424 
425  const HouseSpec *hs = HouseSpec::Get(house_id);
426  PaletteID palette = hs->random_colour[TileHash2Bit(ti->x, ti->y)] + PALETTE_RECOLOUR_START;
428  uint16 callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
429  if (callback != CALLBACK_FAILED) {
430  /* If bit 14 is set, we should use a 2cc colour map, else use the callback value. */
431  palette = HasBit(callback, 14) ? GB(callback, 0, 8) + SPR_2CCMAP_BASE : callback;
432  }
433  }
434 
435  SpriteID image = dts->ground.sprite;
436  PaletteID pal = dts->ground.pal;
437 
438  if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) image += stage;
439  if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += stage;
440 
441  if (GB(image, 0, SPRITE_WIDTH) != 0) {
442  DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
443  }
444 
445  DrawNewGRFTileSeq(ti, dts, TO_HOUSES, stage, palette);
446 }
447 
448 void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
449 {
450  const HouseSpec *hs = HouseSpec::Get(house_id);
451 
452  if (ti->tileh != SLOPE_FLAT) {
453  bool draw_old_one = true;
455  /* Called to determine the type (if any) of foundation to draw for the house tile */
456  uint32 callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile);
457  if (callback_res != CALLBACK_FAILED) draw_old_one = ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res);
458  }
459 
460  if (draw_old_one) DrawFoundation(ti, FOUNDATION_LEVELED);
461  }
462 
463  HouseResolverObject object(house_id, ti->tile, Town::GetByTile(ti->tile));
464 
465  const SpriteGroup *group = object.Resolve();
466  if (group != NULL && group->type == SGT_TILELAYOUT) {
467  /* Limit the building stage to the number of stages supplied. */
468  const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
469  byte stage = GetHouseBuildingStage(ti->tile);
470  DrawTileLayout(ti, tlgroup, stage, house_id);
471  }
472 }
473 
474 /* Simple wrapper for GetHouseCallback to keep the animation unified. */
475 uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, const HouseSpec *spec, Town *town, TileIndex tile, uint32 extra_data)
476 {
477  return GetHouseCallback(callback, param1, param2, spec - HouseSpec::Get(0), town, tile, false, 0, extra_data);
478 }
479 
481 struct HouseAnimationBase : public AnimationBase<HouseAnimationBase, HouseSpec, Town, uint32, GetSimpleHouseCallback> {
482  static const CallbackID cb_animation_speed = CBID_HOUSE_ANIMATION_SPEED;
483  static const CallbackID cb_animation_next_frame = CBID_HOUSE_ANIMATION_NEXT_FRAME;
484 
485  static const HouseCallbackMask cbm_animation_speed = CBM_HOUSE_ANIMATION_SPEED;
486  static const HouseCallbackMask cbm_animation_next_frame = CBM_HOUSE_ANIMATION_NEXT_FRAME;
487 };
488 
489 void AnimateNewHouseTile(TileIndex tile)
490 {
491  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
492  if (hs == NULL) return;
493 
494  HouseAnimationBase::AnimateTile(hs, Town::GetByTile(tile), tile, HasBit(hs->extra_flags, CALLBACK_1A_RANDOM_BITS));
495 }
496 
497 void AnimateNewHouseConstruction(TileIndex tile)
498 {
499  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
500 
503  }
504 }
505 
506 bool CanDeleteHouse(TileIndex tile)
507 {
508  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
509 
510  /* Humans are always allowed to remove buildings, as is water and disasters and
511  * anyone using the scenario editor. */
513  return true;
514  }
515 
517  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
518  return (callback_res == CALLBACK_FAILED || !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DENY_DESTRUCTION, callback_res));
519  } else {
520  return !(hs->extra_flags & BUILDING_IS_PROTECTED);
521  }
522 }
523 
524 static void AnimationControl(TileIndex tile, uint16 random_bits)
525 {
526  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
527 
529  uint32 param = (hs->extra_flags & SYNCHRONISED_CALLBACK_1B) ? (GB(Random(), 0, 16) | random_bits << 16) : Random();
530  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_ANIMATION_START_STOP, hs, Town::GetByTile(tile), tile, param, 0);
531  }
532 }
533 
534 bool NewHouseTileLoop(TileIndex tile)
535 {
536  const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
537 
538  if (GetHouseProcessingTime(tile) > 0) {
540  return true;
541  }
542 
543  TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP);
544  if (hs->building_flags & BUILDING_HAS_1_TILE) TriggerHouse(tile, HOUSE_TRIGGER_TILE_LOOP_TOP);
545 
547  /* If this house is marked as having a synchronised callback, all the
548  * tiles will have the callback called at once, rather than when the
549  * tile loop reaches them. This should only be enabled for the northern
550  * tile, or strange things will happen (here, and in TTDPatch). */
552  uint16 random = GB(Random(), 0, 16);
553 
554  if (hs->building_flags & BUILDING_HAS_1_TILE) AnimationControl(tile, random);
555  if (hs->building_flags & BUILDING_2_TILES_Y) AnimationControl(TILE_ADDXY(tile, 0, 1), random);
556  if (hs->building_flags & BUILDING_2_TILES_X) AnimationControl(TILE_ADDXY(tile, 1, 0), random);
557  if (hs->building_flags & BUILDING_HAS_4_TILES) AnimationControl(TILE_ADDXY(tile, 1, 1), random);
558  } else {
559  AnimationControl(tile, 0);
560  }
561  }
562 
563  /* Check callback 21, which determines if a house should be destroyed. */
565  uint16 callback_res = GetHouseCallback(CBID_HOUSE_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
566  if (callback_res != CALLBACK_FAILED && Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DESTRUCTION, callback_res)) {
567  ClearTownHouse(Town::GetByTile(tile), tile);
568  return false;
569  }
570  }
571 
573  MarkTileDirtyByTile(tile);
574  return true;
575 }
576 
577 static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_random, bool first)
578 {
579  /* We can't trigger a non-existent building... */
580  assert(IsTileType(tile, MP_HOUSE));
581 
582  HouseID hid = GetHouseType(tile);
583  HouseSpec *hs = HouseSpec::Get(hid);
584 
585  if (hs->grf_prop.spritegroup[0] == NULL) return;
586 
587  HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER);
588  object.waiting_triggers = GetHouseTriggers(tile) | trigger;
589  SetHouseTriggers(tile, object.waiting_triggers); // store now for var 5F
590 
591  const SpriteGroup *group = object.Resolve();
592  if (group == NULL) return;
593 
594  /* Store remaining triggers. */
595  SetHouseTriggers(tile, object.GetRemainingTriggers());
596 
597  /* Rerandomise bits. Scopes other than SELF are invalid for houses. For bug-to-bug-compatibility with TTDP we ignore the scope. */
598  byte new_random_bits = Random();
599  byte random_bits = GetHouseRandomBits(tile);
600  uint32 reseed = object.GetReseedSum();
601  random_bits &= ~reseed;
602  random_bits |= (first ? new_random_bits : base_random) & reseed;
603  SetHouseRandomBits(tile, random_bits);
604 
605  switch (trigger) {
606  case HOUSE_TRIGGER_TILE_LOOP:
607  /* Random value already set. */
608  break;
609 
610  case HOUSE_TRIGGER_TILE_LOOP_TOP:
611  if (!first) {
612  /* The top tile is marked dirty by the usual TileLoop */
613  MarkTileDirtyByTile(tile);
614  break;
615  }
616  /* Random value of first tile already set. */
617  if (hs->building_flags & BUILDING_2_TILES_Y) DoTriggerHouse(TILE_ADDXY(tile, 0, 1), trigger, random_bits, false);
618  if (hs->building_flags & BUILDING_2_TILES_X) DoTriggerHouse(TILE_ADDXY(tile, 1, 0), trigger, random_bits, false);
619  if (hs->building_flags & BUILDING_HAS_4_TILES) DoTriggerHouse(TILE_ADDXY(tile, 1, 1), trigger, random_bits, false);
620  break;
621  }
622 }
623 
624 void TriggerHouse(TileIndex t, HouseTrigger trigger)
625 {
626  DoTriggerHouse(t, trigger, 0, true);
627 }
628 
636 void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, uint32 trigger_cargoes, uint16 random)
637 {
638  TileIndexDiffC diff = TileIndexToTileIndexDiffC(origin, tile);
639  uint32 cb_info = random << 16 | (uint8)diff.y << 8 | (uint8)diff.x;
640  HouseAnimationBase::ChangeAnimationFrame(CBID_HOUSE_WATCHED_CARGO_ACCEPTED, HouseSpec::Get(GetHouseType(tile)), Town::GetByTile(tile), tile, 0, cb_info, trigger_cargoes);
641 }
642 
649 void WatchedCargoCallback(TileIndex tile, uint32 trigger_cargoes)
650 {
651  assert(IsTileType(tile, MP_HOUSE));
652  HouseID id = GetHouseType(tile);
653  const HouseSpec *hs = HouseSpec::Get(id);
654 
655  trigger_cargoes &= hs->watched_cargoes;
656  /* None of the trigger cargoes is watched? */
657  if (trigger_cargoes == 0) return;
658 
659  /* Same random value for all tiles of a multi-tile house. */
660  uint16 r = Random();
661 
662  /* Do the callback, start at northern tile. */
663  TileIndex north = tile + GetHouseNorthPart(id);
664  hs = HouseSpec::Get(id);
665 
666  DoWatchedCargoCallback(north, tile, trigger_cargoes, r);
667  if (hs->building_flags & BUILDING_2_TILES_Y) DoWatchedCargoCallback(TILE_ADDXY(north, 0, 1), tile, trigger_cargoes, r);
668  if (hs->building_flags & BUILDING_2_TILES_X) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 0), tile, trigger_cargoes, r);
669  if (hs->building_flags & BUILDING_HAS_4_TILES) DoWatchedCargoCallback(TILE_ADDXY(north, 1, 1), tile, trigger_cargoes, r);
670 }
671 
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
Definition: town_cmd.cpp:2415
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.
Structure with user-data for SearchNearbyHouseXXX - functions.
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:243
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: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
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, uint32 watched_cargo_triggers=0)
Construct a resolver for a house.
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.
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: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
uint32 GetRandomBits() const
Get a few random bits.
static byte GetHouseRandomBits(TileIndex t)
Get the random bits for this house.
Definition: town_map.h:277
const T * Begin() const
Get the pointer to the first item (const)
void DoWatchedCargoCallback(TileIndex tile, TileIndex origin, uint32 trigger_cargoes, uint16 random)
Run the watched cargo accepted callback for a single house tile.
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, uint32 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:15
decides animation speed
const T * End() const
Get the pointer behind the last valid item (const)
a flat tile
Definition: slope_type.h:51
GoodsEntry goods[NUM_CARGO]
Goods at this station.
Definition: station_base.h:472
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, uint32 extra_data=0)
Animate a single tile.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition: landscape.cpp:390
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:144
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
int16 y
The y value of the coordinate.
Definition: map_type.h:60
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:154
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:332
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".
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 give tiletype.
Definition: tile_map.h:143
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:119
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
byte status
Status of this cargo, see GoodsEntryStatus.
Definition: station_base.h:226
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:121
#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:59
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:116
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:1506
uint32 GetTriggers() const
Get the triggers.
The tile has no ownership.
Definition: company_type.h:27
decides next animation frame
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
Invalid cargo type.
Definition: cargo_type.h:70
periodically start/stop the animation
number of bits for the sprite number
Definition: sprites.h:1494
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:1998
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:109
bool has_newhouses
Set if there are any newhouses loaded.
Definition: newgrf.h:164
uint32 watched_cargoes
Cargo types watched for acceptance.
Definition: house.h:123
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:39
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1904
A pair-construct of a TileIndexDiff.
Definition: map_type.h:58
Set when a vehicle ever delivered cargo to the station for final delivery.
Definition: station_base.h:193
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:1538
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:61
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:118
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
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: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: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: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: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:404
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:604
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: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: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:77
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
Structure contains cached list of stations nearby.
Definition: station_type.h:104
Base classes/functions for stations.
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
The tile/execution is done by "water".
Definition: company_type.h:28
Station data structure.
Definition: station_base.h:446
#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
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const
static const GRFFile * GetHouseSpecGrf(HouseID house_id)
Retrieve the grf file associated with a house.
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:104
void WatchedCargoCallback(TileIndex tile, uint32 trigger_cargoes)
Run watched cargo accepted callback for a house.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26
HouseCallbackMask
Callback masks for houses.