Merge branch 'master' into jgrpp

# Conflicts:
#	bin/baseset/no_sound.obs
#	bin/baseset/orig_dos.obg
#	bin/baseset/orig_dos.obs
#	bin/baseset/orig_dos_de.obg
#	bin/baseset/orig_win.obg
#	bin/baseset/orig_win.obm
#	bin/baseset/orig_win.obs
#	src/aircraft_cmd.cpp
#	src/blitter/32bpp_anim.cpp
#	src/blitter/32bpp_anim.hpp
#	src/blitter/32bpp_base.cpp
#	src/blitter/32bpp_base.hpp
#	src/blitter/8bpp_base.cpp
#	src/blitter/8bpp_base.hpp
#	src/blitter/common.hpp
#	src/group_gui.cpp
#	src/lang/korean.txt
#	src/linkgraph/linkgraph_gui.cpp
#	src/saveload/saveload.cpp
#	src/town_cmd.cpp
#	src/viewport.cpp
#	src/viewport_func.h
This commit is contained in:
Jonathan G Rennison
2019-01-29 02:28:14 +00:00
101 changed files with 8211 additions and 1612 deletions

View File

@@ -378,7 +378,7 @@ struct AISettingsWindow : public Window {
for (; this->vscroll->IsVisible(i) && it != visible_settings.end(); i++, it++) {
const ScriptConfigItem &config_item = **it;
int current_value = config->GetSetting((config_item).name);
bool editable = _game_mode == GM_MENU || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot)) || (config_item.flags & SCRIPTCONFIG_INGAME) != 0;
bool editable = this->IsEditableItem(config_item);
StringID str;
TextColour colour;
@@ -441,7 +441,7 @@ struct AISettingsWindow : public Window {
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
for (int i = 0; i < num; i++) it++;
const ScriptConfigItem config_item = **it;
if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
if (!this->IsEditableItem(config_item)) return;
if (this->clicked_row != num) {
DeleteChildWindows(WC_QUERY_STRING);
@@ -586,6 +586,12 @@ struct AISettingsWindow : public Window {
{
this->RebuildVisibleSettings();
}
private:
bool IsEditableItem(const ScriptConfigItem config_item) const
{
return _game_mode == GM_MENU || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot)) || (config_item.flags & SCRIPTCONFIG_INGAME) != 0;
}
};
/** Widgets for the AI settings window. */

View File

