mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
3 Commits
fbab1a3556
...
7b02374cfd
Author | SHA1 | Date |
---|---|---|
|
7b02374cfd | |
|
a8650c6b06 | |
|
bea6f90a7d |
|
@ -454,6 +454,7 @@ add_files(
|
||||||
spritecache.cpp
|
spritecache.cpp
|
||||||
spritecache.h
|
spritecache.h
|
||||||
spritecache_internal.h
|
spritecache_internal.h
|
||||||
|
spritecache_type.h
|
||||||
station.cpp
|
station.cpp
|
||||||
station_base.h
|
station_base.h
|
||||||
station_cmd.cpp
|
station_cmd.cpp
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "heightmap.h"
|
#include "heightmap.h"
|
||||||
|
#include "landscape.h"
|
||||||
#include "clear_map.h"
|
#include "clear_map.h"
|
||||||
#include "strings_func.h"
|
#include "strings_func.h"
|
||||||
#include "void_map.h"
|
#include "void_map.h"
|
||||||
|
@ -523,6 +524,10 @@ bool LoadHeightmap(DetailedFileType dft, std::string_view filename)
|
||||||
GrayscaleToMapHeights(x, y, map);
|
GrayscaleToMapHeights(x, y, map);
|
||||||
|
|
||||||
FixSlopes();
|
FixSlopes();
|
||||||
|
|
||||||
|
/* If all map borders are water, we will draw infinite water. */
|
||||||
|
_settings_game.game_creation.water_borders = (CheckWaterBorders(false) ? BORDERFLAGS_ALL : BorderFlag{});
|
||||||
|
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -635,6 +635,41 @@ void ClearSnowLine()
|
||||||
_snow_line = nullptr;
|
_snow_line = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all tiles on the map edge should be considered water borders.
|
||||||
|
* @param allow_non_flat_void Should we allow non-flat void tiles? (if map edge raised, then flattened to sea level)
|
||||||
|
* @return true If the edge of the map is flat and height 0, allowing for infinite water borders.
|
||||||
|
*/
|
||||||
|
bool CheckWaterBorders(bool allow_non_flat_void)
|
||||||
|
{
|
||||||
|
auto check_tile = [allow_non_flat_void](uint x, uint y, Slope inner_edge) -> bool {
|
||||||
|
auto [slope, h] = GetTilePixelSlopeOutsideMap(x, y);
|
||||||
|
|
||||||
|
/* The edge tile is flat. */
|
||||||
|
if ((slope == SLOPE_FLAT) && (h == 0)) return true;
|
||||||
|
if (allow_non_flat_void && h == 0 && (slope & inner_edge) == 0 && IsTileType(TileXY(x, y), MP_VOID)) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Check the map corners. */
|
||||||
|
if (!check_tile(0, 0, SLOPE_S)) return false;
|
||||||
|
if (!check_tile(0, Map::SizeY(), SLOPE_W)) return false;
|
||||||
|
if (!check_tile(Map::SizeX(), 0, SLOPE_E)) return false;
|
||||||
|
if (!check_tile(Map::SizeX(), Map::SizeY(), SLOPE_N)) return false;
|
||||||
|
|
||||||
|
/* Check the map edges.*/
|
||||||
|
for (uint x = 0; x <= Map::SizeX(); x++) {
|
||||||
|
if (!check_tile(x, 0, SLOPE_SE)) return false;
|
||||||
|
if (!check_tile(x, Map::SizeY(), SLOPE_NW)) return false;
|
||||||
|
}
|
||||||
|
for (uint y = 1; y < Map::SizeY(); y++) {
|
||||||
|
if (!check_tile(0, y, SLOPE_SW)) return false;
|
||||||
|
if (!check_tile(Map::SizeX(), y, SLOPE_NE)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear a piece of landscape
|
* Clear a piece of landscape
|
||||||
* @param flags of operation to conduct
|
* @param flags of operation to conduct
|
||||||
|
|
|
@ -33,6 +33,8 @@ uint8_t HighestSnowLine();
|
||||||
uint8_t LowestSnowLine();
|
uint8_t LowestSnowLine();
|
||||||
void ClearSnowLine();
|
void ClearSnowLine();
|
||||||
|
|
||||||
|
bool CheckWaterBorders(bool allow_non_flat_void);
|
||||||
|
|
||||||
int GetSlopeZInCorner(Slope tileh, Corner corner);
|
int GetSlopeZInCorner(Slope tileh, Corner corner);
|
||||||
std::tuple<Slope, int> GetFoundationSlope(TileIndex tile);
|
std::tuple<Slope, int> GetFoundationSlope(TileIndex tile);
|
||||||
|
|
||||||
|
|
|
@ -1024,6 +1024,27 @@ bool AfterLoadGame()
|
||||||
_settings_game.construction.freeform_edges = false;
|
_settings_game.construction.freeform_edges = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle infinite water borders. */
|
||||||
|
if (IsSavegameVersionBefore(SLV_INFINITE_WATER_BORDERS)) {
|
||||||
|
if (CheckWaterBorders(true)) {
|
||||||
|
/* We passed the water borders check, yay! */
|
||||||
|
_settings_game.game_creation.water_borders = BORDERFLAGS_ALL;
|
||||||
|
|
||||||
|
/* Flatten void tiles, which may have been affected by terraforming near the map edge. */
|
||||||
|
for (uint x = 0; x <= Map::SizeX(); x++) {
|
||||||
|
SetTileHeightOutsideMap(x, 0, 0);
|
||||||
|
SetTileHeightOutsideMap(x, Map::SizeY(), 0);
|
||||||
|
}
|
||||||
|
for (uint y = 1; y < Map::SizeY(); y++) {
|
||||||
|
SetTileHeightOutsideMap(0, y, 0);
|
||||||
|
SetTileHeightOutsideMap(Map::SizeX(), y, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Not all edges are ocean. */
|
||||||
|
_settings_game.game_creation.water_borders = BorderFlag{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* From version 9.0, we update the max passengers of a town (was sometimes negative
|
/* From version 9.0, we update the max passengers of a town (was sometimes negative
|
||||||
* before that. */
|
* before that. */
|
||||||
if (IsSavegameVersionBefore(SLV_9)) {
|
if (IsSavegameVersionBefore(SLV_9)) {
|
||||||
|
|
|
@ -405,6 +405,7 @@ enum SaveLoadVersion : uint16_t {
|
||||||
|
|
||||||
SLV_FACE_STYLES, ///< 355 PR#14319 Addition of face styles, replacing gender and ethnicity.
|
SLV_FACE_STYLES, ///< 355 PR#14319 Addition of face styles, replacing gender and ethnicity.
|
||||||
SLV_INDUSTRY_NUM_VALID_HISTORY, ///< 356 PR#14416 Store number of valid history records for industries.
|
SLV_INDUSTRY_NUM_VALID_HISTORY, ///< 356 PR#14416 Store number of valid history records for industries.
|
||||||
|
SLV_INFINITE_WATER_BORDERS, ///< 357 PR#13289 Draw infinite water when all borders are water.
|
||||||
|
|
||||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
};
|
};
|
||||||
|
|
|
@ -535,7 +535,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty
|
||||||
|
|
||||||
struct GrfSpriteOffset {
|
struct GrfSpriteOffset {
|
||||||
size_t file_pos;
|
size_t file_pos;
|
||||||
uint8_t control_flags;
|
SpriteCacheCtrlFlags control_flags{};
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Map from sprite numbers to position in the GRF file. */
|
/** Map from sprite numbers to position in the GRF file. */
|
||||||
|
@ -565,7 +565,7 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
|
||||||
size_t old_pos = file.GetPos();
|
size_t old_pos = file.GetPos();
|
||||||
file.SeekTo(data_offset, SEEK_CUR);
|
file.SeekTo(data_offset, SEEK_CUR);
|
||||||
|
|
||||||
GrfSpriteOffset offset = { 0, 0 };
|
GrfSpriteOffset offset{0};
|
||||||
|
|
||||||
/* Loop over all sprite section entries and store the file
|
/* Loop over all sprite section entries and store the file
|
||||||
* offset for each newly encountered ID. */
|
* offset for each newly encountered ID. */
|
||||||
|
@ -574,7 +574,6 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
|
||||||
if (id != prev_id) {
|
if (id != prev_id) {
|
||||||
_grf_sprite_offsets[prev_id] = offset;
|
_grf_sprite_offsets[prev_id] = offset;
|
||||||
offset.file_pos = file.GetPos() - 4;
|
offset.file_pos = file.GetPos() - 4;
|
||||||
offset.control_flags = 0;
|
|
||||||
}
|
}
|
||||||
prev_id = id;
|
prev_id = id;
|
||||||
uint length = file.ReadDword();
|
uint length = file.ReadDword();
|
||||||
|
@ -585,11 +584,11 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
|
||||||
uint8_t zoom = file.ReadByte();
|
uint8_t zoom = file.ReadByte();
|
||||||
length--;
|
length--;
|
||||||
if (colour.Any() && zoom == 0) { // ZoomLevel::Normal (normal zoom)
|
if (colour.Any() && zoom == 0) { // ZoomLevel::Normal (normal zoom)
|
||||||
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL);
|
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal);
|
||||||
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
|
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
|
||||||
}
|
}
|
||||||
if (colour.Any() && zoom == 2) { // ZoomLevel::In2x (2x zoomed in)
|
if (colour.Any() && zoom == 2) { // ZoomLevel::In2x (2x zoomed in)
|
||||||
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
|
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,7 +620,7 @@ bool LoadNextSprite(SpriteID load_index, SpriteFile &file, uint file_sprite_id)
|
||||||
uint8_t grf_type = file.ReadByte();
|
uint8_t grf_type = file.ReadByte();
|
||||||
|
|
||||||
SpriteType type;
|
SpriteType type;
|
||||||
uint8_t control_flags = 0;
|
SpriteCacheCtrlFlags control_flags;
|
||||||
if (grf_type == 0xFF) {
|
if (grf_type == 0xFF) {
|
||||||
/* Some NewGRF files have "empty" pseudo-sprites which are 1
|
/* Some NewGRF files have "empty" pseudo-sprites which are 1
|
||||||
* byte long. Catch these so the sprites won't be displayed. */
|
* byte long. Catch these so the sprites won't be displayed. */
|
||||||
|
|
|
@ -11,24 +11,9 @@
|
||||||
#define SPRITECACHE_H
|
#define SPRITECACHE_H
|
||||||
|
|
||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
|
#include "spritecache_type.h"
|
||||||
#include "spriteloader/spriteloader.hpp"
|
#include "spriteloader/spriteloader.hpp"
|
||||||
|
|
||||||
/** Data structure describing a sprite. */
|
|
||||||
struct Sprite {
|
|
||||||
uint16_t height; ///< Height of the sprite.
|
|
||||||
uint16_t width; ///< Width of the sprite.
|
|
||||||
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
|
|
||||||
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
|
|
||||||
std::byte data[]; ///< Sprite data.
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SpriteCacheCtrlFlags : uint8_t {
|
|
||||||
SCCF_ALLOW_ZOOM_MIN_1X_PAL = 0, ///< Allow use of sprite min zoom setting at 1x in palette mode.
|
|
||||||
SCCF_ALLOW_ZOOM_MIN_1X_32BPP = 1, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
|
|
||||||
SCCF_ALLOW_ZOOM_MIN_2X_PAL = 2, ///< Allow use of sprite min zoom setting at 2x in palette mode.
|
|
||||||
SCCF_ALLOW_ZOOM_MIN_2X_32BPP = 3, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
|
|
||||||
};
|
|
||||||
|
|
||||||
extern uint _sprite_cache_size;
|
extern uint _sprite_cache_size;
|
||||||
|
|
||||||
/** SpriteAllocator that allocates memory via a unique_ptr array. */
|
/** SpriteAllocator that allocates memory via a unique_ptr array. */
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "core/math_func.hpp"
|
#include "core/math_func.hpp"
|
||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
|
#include "spritecache_type.h"
|
||||||
#include "spriteloader/spriteloader.hpp"
|
#include "spriteloader/spriteloader.hpp"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
@ -27,7 +28,7 @@ struct SpriteCache {
|
||||||
uint32_t lru = 0;
|
uint32_t lru = 0;
|
||||||
SpriteType type = SpriteType::Invalid; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
|
SpriteType type = SpriteType::Invalid; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
|
||||||
bool warned = false; ///< True iff the user has been warned about incorrect use of this sprite
|
bool warned = false; ///< True iff the user has been warned about incorrect use of this sprite
|
||||||
uint8_t control_flags = 0; ///< Control flags, see SpriteCacheCtrlFlags
|
SpriteCacheCtrlFlags control_flags{}; ///< Control flags, see SpriteCacheCtrlFlags
|
||||||
|
|
||||||
void ClearSpriteData();
|
void ClearSpriteData();
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* 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.
|
||||||
|
* 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.
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file spritecache_type.h Types related to the sprite cache. */
|
||||||
|
|
||||||
|
#ifndef SPRITECACHE_TYPE_H
|
||||||
|
#define SPRITECACHE_TYPE_H
|
||||||
|
|
||||||
|
#include "core/enum_type.hpp"
|
||||||
|
|
||||||
|
/** Data structure describing a sprite. */
|
||||||
|
struct Sprite {
|
||||||
|
uint16_t height; ///< Height of the sprite.
|
||||||
|
uint16_t width; ///< Width of the sprite.
|
||||||
|
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
|
||||||
|
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
|
||||||
|
std::byte data[]; ///< Sprite data.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SpriteCacheCtrlFlag : uint8_t {
|
||||||
|
AllowZoomMin1xPal, ///< Allow use of sprite min zoom setting at 1x in palette mode.
|
||||||
|
AllowZoomMin1x32bpp, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
|
||||||
|
AllowZoomMin2xPal, ///< Allow use of sprite min zoom setting at 2x in palette mode.
|
||||||
|
AllowZoomMin2x32bpp, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
|
||||||
|
};
|
||||||
|
|
||||||
|
using SpriteCacheCtrlFlags = EnumBitSet<SpriteCacheCtrlFlag, uint8_t>;
|
||||||
|
|
||||||
|
#endif /* SPRITECACHE_TYPE_H */
|
|
@ -256,7 +256,7 @@ static ZoomLevels LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFil
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||||
{
|
{
|
||||||
static const ZoomLevel zoom_lvl_map[6] = {ZoomLevel::Normal, ZoomLevel::In4x, ZoomLevel::In2x, ZoomLevel::Out2x, ZoomLevel::Out4x, ZoomLevel::Out8x};
|
static const ZoomLevel zoom_lvl_map[6] = {ZoomLevel::Normal, ZoomLevel::In4x, ZoomLevel::In2x, ZoomLevel::Out2x, ZoomLevel::Out4x, ZoomLevel::Out8x};
|
||||||
|
|
||||||
|
@ -295,11 +295,11 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
|
||||||
is_wanted_zoom_lvl = true;
|
is_wanted_zoom_lvl = true;
|
||||||
ZoomLevel zoom_min = sprite_type == SpriteType::Font ? ZoomLevel::Min : _settings_client.gui.sprite_zoom_min;
|
ZoomLevel zoom_min = sprite_type == SpriteType::Font ? ZoomLevel::Min : _settings_client.gui.sprite_zoom_min;
|
||||||
if (zoom_min >= ZoomLevel::In2x &&
|
if (zoom_min >= ZoomLevel::In2x &&
|
||||||
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl < ZoomLevel::In2x) {
|
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal) && zoom_lvl < ZoomLevel::In2x) {
|
||||||
is_wanted_zoom_lvl = false;
|
is_wanted_zoom_lvl = false;
|
||||||
}
|
}
|
||||||
if (zoom_min >= ZoomLevel::Normal &&
|
if (zoom_min >= ZoomLevel::Normal &&
|
||||||
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl < ZoomLevel::Normal) {
|
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal) && zoom_lvl < ZoomLevel::Normal) {
|
||||||
is_wanted_zoom_lvl = false;
|
is_wanted_zoom_lvl = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -359,7 +359,7 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
|
||||||
return loaded_sprites;
|
return loaded_sprites;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||||
{
|
{
|
||||||
if (this->container_ver >= 2) {
|
if (this->container_ver >= 2) {
|
||||||
return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, control_flags, avail_8bpp, avail_32bpp);
|
return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, control_flags, avail_8bpp, avail_32bpp);
|
||||||
|
|
|
@ -17,7 +17,7 @@ class SpriteLoaderGrf : public SpriteLoader {
|
||||||
uint8_t container_ver;
|
uint8_t container_ver;
|
||||||
public:
|
public:
|
||||||
SpriteLoaderGrf(uint8_t container_ver) : container_ver(container_ver) {}
|
SpriteLoaderGrf(uint8_t container_ver) : container_ver(container_ver) {}
|
||||||
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SPRITELOADER_GRF_HPP */
|
#endif /* SPRITELOADER_GRF_HPP */
|
||||||
|
|
|
@ -48,7 +48,7 @@ static void Convert32bppTo8bpp(SpriteLoader::Sprite &sprite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||||
{
|
{
|
||||||
ZoomLevels avail = this->baseloader.LoadSprite(sprite, file, file_pos, sprite_type, true, control_flags, avail_8bpp, avail_32bpp);
|
ZoomLevels avail = this->baseloader.LoadSprite(sprite, file, file_pos, sprite_type, true, control_flags, avail_8bpp, avail_32bpp);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ class SpriteLoaderMakeIndexed : public SpriteLoader {
|
||||||
SpriteLoader &baseloader;
|
SpriteLoader &baseloader;
|
||||||
public:
|
public:
|
||||||
SpriteLoaderMakeIndexed(SpriteLoader &baseloader) : baseloader(baseloader) {}
|
SpriteLoaderMakeIndexed(SpriteLoader &baseloader) : baseloader(baseloader) {}
|
||||||
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SPRITELOADER_MAKEINDEXED_H */
|
#endif /* SPRITELOADER_MAKEINDEXED_H */
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../core/alloc_type.hpp"
|
#include "../core/alloc_type.hpp"
|
||||||
#include "../core/enum_type.hpp"
|
#include "../core/enum_type.hpp"
|
||||||
#include "../gfx_type.h"
|
#include "../gfx_type.h"
|
||||||
|
#include "../spritecache_type.h"
|
||||||
#include "sprite_file_type.hpp"
|
#include "sprite_file_type.hpp"
|
||||||
|
|
||||||
struct Sprite;
|
struct Sprite;
|
||||||
|
@ -94,7 +95,7 @@ public:
|
||||||
* @param[out] avail_32bpp Available 32bpp sprites.
|
* @param[out] avail_32bpp Available 32bpp sprites.
|
||||||
* @return Available sprites matching \a load_32bpp.
|
* @return Available sprites matching \a load_32bpp.
|
||||||
*/
|
*/
|
||||||
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
|
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
|
||||||
|
|
||||||
virtual ~SpriteLoader() = default;
|
virtual ~SpriteLoader() = default;
|
||||||
};
|
};
|
||||||
|
|
|
@ -264,6 +264,7 @@ cat = SC_BASIC
|
||||||
var = game_creation.water_borders
|
var = game_creation.water_borders
|
||||||
type = SLE_UINT8
|
type = SLE_UINT8
|
||||||
from = SLV_111
|
from = SLV_111
|
||||||
|
flags = SettingFlag::NewgameOnly
|
||||||
def = 15
|
def = 15
|
||||||
min = 0
|
min = 0
|
||||||
max = 16
|
max = 16
|
||||||
|
|
|
@ -111,16 +111,25 @@ static std::tuple<CommandCost, TileIndex> TerraformTileHeight(TerraformerState *
|
||||||
*/
|
*/
|
||||||
if (height == TerraformGetHeightOfTile(ts, tile)) return { CMD_ERROR, INVALID_TILE };
|
if (height == TerraformGetHeightOfTile(ts, tile)) return { CMD_ERROR, INVALID_TILE };
|
||||||
|
|
||||||
/* Check "too close to edge of map". Only possible when freeform-edges is off. */
|
/* If the map has infinite water borders, don't allow terraforming the outer ring of tiles to avoid blocking ships in a confusing way. */
|
||||||
uint x = TileX(tile);
|
if (_settings_game.game_creation.water_borders == BORDERFLAGS_ALL) {
|
||||||
uint y = TileY(tile);
|
uint x = TileX(tile);
|
||||||
if (!_settings_game.construction.freeform_edges && ((x <= 1) || (y <= 1) || (x >= Map::MaxX() - 1) || (y >= Map::MaxY() - 1))) {
|
uint y = TileY(tile);
|
||||||
/*
|
|
||||||
* Determine a sensible error tile
|
auto check_tile = [&](uint x_min, uint y_min, uint x_max, uint y_max) -> bool {
|
||||||
*/
|
return ((x <= x_min) || (y <= y_min) || (x >= Map::MaxX() - x_max) || (y >= Map::MaxY() - y_max));
|
||||||
if (x == 1) x = 0;
|
};
|
||||||
if (y == 1) y = 0;
|
|
||||||
return { CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP), TileXY(x, y) };
|
/* If free-form edges is off, distances are a bit different. */
|
||||||
|
if (!_settings_game.construction.freeform_edges && check_tile(1, 1, 1, 1)) {
|
||||||
|
/* Determine a sensible error tile. */
|
||||||
|
if (x == 1) x = 0;
|
||||||
|
if (y == 1) y = 0;
|
||||||
|
return { CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP), TileXY(x, y) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Freeform edges are enabled. */
|
||||||
|
if (check_tile(2, 2, 1, 1)) return { CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP), TileXY(x, y) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark incident tiles that are involved in the terraforming. */
|
/* Mark incident tiles that are involved in the terraforming. */
|
||||||
|
@ -209,7 +218,11 @@ std::tuple<CommandCost, Money, TileIndex> CmdTerraformLand(DoCommandFlags flags,
|
||||||
assert(t < Map::Size());
|
assert(t < Map::Size());
|
||||||
/* MP_VOID tiles can be terraformed but as tunnels and bridges
|
/* MP_VOID tiles can be terraformed but as tunnels and bridges
|
||||||
* cannot go under / over these tiles they don't need checking. */
|
* cannot go under / over these tiles they don't need checking. */
|
||||||
if (IsTileType(t, MP_VOID)) continue;
|
if (IsTileType(t, MP_VOID)) {
|
||||||
|
/* All water borders are drawn with infinite water, so don't allow terraforming off the map edge. */
|
||||||
|
if (_settings_game.game_creation.water_borders == BORDERFLAGS_ALL) return { CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP), 0, t };
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find new heights of tile corners */
|
/* Find new heights of tile corners */
|
||||||
int z_N = TerraformGetHeightOfTile(&ts, t + TileDiffXY(0, 0));
|
int z_N = TerraformGetHeightOfTile(&ts, t + TileDiffXY(0, 0));
|
||||||
|
|
|
@ -33,7 +33,7 @@ static bool MockLoadNextSprite(SpriteID load_index)
|
||||||
sc->id = 0;
|
sc->id = 0;
|
||||||
sc->type = is_mapgen ? SpriteType::MapGen : SpriteType::Normal;
|
sc->type = is_mapgen ? SpriteType::MapGen : SpriteType::Normal;
|
||||||
sc->warned = false;
|
sc->warned = false;
|
||||||
sc->control_flags = 0;
|
sc->control_flags = {};
|
||||||
|
|
||||||
/* Fill with empty sprites up until the default sprite count. */
|
/* Fill with empty sprites up until the default sprite count. */
|
||||||
return load_index < SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;
|
return load_index < SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;
|
||||||
|
|
|
@ -61,6 +61,18 @@ inline void SetTileHeight(Tile tile, uint height)
|
||||||
tile.height() = height;
|
tile.height() = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the height of a tile, also for tiles outside the map (virtual "black" tiles).
|
||||||
|
*
|
||||||
|
* @param tile The tile to change the height
|
||||||
|
* @param height The new height value of the tile
|
||||||
|
* @pre height <= MAX_TILE_HEIGHT
|
||||||
|
*/
|
||||||
|
inline void SetTileHeightOutsideMap(int x, int y, uint height)
|
||||||
|
{
|
||||||
|
SetTileHeight(TileXY(Clamp(x, 0, Map::MaxX()), Clamp(y, 0, Map::MaxY())), height);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the height of a tile in pixels.
|
* Returns the height of a tile in pixels.
|
||||||
*
|
*
|
||||||
|
|
|
@ -21,7 +21,12 @@
|
||||||
|
|
||||||
static void DrawTile_Void(TileInfo *ti)
|
static void DrawTile_Void(TileInfo *ti)
|
||||||
{
|
{
|
||||||
DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh), PALETTE_ALL_BLACK);
|
/* If all borders are water, draw infinite water off the edges of the map. */
|
||||||
|
if (_settings_game.game_creation.water_borders == BORDERFLAGS_ALL) {
|
||||||
|
DrawGroundSprite(SPR_FLAT_WATER_TILE + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
|
||||||
|
} else {
|
||||||
|
DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh), PALETTE_ALL_BLACK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue