OpenTTD
newgrf_canal.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 "newgrf_spritegroup.h"
13 #include "newgrf_canal.h"
14 #include "water.h"
15 #include "water_map.h"
16 
17 #include "safeguards.h"
18 
21 
25 
27  : ScopeResolver(ro), tile(tile)
28  {
29  }
30 
31  uint32 GetRandomBits() const override;
32  uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
33 };
34 
37  CanalScopeResolver canal_scope;
38 
40  CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
41 
42  ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override
43  {
44  switch (scope) {
45  case VSG_SCOPE_SELF: return &this->canal_scope;
46  default: return ResolverObject::GetScope(scope, relative);
47  }
48  }
49 
50  const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override;
51 };
52 
53 /* virtual */ uint32 CanalScopeResolver::GetRandomBits() const
54 {
55  /* Return random bits only for water tiles, not station tiles */
56  return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
57 }
58 
59 /* virtual */ uint32 CanalScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
60 {
61  switch (variable) {
62  /* Height of tile */
63  case 0x80: {
64  int z = GetTileZ(this->tile);
65  /* Return consistent height within locks */
66  if (IsTileType(this->tile, MP_WATER) && IsLock(this->tile) && GetLockPart(this->tile) == LOCK_PART_UPPER) z--;
67  return z;
68  }
69 
70  /* Terrain type */
71  case 0x81: return GetTerrainType(this->tile);
72 
73  /* Dike map: Connectivity info for river and canal tiles
74  *
75  * Assignment of bits to directions defined in agreement with
76  * http://projects.tt-forums.net/projects/ttdpatch/repository/revisions/2367/entry/trunk/patches/water.asm#L879
77  * 7
78  * 3 0
79  * 6 * 4
80  * 2 1
81  * 5
82  */
83  case 0x82: {
84  uint32 connectivity =
85  (!IsWateredTile(TILE_ADDXY(tile, -1, 0), DIR_SW) << 0) // NE
86  + (!IsWateredTile(TILE_ADDXY(tile, 0, 1), DIR_NW) << 1) // SE
87  + (!IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2) // SW
88  + (!IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3) // NW
89  + (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W) << 4) // E
90  + (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N) << 5) // S
91  + (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E) << 6) // W
92  + (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S) << 7); // N
93  return connectivity;
94  }
95 
96  /* Random data for river or canal tiles, otherwise zero */
97  case 0x83: return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
98  }
99 
100  DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable);
101 
102  *available = false;
103  return UINT_MAX;
104 }
105 
106 
107 /* virtual */ const SpriteGroup *CanalResolverObject::ResolveReal(const RealSpriteGroup *group) const
108 {
109  if (group->num_loaded == 0) return nullptr;
110 
111  return group->loaded[0];
112 }
113 
123  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
124  : ResolverObject(_water_feature[feature].grffile, callback, callback_param1, callback_param2), canal_scope(*this, tile)
125 {
126  this->root_spritegroup = _water_feature[feature].group;
127 }
128 
136 {
137  CanalResolverObject object(feature, tile);
138  const SpriteGroup *group = object.Resolve();
139  if (group == nullptr) return 0;
140 
141  return group->GetResult();
142 }
143 
153 static uint16 GetCanalCallback(CallbackID callback, uint32 param1, uint32 param2, CanalFeature feature, TileIndex tile)
154 {
155  CanalResolverObject object(feature, tile, callback, param1, param2);
156  return object.ResolveCallback();
157 }
158 
166 uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
167 {
168  if (HasBit(_water_feature[feature].callback_mask, CBM_CANAL_SPRITE_OFFSET)) {
169  uint16 cb = GetCanalCallback(CBID_CANALS_SPRITE_OFFSET, cur_offset, 0, feature, tile);
170  if (cb != CALLBACK_FAILED) return cur_offset + cb;
171  }
172  return cur_offset;
173 }
Interface to query and set values specific to a single VarSpriteGroupScope (action 2 scope)...
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
static byte GetLockPart(TileIndex t)
Get the part of a lock.
Definition: water_map.h:320
const SpriteGroup * ResolveReal(const RealSpriteGroup *group) const override
Get the real sprites of the grf.
ResolverObject & ro
Surrounding resolver object.
VarSpriteGroupScope
West.
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override
Get a variable value.
Functions related to debugging.
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 ...
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
Lookup the base sprite to use for a canal.
CanalFeature
List of different canal &#39;features&#39;.
Definition: newgrf.h:25
uint32 GetRandomBits() const override
Get a few random bits.
Set when using the callback resolve system, but not to resolve a callback.
Enable add sprite offset callback.
ScopeResolver * GetScope(VarSpriteGroupScope scope=VSG_SCOPE_SELF, byte relative=0) override
Get a resolver for the scope.
virtual ScopeResolver * GetScope(VarSpriteGroupScope scope=VSG_SCOPE_SELF, byte relative=0)
Get a resolver for the scope.
byte num_loaded
Number of loaded groups.
Southwest.
North.
static bool IsLock(TileIndex t)
Is there a lock on a given water tile?
Definition: water_map.h:297
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition: tile_map.cpp:121
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
bool IsWateredTile(TileIndex tile, Direction from)
return true if a tile is a water tile wrt.
Definition: water_cmd.cpp:599
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
Action 2 handling.
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
East.
Southeast.
Map accessors for water tiles.
Definition of base types and functions in a cross-platform compatible way.
CanalResolverObject(CanalFeature feature, TileIndex tile, CallbackID callback=CBID_NO_CALLBACK, uint32 callback_param1=0, uint32 callback_param2=0)
Canal resolver constructor.
static byte GetWaterTileRandomBits(TileIndex t)
Get the random bits of the water tile.
Definition: water_map.h:332
#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.
Add an offset to the default sprite numbers to show another sprite.
Water tile.
Definition: tile_type.h:47
const SpriteGroup * group
Sprite group to start resolving.
Definition: newgrf_canal.h:23
South.
Resolved object itself.
Scope resolver of a canal tile.
WaterFeature _water_feature[CF_END]
Table of canal &#39;feature&#39; sprite groups.
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
Handling of NewGRF canals.
static uint16 GetCanalCallback(CallbackID callback, uint32 param1, uint32 param2, CanalFeature feature, TileIndex tile)
Run a specific callback for canals.
Upper part of a lock.
Definition: water_map.h:67
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
CallbackID callback
Callback being resolved.
uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
Get the new sprite offset for a water tile.
Northwest.
TileIndex tile
Tile containing the canal.
Northeast.
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 water (management)
Resolver object for canals.
Information about a water feature.
Definition: newgrf_canal.h:22