OpenTTD
newgrf_canal.cpp
Go to the documentation of this file.
1 /* $Id: newgrf_canal.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 "newgrf_spritegroup.h"
15 #include "newgrf_canal.h"
16 #include "water.h"
17 #include "water_map.h"
18 
19 #include "safeguards.h"
20 
23 
27 
29  : ScopeResolver(ro), tile(tile)
30  {
31  }
32 
33  /* virtual */ uint32 GetRandomBits() const;
34  /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
35 };
36 
39  CanalScopeResolver canal_scope;
40 
42  CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
43 
44  /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0)
45  {
46  switch (scope) {
47  case VSG_SCOPE_SELF: return &this->canal_scope;
48  default: return ResolverObject::GetScope(scope, relative);
49  }
50  }
51 
52  /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
53 };
54 
55 /* virtual */ uint32 CanalScopeResolver::GetRandomBits() const
56 {
57  /* Return random bits only for water tiles, not station tiles */
58  return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
59 }
60 
61 /* virtual */ uint32 CanalScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
62 {
63  switch (variable) {
64  /* Height of tile */
65  case 0x80: {
66  int z = GetTileZ(this->tile);
67  /* Return consistent height within locks */
68  if (IsTileType(this->tile, MP_WATER) && IsLock(this->tile) && GetLockPart(this->tile) == LOCK_PART_UPPER) z--;
69  return z;
70  }
71 
72  /* Terrain type */
73  case 0x81: return GetTerrainType(this->tile);
74 
75  /* Dike map: Connectivity info for river and canal tiles
76  *
77  * Assignment of bits to directions defined in agreement with
78  * http://projects.tt-forums.net/projects/ttdpatch/repository/revisions/2367/entry/trunk/patches/water.asm#L879
79  * 7
80  * 3 0
81  * 6 * 4
82  * 2 1
83  * 5
84  */
85  case 0x82: {
86  uint32 connectivity =
87  (!IsWateredTile(TILE_ADDXY(tile, -1, 0), DIR_SW) << 0) // NE
88  + (!IsWateredTile(TILE_ADDXY(tile, 0, 1), DIR_NW) << 1) // SE
89  + (!IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2) // SW
90  + (!IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3) // NW
91  + (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W) << 4) // E
92  + (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N) << 5) // S
93  + (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E) << 6) // W
94  + (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S) << 7); // N
95  return connectivity;
96  }
97 
98  /* Random data for river or canal tiles, otherwise zero */
99  case 0x83: return IsTileType(this->tile, MP_WATER) ? GetWaterTileRandomBits(this->tile) : 0;
100  }
101 
102  DEBUG(grf, 1, "Unhandled canal variable 0x%02X", variable);
103 
104  *available = false;
105  return UINT_MAX;
106 }
107 
108 
109 /* virtual */ const SpriteGroup *CanalResolverObject::ResolveReal(const RealSpriteGroup *group) const
110 {
111  if (group->num_loaded == 0) return NULL;
112 
113  return group->loaded[0];
114 }
115 
125  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
126  : ResolverObject(_water_feature[feature].grffile, callback, callback_param1, callback_param2), canal_scope(*this, tile)
127 {
128  this->root_spritegroup = _water_feature[feature].group;
129 }
130 
138 {
139  CanalResolverObject object(feature, tile);
140  const SpriteGroup *group = object.Resolve();
141  if (group == NULL) return 0;
142 
143  return group->GetResult();
144 }
145 
155 static uint16 GetCanalCallback(CallbackID callback, uint32 param1, uint32 param2, CanalFeature feature, TileIndex tile)
156 {
157  CanalResolverObject object(feature, tile, callback, param1, param2);
158  return object.ResolveCallback();
159 }
160 
168 uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
169 {
170  if (HasBit(_water_feature[feature].callback_mask, CBM_CANAL_SPRITE_OFFSET)) {
171  uint16 cb = GetCanalCallback(CBID_CANALS_SPRITE_OFFSET, cur_offset, 0, feature, tile);
172  if (cb != CALLBACK_FAILED) return cur_offset + cb;
173  }
174  return cur_offset;
175 }
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
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const
Get a variable value.
East.
ResolverObject & ro
Surrounding resolver object.
VarSpriteGroupScope
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:26
Set when using the callback resolve system, but not to resolve a callback.
Enable add sprite offset callback.
virtual ScopeResolver * GetScope(VarSpriteGroupScope scope=VSG_SCOPE_SELF, byte relative=0)
Get a resolver for the scope.
const SpriteGroup * ResolveReal(const RealSpriteGroup *group) const
Get the real sprites of the grf.
byte num_loaded
Number of loaded groups.
Southeast.
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:182
Northeast.
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:548
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 give tiletype.
Definition: tile_map.h:143
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
West.
North.
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:260
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:49
const SpriteGroup * group
Sprite group to start resolving.
Definition: newgrf_canal.h:25
Resolved object itself.
Scope resolver of a canal tile.
ScopeResolver * GetScope(VarSpriteGroupScope scope=VSG_SCOPE_SELF, byte relative=0)
Get a resolver for the scope.
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:39
uint32 GetRandomBits() const
Get a few random bits.
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:69
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
CallbackID callback
Callback being resolved.
uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
Get the new sprite offset for a water tile.
TileIndex tile
Tile containing the canal.
Northwest.
South.
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:24
Southwest.