@@ -129,21 +129,15 @@ static StationID FindNearestHangar(const Aircraft *v)
const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type);
FOR_ALL_STATIONS(st) {
if (!IsInfraUsageAllowed(VEH_AIRCRAFT, v->owner, st->owner) || !(st->facilities & FACIL_AIRPORT)) continue;
if (!IsInfraUsageAllowed(VEH_AIRCRAFT, v->owner, st->owner) || !(st->facilities & FACIL_AIRPORT) || !st->airport.HasHangar()) continue;
const AirportFTAClass *afc = st->airport.GetFTA();
if (!st->airport.HasHangar() || (
/* the airport needs to have facilities for this plane type */
(AircraftVehInfo(v->engine_type)->subtype & AIR_CTOL) ?
!(afc->flags & AirportFTAClass::AIRPLANES) :
!(afc->flags & AirportFTAClass::HELICOPTERS)
) || (
/* don't crash the plane if we know it can't land at the airport */
(afc->flags & AirportFTAClass::SHORT_STRIP) &&
(avi->subtype & AIR_FAST) &&
!_cheats.no_jetcrash.value)) {
continue;
}
/* don't crash the plane if we know it can't land at the airport */
if ((afc->flags & AirportFTAClass::SHORT_STRIP) && (avi->subtype & AIR_FAST) && !_cheats.no_jetcrash.value) continue;
/* the plane won't land at any helicopter station */
if (!(afc->flags & AirportFTAClass::AIRPLANES) && (avi->subtype & AIR_CTOL)) continue;
/* v->tile can't be used here, when aircraft is flying v->tile is set to 0 */
uint distance = DistanceSquare(vtile, st->airport.tile);
@@ -392,7 +386,7 @@ bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination,
{
const Station *st = GetTargetAirportIfValid(this);
/* If the station is not a valid airport or if it has no hangars */
if (st == NULL || !st->airport.HasHangar()) {
if (st == NULL || !CanVehicleUseStation(this, st) || !st->airport.HasHangar()) {
/* the aircraft has to search for a hangar on its own */
StationID station = FindNearestHangar(this);
@@ -1624,7 +1618,7 @@ static void AircraftEventHandler_AtTerminal(Aircraft *v, const AirportFTAClass *
go_to_hangar = Station::Get(v->targetairport)->airport.HasHangar();
}
if (go_to_hangar) {
if (go_to_hangar && Station::Get(v->targetairport)->airport.HasHangar()) {
v->state = HANGAR;
} else {
/* airplane goto state takeoff, helicopter to helitakeoff */

View File

@@ -7,7 +7,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/>.
*/
/** @file base.hpp Common functionality for all blitter implemenytations. */
/** @file common.hpp Common functionality for all blitter implementations. */
#ifndef BLITTER_COMMON_HPP
#define BLITTER_COMMON_HPP

View File

@@ -1092,7 +1092,7 @@ struct BuildVehicleWindow : Window {
* This could also be useful for eyecandy vehicles of other types, but is likely too confusing for joe, */
if (this->vehicle_type == VEH_TRAIN) {
this->cargo_filter[filter_items] = CF_NONE;
this->cargo_filter_texts[filter_items] = STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE;
this->cargo_filter_texts[filter_items] = STR_PURCHASE_INFO_NONE;
filter_items++;
}

View File

@@ -652,9 +652,11 @@ public:
virtual void OnPaint()
{
bool local = (CompanyID)this->window_number == _local_company;
/* Disable dropdown controls if no scheme is selected */
this->SetWidgetDisabledState(WID_SCL_PRI_COL_DROPDOWN, this->sel == 0);
this->SetWidgetDisabledState(WID_SCL_SEC_COL_DROPDOWN, this->sel == 0);
this->SetWidgetDisabledState(WID_SCL_PRI_COL_DROPDOWN, !local || this->sel == 0);
this->SetWidgetDisabledState(WID_SCL_SEC_COL_DROPDOWN, !local || this->sel == 0);
this->DrawWidgets();
}
@@ -662,6 +664,10 @@ public:
virtual void SetStringParameters(int widget) const
{
switch (widget) {
case WID_SCL_CAPTION:
SetDParam(0, (CompanyID)this->window_number);
break;
case WID_SCL_PRI_COL_DROPDOWN:
case WID_SCL_SEC_COL_DROPDOWN: {
const Company *c = Company::Get((CompanyID)this->window_number);
@@ -793,6 +799,9 @@ public:
virtual void OnDropdownSelect(int widget, int index)
{
bool local = (CompanyID)this->window_number == _local_company;
if (!local) return;
for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
/* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */
if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) {

View File

@@ -1320,7 +1320,11 @@ void DrawDirtyBlocks()
/* Wait a while and update _realtime_tick so we are given the rights */
if (!IsFirstModalProgressLoop()) CSleep(MODAL_PROGRESS_REDRAW_TIMEOUT);
_realtime_tick += MODAL_PROGRESS_REDRAW_TIMEOUT;
/* Modal progress thread may need blitter access while we are waiting for it. */
VideoDriver::GetInstance()->ReleaseBlitterLock();
_modal_progress_paint_mutex->BeginCritical();
VideoDriver::GetInstance()->AcquireBlitterLock();
_modal_progress_work_mutex->BeginCritical();
/* When we ended with the modal progress, do not draw the blocks.

View File

@@ -159,7 +159,7 @@ private:
Dimension column_size[VGC_END]; ///< Size of the columns in the group list.
/** return true if group has children */
bool AddParents(GUIGroupList *source, GroupID parent, int indent, bool parent_collapsed)
bool AddChildren(GUIGroupList *source, GroupID parent, int indent, bool parent_collapsed)
{
bool is_collapsed = this->collapsed_groups.Contains(parent);
bool overall_collapsed = is_collapsed || parent_collapsed;
@@ -173,7 +173,7 @@ private:
*this->groups.Append() = *g;
*this->indents.Append() = indent;
}
bool child_has_children = AddParents(source, (*g)->index, indent + 1, overall_collapsed);
bool child_has_children = AddChildren(source, (*g)->index, indent + 1, overall_collapsed);
if (child_has_children) *this->collapsable_groups.Append() = (*g)->index;
}
}
@@ -218,7 +218,7 @@ private:
list.ForceResort();
list.Sort(&GroupNameSorter);
AddParents(&list, INVALID_GROUP, 0, false);
AddChildren(&list, INVALID_GROUP, 0, false);
this->groups.Compact();
this->groups.RebuildDone();
@@ -302,7 +302,7 @@ private:
str = STR_GROUP_NAME;
}
int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8;
DrawString(x + indent * LEVEL_WIDTH, x + this->column_size[VGC_NAME].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
DrawString(x + (rtl ? 0 : indent), x + this->column_size[VGC_NAME].width - 1 - (rtl ? indent : 0), y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
/* draw collapse state */
x = rtl ? x - 8 - this->column_size[VGC_COLLAPSED].width : x + 8 + this->column_size[VGC_NAME].width;
@@ -660,7 +660,7 @@ public:
assert(g->owner == this->owner);
DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i], g->replace_protection);
DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * LEVEL_WIDTH, g->replace_protection);
y1 += this->tiny_step_height;
}

View File

@@ -31,6 +31,8 @@ static const HouseID NEW_HOUSE_OFFSET = 110; ///< Offset for new houses.
static const HouseID NUM_HOUSES = 512; ///< Total number of houses.
static const HouseID INVALID_HOUSE_ID = 0xFFFF;
static const uint HOUSE_NUM_ACCEPTS = 16; ///< Max number of cargoes accepted by a tile
/**
* There can only be as many classes as there are new houses, plus one for
* NO_CLASS, as the original houses don't have classes.
@@ -97,30 +99,30 @@ DECLARE_ENUM_AS_BIT_SET(HouseExtraFlags)
struct HouseSpec {
/* Standard properties */
Year min_year; ///< introduction year of the house
Year max_year; ///< last year it can be built
byte population; ///< population (Zero on other tiles in multi tile house.)
byte removal_cost; ///< cost multiplier for removing it
StringID building_name; ///< building name
uint16 remove_rating_decrease; ///< rating decrease if removed
byte mail_generation; ///< mail generation multiplier (tile based, as the acceptances below)
byte cargo_acceptance[3]; ///< acceptance level for the cargo slots
CargoID accepts_cargo[3]; ///< 3 input cargo slots
BuildingFlags building_flags; ///< some flags that describe the house (size, stadium etc...)
HouseZones building_availability; ///< where can it be built (climates, zones)
bool enabled; ///< the house is available to build (true by default, but can be disabled by newgrf)
Year min_year; ///< introduction year of the house
Year max_year; ///< last year it can be built
byte population; ///< population (Zero on other tiles in multi tile house.)
byte removal_cost; ///< cost multiplier for removing it
StringID building_name; ///< building name
uint16 remove_rating_decrease; ///< rating decrease if removed
byte mail_generation; ///< mail generation multiplier (tile based, as the acceptances below)
byte cargo_acceptance[HOUSE_NUM_ACCEPTS]; ///< acceptance level for the cargo slots
CargoID accepts_cargo[HOUSE_NUM_ACCEPTS]; ///< input cargo slots
BuildingFlags building_flags; ///< some flags that describe the house (size, stadium etc...)
HouseZones building_availability; ///< where can it be built (climates, zones)
bool enabled; ///< the house is available to build (true by default, but can be disabled by newgrf)
/* NewHouses properties */
GRFFileProps grf_prop; ///< Properties related the the grf file
uint16 callback_mask; ///< Bitmask of house callbacks that have to be called
byte random_colour[4]; ///< 4 "random" colours
byte probability; ///< Relative probability of appearing (16 is the standard value)
HouseExtraFlags extra_flags; ///< some more flags
HouseClassID class_id; ///< defines the class this house has (not grf file based)
AnimationInfo animation; ///< information about the animation.
byte processing_time; ///< Periodic refresh multiplier
byte minimum_life; ///< The minimum number of years this house will survive before the town rebuilds it
CargoTypes watched_cargoes; ///< Cargo types watched for acceptance.
GRFFileProps grf_prop; ///< Properties related the the grf file
uint16 callback_mask; ///< Bitmask of house callbacks that have to be called
byte random_colour[4]; ///< 4 "random" colours
byte probability; ///< Relative probability of appearing (16 is the standard value)
HouseExtraFlags extra_flags; ///< some more flags
HouseClassID class_id; ///< defines the class this house has (not grf file based)
AnimationInfo animation; ///< information about the animation.
byte processing_time; ///< Periodic refresh multiplier
byte minimum_life; ///< The minimum number of years this house will survive before the town rebuilds it
CargoTypes watched_cargoes; ///< Cargo types watched for acceptance.
Money GetRemovalCost() const;

View File

@@ -93,6 +93,70 @@ extern const byte _slope_to_sprite_offset[32] = {
*/
static SnowLine *_snow_line = NULL;
/**
* Map 2D viewport or smallmap coordinate to 3D world or tile coordinate.
* Function takes into account height of tiles and foundations.
*
* @param x X viewport 2D coordinate.
* @param y Y viewport 2D coordinate.
* @param clamp_to_map Clamp the coordinate outside of the map to the closest, non-void tile within the map.
* @param[out] clamped Whether coordinates were clamped.
* @return 3D world coordinate of point visible at the given screen coordinate (3D perspective).
*
* @note Inverse of #RemapCoords2 function. Smaller values may get rounded.
* @see InverseRemapCoords
*/
Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped)
{
if (clamped != NULL) *clamped = false; // Not clamping yet.
/* Initial x/y world coordinate is like if the landscape
* was completely flat on height 0. */
Point pt = InverseRemapCoords(x, y);
const uint min_coord = _settings_game.construction.freeform_edges ? TILE_SIZE : 0;
const uint max_x = MapMaxX() * TILE_SIZE - 1;
const uint max_y = MapMaxY() * TILE_SIZE - 1;
if (clamp_to_map) {
/* Bring the coordinates near to a valid range. At the top we allow a number
* of extra tiles. This is mostly due to the tiles on the north side of
* the map possibly being drawn higher due to the extra height levels. */
int extra_tiles = CeilDiv(_settings_game.construction.max_heightlevel * TILE_HEIGHT, TILE_PIXELS);
Point old_pt = pt;
pt.x = Clamp(pt.x, -extra_tiles * TILE_SIZE, max_x);
pt.y = Clamp(pt.y, -extra_tiles * TILE_SIZE, max_y);
if (clamped != NULL) *clamped = (pt.x != old_pt.x) || (pt.y != old_pt.y);
}
/* Now find the Z-world coordinate by fix point iteration.
* This is a bit tricky because the tile height is non-continuous at foundations.
* The clicked point should be approached from the back, otherwise there are regions that are not clickable.
* (FOUNDATION_HALFTILE_LOWER on SLOPE_STEEP_S hides north halftile completely)
* So give it a z-malus of 4 in the first iterations. */
int z = 0;
if (clamp_to_map) {
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + max(z, 4) - 4, min_coord, max_x), Clamp(pt.y + max(z, 4) - 4, min_coord, max_y)) / 2;
for (int m = 3; m > 0; m--) z = GetSlopePixelZ(Clamp(pt.x + max(z, m) - m, min_coord, max_x), Clamp(pt.y + max(z, m) - m, min_coord, max_y)) / 2;
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + z, min_coord, max_x), Clamp(pt.y + z, min_coord, max_y)) / 2;
} else {
for (int i = 0; i < 5; i++) z = GetSlopePixelZOutsideMap(pt.x + max(z, 4) - 4, pt.y + max(z, 4) - 4) / 2;
for (int m = 3; m > 0; m--) z = GetSlopePixelZOutsideMap(pt.x + max(z, m) - m, pt.y + max(z, m) - m) / 2;
for (int i = 0; i < 5; i++) z = GetSlopePixelZOutsideMap(pt.x + z, pt.y + z ) / 2;
}
pt.x += z;
pt.y += z;
if (clamp_to_map) {
Point old_pt = pt;
pt.x = Clamp(pt.x, min_coord, max_x);
pt.y = Clamp(pt.y, min_coord, max_y);
if (clamped != NULL) *clamped = *clamped || (pt.x != old_pt.x) || (pt.y != old_pt.y);
}
return pt;
}
/**
* Applies a foundation to a slope.
*
@@ -288,6 +352,23 @@ int GetSlopePixelZ(int x, int y)
return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
}
/**
* Return world \c z coordinate of a given point of a tile,
* also for tiles outside the map (virtual "black" tiles).
*
* @param x World X coordinate in tile "units", may be ouside the map.
* @param y World Y coordinate in tile "units", may be ouside the map.
* @return World Z coordinate at tile ground level, including slopes and foundations.
*/
int GetSlopePixelZOutsideMap(int x, int y)
{
if (IsInsideBS(x, 0, MapSizeX() * TILE_SIZE) && IsInsideBS(y, 0, MapSizeY() * TILE_SIZE)) {
return GetSlopePixelZ(x, y);
} else {
return _tile_type_procs[MP_VOID]->get_slope_z_proc(INVALID_TILE, x, y);
}
}
/**
* Determine the Z height of a corner relative to TileZ.
*

View File

@@ -40,6 +40,7 @@ Slope GetFoundationSlope(TileIndex tile, int *z = NULL);
uint GetPartialPixelZ(int x, int y, Slope corners);
int GetSlopePixelZ(int x, int y);
int GetSlopePixelZOutsideMap(int x, int y);
void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2);
/**
@@ -108,6 +109,7 @@ static inline Point RemapCoords2(int x, int y)
* @param y Y coordinate of the 2D coordinate.
* @return X and Y components of equivalent world or tile coordinate.
* @note Inverse of #RemapCoords function. Smaller values may get rounded.
* @see InverseRemapCoords2
*/
static inline Point InverseRemapCoords(int x, int y)
{
@@ -115,6 +117,8 @@ static inline Point InverseRemapCoords(int x, int y)
return pt;
}
Point InverseRemapCoords2(int x, int y, bool clamp_to_map = false, bool *clamped = NULL);
uint ApplyFoundationToSlope(Foundation f, Slope *s);
/**
* Applies a foundation to a slope.

View File

@@ -3451,6 +3451,9 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centrira
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Razina proizvodnje: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Industrija je najavila uskoro zatvaranje!
STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Treba: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Proizvodi: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING}
STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Treba:
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING}

View File

@@ -2027,7 +2027,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Change c
STR_CHEAT_SETUP_PROD :{LTBLUE}Enable modifying production values: {ORANGE}{STRING1}
# Livery window
STR_LIVERY_CAPTION :{WHITE}New Colour Scheme
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Colour Scheme
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Show general colour schemes
STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Show train colour schemes
@@ -3415,8 +3415,13 @@ STR_NEWGRF_SETTINGS_GRF_ID :{BLACK}GRF ID:
STR_NEWGRF_SETTINGS_VERSION :{BLACK}Version: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Min. compatible version: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{RAW_STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palette: {SILVER}{RAW_STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palette: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Default (D)
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Default (D) / 32 bpp
STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Legacy (W)
STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Legacy (W) / 32 bpp
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parameters: {SILVER}{STRING1}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :None
STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}No information available
STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Matching file not found
@@ -4132,6 +4137,7 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacity
STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Powered Wagons: {GOLD}+{POWER}{BLACK} Weight: {GOLD}+{WEIGHT_SHORT}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}{STRING2}
STR_PURCHASE_INFO_ALL_TYPES :All cargo types
STR_PURCHASE_INFO_NONE :None
STR_PURCHASE_INFO_ALL_BUT :All but {CARGO_LIST}
STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Tractive Effort: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Range: {GOLD}{COMMA} tiles

View File

@@ -1821,7 +1821,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Modifier
STR_CHEAT_SETUP_PROD :{LTBLUE}Permettre la modification des valeurs de production{NBSP}: {ORANGE}{STRING}
# Livery window
STR_LIVERY_CAPTION :{WHITE}Nouvelle couleur
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Couleur
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Montrer les livrées générales
STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Montrer les livrées de trains
@@ -2894,7 +2894,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Version{
STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Version compatible min.{NBSP}: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum{NBSP}: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palette{NBSP}: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Défaut (D)
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Défaut (D) / 32 bpp
STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Ancienne (W)
STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Ancienne (W) / 32 bpp
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Paramètres{NBSP}: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :Aucuns
STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}Pas d'informations disponibles
STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Module correspondant non trouvé
@@ -3459,6 +3464,7 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacit
STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Wagons motorisés{NBSP}: {GOLD}+{POWER}{BLACK} Poids{NBSP}: {GOLD}+{WEIGHT_SHORT}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Réaménageable pour{NBSP}: {GOLD}{STRING}
STR_PURCHASE_INFO_ALL_TYPES :Tous les types de cargaison
STR_PURCHASE_INFO_NONE :Aucune cargaison
STR_PURCHASE_INFO_ALL_BUT :Tous sauf {CARGO_LIST}
STR_PURCHASE_INFO_MAX_TE :{BLACK}Effort de traction max.{NBSP}: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Rayon d'action{NBSP}: {GOLD}{COMMA}{NBSP}cases

View File

@@ -191,6 +191,7 @@ STR_COLOUR_ORANGE :Arancio
STR_COLOUR_BROWN :Marrone
STR_COLOUR_GREY :Grigio
STR_COLOUR_WHITE :Bianco
STR_COLOUR_RANDOM :Casuale
# Units used in OpenTTD
STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mph
@@ -931,6 +932,7 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personalizzata.
STR_GAME_OPTIONS_CURRENCY_GEL :Lari georgiano (GEL)
STR_GAME_OPTIONS_CURRENCY_IRR :Rial iraniano (IRR)
STR_GAME_OPTIONS_CURRENCY_RUB :Nuovo rublo russo (RUB)
STR_GAME_OPTIONS_CURRENCY_MXN :Peso messicano (MXN)
############ end of currency region
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Automezzi
@@ -1282,6 +1284,8 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Non è p
STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Manutenzione infrastrutture: {STRING}
STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Se abilitata, le infrastrutture causano dei costi di manutenzione. I costi crescono in modo più che proporzionale alla dimensione della rete, influenzando maggiormente le compagnie più grandi rispetto alle piccole
STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Colore iniziale compagnia: {STRING}
STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Sceglie il colore iniziale della compagnia
STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Non rendere mai obsoleti i tipi di aeroporto: {STRING}
STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Abilitando questa impostazione, tutti i tipi di aeroporto rimangono disponibili indefinitamente dopo essere stati introdotti
@@ -2919,7 +2923,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Versione
STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Versione minima compatibile: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}Somma MD5: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Tavolozza: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Predefinita (D)
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Predefinita (D) / 32 bpp
STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Legacy (W)
STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Legacy (W) / 32 bpp
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parametri: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :Nessuno
STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}Informazioni non disponibili
STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}File corrispondente non trovato
@@ -3381,6 +3390,9 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centra l
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Livello di produzione: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}L'industria ha annunciato che a breve chiuderà!
STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Richiede: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING}
STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Richiede:
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING}
@@ -3481,6 +3493,7 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacit
STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagoni motorizzati: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_SHORT}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Riadattabile per: {GOLD}{STRING}
STR_PURCHASE_INFO_ALL_TYPES :Tutti i tipi di carico
STR_PURCHASE_INFO_NONE :Niente
STR_PURCHASE_INFO_ALL_BUT :Tutto tranne {CARGO_LIST}
STR_PURCHASE_INFO_MAX_TE :{BLACK}Sforzo di trazione massimo: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Autonomia: {GOLD}{COMMA} riquadr{P o i}

View File

@@ -189,6 +189,7 @@ STR_COLOUR_ORANGE :주황
STR_COLOUR_BROWN :갈색
STR_COLOUR_GREY :회색
STR_COLOUR_WHITE :흰색
STR_COLOUR_RANDOM :무작위
# Units used in OpenTTD
STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mph
@@ -937,6 +938,7 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :사용자 설
STR_GAME_OPTIONS_CURRENCY_GEL :그루지야 라리 (GEL)
STR_GAME_OPTIONS_CURRENCY_IRR :이란 리알 (IRR)
STR_GAME_OPTIONS_CURRENCY_RUB :신 러시아 루블 (RUB)
STR_GAME_OPTIONS_CURRENCY_MXN :멕시코 페소 (MXN)
############ end of currency region
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}차량 통행 방식
@@ -1282,6 +1284,8 @@ STR_CONFIG_SETTING_NO_TRAIN_CRASH_OTHER_COMPANY_HELPTEXT :이 옵션은
STR_CONFIG_SETTING_FLIP_DIRECTION_ALL_TRAINS :모든 열차가 차량기지에서 뒤집어질 수 있게 함: {STRING}
STR_CONFIG_SETTING_FLIP_DIRECTION_ALL_TRAINS_HELPTEXT :NewGRF에서 차량기지에서 열차의 방향을 뒤집을 수 없도록 설정되어 있어도 무시하고 열차를 차량기지에서 뒤집을 수 있게 합니다.
STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :시작시 회사 색상: {STRING}
STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :새 회사에서 사용할 색상을 선택하세요.
STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :옛날 공항을 사라지지 않고 계속 만들 수 있게 함: {STRING}
STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :이 설정을 켜면, 소형 공항을 포함한 모든 공항 종류를 도입 이후에 계속 사용할 수 있게 됩니다.
@@ -2023,7 +2027,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}현재
STR_CHEAT_SETUP_PROD :{LTBLUE}1차 산업시설 생산량 조절 허용: {ORANGE}{STRING}
# Livery window
STR_LIVERY_CAPTION :{WHITE} 색상
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - 색상
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}기본 색상 선택
STR_LIVERY_TRAIN_TOOLTIP :{BLACK}열차 색상 선택
@@ -3411,7 +3415,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}버전:
STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}최소 이용 가능한 버전: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5합: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}색상표: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :도스
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :도스 / 32 bpp
STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Windows
STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Windows / 32 bpp
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}매개 변숫값: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :없음
STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}관련 정보 없음
STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}일치하는 파일을 찾을 수 없습니다
@@ -3980,6 +3989,10 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}이 산
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}생산 수준: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}산업시설이 곧 폐쇄됩니다!
STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}받는 화물: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}생산 화물: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING}
STR_INDUSTRY_VIEW_TRANSPORTED_TOOLTIP :{BLACK}{STRING}{STRING}
STR_INDUSTRY_VIEW_TRANSPORTED_TOOLTIP_EXTENSION :{}{BLACK}{CARGO_LONG} ({COMMA}%)
@@ -4123,6 +4136,7 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}수용
STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}전원 화물차: {GOLD}+{POWER}{BLACK} 무게: {GOLD}+{WEIGHT_SHORT}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}개조가능 화물: {GOLD}{STRING}
STR_PURCHASE_INFO_ALL_TYPES :모든 화물
STR_PURCHASE_INFO_NONE :없음
STR_PURCHASE_INFO_ALL_BUT :{CARGO_LIST} 이외의 모든 화물
STR_PURCHASE_INFO_MAX_TE :{BLACK}최고 견인력: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}항속거리: {GOLD}{COMMA} 칸
@@ -4568,6 +4582,7 @@ STR_ORDER_CONDITIONAL_AGE :연령 (년)
STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :정비 필요성
STR_ORDER_CONDITIONAL_UNCONDITIONALLY :항상
STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :남은 수명 (년)
STR_ORDER_CONDITIONAL_MAX_RELIABILITY :최대 신뢰도
STR_ORDER_CONDITIONAL_CARGO_WAITING :대기 화물
STR_ORDER_CONDITIONAL_ACCEPTANCE_DROPDOWN :받는 화물
STR_ORDER_CONDITIONAL_FREE_PLATFORMS :빈 승강장

View File

@@ -568,6 +568,7 @@ STR_COLOUR_ORANGE :Pomarańczowy
STR_COLOUR_BROWN :Brązowy
STR_COLOUR_GREY :Szary
STR_COLOUR_WHITE :Biały
STR_COLOUR_RANDOM :Losowy
# Units used in OpenTTD
STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mph
@@ -854,6 +855,7 @@ STR_ABOUT_MENU_SCREENSHOT :Zrzut ekranu
STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zrzut ekranu z pełnym przybliżeniem
STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Zrzut ekranu z przybliżeniem domyślnym
STR_ABOUT_MENU_GIANT_SCREENSHOT :Zrzut ekranu całej mapy
STR_ABOUT_MENU_SHOW_FRAMERATE :Pokaż ilość klatek na sekundę
STR_ABOUT_MENU_ABOUT_OPENTTD :Info o 'OpenTTD'
STR_ABOUT_MENU_SPRITE_ALIGNER :Wyrównywanie sprite'ów
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Włącz/wyłącz ramki
@@ -1056,6 +1058,7 @@ STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLA
STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Wyczyść
STR_PLAYLIST_CHANGE_SET :{BLACK}Zmień zestaw
STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Wyczyść obecny program (tylko Wlasny1 lub Wlasny2)
STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Zmień wybór muzyki na następny zainstalowany zestaw
STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klik na ścieżce aby dodać do obecnego programu (Wlasny1 i Wlasny2)
STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Kliknij na ścieżce muzycznej aby usunąć ją z wybranego programu (Wlasny1 lub Wlasny2)
@@ -1192,6 +1195,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC
STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Prezes)
STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} sponsoruje konstrukcję nowego miasta {TOWN}!
STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Zostało wybudowane nowe miasto o nazwie {TOWN}!
STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Rozpoczęto budowę nowe{G go j go} {STRING.d} blisko {TOWN}!
STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Now{G y a e} {STRING} został{G 0 "" a o} posadzon{G 0 y a e} blisko {TOWN}!
@@ -1304,6 +1308,8 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand Południow
STR_GAME_OPTIONS_CURRENCY_CUSTOM :Własna...
STR_GAME_OPTIONS_CURRENCY_GEL :Lari gruzińskie (GEL)
STR_GAME_OPTIONS_CURRENCY_IRR :Rial irański (IRR)
STR_GAME_OPTIONS_CURRENCY_RUB :Nowy rubel rosyjski (RUB)
STR_GAME_OPTIONS_CURRENCY_MXN :Peso meksykańskie (MXN)
############ end of currency region
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Pojazdy drogowe
@@ -1633,6 +1639,7 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Zmiana t
STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Utrzymywanie infrastruktury: {STRING}
STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Kiedy włączone, utrzymanie infrastruktury jest naliczane w kosztach. Koszty wzrastają nadproporcjonalnie do rozmiarów sieci połączeń, a więc dotykają bardziej duże niż małe firmy
STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Wybierz początkowy kolor dla firmy
STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Pozwól budować stare lotniska: {STRING}
STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Włączona opcja sprawia, że każdy typ lotniska będzie dostępny na zawsze od chwili wprowadzenia
@@ -1776,7 +1783,7 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Wlącz obsług
STR_CONFIG_SETTING_LOADING_INDICATORS :Pokazuj wskaźniki załadunku: {STRING}
STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Wybierz, czy wskaźnik załadunku pokazuje się nad ładowanym/rozładowywanym pojazdem
STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Pokazuj rozkłady jazdy w tickach, a nie w dniach: {STRING}
STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :W tabelach czasu, czas podróży pokaż w tyknięciach gry zamiast w dniach
STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :W tabelach czasu, czas podróży pokaż w tickach gry zamiast w dniach
STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Pokazuj przyjazdy i odjazdy w rozkładach: {STRING}
STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Wyświetlanie przewidywanego przyjazdu i odjazdu w rozkładach
STR_CONFIG_SETTING_QUICKGOTO :Szybkie tworzenie poleceń pojazdu: {STRING}
@@ -3071,14 +3078,28 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2018 Zespół OpenTTD
# Framerate display window
STR_FRAMERATE_CAPTION :{WHITE}Ilość klatek na sekundę
STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Liczba ticków gry symulowanych na sekundę.
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Liczba renderowanych klatek wideo na sekundę.
STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Jak szybko gra obecnie działa, w porównaniu do oczekiwanej prędkości przy normalnym tempie symulacji.
STR_FRAMERATE_CURRENT :{WHITE}Obecny
STR_FRAMERATE_AVERAGE :{WHITE}Średnia
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms
STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms
STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} klatek/sek.
STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} klatek/sek.
STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} klatek/sek.
STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms
STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} sek.
############ Leave those lines in this order!!
STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Opóźnienie wykresu połączeń:
STR_FRAMERATE_DRAWING :{BLACK}Renderowanie grafiki:
STR_FRAMERATE_VIDEO :{WHITE}Wyjście video:
STR_FRAMERATE_SOUND :{WHITE}Miksowanie dźwięku:
############ End of leave-in-this-order
############ Leave those lines in this order!!
STR_FRAMETIME_CAPTION_DRAWING :Renderowanie grafiki
STR_FRAMETIME_CAPTION_VIDEO :Wyjście wideo
STR_FRAMETIME_CAPTION_SOUND :Miksowanie dźwięku
############ End of leave-in-this-order
@@ -3368,6 +3389,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Wpisz na
STR_TOWN_DIRECTORY_CAPTION :{WHITE}Miasta
STR_TOWN_DIRECTORY_NONE :{ORANGE}- Żaden -
STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA})
STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Miasto){BLACK} ({COMMA})
STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nazwy miast - klik na nazwie aby wycentrować widok na mieście. Ctrl+klik otwiera nowy podgląd na lokację miasta
STR_TOWN_POPULATION :{BLACK}Populacja świata: {COMMA}
@@ -4187,6 +4209,7 @@ STR_ORDER_CONDITIONAL_AGE :Wiek (w latach)
STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Wymaga serwisowania
STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Zawsze
STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Pozostały czas życia (w latach)
STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Maksymalna niezawodność
STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Jak porównać dane pojazdu z zadaną wartością
STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :jest równy

View File

@@ -603,7 +603,7 @@ STR_ABOUT_MENU_SCREENSHOT :Снимок э
STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Снимок экрана в макс. приближении
STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Снимок экрана в обычном масштабе
STR_ABOUT_MENU_GIANT_SCREENSHOT :Снимок всей карты
STR_ABOUT_MENU_SHOW_FRAMERATE :Показать кол-во кадров/с
STR_ABOUT_MENU_SHOW_FRAMERATE :Информация о скорости игры
STR_ABOUT_MENU_ABOUT_OPENTTD :Об игре
STR_ABOUT_MENU_SPRITE_ALIGNER :Выравнивание спрайтов
STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Переключить ограничивающие рамки
@@ -1975,7 +1975,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Изме
STR_CHEAT_SETUP_PROD :{LTBLUE}Разрешить изменение производительности: {ORANGE}{STRING}
# Livery window
STR_LIVERY_CAPTION :{WHITE}Новая цветовая схема
STR_LIVERY_CAPTION :{WHITE}Цвета компании «{COMPANY}»
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Настройка основной цветовой схемы
STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Настройка цветовой схемы поездов
@@ -2558,9 +2558,9 @@ STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Комб
STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Маршрутный светофор{}Позволяет нескольким поездам находиться в одном сигнальном блоке, если каждый из них может зарезервировать безопасный путь. Допускает следование поездов в обе стороны.
STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Односторонний маршрутн. светофор{}Позволяет нескольким поездам находиться в одном сигнальном блоке, если каждый из них может зарезервировать безопасный путь. Не допускает следования поездов в обратную сторону.
STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Изменение типа сигнала{}Когда кнопка нажата, щёлкните для преобразования существующего сигнала в сигнал выбранного типа и варианта, или щёлкните с нажатым Ctrl для перебора существующих вариантов. Shift+щелчок - оценка стоимости преобразования.
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Плотность расстановки сигналов при протягивании.
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Уменьшить плотность сигналов при протягивании
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Увеличить плотность сигналов при протягивании
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Расстояние между сигналами при протягивании.
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Уменьшить расстояние между сигналами при протягивании
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Увеличить расстояние между сигналами при протягивании
# Bridge selection window
STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Выберите железнодорожный мост
@@ -2890,9 +2890,16 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD
STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2018 Команда разработчиков OpenTTD
# Framerate display window
STR_FRAMERATE_CAPTION :{WHITE}Скорость игры
STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x)
STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Скорость расчёта игры: {STRING}
STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Кол-во игровых циклов, рассчитываемых в секунду.
STR_FRAMERATE_RATE_BLITTER :{BLACK}Вывод на экран: {STRING}
STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Кол-во отображаемых кадров в секунду.
STR_FRAMERATE_SPEED_FACTOR :{BLACK}Текущая скорость игры: {DECIMAL}x
STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Фактическая скорость игры
STR_FRAMERATE_CURRENT :{WHITE}Сейчас
STR_FRAMERATE_AVERAGE :{WHITE}В среднем
STR_FRAMERATE_DATA_POINTS :{BLACK}Данные по {COMMA} измерени{P ю ям ям}
STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} мс
STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} мс
@@ -2903,11 +2910,32 @@ STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}
STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} мс
STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} с
############ Leave those lines in this order!!
STR_FRAMERATE_GAMELOOP :{BLACK}Расчёт игрового цикла:
STR_FRAMERATE_GL_ECONOMY :{BLACK} Расчёт объёмов груза:
STR_FRAMERATE_GL_TRAINS :{BLACK} Движение поездов:
STR_FRAMERATE_GL_ROADVEHS :{BLACK} Движение автомобилей:
STR_FRAMERATE_GL_SHIPS :{BLACK} Движение кораблей:
STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Движение воздушных судов:
STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Изменения на карте:
STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Задержка графа распределения:
STR_FRAMERATE_DRAWING :{BLACK}Отрисовка изображения:
STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Дополнительные окна:
STR_FRAMERATE_VIDEO :{BLACK}Вывод на экран:
STR_FRAMERATE_SOUND :{BLACK}Обработка звука:
############ End of leave-in-this-order
############ Leave those lines in this order!!
STR_FRAMETIME_CAPTION_GAMELOOP :Расчёт игрового цикла
STR_FRAMETIME_CAPTION_GL_ECONOMY :Расчёт объёмов груза
STR_FRAMETIME_CAPTION_GL_TRAINS :Движение поездов
STR_FRAMETIME_CAPTION_GL_ROADVEHS :Движение автомобилей
STR_FRAMETIME_CAPTION_GL_SHIPS :Движение кораблей
STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Движение воздушных судов
STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Расчёт изменений на карте
STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Задержка графа распределения
STR_FRAMETIME_CAPTION_DRAWING :Отрисовка графики
STR_FRAMETIME_CAPTION_DRAWING :Отрисовка изображения
STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Отрисовка изображения в доп. окнах
STR_FRAMETIME_CAPTION_VIDEO :Вывод на экран
STR_FRAMETIME_CAPTION_SOUND :Обработка звука
############ End of leave-in-this-order
@@ -3051,7 +3079,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Верс
STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Совместимо с версией не ниже: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Палитра: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Стандартная (D)
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Стандартная (D) / 32 bpp
STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Устаревшая (W)
STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Устаревшая (W) / 32 bpp
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Параметры: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :Нет
STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}Нет доступной информации
STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Файл не найден
@@ -3133,6 +3166,7 @@ STR_NEWGRF_ERROR_GRM_FAILED :Запроше
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} был отключён из-за {2:STRING}
STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Недопустимый/неизвестный формат расположения спрайтов (спрайт {3:NUM})
STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Слишком много элементов в списке значений (спрайт {3:NUM}, свойство {4:HEX})
STR_NEWGRF_ERROR_INDPROD_CALLBACK :Неверная обработка продукции предприятия (спрайт {3:NUM}, "{1:STRING}")
# NewGRF related 'general' warnings
STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Осторожно!
@@ -3615,6 +3649,7 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Ёмко
STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Ведущие вагоны: {GOLD}+{POWER}{BLACK} Вес: {GOLD}+{WEIGHT_SHORT}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Может перевозить: {GOLD}{STRING}
STR_PURCHASE_INFO_ALL_TYPES :Все типы грузов
STR_PURCHASE_INFO_NONE :Нет
STR_PURCHASE_INFO_ALL_BUT :Всё, кроме {CARGO_LIST}
STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс. тяговое усилие: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Дальность: {GOLD}{COMMA} клет{P ка ки ок}

View File

@@ -931,6 +931,7 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Personalizada..
STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgiano (GEL)
STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iraní (IRR)
STR_GAME_OPTIONS_CURRENCY_RUB :Nuevo Rublo Ruso (RUB)
STR_GAME_OPTIONS_CURRENCY_MXN :Peso mexicano (MXN)
############ end of currency region
STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Vehículos de carretera
@@ -1073,7 +1074,7 @@ STR_RIVERS_FEW :Pocos
STR_RIVERS_MODERATE :Medio
STR_RIVERS_LOT :Muchos
STR_DISASTER_NONE :Ninguna
STR_DISASTER_NONE :Ninguno
STR_DISASTER_REDUCED :Reducidas
STR_DISASTER_NORMAL :Normales
@@ -1597,7 +1598,7 @@ STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X :4x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x
STR_CONFIG_SETTING_TOWN_GROWTH :Velocidad crecimiento población: {STRING}
STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :Velocidad de crecimiento de los municipios
STR_CONFIG_SETTING_TOWN_GROWTH_NONE :Ninguna
STR_CONFIG_SETTING_TOWN_GROWTH_NONE :Ninguno
STR_CONFIG_SETTING_TOWN_GROWTH_SLOW :Lenta
STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :Normal
STR_CONFIG_SETTING_TOWN_GROWTH_FAST :Rápida
@@ -1812,7 +1813,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Cambiar
STR_CHEAT_SETUP_PROD :{LTBLUE}Permitir modificación de los valores de producción: {ORANGE}{STRING}
# Livery window
STR_LIVERY_CAPTION :{WHITE}Nuevo Esquema de Color
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Esquema de Color
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Mostrar esquema de colores general
STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Ver esquema de color de los trenes
@@ -2720,6 +2721,8 @@ STR_FRAMERATE_SOUND :{BLACK}Mezcla d
############ End of leave-in-this-order
############ Leave those lines in this order!!
STR_FRAMETIME_CAPTION_GL_TRAINS :Ticks de trenes
STR_FRAMETIME_CAPTION_GL_SHIPS :Ticks de barcos
STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Ticks de aeronaves
STR_FRAMETIME_CAPTION_DRAWING :Renderizado gráfico
STR_FRAMETIME_CAPTION_VIDEO :Salida de vídeo
STR_FRAMETIME_CAPTION_SOUND :Mezcla de sonido
@@ -2867,6 +2870,7 @@ STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Mín. ve
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Paleta: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parámetros: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :Ninguno
STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}No hay información disponible
STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Archivo no encontrado
@@ -3327,6 +3331,7 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centrar
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Nivel de producción: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}La industria ha anunciado su cierre inminente!
STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Requiere: {YELLOW}{STRING}{STRING}
STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necesita:
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING}
@@ -3826,6 +3831,7 @@ STR_ORDER_CONDITIONAL_AGE :Edad (años)
STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Requiere mantenimiento
STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Siempre
STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Tiempo de vida restante (años)
STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Fiabilidad máxima
STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Como comparar los datos del vehículo al valor dado
STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :es igual a

View File

@@ -1548,12 +1548,12 @@ STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI :Activar interfa
STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI_HELPTEXT :Mostrar una ventana para elegir los tipos de señales a instalar. Si no se activa, se instalan las señales y se selecciona un tipo determinado mediante Ctrl+Clic, sin que aparezca ninguna interfaz
STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE :Tipo de señal predeterminada a instalar: {STRING}
STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE_HELPTEXT :Tipo de señal predeterminada a utilizar
STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL :Señales de bloqueo
STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL :Señales de tramo
STR_CONFIG_SETTING_DEFAULT_SIGNAL_PBS :Señales de ruta
STR_CONFIG_SETTING_DEFAULT_SIGNAL_PBSOWAY :Señales de ruta de un sentido
STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Cambiar entre tipos de señales: {STRING}
STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Elegir entre qué señales se debe cambiar al usar Ctrl+Clic con la herramienta de señales
STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL :Solo señales de bloqueo
STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL :Solo señales de tramo
STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Solo señales de ruta
STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :Todas
@@ -2329,7 +2329,7 @@ STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Construi
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construir depósito de trenes (para comprar y dar mantenimiento a trenes). Mayús muestra una estimación del precio
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Construir punto guía sobre vías férreas. Ctrl activa la unión de puntos guías. Mayús muestra una estimación del precio
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Construir estación de ferrocarril. Ctrl activa la ampliación de estaciones. Mayús muestra una estimación del precio
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Instalar señales de ferrocarril. Ctrl cambia entre señales mecánicas y eléctricas{}Al arrastrar sobre las vías se instalan señales a lo largo de un tramo recto elegido. Ctrl instala señales hasta el siguiente desvío u otra señal{}Ctrl+Clic cambia a la herramienta de selección de señales. Mayús muestra una estimación del precio
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Poner señales. Ctrl intercambia señales mecánicas y eléctricas{}Arrastrar sobre un tramo recto permite poner señales intercaladas. Ctrl pone señales hasta un desvío u otra señal{}Ctrl+Clic cambia al modo de selección de señales. Mayús muestra una estimación del precio
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Construir puente de ferrocarril. Mayús muestra una estimación del precio
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Construir túnel de ferrocarril. Mayús muestra una estimación del precio
STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Quitar vías férreas, señales, estaciones y puntos guías. Al mantener pulsado Ctrl se quitan también las vías al retirar estaciones o puntos guías
@@ -2367,17 +2367,17 @@ STR_STATION_CLASS_WAYP :Puntos guías
# Signal window
STR_BUILD_SIGNAL_CAPTION :{WHITE}Selección de señales
STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Señal de bloqueo (mecánica){}Es el tipo de señal más básico que permite a un único tren ocupar al mismo tiempo un tramo de vía entre dos señales
STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Señal de entrada (mecánica){}Abierta si existe una o más señales de salida en el siguiente tramo, de lo contrario se mostrará cerrada
STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Señal de salida (mecánica){}Igual que una señal de bloqueo pero es necesaria para activar la posición correcta de las señales de entrada y combo
STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Señal de combo (mecánica){}La señal hace lo mismo que una señal de entrada y salida a la vez, lo que permite construir grandes "árboles" de señales condicionales
STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Señal de ruta (mecánica){}Una señal de ruta permite a más de un tren entrar al mismo tiempo en un tramo de vía con señales, en tanto que el tren pueda reservar una ruta hasta un lugar seguro. Puede ser pasada por detrás
STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Señal de tramo (mecánica){}Es la señal más básica. Permite a un solo tren ocupar un tramo de vía entre dos señales
STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Señal de entrada (mecánica){}Se abre si existe una o más señales de salida en el siguiente tramo, de lo contrario se mostrará cerrada
STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Señal de salida (mecánica){}Igual que una señal de tramo pero es necesaria para activar la posición correcta de las señales de entrada y combo
STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Señal combo (mecánica){}Hace lo mismo que las señales de entrada y de salida, lo que permite construir amplios "árboles" de señales condicionales
STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Señal de ruta (mecánica){}Permite a más de un tren entrar al mismo tiempo en un tramo de vía con señales, en tanto que el tren pueda reservar una ruta hasta un lugar seguro. Puede ser pasada por detrás
STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Señal de ruta de un sentido (mecánica){}Igual que una señal de ruta pero no puede ser pasada por detrás
STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Señal de bloqueo (eléctrica){}Es el tipo de señal más básico que permite a un único tren ocupar al mismo tiempo un tramo de vía entre dos señales
STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Señal de entrada (eléctrica){}Verde si existe una o más señales de salida en el siguiente tramo, de lo contrario se mostrará en rojo
STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Señal de salida (eléctrica){}Igual que una señal de bloqueo pero es necesaria para activar el color correcto de las señales de entrada y combo
STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Señal combo (eléctrica){}La señal hace lo mismo que una señal de entrada y salida a la vez, lo que permite construir grandes "árboles" de señales condicionales
STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Señal de ruta (eléctrica){}Una señal de ruta permite a más de un tren entrar al mismo tiempo en un tramo de vía con señales, en tanto que el tren pueda reservar una ruta hasta un lugar seguro. Puede ser pasada por detrás
STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Señal de tramo (eléctrica){}Es la señal más básica. Permite a un solo tren ocupar un tramo de vía entre dos señales
STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Señal de entrada (eléctrica){}En verde si existe una o más señales de salida en el siguiente tramo, de lo contrario se mostrará en rojo
STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Señal de salida (eléctrica){}Igual que una señal de tramo pero es necesaria para activar el color correcto de las señales de entrada y combo
STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Señal combo (eléctrica){}Hace lo mismo que las señales de entrada y de salida, lo que permite construir amplios "árboles" de señales condicionales
STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Señal de ruta (eléctrica){}Permite a más de un tren entrar al mismo tiempo en un tramo de vía con señales, en tanto que el tren pueda reservar una ruta hasta un lugar seguro. Puede ser pasada por detrás
STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Señal de ruta de un sentido (eléctrica){}Igual que una señal de ruta pero no puede ser pasada por detrás
STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Conversión de señal{}Activar para pulsar sobre una señal existente y convertirla en el tipo y variante elegidos. Ctrl+Clic permite cambiar entre variantes de señales. Mayús+Clic muestra una estimación del precio de conversión
STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Distancia entre señales
@@ -2894,7 +2894,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Versión
STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Mín. versión compatible: {SILVER}{NUM}
STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Paleta: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Por defecto (D)
STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Por defecto (D) / 32 bpp
STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Tradicional (W)
STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Tradicional (W) / 32 bpp
STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parámetros: {SILVER}{STRING}
STR_NEWGRF_SETTINGS_PARAMETER_NONE :Ninguna
STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}No hay información disponible
STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Archivo no encontrado
@@ -3459,6 +3464,7 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacida
STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagones con motor: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_SHORT}
STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Reforma: {GOLD}{STRING}
STR_PURCHASE_INFO_ALL_TYPES :Todo tipo de carga
STR_PURCHASE_INFO_NONE :Ninguno
STR_PURCHASE_INFO_ALL_BUT :Todo excepto {CARGO_LIST}
STR_PURCHASE_INFO_MAX_TE :{BLACK}Máx. fuerza de tracción: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Alcance: {GOLD}{COMMA} casillas

View File

@@ -239,13 +239,16 @@ inline bool LinkGraphOverlay::IsLinkVisible(Point pta, Point ptb, const DrawPixe
const int top = dpi->top - padding;
const int bottom = dpi->top + dpi->height + padding;
// Cut-down CohenSutherland algorithm
/*
* This method is an implementation of the Cohen-Sutherland line-clipping algorithm.
* See: https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm
*/
const unsigned char INSIDE = 0; // 0000
const unsigned char LEFT = 1; // 0001
const unsigned char RIGHT = 2; // 0010
const unsigned char BOTTOM = 4; // 0100
const unsigned char TOP = 8; // 1000
const uint8 INSIDE = 0; // 0000
const uint8 LEFT = 1; // 0001
const uint8 RIGHT = 2; // 0010
const uint8 BOTTOM = 4; // 0100
const uint8 TOP = 8; // 1000
int x0 = pta.x;
int y0 = pta.y;
@@ -253,7 +256,7 @@ inline bool LinkGraphOverlay::IsLinkVisible(Point pta, Point ptb, const DrawPixe
int y1 = ptb.y;
auto out_code = [&](int x, int y) -> unsigned char {
unsigned char out = INSIDE;
uint8 out = INSIDE;
if (x < left) {
out |= LEFT;
} else if (x > right) {
@@ -267,8 +270,8 @@ inline bool LinkGraphOverlay::IsLinkVisible(Point pta, Point ptb, const DrawPixe
return out;
};
unsigned char c0 = out_code(x0, y0);
unsigned char c1 = out_code(x1, y1);
uint8 c0 = out_code(x0, y0);
uint8 c1 = out_code(x1, y1);
while (true) {
if (c0 == 0 || c1 == 0) return true;

View File

@@ -2365,6 +2365,10 @@ static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
break;
}
case 0x23:
buf->Skip(buf->ReadByte() * 2);
break;
default:
ret = HandleAction0PropertyDefault(buf, prop);
break;
@@ -2597,6 +2601,28 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, con
housespec->max_year = buf->ReadWord();
break;
case 0x23: { // variable length cargo types accepted
uint count = buf->ReadByte();
if (count > lengthof(housespec->accepts_cargo)) {
GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
error->param_value[1] = prop;
return CIR_DISABLED;
}
/* Always write the full accepts_cargo array, and check each index for being inside the
* provided data. This ensures all values are properly initialized, and also avoids
* any risks of array overrun. */
for (uint i = 0; i < lengthof(housespec->accepts_cargo); i++) {
if (i < count) {
housespec->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
housespec->cargo_acceptance[i] = buf->ReadByte();
} else {
housespec->accepts_cargo[i] = CT_INVALID;
housespec->cargo_acceptance[i] = 0;
}
}
break;
}
default:
ret = HandleAction0PropertyDefault(buf, prop);
break;

View File

@@ -113,15 +113,15 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint
SetDParam(0, STR_JUST_RAW_STRING);
SetDParamStr(1, buff);
} else {
SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE);
SetDParam(0, STR_NEWGRF_SETTINGS_PARAMETER_NONE);
}
y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PARAMETER);
/* Draw the palette of the NewGRF */
if (c->palette & GRFP_BLT_32BPP) {
SetDParamStr(0, (c->palette & GRFP_USE_WINDOWS) ? "Legacy (W) / 32 bpp" : "Default (D) / 32 bpp");
SetDParam(0, (c->palette & GRFP_USE_WINDOWS) ? STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP : STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP);
} else {
SetDParamStr(0, (c->palette & GRFP_USE_WINDOWS) ? "Legacy (W)" : "Default (D)");
SetDParam(0, (c->palette & GRFP_USE_WINDOWS) ? STR_NEWGRF_SETTINGS_PALETTE_LEGACY : STR_NEWGRF_SETTINGS_PALETTE_DEFAULT);
}
y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PALETTE);
}

View File

@@ -2519,6 +2519,13 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
} else {
if (v->type != VEH_AIRCRAFT) {
v->SetDestTile(Depot::Get(order->GetDestination())->xy);
} else {
Aircraft *a = Aircraft::From(v);
DestinationID destination = a->current_order.GetDestination();
if (a->targetairport != destination) {
/* The aircraft is now heading for a different hangar than the next in the orders */
a->SetDestTile(a->GetOrderStationLocation(destination));
}
}
return true;
}

View File

@@ -14,7 +14,7 @@
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
#ifdef MSVC
#ifndef __MINGW32__
#include "winres.h"
#else
#define IDC_STATIC (-1) // all static controls
@@ -117,5 +117,9 @@ END
#endif // !_MAC
#ifdef __MINGW32__
1 24 "..\\..\\..\\projects\\dpi_aware.manifest"
#endif
#endif // Neutral (Default) resources
/////////////////////////////////////////////////////////////////////////////

View File

@@ -59,7 +59,7 @@ public:
/* handle special case - when next tile is destination tile */
if (tile == v->dest_tile) {
/* convert tracks to trackdirs */
TrackdirBits trackdirs = (TrackdirBits)(tracks | ((int)tracks << 8));
TrackdirBits trackdirs = TrackBitsToTrackdirBits(tracks);
/* limit to trackdirs reachable from enterdir */
trackdirs &= DiagdirReachesTrackdirs(enterdir);

View File

@@ -282,8 +282,9 @@
* 201 #6885 Extend NewGRF persistant storages.
* 202 #6867 Increase industry cargo slots to 16 in, 16 out
* 203 #7072 Add path cache for ships
* 204 #7065 Add extra rotation stages for ships.
*/
extern const uint16 SAVEGAME_VERSION = 203; ///< Current savegame version of OpenTTD.
extern const uint16 SAVEGAME_VERSION = 204; ///< Current savegame version of OpenTTD.
const uint16 SAVEGAME_VERSION_EXT = 0x8000; ///< Savegame extension indicator mask
SavegameType _savegame_type; ///< type of savegame we are loading

View File

@@ -371,6 +371,14 @@ void AfterLoadVehicles(bool part_of_load)
v->SetServiceIntervalIsPercent(c->settings.vehicle.servint_ispercent);
}
}
if (IsSavegameVersionBefore(204)) {
/* Ship rotation added */
Ship *s;
FOR_ALL_SHIPS(s) {
s->rotation = s->direction;
}
}
}
v = nullptr;
@@ -792,8 +800,9 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
static const SaveLoad _ship_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
SLE_VEH_INCLUDE(),
SLE_VAR(Ship, state, SLE_UINT8),
SLE_CONDDEQUE(Ship, path, SLE_UINT8, 203, SL_MAX_VERSION),
SLE_VAR(Ship, state, SLE_UINT8),
SLE_CONDDEQUE(Ship, path, SLE_UINT8, 203, SL_MAX_VERSION),
SLE_CONDVAR(Ship, rotation, SLE_UINT8, 204, SL_MAX_VERSION),
SLE_CONDNULL(16, 2, 143), // old reserved space

