OpenTTD Source  1.10.0-RC1
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 #include "spritecache.h"
17 
18 #include "safeguards.h"
19 
22 
26 
28  : ScopeResolver(ro), tile(tile)
29  {
30  }
31 
32  uint32 GetRandomBits() const override;
33  uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override;
34 };
35 
38  CanalScopeResolver canal_scope;
39  CanalFeature feature;
40 
42  CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
43 
44  ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override
45  {
46  switch (scope) {
47  case VSG_SCOPE_SELF: return &this->canal_scope;
48  default: return ResolverObject::GetScope(scope, relative);
49  }
50  }
51 
52  const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override;
53 
54  GrfSpecFeature GetFeature() const override;
55  uint32 GetDebugID() const override;
56 };
57 
58 /* virtual */ uint32 CanalScopeResolver::GetRandomBits() const
59 {
60  /* Return random bits only for water tiles, not station tiles */
61  return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
62 }
63 
64 /* virtual */ uint32 CanalScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
65 {
66  switch (variable) {
67  /* Height of tile */
68  case 0x80: {
69  int z = GetTileZ(this->tile);
70  /* Return consistent height within locks */
71  if (IsTileType(this->tile, MP_WATER) && IsLock(this->tile) && GetLockPart(this->tile) == LOCK_PART_UPPER) z--;
72  return z;
73  }
74 
75  /* Terrain type */
76  case 0x81: return GetTerrainType(this->tile);
77 
78  /* Dike map: Connectivity info for river and canal tiles
79  *
80  * Assignment of bits to directions defined in agreement with
81  * http://projects.tt-forums.net/projects/ttdpatch/repository/revisions/2367/entry/trunk/patches/water.asm#L879
82  * 7
83  * 3 0
84  * 6 * 4
85  * 2 1
86  * 5
87  */
88  case 0x82: {
89  uint32 connectivity =
90  (!IsWateredTile(TILE_ADDXY(tile, -1, 0), DIR_SW) << 0) // NE
91  + (!IsWateredTile(TILE_ADDXY(tile, 0, 1), DIR_NW) << 1) // SE
92  + (!IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2) // SW
93  + (!IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3) // NW
94  + (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W) << 4) // E
95  + (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N) << 5) // S
96  + (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E) << 6) // W
97  + (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S) << 7); // N
98  return connectivity;
99  }
100 
101  /* Random data for river or canal tiles, otherwise zero */
102  case 0x83: return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
103  }
104 
105  DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable);
106 
107  *available = false;
108  return UINT_MAX;
109 }
110 
111 
112 /* virtual */ const SpriteGroup *CanalResolverObject::ResolveReal(const RealSpriteGroup *group) const
113 {
114  if (group->num_loaded == 0) return nullptr;
115 
116  return group->loaded[0];
117 }
118 
120 {
121  return GSF_CANALS;
122 }
123 
125 {
126  return this->feature;
127 }
128 
138  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
139  : ResolverObject(_water_feature[feature].grffile, callback, callback_param1, callback_param2), canal_scope(*this, tile), feature(feature)
140 {
141  this->root_spritegroup = _water_feature[feature].group;
142 }
143 
151 {
152  CanalResolverObject object(feature, tile);
153  const SpriteGroup *group = object.Resolve();
154  if (group == nullptr) return 0;
155 
156  return group->GetResult();
157 }
158 
168 static uint16 GetCanalCallback(CallbackID callback, uint32 param1, uint32 param2, CanalFeature feature, TileIndex tile)
169 {
170  CanalResolverObject object(feature, tile, callback, param1, param2);
171  return object.ResolveCallback();
172 }
173 
181 uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
182 {
183  if (HasBit(_water_feature[feature].callback_mask, CBM_CANAL_SPRITE_OFFSET)) {
184  uint16 cb = GetCanalCallback(CBID_CANALS_SPRITE_OFFSET, cur_offset, 0, feature, tile);
185  if (cb != CALLBACK_FAILED) return cur_offset + cb;
186  }
187  return cur_offset;
188 }
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
GrfSpecFeature
Definition: newgrf.h:66
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.
Functions to cache sprites in memory.
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.
uint32 GetDebugID() const override
Get an identifier for the item being resolved.
GrfSpecFeature GetFeature() const override
Get the feature number being resolved for.
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
static const NIFeature * GetFeature(uint window_number)
Get the NIFeature related to the window number.