View File

@@ -24,6 +24,8 @@ BEGIN {
skiptillend = 0;
}
{ CR = (match($0, "\\r$") > 0 ? "\r" : "") }
/@enum/ {
print;
add_indent = gensub("[^ ]*", "", "g");
@@ -42,7 +44,7 @@ BEGIN {
active_comment = 0;
comment = "";
file = filearray[i];
print add_indent "/* automatically generated from " file " */"
print add_indent "/* automatically generated from " file " */" CR
while ((getline < file) > 0) {
sub(rm_indent, "");
@@ -65,7 +67,7 @@ BEGIN {
}
# Forget doxygen comment, if no enum follows
if (active_comment == 2 && $0 != "") {
if (active_comment == 2 && $0 != "" CR) {
active_comment = 0;
comment = "";
}
@@ -78,22 +80,21 @@ BEGIN {
sub(" *//", " //");
match($0, "^( *)([A-Za-z0-9_]+),(.*)", parts);
enumwidth - length(parts[2])
if (parts[3] == "") {
printf "%s%s%-45s= ::%s\n", add_indent, parts[1], parts[2], (parts[2] ",")
if (parts[3] == "" CR) {
printf "%s%s%-45s= ::%s\n", add_indent, parts[1], parts[2], (parts[2] "," CR)
} else {
printf "%s%s%-45s= ::%-45s%s\n", add_indent, parts[1], parts[2], (parts[2] ","), parts[3];
printf "%s%s%-45s= ::%-45s%s\n", add_indent, parts[1], parts[2], (parts[2] ","), (parts[3]);
}
} else if ($0 == "") {
print "";
} else if ($0 == "" CR) {
print "" CR;
} else {
print add_indent $0;
}
}
if (match($0, "^ *\\};") > 0) {
if (active != 0) print "";
if (active != 0) print "" CR;
active = 0;
}
}

View File

@@ -0,0 +1,192 @@
Option Explicit
' $Id$
'
' 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/>.
Dim FSO, filename, skiptillend, eof
Set FSO = CreateObject("Scripting.FileSystemObject")
filename = "script_window.hpp"
skiptillend = False
eof = vbCrLf
If Not FSO.FileExists(filename) Then
WScript.Echo filename & " not found"
WScript.Quit 1
End If
Function GetFiles(pattern)
Dim parent, re, files, f
Set files = CreateObject("Scripting.Dictionary")
Set re = New RegExp
parent = FSO.GetParentFolderName(pattern)
pattern = FSO.GetFileName(pattern)
' Convert pattern to a valid regex
re.Global = True
re.Pattern = "\."
pattern = re.Replace(pattern, "\.")
re.Pattern = "\*"
pattern = re.Replace(pattern, ".*")
re.Pattern = pattern
' Get the file list
For Each f In FSO.GetFolder(parent).Files
If re.Test(f.Path) Then
f = parent & "/" & f.Name
files.Add f, f
End If
Next
' Sort the file list
Set GetFiles = CreateObject("Scripting.Dictionary")
While files.Count <> 0
Dim first
first = ""
For Each f in files
If first = "" Or StrComp(first, f) = 1 Then first = f
Next
GetFiles.Add first, first
files.Remove(First)
Wend
End Function
Sub Generate(line, file)
Dim re, add_indent, enum_pattern, file_pattern, f, active, active_comment, comment, rm_indent
Set re = New RegExp
re.Global = True
re.Pattern = "[^ ]*"
add_indent = re.Replace(line, "")
re.Global = False
re.Pattern = ".*@enum *"
line = Split(re.Replace(line, ""))
enum_pattern = line(0)
file_pattern = line(1)
For Each f In GetFiles(file_pattern).Items
active = 0
active_comment = 0
comment = ""
file.Write add_indent & "/* automatically generated from " & f & " */" & eof
Set f = FSO.OpenTextFile(f, 1)
While Not f.AtEndOfStream
re.Pattern = rm_indent
line = re.Replace(f.ReadLine, "")
' Remember possible doxygen comment before enum declaration
re.Pattern = "/\*\*"
If active = 0 And re.Test(line) Then
comment = add_indent & line
active_comment = 1
ElseIf active_comment = 1 Then
comment = comment & vbCrLf & add_indent & line
End If
' Check for enum match
re.Pattern = "^ *enum *" & enum_pattern & " *\{"
If re.Test(line) Then
re.Global = True
re.Pattern = "[^ ]*"
rm_indent = re.Replace(line, "")
re.Global = False
active = 1
If active_comment > 0 Then file.Write comment & eof
active_comment = 0
comment = ""
End If
' Forget doxygen comment, if no enum follows
If active_comment = 2 And line <> "" Then
active_comment = 0
comment = ""
End If
re.Pattern = "\*/"
If active_comment = 1 And re.Test(line) Then active_comment = 2
If active <> 0 Then
re.Pattern = "^ *[A-Za-z0-9_]* *[,=]"
If re.Test(line) Then
Dim parts
' Transform enum values
re.Pattern = " *=[^,]*"
line = re.Replace(line, "")
re.Pattern = " *//"
line = re.Replace(line, " //")
re.Pattern = "^( *)([A-Za-z0-9_]+),(.*)"
Set parts = re.Execute(line)
With parts.Item(0).SubMatches
If .Item(2) = "" Then
file.Write add_indent & .Item(0) & .Item(1) & String(45 - Len(.Item(1)), " ") & "= ::" & .Item(1) & "," & eof
Else
file.Write add_indent & .Item(0) & .Item(1) & String(45 - Len(.Item(1)), " ") & "= ::" & .Item(1) & "," & String(44 - Len(.Item(1)), " ") & .Item(2) & eof
End If
End With
ElseIf line = "" Then
file.Write eof
Else
file.Write add_indent & line & eof
End If
End If
re.Pattern = "^ *\};"
If re.Test(line) Then
If active <> 0 Then file.Write eof
active = 0
End If
Wend
f.Close
Next
End Sub
Sub Parse(line, file)
Dim re
Set re = New RegExp
re.pattern = "@enum"
If re.Test(line) Then
file.Write line & eof
Generate line, file
skiptillend = True
Exit Sub
End If
re.pattern = "@endenum"
If re.Test(line) Then
file.Write line & eof
skiptillend = False
Exit Sub
End If
If Not skiptillend Then
file.Write line & eof
End If
End Sub
Dim file, source, lines, i
WScript.Echo "Starting to parse " & filename
Set file = FSO.OpenTextFile(filename, 1)
If Not file.AtEndOfStream Then
source = file.ReadAll
End IF
file.Close
lines = Split(source, eof)
If UBound(lines) = 0 Then
eof = vbLf
lines = Split(source, eof)
End If
Set file = FSO.OpenTextFile(filename, 2)
For i = LBound(lines) To UBound(lines) - 1 ' Split adds an extra line, we must ignore it
Parse lines(i), file
Next
file.Close
WScript.Echo "Done"

View File

@@ -170,7 +170,7 @@
break;
default:
EnforcePrecondition(false, days_between_town_growth <= MAX_TOWN_GROWTH_TICKS);
EnforcePrecondition(false, (days_between_town_growth * DAY_TICKS / TOWN_GROWTH_TICKS) <= MAX_TOWN_GROWTH_TICKS);
/* Don't use growth_rate 0 as it means GROWTH_NORMAL */
growth_rate = max(days_between_town_growth * DAY_TICKS, 2u) - 1;
break;

View File

@@ -28,8 +28,9 @@ typedef std::deque<TrackdirByte> ShipPathCache;
* All ships have this type.
*/
struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
TrackBitsByte state; ///< The "track" the ship is following.
ShipPathCache path; ///< Cached path.
TrackBitsByte state; ///< The "track" the ship is following.
ShipPathCache path; ///< Cached path.
DirectionByte rotation; ///< Visible direction.
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
Ship() : SpecializedVehicleBase() {}

View File

@@ -129,6 +129,8 @@ void Ship::GetImage(Direction direction, EngineImageType image_type, VehicleSpri
{
uint8 spritenum = this->spritenum;
if (image_type == EIT_ON_MAP) direction = this->rotation;
if (is_custom_sprite(spritenum)) {
GetCustomVehicleSprite(this, direction, image_type, result);
if (result->IsValid()) return;
@@ -312,7 +314,7 @@ void Ship::UpdateDeltaXY()
{32, 6, -16, -3}, // NW
};
const int8 *bb = _delta_xy_table[this->direction];
const int8 *bb = _delta_xy_table[this->rotation];
this->x_offs = bb[3];
this->y_offs = bb[2];
this->x_extent = bb[1];
@@ -378,10 +380,10 @@ static bool CheckShipLeaveDepot(Ship *v)
if (north_tracks) {
/* Leave towards north */
v->direction = DiagDirToDir(north_dir);
v->rotation = v->direction = DiagDirToDir(north_dir);
} else if (south_tracks) {
/* Leave towards south */
v->direction = DiagDirToDir(south_dir);
v->rotation = v->direction = DiagDirToDir(south_dir);
} else {
/* Both ways blocked */
return false;
@@ -482,7 +484,7 @@ static Track ChooseShipTrack(Ship *v, TileIndex tile, DiagDirection enterdir, Tr
if (v->dest_tile == 0 || DistanceManhattan(tile, v->dest_tile) > SHIP_MAX_ORDER_DISTANCE + 5) {
/* No destination or destination too far, don't invoke pathfinder. */
track = TrackBitsToTrack(v->state);
if (track != TRACK_X && track != TRACK_Y) track = TrackToOppositeTrack(track);
if (!IsDiagonalTrack(track)) track = TrackToOppositeTrack(track);
if (!HasBit(tracks, track)) {
/* Can't continue in same direction so pick first available track. */
if (_settings_game.pf.forbid_90_deg) {
@@ -694,7 +696,6 @@ static void ShipController(Ship *v)
{
uint32 r;
const byte *b;
Direction dir;
Track track;
TrackBits tracks;
@@ -714,6 +715,16 @@ static void ShipController(Ship *v)
v->ShowVisualEffect();
/* Rotating on spot */
if (v->direction != v->rotation) {
if ((v->tick_counter & 7) == 0) {
DirDiff diff = DirDifference(v->direction, v->rotation);
v->rotation = ChangeDir(v->rotation, diff > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
v->UpdateViewport(true, true);
}
return;
}
if (!ShipAccelerate(v)) return;
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
@@ -804,7 +815,22 @@ static void ShipController(Ship *v)
if (old_wc != new_wc) v->UpdateCache();
}
v->direction = (Direction)b[2];
Direction new_direction = (Direction)b[2];
DirDiff diff = DirDifference(new_direction, v->direction);
switch (diff) {
case DIRDIFF_SAME:
case DIRDIFF_45RIGHT:
case DIRDIFF_45LEFT:
/* Continue at speed */
v->rotation = v->direction = new_direction;
break;
default:
/* Stop for rotation */
v->cur_speed = 0;
v->direction = new_direction;
break;
}
}
} else {
/* On a bridge */
@@ -831,8 +857,8 @@ getout:
return;
reverse_direction:
dir = ReverseDir(v->direction);
v->direction = dir;
v->direction = ReverseDir(v->direction);
v->cur_speed = 0;
v->path.clear();
goto getout;
}

View File

@@ -827,8 +827,8 @@ void SmallMapWindow::DrawMapIndicators() const
/* Find main viewport. */
const ViewPort *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
Point upper_left_smallmap_coord = TranslateXYToTileCoord(vp, vp->left, vp->top, false);
Point lower_right_smallmap_coord = TranslateXYToTileCoord(vp, vp->left + vp->width - 1, vp->top + vp->height - 1, false);
Point upper_left_smallmap_coord = InverseRemapCoords2(vp->virtual_left, vp->virtual_top);
Point lower_right_smallmap_coord = InverseRemapCoords2(vp->virtual_left + vp->virtual_width - 1, vp->virtual_top + vp->virtual_height - 1);
Point upper_left = this->RemapTile(upper_left_smallmap_coord.x / (int)TILE_SIZE, upper_left_smallmap_coord.y / (int)TILE_SIZE);
upper_left.x -= this->subscroll;
@@ -1557,7 +1557,7 @@ void SmallMapWindow::SetNewScroll(int sx, int sy, int sub)
void SmallMapWindow::SmallMapCenterOnCurrentPos()
{
const ViewPort *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
Point viewport_center = TranslateXYToTileCoord(vp, vp->left + vp->width / 2, vp->top + vp->height / 2);
Point viewport_center = InverseRemapCoords2(vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2);
int sub;
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);

View File

@@ -1812,8 +1812,11 @@ assert_compile(lengthof(_town_draw_tile_data) == (NEW_HOUSE_OFFSET) * 4 * 4);
* @see HouseSpec
*/
#define MS(mnd, mxd, p, rc, bn, rr, mg, ca1, ca2, ca3, bf, ba, cg1, cg2, cg3) \
{mnd, mxd, p, rc, bn, rr, mg, {ca1, ca2, ca3}, {cg1, cg2, cg3}, bf, ba, true, \
GRFFileProps(INVALID_HOUSE_ID), 0, {0, 0, 0, 0}, 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, {0, 2, 0, 0}, 0, 0, 0}
{mnd, mxd, p, rc, bn, rr, mg, \
{ca1, ca2, ca3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
{cg1, cg2, cg3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \
bf, ba, true, GRFFileProps(INVALID_HOUSE_ID), 0, {0, 0, 0, 0}, \
16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, {0, 2, 0, 0}, 0, 0, 0}
/** House specifications from original data */
static const HouseSpec _original_house_specs[] = {
/**

View File

@@ -762,7 +762,7 @@ static const char * const _name_french_real[] = {
"Blois",
"Troyes",
"Charolles",
"Grenoble",
"Toulouse",
"Chamb\xC3\xA9ry",
"Tours",
"St. Brieuc",
@@ -773,7 +773,7 @@ static const char * const _name_french_real[] = {
"Vichy",
"St. Valery",
"Beaujolais",
"Narbonne",
"Reims",
"Albi",
"Paris",
"Biarritz",
@@ -2041,8 +2041,8 @@ static const char * const _name_romanian_real[] = {
static const char * const _name_slovak_real[] = {
"Bratislava",
"Banovce nad Bebravou",
"Banska Bystrica",
"Banska Stiavnica",
"Bansk\xC3\xA1 Bystrica",
"Bansk\xC3\xA1 \xC5\xA0tiavnica",
"Bardejov",
"Brezno",
"Brezova pod Bradlom",
@@ -2050,9 +2050,9 @@ static const char * const _name_slovak_real[] = {
"Cadca",
"Cierna nad Tisou",
"Detva",
"Detva",
"Dolny Kubin",
"Pre\xC5\xA1ov",
"Dolny Kubin",
"Spi\xC5\xA1sk\xC3\xA1 Nov\xC3\xA1 Ves",
"Dunajska Streda",
"Gabcikovo",
"Galanta",
@@ -2064,8 +2064,8 @@ static const char * const _name_slovak_real[] = {
"Humenne",
"Hurbanovo",
"Kezmarok",
"Komarno",
"Kosice",
"Kom\xC3\xA1rno",
"Ko\xC5\xA1ice",
"Kremnica",
"Krompachy",
"Kuty",
@@ -2081,15 +2081,15 @@ static const char * const _name_slovak_real[] = {
"Myjava",
"Namestovo",
"Nitra",
"Nova Bana",
"Nove Mesto nad Vahom",
"Nove Zamky",
"Nov\xC3\xA1 Ba\xC5\x88""a",
"Nov\xC3\xA9"" Mesto nad V\xC3\xA1hom",
"Nov\xC3\xA9"" Z\xC3\xA1""mky",
"Partizanske",
"Pezinok",
"Piestany",
"Poltar",
"Poprad",
"Povazska Bystrica",
"Pova\xC5\xBEsk\xC3\xA1 Bystrica",
"Prievidza",
"Puchov",
"Revuca",
@@ -2123,7 +2123,7 @@ static const char * const _name_slovak_real[] = {
"Zahorska Bystrica",
"Zdiar",
"Ziar nad Hronom",
"Zilina",
"\xC5\xBDilina",
"Zlate Moravce",
"Zvolen",
};

View File

@@ -309,6 +309,14 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
}
if (flags & DC_EXEC) {
/* Mark affected areas dirty. */
for (TileIndexSet::const_iterator it = ts.dirty_tiles.begin(); it != ts.dirty_tiles.end(); it++) {
MarkTileDirtyByTile(*it);
TileIndexToHeightMap::const_iterator new_height = ts.tile_to_new_height.find(tile);
if (new_height == ts.tile_to_new_height.end()) continue;
MarkTileDirtyByTile(*it, ZOOM_LVL_END, 0, new_height->second);
}
/* change the height */
for (TileIndexToHeightMap::const_iterator it = ts.tile_to_new_height.begin();
it != ts.tile_to_new_height.end(); it++) {
@@ -318,91 +326,6 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
SetTileHeight(tile, (uint)height);
}
/* Finally mark the dirty tiles dirty */
for (TileIndexSet::const_iterator it = ts.dirty_tiles.begin(); it != ts.dirty_tiles.end(); it++) {
MarkTileDirtyByTile(*it);
int height = TerraformGetHeightOfTile(&ts, *it);
/* Now, if we alter the height of the map edge, we need to take care
* about repainting the affected areas outside map as well.
* Remember:
* Outside map, we assume that our landscape descends to
* height zero as fast as possible.
* Those simulated tiles (they don't exist as datastructure,
* only as concept in code) need to be repainted properly,
* otherwise we will get ugly glitches.
*
* Furthermore, note that we have to take care about the possibility,
* that landscape was higher before the change,
* so also tiles a bit outside need to be repainted.
*/
int x = TileX(*it);
int y = TileY(*it);
if (x == 0) {
if (y == 0) {
/* Height of the northern corner is altered. */
for (int cx = 0; cx >= -height - 1; cx--) {
for (int cy = 0; cy >= -height - 1; cy--) {
/* This means, tiles in the sector north of that
* corner need to be repainted.
*/
if (cx + cy >= -height - 2) {
/* But only tiles that actually might have changed. */
MarkTileDirtyByTileOutsideMap(cx, cy);
}
}
}
} else if (y < (int)MapMaxY()) {
for (int cx = 0; cx >= -height - 1; cx--) {
MarkTileDirtyByTileOutsideMap(cx, y);
}
} else {
for (int cx = 0; cx >= -height - 1; cx--) {
for (int cy = (int)MapMaxY(); cy <= (int)MapMaxY() + height + 1; cy++) {
if (cx + ((int)MapMaxY() - cy) >= -height - 2) {
MarkTileDirtyByTileOutsideMap(cx, cy);
}
}
}
}
} else if (x < (int)MapMaxX()) {
if (y == 0) {
for (int cy = 0; cy >= -height - 1; cy--) {
MarkTileDirtyByTileOutsideMap(x, cy);
}
} else if (y < (int)MapMaxY()) {
/* Nothing to be done here, we are inside the map. */
} else {
for (int cy = (int)MapMaxY(); cy <= (int)MapMaxY() + height + 1; cy++) {
MarkTileDirtyByTileOutsideMap(x, cy);
}
}
} else {
if (y == 0) {
for (int cx = (int)MapMaxX(); cx <= (int)MapMaxX() + height + 1; cx++) {
for (int cy = 0; cy >= -height - 1; cy--) {
if (((int)MapMaxX() - cx) + cy >= -height - 2) {
MarkTileDirtyByTileOutsideMap(cx, cy);
}
}
}
} else if (y < (int)MapMaxY()) {
for (int cx = (int)MapMaxX(); cx <= (int)MapMaxX() + height + 1; cx++) {
MarkTileDirtyByTileOutsideMap(cx, y);
}
} else {
for (int cx = (int)MapMaxX(); cx <= (int)MapMaxX() + height + 1; cx++) {
for (int cy = (int)MapMaxY(); cy <= (int)MapMaxY() + height + 1; cy++) {
if (((int)MapMaxX() - cx) + ((int)MapMaxY() - cy) >= -height - 2) {
MarkTileDirtyByTileOutsideMap(cx, cy);
}
}
}
}
}
}
if (c != NULL) c->terraform_limit -= (uint32)ts.tile_to_new_height.size() << 16;
}
return total_cost;

View File

@@ -14,60 +14,6 @@
#include "safeguards.h"
/**
* Returns the tile height for a coordinate outside map. Such a height is
* needed for painting the area outside map using completely black tiles.
* The idea is descending to heightlevel 0 as fast as possible.
* @param x The X-coordinate (same unit as TileX).
* @param y The Y-coordinate (same unit as TileY).
* @return The height in the same unit as TileHeight.
*/
uint TileHeightOutsideMap(int x, int y)
{
/* In all cases: Descend to heightlevel 0 as fast as possible.
* So: If we are at the 0-side of the map (x<0 or y<0), we must
* subtract the distance to coordinate 0 from the heightlevel at
* coordinate 0.
* In other words: Subtract e.g. -x. If we are at the MapMax
* side of the map, we also need to subtract the distance to
* the edge of map, e.g. MapMaxX - x.
*
* NOTE: Assuming constant heightlevel outside map would be
* simpler here. However, then we run into painting problems,
* since whenever a heightlevel change at the map border occurs,
* we would need to repaint anything outside map.
* In contrast, by doing it this way, we can localize this change,
* which means we may assume constant heightlevel for all tiles
* at more than <heightlevel at map border> distance from the
* map border.
*/
if (x < 0) {
if (y < 0) {
return max((int)TileHeight(TileXY(0, 0)) - (-x) - (-y), 0);
} else if (y < (int)MapMaxY()) {
return max((int)TileHeight(TileXY(0, y)) - (-x), 0);
} else {
return max((int)TileHeight(TileXY(0, (int)MapMaxY())) - (-x) - (y - (int)MapMaxY()), 0);
}
} else if (x < (int)MapMaxX()) {
if (y < 0) {
return max((int)TileHeight(TileXY(x, 0)) - (-y), 0);
} else if (y < (int)MapMaxY()) {
return TileHeight(TileXY(x, y));
} else {
return max((int)TileHeight(TileXY(x, (int)MapMaxY())) - (y - (int)MapMaxY()), 0);
}
} else {
if (y < 0) {
return max((int)TileHeight(TileXY((int)MapMaxX(), 0)) - (x - (int)MapMaxX()) - (-y), 0);
} else if (y < (int)MapMaxY()) {
return max((int)TileHeight(TileXY((int)MapMaxX(), y)) - (x - (int)MapMaxX()), 0);
} else {
return max((int)TileHeight(TileXY((int)MapMaxX(), (int)MapMaxY())) - (x - (int)MapMaxX()) - (y - (int)MapMaxY()), 0);
}
}
}
/**
* Get a tile's slope given the heigh of its four corners.
* @param hnorth The height at the northern corner in the same unit as TileHeight.
@@ -114,30 +60,26 @@ static Slope GetTileSlopeGivenHeight(int hnorth, int hwest, int heast, int hsout
*/
Slope GetTileSlope(TileIndex tile, int *h)
{
assert(tile < MapSize());
uint x1 = TileX(tile);
uint y1 = TileY(tile);
uint x2 = min(x1 + 1, MapMaxX());
uint y2 = min(y1 + 1, MapMaxY());
uint x = TileX(tile);
uint y = TileY(tile);
if (x == MapMaxX() || y == MapMaxY()) {
if (h != NULL) *h = TileHeight(tile);
return SLOPE_FLAT;
}
int hnorth = TileHeight(tile); // Height of the North corner.
int hwest = TileHeight(tile + TileDiffXY(1, 0)); // Height of the West corner.
int heast = TileHeight(tile + TileDiffXY(0, 1)); // Height of the East corner.
int hsouth = TileHeight(tile + TileDiffXY(1, 1)); // Height of the South corner.
int hnorth = TileHeight(tile); // Height of the North corner.
int hwest = TileHeight(TileXY(x2, y1)); // Height of the West corner.
int heast = TileHeight(TileXY(x1, y2)); // Height of the East corner.
int hsouth = TileHeight(TileXY(x2, y2)); // Height of the South corner.
return GetTileSlopeGivenHeight(hnorth, hwest, heast, hsouth, h);
}
/**
* Return the slope of a given tile outside the map.
* Return the slope of a given tile, also for tiles outside the map (virtual "black" tiles).
*
* @param x X-coordinate of the tile outside to compute height of.
* @param y Y-coordinate of the tile outside to compute height of.
* @param h If not \c NULL, pointer to storage of z height.
* @return Slope of the tile outside map, except for the HALFTILE part.
* @param x X coordinate of the tile to compute slope of, may be ouside the map.
* @param y Y coordinate of the tile to compute slope of, may be ouside the map.
* @param h If not \c NULL, pointer to storage of z height.
* @return Slope of the tile, except for the HALFTILE part.
*/
Slope GetTilePixelSlopeOutsideMap(int x, int y, int *h)
{
@@ -159,17 +101,15 @@ Slope GetTilePixelSlopeOutsideMap(int x, int y, int *h)
*/
bool IsTileFlat(TileIndex tile, int *h)
{
assert(tile < MapSize());
if (!IsInnerTile(tile)) {
if (h != NULL) *h = TileHeight(tile);
return true;
}
uint x1 = TileX(tile);
uint y1 = TileY(tile);
uint x2 = min(x1 + 1, MapMaxX());
uint y2 = min(y1 + 1, MapMaxY());
uint z = TileHeight(tile);
if (TileHeight(tile + TileDiffXY(1, 0)) != z) return false;
if (TileHeight(tile + TileDiffXY(0, 1)) != z) return false;
if (TileHeight(tile + TileDiffXY(1, 1)) != z) return false;
if (TileHeight(TileXY(x2, y1)) != z) return false;
if (TileHeight(TileXY(x1, y2)) != z) return false;
if (TileHeight(TileXY(x2, y2)) != z) return false;
if (h != NULL) *h = z;
return true;
@@ -182,33 +122,19 @@ bool IsTileFlat(TileIndex tile, int *h)
*/
int GetTileZ(TileIndex tile)
{
if (TileX(tile) == MapMaxX() || TileY(tile) == MapMaxY()) return 0;
uint x1 = TileX(tile);
uint y1 = TileY(tile);
uint x2 = min(x1 + 1, MapMaxX());
uint y2 = min(y1 + 1, MapMaxY());
int h = TileHeight(tile); // N corner
h = min(h, TileHeight(tile + TileDiffXY(1, 0))); // W corner
h = min(h, TileHeight(tile + TileDiffXY(0, 1))); // E corner
h = min(h, TileHeight(tile + TileDiffXY(1, 1))); // S corner
int h = TileHeight(tile); // N corner
h = min(h, TileHeight(TileXY(x2, y1))); // W corner
h = min(h, TileHeight(TileXY(x1, y2))); // E corner
h = min(h, TileHeight(TileXY(x2, y2))); // S corner
return h;
}
/**
* Get bottom height of the tile outside map.
*
* @param x X-coordinate of the tile outside to compute height of.
* @param y Y-coordinate of the tile outside to compute height of.
* @return Minimum height of the tile outside the map.
*/
int GetTilePixelZOutsideMap(int x, int y)
{
uint h = TileHeightOutsideMap(x, y); // N corner.
h = min(h, TileHeightOutsideMap(x + 1, y)); // W corner.
h = min(h, TileHeightOutsideMap(x, y + 1)); // E corner.
h = min(h, TileHeightOutsideMap(x + 1, y + 1)); // S corner
return h * TILE_HEIGHT;
}
/**
* Get top height of the tile inside the map.
* @param t Tile to compute height of
@@ -216,31 +142,15 @@ int GetTilePixelZOutsideMap(int x, int y)
*/
int GetTileMaxZ(TileIndex t)
{
if (TileX(t) == MapMaxX() || TileY(t) == MapMaxY()) return TileHeightOutsideMap(TileX(t), TileY(t));
uint x1 = TileX(t);
uint y1 = TileY(t);
uint x2 = min(x1 + 1, MapMaxX());
uint y2 = min(y1 + 1, MapMaxY());
int h = TileHeight(t); // N corner
h = max<int>(h, TileHeight(t + TileDiffXY(1, 0))); // W corner
h = max<int>(h, TileHeight(t + TileDiffXY(0, 1))); // E corner
h = max<int>(h, TileHeight(t + TileDiffXY(1, 1))); // S corner
int h = TileHeight(t); // N corner
h = max<int>(h, TileHeight(TileXY(x2, y1))); // W corner
h = max<int>(h, TileHeight(TileXY(x1, y2))); // E corner
h = max<int>(h, TileHeight(TileXY(x2, y2))); // S corner
return h;
}
/**
* Get top height of the tile outside the map.
*
* @see Detailed description in header.
*
* @param x X-coordinate of the tile outside to compute height of.
* @param y Y-coordinate of the tile outside to compute height of.
* @return Maximum height of the tile.
*/
int GetTileMaxPixelZOutsideMap(int x, int y)
{
uint h = TileHeightOutsideMap(x, y);
h = max(h, TileHeightOutsideMap(x + 1, y));
h = max(h, TileHeightOutsideMap(x, y + 1));
h = max(h, TileHeightOutsideMap(x + 1, y + 1));
return h * TILE_HEIGHT;
}

View File

@@ -37,7 +37,17 @@ static inline uint TileHeight(TileIndex tile)
return _m[tile].height;
}
uint TileHeightOutsideMap(int x, int y);
/**
* Returns the height of a tile, also for tiles outside the map (virtual "black" tiles).
*
* @param x X coordinate of the tile, may be ouside the map.
* @param y Y coordinate of the tile, may be ouside the map.
* @return The height in the same unit as TileHeight.
*/
static inline uint TileHeightOutsideMap(int x, int y)
{
return TileHeight(TileXY(Clamp(x, 0, MapMaxX()), Clamp(y, 0, MapMaxY())));
}
/**
* Sets the height of a tile.
@@ -70,11 +80,10 @@ static inline uint TilePixelHeight(TileIndex tile)
}
/**
* Returns the tile height for a coordinate outside map. Such a height is
* needed for painting the area outside map using completely black tiles.
* The idea is descending to heightlevel 0 as fast as possible.
* @param x The X-coordinate (same unit as TileX).
* @param y The Y-coordinate (same unit as TileY).
* Returns the height of a tile in pixels, also for tiles outside the map (virtual "black" tiles).
*
* @param x X coordinate of the tile, may be ouside the map.
* @param y Y coordinate of the tile, may be ouside the map.
* @return The height in pixels in the same unit as TilePixelHeight.
*/
static inline uint TilePixelHeightOutsideMap(int x, int y)
@@ -293,8 +302,6 @@ static inline int GetTilePixelZ(TileIndex tile)
return GetTileZ(tile) * TILE_HEIGHT;
}
int GetTilePixelZOutsideMap(int x, int y);
/**
* Get top height of the tile
* @param tile Tile to compute height of
@@ -305,9 +312,6 @@ static inline int GetTileMaxPixelZ(TileIndex tile)
return GetTileMaxZ(tile) * TILE_HEIGHT;
}
int GetTileMaxPixelZOutsideMap(int x, int y);
/**
* Calculate a hash value from a tile position
*

View File

@@ -121,12 +121,14 @@ public:
*/
class DropDownListCompanyItem : public DropDownListItem {
Dimension icon_size;
Dimension lock_size;
public:
bool greyed;
DropDownListCompanyItem(int result, bool masked, bool greyed) : DropDownListItem(result, masked), greyed(greyed)
{
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
this->lock_size = GetSpriteSize(SPR_LOCK);
}
virtual ~DropDownListCompanyItem() {}
@@ -141,12 +143,12 @@ public:
CompanyID company = (CompanyID)this->result;
SetDParam(0, company);
SetDParam(1, company);
return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + 3;
return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lock_size.width + 6;
}
uint Height(uint width) const
{
return max(this->icon_size.height + 2U, (uint)FONT_HEIGHT_NORMAL);
return max(max(this->icon_size.height, this->lock_size.height) + 2U, (uint)FONT_HEIGHT_NORMAL);
}
void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
@@ -159,8 +161,12 @@ public:
int icon_offset = (bottom - top - icon_size.height) / 2;
int text_offset = (bottom - top - FONT_HEIGHT_NORMAL) / 2;
int lock_offset = (bottom - top - lock_size.height) / 2;
DrawCompanyIcon(company, rtl ? right - this->icon_size.width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + icon_offset);
if (NetworkCompanyIsPassworded(company)) {
DrawSprite(SPR_LOCK, PAL_NONE, rtl ? left + WD_FRAMERECT_LEFT : right - this->lock_size.width - WD_FRAMERECT_RIGHT, top + lock_offset);
}
SetDParam(0, company);
SetDParam(1, company);
@@ -170,7 +176,7 @@ public:
} else {
col = sel ? TC_WHITE : TC_BLACK;
}
DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : 3 + this->icon_size.width), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 0), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 3 + this->lock_size.width : 3 + this->icon_size.width), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 3 + this->lock_size.width), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col);
}
};

View File

@@ -784,7 +784,7 @@ void AddAcceptedHouseCargo(HouseID house_id, TileIndex tile, CargoArray &accepta
{
const HouseSpec *hs = HouseSpec::Get(house_id);
Town *t = (tile == INVALID_TILE) ? NULL : Town::GetByTile(tile);
CargoID accepts[3];
CargoID accepts[lengthof(hs->accepts_cargo)];
/* Set the initial accepted cargo types */
for (uint8 i = 0; i < lengthof(accepts); i++) {

View File

@@ -519,65 +519,27 @@ ViewPort *IsPtInWindowViewport(const Window *w, int x, int y)
}
/**
* Translate screen coordinate in a viewport to a tile coordinate
* Translate screen coordinate in a viewport to underlying tile coordinate.
*
* Returns exact point of the map that is visible in the given place
* of the viewport (3D perspective), height of tiles and foundations matter.
*
* @param vp Viewport that contains the (\a x, \a y) screen coordinate
* @param x Screen x coordinate
* @param y Screen y coordinate
* @param clamp_to_map Clamp the coordinate outside of the map to the closest tile within the map.
* @return Tile coordinate
* @param x Screen x coordinate, distance in pixels from the left edge of viewport frame
* @param y Screen y coordinate, distance in pixels from the top edge of viewport frame
* @param clamp_to_map Clamp the coordinate outside of the map to the closest, non-void tile within the map
* @return Tile coordinate or (-1, -1) if given x or y is not within viewport frame
*/
Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y, bool clamp_to_map)
{
Point pt;
int a, b;
int z;
if ( (uint)(x -= vp->left) >= (uint)vp->width ||
(uint)(y -= vp->top) >= (uint)vp->height) {
Point pt = {-1, -1};
return pt;
if (!IsInsideBS(x, vp->left, vp->width) || !IsInsideBS(y, vp->top, vp->height)) {
Point pt = { -1, -1 };
return pt;
}
x = (ScaleByZoom(x, vp->zoom) + vp->virtual_left) >> (2 + ZOOM_LVL_SHIFT);
y = (ScaleByZoom(y, vp->zoom) + vp->virtual_top) >> (1 + ZOOM_LVL_SHIFT);
a = y - x;
b = y + x;
if (clamp_to_map) {
/* Bring the coordinates near to a valid range. This is mostly due to the
* tiles on the north side of the map possibly being drawn too high due to
* the extra height levels. So at the top we allow a number of extra tiles.
* This number is based on the tile height and pixels. */
int extra_tiles = CeilDiv(_settings_game.construction.max_heightlevel * TILE_HEIGHT, TILE_PIXELS);
a = Clamp(a, -extra_tiles * TILE_SIZE, MapMaxX() * TILE_SIZE - 1);
b = Clamp(b, -extra_tiles * TILE_SIZE, MapMaxY() * TILE_SIZE - 1);
}
/* (a, b) is the X/Y-world coordinate that belongs to (x,y) if the landscape would be completely flat on height 0.
* Now find the Z-world coordinate by fix point iteration.
* This is a bit tricky because the tile height is non-continuous at foundations.
* The clicked point should be approached from the back, otherwise there are regions that are not clickable.
* (FOUNDATION_HALFTILE_LOWER on SLOPE_STEEP_S hides north halftile completely)
* So give it a z-malus of 4 in the first iterations.
*/
z = 0;
int min_coord = _settings_game.construction.freeform_edges ? TILE_SIZE : 0;
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(a + max(z, 4) - 4, min_coord, MapMaxX() * TILE_SIZE - 1), Clamp(b + max(z, 4) - 4, min_coord, MapMaxY() * TILE_SIZE - 1)) / 2;
for (int malus = 3; malus > 0; malus--) z = GetSlopePixelZ(Clamp(a + max(z, malus) - malus, min_coord, MapMaxX() * TILE_SIZE - 1), Clamp(b + max(z, malus) - malus, min_coord, MapMaxY() * TILE_SIZE - 1)) / 2;
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(a + z, min_coord, MapMaxX() * TILE_SIZE - 1), Clamp(b + z, min_coord, MapMaxY() * TILE_SIZE - 1)) / 2;
if (clamp_to_map) {
pt.x = Clamp(a + z, min_coord, MapMaxX() * TILE_SIZE - 1);
pt.y = Clamp(b + z, min_coord, MapMaxY() * TILE_SIZE - 1);
} else {
pt.x = a + z;
pt.y = b + z;
}
return pt;
return InverseRemapCoords2(
ScaleByZoom(x - vp->left, vp->zoom) + vp->virtual_left,
ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top, clamp_to_map);
}
/* When used for zooming, check area below current coordinates (x,y)
@@ -1214,29 +1176,41 @@ static void DrawTileSelection(const TileInfo *ti)
}
/**
* Returns the y coordinate in the viewport coordinate system where the given
* tile is painted.
* @param tile Any tile.
* @return The viewport y coordinate where the tile is painted.
* Returns the Y coordinate in the viewport coordinate system where a given
* tile should be painted. Can be used on virtual "black" tiles outside map.
*
* @param tile Tile coordinates of the tile. Map outside is allowed.
* @return Viewport Y coordinate where the northern corner of the tile is located (foundations not included).
*/
static int GetViewportY(Point tile)
static inline int GetTilePaintY(Point tile)
{
/* Each increment in X or Y direction moves down by half a tile, i.e. TILE_PIXELS / 2. */
return (tile.y * (int)(TILE_PIXELS / 2) + tile.x * (int)(TILE_PIXELS / 2) - TilePixelHeightOutsideMap(tile.x, tile.y)) << ZOOM_LVL_SHIFT;
return RemapCoords(tile.x * TILE_SIZE, tile.y * TILE_SIZE, TilePixelHeightOutsideMap(tile.x, tile.y)).y;
}
/**
* Add the landscape to the viewport, i.e. all ground tiles and buildings.
* Add sprites of a single tile to the viewport.
*
* @param[in,out] ti Filled-in tile information of the tile. On return, \a z coordinate will be updated and include foundations (if any).
* @param tile_type Type of the tile (#GetTileType) or #MP_VOID for virtual "black" tiles outside map.
*/
static void ViewportAddTile(TileInfo *ti, TileType tile_type)
{
_vd.foundation_part = FOUNDATION_PART_NONE;
_vd.foundation[0] = -1;
_vd.foundation[1] = -1;
_vd.last_foundation_child[0] = NULL;
_vd.last_foundation_child[1] = NULL;
_cur_ti = ti;
_tile_type_procs[tile_type]->draw_tile_proc(ti);
}
/**
* Add the landscape to the viewport, i.e. all ground tiles, buildings and bridges.
*/
static void ViewportAddLandscape()
{
assert(_vd.dpi.top <= _vd.dpi.top + _vd.dpi.height);
assert(_vd.dpi.left <= _vd.dpi.left + _vd.dpi.width);
Point upper_left = InverseRemapCoords(_vd.dpi.left, _vd.dpi.top);
Point upper_right = InverseRemapCoords(_vd.dpi.left + _vd.dpi.width, _vd.dpi.top);
/* Transformations between tile coordinates and viewport rows/columns: See vp_column_row
/* Transformations between tile x/y coordinates and 45-degree rotated rows/columns:
* column = y - x
* row = x + y
* x = (row - column) / 2
@@ -1244,38 +1218,46 @@ static void ViewportAddLandscape()
* Note: (row, columns) pairs are only valid, if they are both even or both odd.
*/
/* Columns overlap with neighbouring columns by a half tile.
* - Left column is column of upper_left (rounded down) and one column to the left.
* - Right column is column of upper_right (rounded up) and one column to the right.
* Note: Integer-division does not round down for negative numbers, so ensure rounding with another increment/decrement.
*/
int left_column = (upper_left.y - upper_left.x) / (int)TILE_SIZE - 2;
int right_column = (upper_right.y - upper_right.x) / (int)TILE_SIZE + 2;
/* Rectangle to repaint. Includes oversize for tile sprites.
* There is no oversize for the bottom side of a tile so the first tile we draw
* in a column must have its northern corner above or at the 'top' bound. */
const int left = _vd.dpi.left - MAX_TILE_EXTENT_RIGHT; // inclusive
const int top = _vd.dpi.top; // unlike to other bounds, this one is relative to S tile corner, not N, not inclusive (for S corner)
const int right = _vd.dpi.left + _vd.dpi.width + MAX_TILE_EXTENT_LEFT; // not inclusive
const int bottom_empty = _vd.dpi.top + _vd.dpi.height; // bottom bound for void tiles and tiles outside map, includes only clear ground sprites, not inclusive
const int bottom_building = bottom_empty + MAX_TILE_EXTENT_TOP; // bottom bound that accounts for buildings but does not include oversize for bridges, not inclusive
const int bottom = bottom_building + ZOOM_LVL_BASE * TILE_HEIGHT * _settings_game.construction.max_bridge_height; // bottom bound that includes entire oversize, also for bridges, not inclusive
assert(left < right && top < bottom);
int potential_bridge_height = ZOOM_LVL_BASE * TILE_HEIGHT * _settings_game.construction.max_bridge_height;
/* Base 2 logarithm of the distance between tile columns in a viewport.
* It will be used to achieve proper rounding easily. */
assert_compile(TILE_SIZE == 1 << 4);
static const uint column_log = ZOOM_LVL_SHIFT + 4 + 1; // +1 comes from the factor 2 that is used when remapping to horizontal 'x' screen coordinate (see RemapCoords)
/* Rows overlap with neighbouring rows by a half tile.
* The first row that could possibly be visible is the row above upper_left (if it is at height 0).
* Due to integer-division not rounding down for negative numbers, we need another decrement.
*/
int row = (upper_left.x + upper_left.y) / (int)TILE_SIZE - 2;
bool last_row = false;
for (; !last_row; row++) {
last_row = true;
for (int column = left_column; column <= right_column; column++) {
/* Valid row/column? */
if ((row + column) % 2 != 0) continue;
/* Horizontal iteration bounds. */
int first_col = left >> column_log; // inclusive, round toward -inf
int last_col = -(-right >> column_log); // not inclusive, round toward +inf
Point tilecoord;
tilecoord.x = (row - column) / 2;
tilecoord.y = (row + column) / 2;
assert(column == tilecoord.y - tilecoord.x);
assert(row == tilecoord.y + tilecoord.x);
/* Use tile that intersects with the left-top corner of the repaint
* rectangle as an approximate start row of the iteration. */
Point start = InverseRemapCoords2(left, top, false); // warning, it will take foundations into account, might return a tile that is further to S, but that's OK because coordinates will be moved toward N later if needed
int first_row = (start.x >> 4) + (start.y >> 4);
/* Combine with the first column, round toward S. */
start.x = (first_row - first_col + 1) >> 1;
start.y = (first_row + first_col + 1) >> 1;
/* Iterate over columns of tiles. */
while (first_col++ < last_col) {
/* Fix column start tile - move it toward N until it reaches the 'top' bound. */
int y_pos;
while (top < (y_pos = GetTilePaintY(start))) start.x--, start.y--;
/* Iterate over tiles in a column. */
Point tilecoord = start;
do {
TileType tile_type;
TileInfo tile_info;
_cur_ti = &tile_info;
tile_info.x = tilecoord.x * TILE_SIZE; // FIXME tile_info should use signed integers
tile_info.x = tilecoord.x * TILE_SIZE; // FIXME: tile_info should use signed integers
tile_info.y = tilecoord.y * TILE_SIZE;
if (IsInsideBS(tilecoord.x, 0, MapSizeX()) && IsInsideBS(tilecoord.y, 0, MapSizeY())) {
@@ -1287,61 +1269,35 @@ static void ViewportAddLandscape()
tile_type = MP_VOID;
}
if (tile_type != MP_VOID) {
/* We are inside the map => paint landscape. */
tile_info.tileh = GetTilePixelSlope(tile_info.tile, &tile_info.z);
} else {
/* We are outside the map => paint black. */
tile_info.tileh = GetTilePixelSlopeOutsideMap(tilecoord.x, tilecoord.y, &tile_info.z);
}
/* Check if tile is "visible".
*
* Until 'bottom_empty' every tile is visible, also "black" tiles outside map.
* Since 'bottom_empty' only tiles with a content might be visible. */
if (y_pos >= bottom_empty) {
if (tilecoord.x >= (int)MapSizeX() || tilecoord.y >= (int)MapSizeY()) break; // No more non-void tiles in this column? Then stop.
if (tile_type == MP_VOID) continue; // No content on the tile? Then skip.
int viewport_y = GetViewportY(tilecoord);
if (viewport_y + MAX_TILE_EXTENT_BOTTOM < _vd.dpi.top) {
/* The tile in this column is not visible yet.
* Tiles in other columns may be visible, but we need more rows in any case. */
last_row = false;
continue;
}
int min_visible_height = viewport_y - (_vd.dpi.top + _vd.dpi.height);
bool tile_visible = min_visible_height <= 0;
if (tile_type != MP_VOID) {
/* Is tile with buildings visible? */
if (min_visible_height < MAX_TILE_EXTENT_TOP) tile_visible = true;
if (IsBridgeAbove(tile_info.tile)) {
/* Is the bridge visible? */
TileIndex bridge_tile = GetNorthernBridgeEnd(tile_info.tile);
int bridge_height = ZOOM_LVL_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(tile_info.tile));
if (min_visible_height < bridge_height + MAX_TILE_EXTENT_TOP) tile_visible = true;
}
/* Would a higher bridge on a more southern tile be visible?
* If yes, we need to loop over more rows to possibly find one. */
if (min_visible_height < potential_bridge_height + MAX_TILE_EXTENT_TOP) last_row = false;
} else {
/* Outside of map. If we are on the north border of the map, there may still be a bridge visible,
* so we need to loop over more rows to possibly find one. */
if ((tilecoord.x <= 0 || tilecoord.y <= 0) && min_visible_height < potential_bridge_height + MAX_TILE_EXTENT_TOP) last_row = false;
}
if (tile_visible) {
last_row = false;
_vd.foundation_part = FOUNDATION_PART_NONE;
_vd.foundation[0] = -1;
_vd.foundation[1] = -1;
_vd.last_foundation_child[0] = NULL;
_vd.last_foundation_child[1] = NULL;
_tile_type_procs[tile_type]->draw_tile_proc(&tile_info);
if (tile_info.tile != INVALID_TILE) {
DrawTileSelection(&tile_info);
DrawTileZoning(&tile_info);
/* Since 'bottom_building' only bridges might be visible. */
if (y_pos >= bottom_building) {
if (!IsBridgeAbove(tile_info.tile)) continue; // no bridge above, skip
if (RemapCoords(tile_info.x, tile_info.y, GetBridgePixelHeight(GetNorthernBridgeEnd(tile_info.tile))).y >= bottom_building) continue; // bridge isn't high enough, skip
}
}
}
/* Paint the tile. */
tile_info.tileh = (tile_info.tile != INVALID_TILE) ? GetTilePixelSlope(tile_info.tile, &tile_info.z) : GetTilePixelSlopeOutsideMap(tilecoord.x, tilecoord.y, &tile_info.z);
ViewportAddTile(&tile_info, tile_type);
if (tile_info.tile != INVALID_TILE) {
DrawTileSelection(&tile_info);
DrawTileZoning(&tile_info);
}
/* Next tile. */
} while (tilecoord.x++, tilecoord.y++, y_pos = GetTilePaintY(tilecoord), y_pos < bottom);
/* Go one tile toward SE. This will advance us to next column. Bias toward S will
* take care of slopes too. Coordinates will be moved toward N later if needed. */
start.y++;
}
}
@@ -2775,121 +2731,33 @@ void Window::DrawViewport() const
}
/**
* Continue criteria for the SearchMapEdge function.
* @param iter Value to check.
* @param iter_limit Maximum value for the iter
* @param sy Screen y coordinate calculated for the tile at hand
* @param sy_limit Limit to the screen y coordinate
* @return True when we should continue searching.
* Ensure that a given viewport has a valid scroll position.
*
* There must be a visible piece of the map in the center of the viewport.
* If there isn't, the viewport will be scrolled to nearest such location.
*
* @param vp The viewport.
* @param[in,out] scroll_x Viewport X scroll.
* @param[in,out] scroll_y Viewport Y scroll.
*/
typedef bool ContinueMapEdgeSearch(int iter, int iter_limit, int sy, int sy_limit);
/** Continue criteria for searching a no-longer-visible tile in negative direction, starting at some tile. */
static inline bool ContinueLowerMapEdgeSearch(int iter, int iter_limit, int sy, int sy_limit) { return iter > 0 && sy > sy_limit; }
/** Continue criteria for searching a no-longer-visible tile in positive direction, starting at some tile. */
static inline bool ContinueUpperMapEdgeSearch(int iter, int iter_limit, int sy, int sy_limit) { return iter < iter_limit && sy < sy_limit; }
/**
* Searches, starting at the given tile, by applying the given offset to iter, for a no longer visible tile.
* The whole sense of this function is keeping the to-be-written code small, thus it is a little bit abstracted
* so the same function can be used for both the X and Y locations. As such a reference to one of the elements
* in curr_tile was needed.
* @param curr_tile A tile
* @param iter Reference to either the X or Y of curr_tile.
* @param iter_limit Upper search limit for the iter value.
* @param offset Search in steps of this size
* @param sy_limit Search limit to be passed to the criteria
* @param continue_criteria Search as long as this criteria is true
* @return The final value of iter.
*/
static int SearchMapEdge(Point &curr_tile, int &iter, int iter_limit, int offset, int sy_limit, ContinueMapEdgeSearch continue_criteria)
static inline void ClampViewportToMap(const ViewPort *vp, int *scroll_x, int *scroll_y)
{
int sy;
do {
iter = Clamp(iter + offset, 0, iter_limit);
sy = GetViewportY(curr_tile);
} while (continue_criteria(iter, iter_limit, sy, sy_limit));
/* Centre of the viewport is hot spot. */
Point pt = {
*scroll_x + vp->virtual_width / 2,
*scroll_y + vp->virtual_height / 2
};
return iter;
}
/* Find nearest tile that is within borders of the map. */
bool clamped;
pt = InverseRemapCoords2(pt.x, pt.y, true, &clamped);
/**
* Determine the clamping of either the X or Y coordinate to the map.
* @param curr_tile A tile
* @param iter Reference to either the X or Y of curr_tile.
* @param iter_limit Upper search limit for the iter value.
* @param start Start value for the iteration.
* @param other_ref Reference to the opposite axis in curr_tile than of iter.
* @param other_value Start value for of the opposite axis
* @param vp_value Value of the viewport location in the opposite axis as for iter.
* @param other_limit Limit for the other value, so if iter is X, then other_limit is for Y.
* @param vp_top Top of the viewport.
* @param vp_bottom Bottom of the viewport.
* @return Clamped version of vp_value.
*/
static inline int ClampXYToMap(Point &curr_tile, int &iter, int iter_limit, int start, int &other_ref, int other_value, int vp_value, int other_limit, int vp_top, int vp_bottom)
{
bool upper_edge = other_value < _settings_game.construction.max_heightlevel / 4;
/*
* First get an estimate of the tiles relevant for us at that edge. Relevant in the sense
* "at least close to the visible area". Thus, we don't look at exactly each tile, inspecting
* e.g. every tenth should be enough. After all, the desired screen limit is set such that
* the bordermost tiles are painted in the middle of the screen when one hits the limit,
* i.e. it is no harm if there is some small error in that calculation
*/
other_ref = upper_edge ? 0 : other_limit;
iter = start;
int min_iter = SearchMapEdge(curr_tile, iter, iter_limit, upper_edge ? -10 : +10, vp_top, upper_edge ? ContinueLowerMapEdgeSearch : ContinueUpperMapEdgeSearch);
iter = start;
int max_iter = SearchMapEdge(curr_tile, iter, iter_limit, upper_edge ? +10 : -10, vp_bottom, upper_edge ? ContinueUpperMapEdgeSearch : ContinueLowerMapEdgeSearch);
max_iter = min(max_iter + _settings_game.construction.max_heightlevel / 4, iter_limit);
min_iter = min(min_iter, max_iter);
/* Now, calculate the highest heightlevel of these tiles. Again just as an estimate. */
int max_heightlevel_at_edge = 0;
for (iter = min_iter; iter <= max_iter; iter += 10) {
max_heightlevel_at_edge = max(max_heightlevel_at_edge, (int)TileHeight(TileXY(curr_tile.x, curr_tile.y)));
if (clamped) {
/* Convert back to viewport coordinates and remove centering. */
pt = RemapCoords2(pt.x, pt.y);
*scroll_x = pt.x - vp->virtual_width / 2;
*scroll_y = pt.y - vp->virtual_height / 2;
}
/* Based on that heightlevel, calculate the limit. For the upper edge a tile with height zero would
* get a limit of zero, on the other side it depends on the number of tiles along the axis. */
return upper_edge ?
max(vp_value, -max_heightlevel_at_edge * (int)(TILE_HEIGHT * 2 * ZOOM_LVL_BASE)) :
min(vp_value, (other_limit * TILE_SIZE * 4 - max_heightlevel_at_edge * TILE_HEIGHT * 2) * ZOOM_LVL_BASE);
}
static inline void ClampViewportToMap(const ViewPort *vp, int &x, int &y)
{
int original_y = y;
/* Centre of the viewport is hot spot */
x += vp->virtual_width / 2;
y += vp->virtual_height / 2;
/* Convert viewport coordinates to map coordinates
* Calculation is scaled by 4 to avoid rounding errors */
int vx = -x + y * 2;
int vy = x + y * 2;
/* Find out which tile corresponds to (vx,vy) if one assumes height zero. The cast is necessary to prevent C++ from
* converting the result to an uint, which gives an overflow instead of a negative result... */
int tx = vx / (int)(TILE_SIZE * 4 * ZOOM_LVL_BASE);
int ty = vy / (int)(TILE_SIZE * 4 * ZOOM_LVL_BASE);
Point curr_tile;
vx = ClampXYToMap(curr_tile, curr_tile.y, MapMaxY(), ty, curr_tile.x, tx, vx, MapMaxX(), original_y, original_y + vp->virtual_height);
vy = ClampXYToMap(curr_tile, curr_tile.x, MapMaxX(), tx, curr_tile.y, ty, vy, MapMaxY(), original_y, original_y + vp->virtual_height);
/* Convert map coordinates to viewport coordinates */
x = (-vx + vy) / 2;
y = ( vx + vy) / 4;
/* Remove centering */
x -= vp->virtual_width / 2;
y -= vp->virtual_height / 2;
}
/**
@@ -2909,7 +2777,7 @@ void UpdateViewportPosition(Window *w)
SetViewportPosition(w, pt.x, pt.y, false);
} else {
/* Ensure the destination location is within the map */
ClampViewportToMap(vp, w->viewport->dest_scrollpos_x, w->viewport->dest_scrollpos_y);
ClampViewportToMap(vp, &w->viewport->dest_scrollpos_x, &w->viewport->dest_scrollpos_y);
int delta_x = w->viewport->dest_scrollpos_x - w->viewport->scrollpos_x;
int delta_y = w->viewport->dest_scrollpos_y - w->viewport->scrollpos_y;
@@ -2929,7 +2797,7 @@ void UpdateViewportPosition(Window *w)
w->viewport->scrollpos_y == w->viewport->dest_scrollpos_y);
}
ClampViewportToMap(vp, w->viewport->scrollpos_x, w->viewport->scrollpos_y);
ClampViewportToMap(vp, &w->viewport->scrollpos_x, &w->viewport->scrollpos_y);
if (_scrolling_viewport == w) UpdateActiveScrollingViewport(w);
@@ -3104,11 +2972,12 @@ void ConstrainAllViewportsZoom()
* @param tile The tile to mark dirty.
* @param mark_dirty_if_zoomlevel_is_below To tell if an update is relevant or not (for example, animations in map mode are not).
* @param bridge_level_offset Height of bridge on tile to also mark dirty. (Height level relative to north corner.)
* @param tile_height_override Height of the tile (#TileHeight).
* @ingroup dirty
*/
void MarkTileDirtyByTile(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below, int bridge_level_offset)
void MarkTileDirtyByTile(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below, int bridge_level_offset, int tile_height_override)
{
Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, TilePixelHeight(tile));
Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, tile_height_override * TILE_HEIGHT);
MarkAllViewportsDirty(
pt.x - 31 * ZOOM_LVL_BASE,
pt.y - 122 * ZOOM_LVL_BASE - ZOOM_LVL_BASE * TILE_HEIGHT * bridge_level_offset,
@@ -3118,22 +2987,6 @@ void MarkTileDirtyByTile(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel
);
}
/**
* Mark a (virtual) tile outside the map dirty for repaint.
* @param x Tile X position.
* @param y Tile Y position.
* @ingroup dirty
*/
void MarkTileDirtyByTileOutsideMap(int x, int y)
{
Point pt = RemapCoords(x * TILE_SIZE, y * TILE_SIZE, TilePixelHeightOutsideMap(x, y));
MarkAllViewportsDirty(
pt.x - MAX_TILE_EXTENT_LEFT,
pt.y, // no buildings outside of map
pt.x + MAX_TILE_EXTENT_RIGHT,
pt.y + MAX_TILE_EXTENT_BOTTOM);
}
void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile)
{
assert(from_tile != INVALID_TILE);

View File

@@ -15,7 +15,7 @@
#include "gfx_type.h"
#include "viewport_type.h"
#include "window_type.h"
#include "tile_type.h"
#include "tile_map.h"
#include "station_type.h"
#include "vehicle_base.h"
@@ -90,9 +90,19 @@ void UpdateAllVirtCoords();
extern Point _tile_fract_coords;
void MarkTileDirtyByTile(const TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END, int bridge_level_offset = 0);
void MarkTileDirtyByTile(const TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below, int bridge_level_offset, int tile_height_override);
void MarkTileDirtyByTileOutsideMap(int x, int y);
/**
* Mark a tile given by its index dirty for repaint.
* @param tile The tile to mark dirty.
* @param mark_dirty_if_zoomlevel_is_below To tell if an update is relevant or not (for example, animations in map mode are not).
* @param bridge_level_offset Height of bridge on tile to also mark dirty. (Height level relative to north corner.)
* @ingroup dirty
*/
static inline void MarkTileDirtyByTile(TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END, int bridge_level_offset = 0)
{
MarkTileDirtyByTile(tile, mark_dirty_if_zoomlevel_is_below, bridge_level_offset, TileHeight(tile));
}
ViewportMapType ChangeRenderMode(const ViewPort *vp, bool down);

View File

@@ -10,7 +10,7 @@
/** @file void_cmd.cpp Handling of void tiles. */
#include "stdafx.h"
#include "tile_cmd.h"
#include "landscape.h"
#include "command_func.h"
#include "viewport_func.h"
#include "slope_func.h"
@@ -28,7 +28,12 @@ static void DrawTile_Void(TileInfo *ti)
static int GetSlopePixelZ_Void(TileIndex tile, uint x, uint y)
{
return TilePixelHeight(tile);
/* This function may be called on tiles outside the map, don't asssume
* that 'tile' is a valid tile index. See GetSlopePixelZOutsideMap. */
int z;
Slope tileh = GetTilePixelSlopeOutsideMap(x >> 4, y >> 4, &z);
return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
}
static Foundation GetFoundation_Void(TileIndex tile, Slope tileh)