From 6de087786cbd83ad1cc938d6f68e303cf4e5d0a7 Mon Sep 17 00:00:00 2001 From: patch-import Date: Sun, 2 Aug 2015 10:57:53 +0100 Subject: [PATCH 1/3] Import and rebase zoning patch Fix some of the whitespace issues http://www.tt-forums.net/viewtopic.php?p=888801#p888801 --- bin/data/innerhighlight.grf | Bin 0 -> 6953 bytes projects/openttd_vs100.vcxproj | 3 + projects/openttd_vs100.vcxproj.filters | 9 + projects/openttd_vs80.vcproj | 12 + projects/openttd_vs90.vcproj | 12 + source.list | 3 + src/gfxinit.cpp | 2 + src/lang/danish.txt | 1 + src/lang/english.txt | 18 ++ src/table/sprites.h | 12 + src/toolbar_gui.cpp | 4 + src/viewport.cpp | 6 +- src/window_type.h | 1 + src/zoning.h | 39 +++ src/zoning_cmd.cpp | 378 +++++++++++++++++++++++++ src/zoning_gui.cpp | 127 +++++++++ 16 files changed, 626 insertions(+), 1 deletion(-) create mode 100644 bin/data/innerhighlight.grf create mode 100644 src/zoning.h create mode 100644 src/zoning_cmd.cpp create mode 100644 src/zoning_gui.cpp diff --git a/bin/data/innerhighlight.grf b/bin/data/innerhighlight.grf new file mode 100644 index 0000000000000000000000000000000000000000..4118f515d1b0885c54907d5dfe4644bcdb928130 GIT binary patch literal 6953 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 J?umox{uOh1#7O`E literal 0 HcmV?d00001 diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index 37f9948032..47c821b9dd 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -660,6 +660,7 @@ + @@ -745,6 +746,7 @@ + @@ -828,6 +830,7 @@ + diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index 06800ffdaf..911fef1d70 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -1209,6 +1209,9 @@ Header Files + + Header Files + Core Source Code @@ -1464,6 +1467,9 @@ GUI Source Code + + GUI Source Code + Widgets @@ -1713,6 +1719,9 @@ Command handlers + + Command handlers + Save/Load handlers diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index f859fcf18a..e589269151 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1914,6 +1914,10 @@ RelativePath=".\..\src\zoom_type.h" > + + + + + + + + + + + + Append() = new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false); *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false); + *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_ZONING, OME_ZONING, false); *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false); *list->Append() = new DropDownListItem(-1, false); *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)); @@ -347,6 +350,7 @@ static CallBackFunction MenuClickSettings(int index) case OME_SETTINGS: ShowGameSettings(); return CBF_NONE; case OME_SCRIPT_SETTINGS: ShowAIConfigWindow(); return CBF_NONE; case OME_NEWGRFSETTINGS: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); return CBF_NONE; + case OME_ZONING: ShowZoningToolbar(); break; case OME_TRANSPARENCIES: ShowTransparencyToolbar(); break; case OME_SHOW_TOWNNAMES: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break; diff --git a/src/viewport.cpp b/src/viewport.cpp index a1bb2c81d1..142738be41 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -80,6 +80,7 @@ #include "waypoint_func.h" #include "window_func.h" #include "tilehighlight_func.h" +#include "zoning.h" #include "window_gui.h" #include "linkgraph/linkgraph_gui.h" #include "viewport_sprite_sorter.h" @@ -1200,7 +1201,10 @@ static void ViewportAddLandscape() _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); + if (tile_info.tile != INVALID_TILE) { + DrawTileSelection(&tile_info); + DrawTileZoning(&tile_info); + } } } } diff --git a/src/window_type.h b/src/window_type.h index 809e81d485..bc4e014964 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -668,6 +668,7 @@ enum WindowClass { * - 0 = #SpriteAlignerWidgets */ WC_SPRITE_ALIGNER, + WC_ZONING_TOOLBAR, /** * Linkgraph legend; %Window numbers: diff --git a/src/zoning.h b/src/zoning.h new file mode 100644 index 0000000000..01842a91e2 --- /dev/null +++ b/src/zoning.h @@ -0,0 +1,39 @@ +/** @file zoning.h */ + +#ifndef ZONING_H_ +#define ZONING_H_ + +#include "openttd.h" +#include "tile_cmd.h" + +enum EvaluationMode { + CHECKNOTHING = 0, + CHECKOPINION = 1, ///< Check the local authority's opinion. + CHECKBUILD = 2, ///< Check wither or not the player can build. + CHECKSTACATCH = 3, ///< Check catchment area for stations + CHECKINDCATCH = 4, ///< Check catchment area for industries + CHECKBULCATCH = 5, ///< Check catchment area for buildings + CHECKBULUNSER = 6, ///< Check for unserved buildings + CHECKINDUNSER = 7, ///< Check for unserved industries +}; + +struct Zoning { + EvaluationMode inner; + EvaluationMode outer; + int inner_val; + int outer_val; +}; + +VARDEF Zoning _zoning; + +SpriteID TileZoningSpriteEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode); + +int TileZoningEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode); + +void DrawTileZoning(const TileInfo *ti); + +void ShowZoningToolbar(); + +EvaluationMode GetEvaluationModeFromInt(int ev_mode); + +#endif /*ZONING_H_*/ diff --git a/src/zoning_cmd.cpp b/src/zoning_cmd.cpp new file mode 100644 index 0000000000..671d8c6dc6 --- /dev/null +++ b/src/zoning_cmd.cpp @@ -0,0 +1,378 @@ + +/** @file zoning_cmd.cpp */ + +#include "stdafx.h" +#include "openttd.h" +#include "station_type.h" +#include "station_base.h" +#include "industry.h" +#include "gfx_func.h" +#include "viewport_func.h" +#include "variables.h" +#include "map_func.h" +#include "company_func.h" +#include "town_map.h" +#include "table/sprites.h" +#include "station_func.h" +#include "station_map.h" +#include "town.h" +#include "zoning.h" + +Zoning _zoning; + +/** + * Draw the zoning sprites. + * + * @param SpriteID image + * the image + * @param SpriteID colour + * the colour of the zoning + * @param TileInfo ti + * the tile + */ +void DrawZoningSprites(SpriteID image, SpriteID colour, const TileInfo *ti) { + if ( colour!=INVALID_SPRITE_ID ) + AddSortableSpriteToDraw(image + _tileh_to_sprite[ti->tileh], colour, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7); +} + +/** + * Detect whether this area is within the acceptance of any station. + * + * @param TileArea area + * the area to search by + * @param Owner owner + * the owner of the stations which we need to match again + * @return true if a station is found + */ +bool IsAreaWithinAcceptanceZoneOfStation(TileArea area, Owner owner) { + + // TODO: Actually do owner check. + + int catchment = _settings_game.station.station_spread + (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); + + StationFinder morestations(TileArea(TileXY(TileX(area.tile)-catchment/2, TileY(area.tile)-catchment/2), + TileX(area.tile) + area.w + catchment, TileY(area.tile) + area.h + catchment)); + + for ( Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter ) { + Station *st = *st_iter; + Rect rect = st->GetCatchmentRect(); + return TileArea(TileXY(rect.left, rect.top), TileXY(rect.right, rect.bottom)).Intersects(area); + } + + return false; +} + +/** + * Detect whether this tile is within the acceptance of any station. + * + * @param TileIndex tile + * the tile to search by + * @param Owner owner + * the owner of the stations + * @return true if a station is found + */ +bool IsTileWithinAcceptanceZoneOfStation(TileIndex tile, Owner owner) { + + // TODO: Actually do owner check. + + int catchment = _settings_game.station.station_spread + (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); + + StationFinder morestations(TileArea(TileXY(TileX(tile)-catchment/2, TileY(tile)-catchment/2), + catchment, catchment)); + + for ( Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter ) { + Station *st = *st_iter; + Rect rect = st->GetCatchmentRect(); + if ( (uint)rect.left <= TileX(tile) && TileX(tile) <= (uint)rect.right + && (uint)rect.top <= TileY(tile) && TileY(tile) <= (uint)rect.bottom ) + return true; + } + + return false; +} + +/** + * Check whether the player can build in tile. + * + * @param TileIndex tile + * @param Owner owner + * @return red if they cannot + */ +SpriteID TileZoneCheckBuildEvaluation(TileIndex tile, Owner owner) { + /* Let's first check for the obvious things you cannot build on */ + switch ( GetTileType(tile) ) { + case MP_INDUSTRY: + case MP_UNMOVABLE: + case MP_STATION: + case MP_HOUSE: + case MP_TUNNELBRIDGE: return SPR_PALETTE_ZONING_RED; + /* There are only two things you can own (or some else + * can own) that you can still build on. i.e. roads and + * railways. + * @todo + * Add something more intelligent, check what tool the + * user is currently using (and if none, assume some + * standards), then check it against if owned by some- + * one else (e.g. railway on someone else's road). + * While that being said, it should also check if it + * is not possible to build railway/road on someone + * else's/your own road/railway (e.g. the railway track + * is curved or a cross).*/ + case MP_ROAD: + case MP_RAILWAY: { + if ( GetTileOwner(tile) != owner ) + return SPR_PALETTE_ZONING_RED; + else + return INVALID_SPRITE_ID; + } + default: return INVALID_SPRITE_ID; + } +} + +/** + * Check the opinion of the local authority in the tile. + * + * @param TileIndex tile + * @param Owner owner + * @return black if no opinion, orange if bad, + * light blue if good or invalid if no town + */ +SpriteID TileZoneCheckOpinionEvaluation(TileIndex tile, Owner owner) { + int opinion = 0; // 0: no town, 1: no opinion, 2: bad, 3: good + Town *town = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); + + if ( town !=NULL ) { + if ( HasBit(town->have_ratings, owner) ) { + opinion = ( town->ratings[owner] > 0 ) ? 3 : 2; + } else { + opinion = 1; + } + } + + switch ( opinion ) { + case 1: return SPR_PALETTE_ZONING_BLACK; // no opinion + case 2: return SPR_PALETTE_ZONING_ORANGE; // bad + case 3: return SPR_PALETTE_ZONING_LIGHT_BLUE; // good + default: return INVALID_SPRITE_ID; // no town + } +} + +/** + * Detect whether the tile is within the 'catchment' zone of an industry. + * + * @param TileIndex tile + * @param Owner owner + * @return The colour depends on the distance to the industry: + * 1-3 White (lorry/bus) + * 4 Blue (train station/some airports) + * 5 Green (docks/some airports) + * 6 Yellow (some airports) + * 7-9 Light blue (international airport) + */ +SpriteID TileZoneCheckIndustryCatchmentEvaluation(TileIndex tile, Owner owner) { + + // TODO: Implement this! + + return INVALID_SPRITE_ID; +} + +/** + * Detect whether the tile is within the catchment zone of a station. + * + * @param TileIndex tile + * @param Owner owner + * @return black if within, light blue if only in acceptance zone + * and nothing if no nearby station. + */ +SpriteID TileZoneCheckStationCatchmentEvaluation(TileIndex tile, Owner owner) { + + //TODO: Actually check owner. + + // Never on a station. + if ( IsTileType(tile, MP_STATION) ) + return INVALID_SPRITE_ID; + + // For provided goods + + StationFinder stations(TileArea(tile, 1, 1)); + + if ( stations.GetStations()->Length() > 0 ) { + return SPR_PALETTE_ZONING_BLACK; + } + + // For accepted goods + + if ( IsTileWithinAcceptanceZoneOfStation(tile, owner) ) + return SPR_PALETTE_ZONING_LIGHT_BLUE; + + return INVALID_SPRITE_ID; +} + +/** + * Detect whether a tile is within the 'catchment' zone of a building. + * + * @param TileIndex tile + * @param Owner owner + * @return The colour depends on the distance to the building: + * 1-3 White (lorry/bus) + * 4 Blue (train station/some airports) + * 5 Green (docks/some airports) + * 6 Yellow (some airports) + * 7-9 Light blue (international airport) + */ +SpriteID TileZoneCheckBuildingCatchmentEvaluation(TileIndex tile, Owner owner) { + // TODO: Implement this! + + return INVALID_SPRITE_ID; +} + +/** + * Detect whether a building is unserved by a station of owner. + * + * @param TileIndex tile + * @param Owner owner + * @return red if unserved, orange if only accepting, nothing if served or not + * a building + */ +SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner) { + + //TODO: Actually use owner. + + CargoArray dat; + + if ( IsTileType (tile, MP_HOUSE) + && ( ( memset(&dat, 0, sizeof(dat)), AddAcceptedCargo(tile, dat, NULL), (dat[CT_MAIL] + dat[CT_PASSENGERS] > 0) ) + || ( memset(&dat, 0, sizeof(dat)), AddProducedCargo(tile, dat), (dat[CT_MAIL] + dat[CT_PASSENGERS] > 0) ) ) ) { + StationFinder stations(TileArea(tile, 1, 1)); + + if ( stations.GetStations()->Length() > 0 ) { + return INVALID_SPRITE_ID; + } + + // For accepted goods + + if ( IsTileWithinAcceptanceZoneOfStation(tile, owner) ) + return SPR_PALETTE_ZONING_ORANGE; + + //TODO: Check for stations that does not accept mail/passengers, + //which is currently only truck stops. + + return SPR_PALETTE_ZONING_RED; + } + + return INVALID_SPRITE_ID; +} + +/** + * Detect whether an industry is unserved by a station of owner. + * + * @param TileIndex tile + * @param Owner owner + * @return red if unserved, orange if only accepting, nothing if served or not + * a building + */ +SpriteID TileZoneCheckUnservedIndustriesEvaluation(TileIndex tile, Owner owner) { + + //TODO: Actually use owner. + + if ( IsTileType(tile, MP_INDUSTRY) ) { + Industry *ind = Industry::GetByTile(tile); + StationFinder stations(ind->location); + + if ( stations.GetStations()->Length() > 0 ) { + return INVALID_SPRITE_ID; + } + + // For accepted goods + + if ( IsAreaWithinAcceptanceZoneOfStation(ind->location, owner) ) + return SPR_PALETTE_ZONING_ORANGE; + + //TODO: Check for stations that only accepts mail/passengers, + //which is currently only bus stops. + + return SPR_PALETTE_ZONING_RED; + } + + return INVALID_SPRITE_ID; +} + +/** + * General evaluation function; calls all the other functions depending on + * evaluation mode. + * + * @param TileIndex tile + * Tile to be evaluated. + * @param Owner owner + * The current player + * @param EvaluationMode ev_mode + * The current evaluation mode. + * @return The colour returned by the evaluation functions (none if no ev_mode). + */ +SpriteID TileZoningSpriteEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode) { + switch ( ev_mode ) { + case CHECKBUILD: return TileZoneCheckBuildEvaluation(tile, owner); + case CHECKOPINION: return TileZoneCheckOpinionEvaluation(tile, owner); + case CHECKINDCATCH: return TileZoneCheckIndustryCatchmentEvaluation(tile, owner); + case CHECKSTACATCH: return TileZoneCheckStationCatchmentEvaluation(tile, owner); + case CHECKBULCATCH: return TileZoneCheckBuildingCatchmentEvaluation(tile, owner); + case CHECKBULUNSER: return TileZoneCheckUnservedBuildingsEvaluation(tile, owner); + case CHECKINDUNSER: return TileZoneCheckUnservedIndustriesEvaluation(tile, owner); + default: return INVALID_SPRITE_ID; + } +} + +/** + * Same as above, but not return an integer instead of sprite. However, it + * has so far not yet seem a real purpose, so therefore has not been implemented. + * + * @param TileIndex tile + * Tile to be evaluated. + * @param Owner owner + * The current player + * @param EvaluationMode ev_mode + * The current evaluation mode. + * @return Probably an integer based on the evaluation mode. + */ +int TileZoningEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode) { + return 0; +} + +/** + * Draw the the zoning on the tile. + * + * @param TileInfo ti + * the tile to draw on. + */ +void DrawTileZoning(const TileInfo *ti) { + if ( IsTileType(ti->tile, MP_VOID) + || _game_mode != GM_NORMAL ) + return; + + if ( _zoning.outer != CHECKNOTHING ) + DrawZoningSprites(SPR_SELECT_TILE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.outer), ti); + + if ( _zoning.inner != CHECKNOTHING ) + DrawZoningSprites(SPR_INNER_HIGHLIGHT_BASE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.inner), ti); +} + +/** + * Get the evaluation mode depending on an integer. Though, this may be better + * implemented so the code does not need to be updated several places everything + * a new type of evaluation is added. + * + * @param int ev_mode + * @return EvaluationMode + */ +EvaluationMode GetEvaluationModeFromInt(int ev_mode) { + switch ( ev_mode ) { + case 1: return CHECKOPINION; + case 2: return CHECKBUILD; + case 3: return CHECKSTACATCH; + case 4: return CHECKINDCATCH; + case 5: return CHECKBULCATCH; + case 6: return CHECKBULUNSER; + case 7: return CHECKINDUNSER; + default: return CHECKNOTHING; + } +} diff --git a/src/zoning_gui.cpp b/src/zoning_gui.cpp new file mode 100644 index 0000000000..42161d1036 --- /dev/null +++ b/src/zoning_gui.cpp @@ -0,0 +1,127 @@ + +/** @file zoning_gui.cpp */ + +#include "stdafx.h" +#include "openttd.h" +#include "widgets/dropdown_func.h" +#include "widget_type.h" +#include "functions.h" +#include "window_func.h" +#include "gui.h" +#include "viewport_func.h" +#include "sound_func.h" +#include "variables.h" +#include "table/sprites.h" +#include "table/strings.h" +#include "strings_func.h" +#include "gfx_func.h" +#include "core/geometry_func.hpp" +#include "core/random_func.hpp" +#include "zoning.h" + +enum ZoningToolbarWidgets { + ZTW_OUTER = 4, + ZTW_OUTER_DROPDOWN, + ZTW_INNER, + ZTW_INNER_DROPDOWN, + ZTW_CAPTION +}; + +const StringID _zone_types[] = { STR_ZONING_NO_ZONING, STR_ZONING_AUTHORITY, STR_ZONING_CAN_BUILD, STR_ZONING_STA_CATCH, STR_ZONING_IND_CATCH, STR_ZONING_BUL_CATCH, STR_ZONING_BUL_UNSER, STR_ZONING_IND_UNSER, INVALID_STRING_ID }; + +struct ZoningWindow : public Window { + + ZoningWindow(const WindowDesc *desc, int window_number) : Window() { + this->InitNested(desc, window_number); + this->InvalidateData(); + } + + virtual void OnPaint() { + this->DrawWidgets(); + } + + virtual void OnClick(Point pt, int widget, int click_count) { + switch ( widget ) { + case ZTW_OUTER_DROPDOWN: + ShowDropDownMenu(this, _zone_types, _zoning.outer_val, ZTW_OUTER_DROPDOWN, 0, 0); + break; + case ZTW_INNER_DROPDOWN: + ShowDropDownMenu(this, _zone_types, _zoning.inner_val, ZTW_INNER_DROPDOWN, 0, 0); + break; + } + } + + virtual void OnDropdownSelect(int widget, int index) { + switch(widget) { + case ZTW_OUTER_DROPDOWN: + _zoning.outer_val = index; + _zoning.outer = GetEvaluationModeFromInt(_zoning.outer_val); + break; + case ZTW_INNER_DROPDOWN: + _zoning.inner_val = index; + _zoning.inner = GetEvaluationModeFromInt(_zoning.inner_val); + break; + } + this->InvalidateData(); + MarkWholeScreenDirty(); + } + + virtual void SetStringParameters(int widget) const { + switch ( widget ) { + case ZTW_OUTER_DROPDOWN: SetDParam(0, _zone_types[_zoning.outer]); break; + case ZTW_INNER_DROPDOWN: SetDParam(0, _zone_types[_zoning.inner]); break; + } + } + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { + const StringID *strs = NULL; + switch ( widget ) { + case ZTW_OUTER_DROPDOWN: strs = _zone_types; break; + case ZTW_INNER_DROPDOWN: strs = _zone_types; break; + } + if ( strs != NULL ) { + while ( *strs != INVALID_STRING_ID ) { + *size = maxdim(*size, GetStringBoundingBox(*strs++)); + } + } + size->width += padding.width; + size->height = FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM; + } +}; + +static const NWidgetPart _nested_zoning_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, ZTW_CAPTION), SetDataTip(STR_ZONING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_GREY), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL, COLOUR_GREY), SetPIP(10, 3, 10), + NWidget(NWID_VERTICAL, COLOUR_GREY), SetPadding(5, 0, 5, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_ZONING_OUTER, STR_NULL), SetResize(1, 0), SetPadding(1, 6, 1, 6), + NWidget(WWT_TEXT, COLOUR_GREY, ZTW_OUTER), + NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_ZONING_INNER, STR_NULL), SetResize(1, 0), SetPadding(1, 6, 1, 6), + NWidget(WWT_TEXT, COLOUR_GREY, ZTW_INNER), + EndContainer(), + NWidget(NWID_VERTICAL, COLOUR_GREY), SetPadding(5, 0, 5, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, ZTW_OUTER_DROPDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXT, COLOUR_GREY), + NWidget(WWT_DROPDOWN, COLOUR_GREY, ZTW_INNER_DROPDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXT, COLOUR_GREY), + EndContainer(), + EndContainer(), + EndContainer() +}; + +static const WindowDesc _zoning_desc ( + WDP_CENTER, 0, 0, + WC_ZONING_TOOLBAR, WC_NONE, + 0, + _nested_zoning_widgets, lengthof(_nested_zoning_widgets) +); + +void ShowZoningToolbar() { + AllocateWindowDescFront(&_zoning_desc, 0); +} From 03373c7ef4882df4df84fc67a41fe11fc9b814a9 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 2 Aug 2015 12:29:04 +0100 Subject: [PATCH 2/3] Zoning: Remove unimplemented modes, fix some whitespace and style issues, add missing licence headers, move/rename some declarations, fix sprite ID allocation, update to build on trunk. --- src/gfxinit.cpp | 2 +- src/lang/english.txt | 2 - src/table/sprites.h | 24 ++- src/zoning.h | 53 ++++--- src/zoning_cmd.cpp | 359 +++++++++++++++++++------------------------ src/zoning_gui.cpp | 132 +++++++++++----- 6 files changed, 293 insertions(+), 279 deletions(-) diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index 2affb67c59..0b7d9e897a 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -193,7 +193,7 @@ static void LoadSpriteTables() ); } - LoadGrfFile("innerhighlight.grf", SPR_INNER_HIGHLIGHT_BASE, i++); + LoadGrfFile("innerhighlight.grf", SPR_ZONING_INNER_HIGHLIGHT_BASE, i++); /* Initialize the unicode to sprite mapping table */ InitializeUnicodeGlyphMap(); diff --git a/src/lang/english.txt b/src/lang/english.txt index 58f66c03af..f0f4d5823f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4982,7 +4982,5 @@ STR_ZONING_NO_ZONING :Nothing STR_ZONING_AUTHORITY :Authority STR_ZONING_CAN_BUILD :Where I can't build STR_ZONING_STA_CATCH :Station catchment -STR_ZONING_IND_CATCH :Industry catchment -STR_ZONING_BUL_CATCH :City catchment STR_ZONING_BUL_UNSER :Unserved buildings STR_ZONING_IND_UNSER :Unserved industries diff --git a/src/table/sprites.h b/src/table/sprites.h index 0c6e4e71f1..c2b14e33ec 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -296,8 +296,18 @@ static const uint16 EMPTY_BOUNDING_BOX_SPRITE_COUNT = 1; static const SpriteID SPR_PALETTE_BASE = SPR_EMPTY_BOUNDING_BOX + EMPTY_BOUNDING_BOX_SPRITE_COUNT; static const uint16 PALETTE_SPRITE_COUNT = 1; +/* Zoning sprites */ +static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_BASE = SPR_PALETTE_BASE + PALETTE_SPRITE_COUNT; +static const uint16 ZONING_INNER_HIGHLIGHT_SPRITE_COUNT = 32; +static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_RED = SPR_ZONING_INNER_HIGHLIGHT_BASE + 19; +static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_GREEN = SPR_ZONING_INNER_HIGHLIGHT_BASE + 20; +static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_BLACK = SPR_ZONING_INNER_HIGHLIGHT_BASE + 21; +static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_LIGHT_BLUE = SPR_ZONING_INNER_HIGHLIGHT_BASE + 22; +static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_ORANGE = SPR_ZONING_INNER_HIGHLIGHT_BASE + 23; +static const SpriteID SPR_ZONING_INNER_HIGHLIGHT_WHITE = SPR_ZONING_INNER_HIGHLIGHT_BASE + 24; + /* From where can we start putting NewGRFs? */ -static const SpriteID SPR_NEWGRFS_BASE = SPR_PALETTE_BASE + PALETTE_SPRITE_COUNT; +static const SpriteID SPR_NEWGRFS_BASE = SPR_ZONING_INNER_HIGHLIGHT_BASE + ZONING_INNER_HIGHLIGHT_SPRITE_COUNT; /* Manager face sprites */ static const SpriteID SPR_GRADIENT = 874; // background gradient behind manager face @@ -1342,16 +1352,6 @@ static const SpriteID SPR_SELECT_SUB_TROPICAL_PUSHED = 4887; static const SpriteID SPR_SELECT_TOYLAND = 4888; static const SpriteID SPR_SELECT_TOYLAND_PUSHED = 4889; -/* zoning stuff; dunno where else to put it */ - -static const SpriteID SPR_INNER_HIGHLIGHT_BASE = 11000; -static const SpriteID SPR_PALETTE_ZONING_RED = SPR_INNER_HIGHLIGHT_BASE + 19; -static const SpriteID SPR_PALETTE_ZONING_GREEN = SPR_INNER_HIGHLIGHT_BASE + 20; -static const SpriteID SPR_PALETTE_ZONING_BLACK = SPR_INNER_HIGHLIGHT_BASE + 21; -static const SpriteID SPR_PALETTE_ZONING_LIGHT_BLUE = SPR_INNER_HIGHLIGHT_BASE + 22; -static const SpriteID SPR_PALETTE_ZONING_ORANGE = SPR_INNER_HIGHLIGHT_BASE + 23; -static const SpriteID SPR_PALETTE_ZONING_WHITE = SPR_INNER_HIGHLIGHT_BASE + 24; - /** Cursor sprite numbers */ /* Terraform @@ -1584,6 +1584,4 @@ static const PaletteID PALETTE_CHURCH_CREAM = 1439; ///< Recolour sprite static const PaletteID PALETTE_ALL_BLACK = SPR_PALETTE_BASE; ///< Exchange any color by black, needed for painting fictive tiles outside map -static const SpriteID INVALID_SPRITE_ID = UINT_MAX; - #endif /* SPRITES_H */ diff --git a/src/zoning.h b/src/zoning.h index 01842a91e2..bfea293342 100644 --- a/src/zoning.h +++ b/src/zoning.h @@ -1,39 +1,48 @@ +/* $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 . + */ + /** @file zoning.h */ -#ifndef ZONING_H_ -#define ZONING_H_ +#ifndef ZONING_H +#define ZONING_H -#include "openttd.h" #include "tile_cmd.h" +#include "company_type.h" -enum EvaluationMode { - CHECKNOTHING = 0, - CHECKOPINION = 1, ///< Check the local authority's opinion. - CHECKBUILD = 2, ///< Check wither or not the player can build. - CHECKSTACATCH = 3, ///< Check catchment area for stations - CHECKINDCATCH = 4, ///< Check catchment area for industries - CHECKBULCATCH = 5, ///< Check catchment area for buildings - CHECKBULUNSER = 6, ///< Check for unserved buildings - CHECKINDUNSER = 7, ///< Check for unserved industries +/** + * Zoning evaluation modes + */ +enum ZoningEvaluationMode { + ZEM_NOTHING = 0, ///< No zoning action selected + ZEM_AUTHORITY, ///< Check the local authority's opinion. + ZEM_CAN_BUILD, ///< Check wither or not the player can build. + ZEM_STA_CATCH, ///< Check catchment area for stations + ZEM_BUL_UNSER, ///< Check for unserved buildings + ZEM_IND_UNSER, ///< Check for unserved industries }; +/** + * Global Zoning state structure + */ struct Zoning { - EvaluationMode inner; - EvaluationMode outer; - int inner_val; - int outer_val; + ZoningEvaluationMode inner; + ZoningEvaluationMode outer; }; -VARDEF Zoning _zoning; +extern Zoning _zoning; -SpriteID TileZoningSpriteEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode); +SpriteID TileZoningSpriteEvaluation(TileIndex tile, Owner owner, ZoningEvaluationMode ev_mode); -int TileZoningEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode); +int TileZoningEvaluation(TileIndex tile, Owner owner, ZoningEvaluationMode ev_mode); void DrawTileZoning(const TileInfo *ti); void ShowZoningToolbar(); -EvaluationMode GetEvaluationModeFromInt(int ev_mode); - -#endif /*ZONING_H_*/ +#endif /* ZONING_H */ diff --git a/src/zoning_cmd.cpp b/src/zoning_cmd.cpp index 671d8c6dc6..9edcba8dd8 100644 --- a/src/zoning_cmd.cpp +++ b/src/zoning_cmd.cpp @@ -1,3 +1,11 @@ +/* $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 . + */ /** @file zoning_cmd.cpp */ @@ -8,7 +16,6 @@ #include "industry.h" #include "gfx_func.h" #include "viewport_func.h" -#include "variables.h" #include "map_func.h" #include "company_func.h" #include "town_map.h" @@ -19,6 +26,7 @@ #include "zoning.h" Zoning _zoning; +static const SpriteID ZONING_INVALID_SPRITE_ID = UINT_MAX; /** * Draw the zoning sprites. @@ -30,9 +38,11 @@ Zoning _zoning; * @param TileInfo ti * the tile */ -void DrawZoningSprites(SpriteID image, SpriteID colour, const TileInfo *ti) { - if ( colour!=INVALID_SPRITE_ID ) - AddSortableSpriteToDraw(image + _tileh_to_sprite[ti->tileh], colour, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7); +void DrawZoningSprites(SpriteID image, SpriteID colour, const TileInfo *ti) +{ + if (colour != ZONING_INVALID_SPRITE_ID) { + AddSortableSpriteToDraw(image + ti->tileh, colour, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7); + } } /** @@ -44,22 +54,22 @@ void DrawZoningSprites(SpriteID image, SpriteID colour, const TileInfo *ti) { * the owner of the stations which we need to match again * @return true if a station is found */ -bool IsAreaWithinAcceptanceZoneOfStation(TileArea area, Owner owner) { - +bool IsAreaWithinAcceptanceZoneOfStation(TileArea area, Owner owner) +{ // TODO: Actually do owner check. - + int catchment = _settings_game.station.station_spread + (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); - - StationFinder morestations(TileArea(TileXY(TileX(area.tile)-catchment/2, TileY(area.tile)-catchment/2), - TileX(area.tile) + area.w + catchment, TileY(area.tile) + area.h + catchment)); - - for ( Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter ) { + + StationFinder morestations(TileArea(TileXY(TileX(area.tile) - (catchment / 2), TileY(area.tile) - (catchment / 2)), + TileX(area.tile) + area.w + catchment, TileY(area.tile) + area.h + catchment)); + + for (Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter) { Station *st = *st_iter; Rect rect = st->GetCatchmentRect(); return TileArea(TileXY(rect.left, rect.top), TileXY(rect.right, rect.bottom)).Intersects(area); } - - return false; + + return false; } /** @@ -71,24 +81,25 @@ bool IsAreaWithinAcceptanceZoneOfStation(TileArea area, Owner owner) { * the owner of the stations * @return true if a station is found */ -bool IsTileWithinAcceptanceZoneOfStation(TileIndex tile, Owner owner) { - +bool IsTileWithinAcceptanceZoneOfStation(TileIndex tile, Owner owner) +{ // TODO: Actually do owner check. - + int catchment = _settings_game.station.station_spread + (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); - - StationFinder morestations(TileArea(TileXY(TileX(tile)-catchment/2, TileY(tile)-catchment/2), - catchment, catchment)); - - for ( Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter ) { + + StationFinder morestations(TileArea(TileXY(TileX(tile) - (catchment / 2), TileY(tile) - (catchment / 2)), + catchment, catchment)); + + for (Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter) { Station *st = *st_iter; Rect rect = st->GetCatchmentRect(); - if ( (uint)rect.left <= TileX(tile) && TileX(tile) <= (uint)rect.right - && (uint)rect.top <= TileY(tile) && TileY(tile) <= (uint)rect.bottom ) + if ((uint)rect.left <= TileX(tile) && TileX(tile) <= (uint)rect.right + && (uint)rect.top <= TileY(tile) && TileY(tile) <= (uint)rect.bottom) { return true; + } } - - return false; + + return false; } /** @@ -98,14 +109,17 @@ bool IsTileWithinAcceptanceZoneOfStation(TileIndex tile, Owner owner) { * @param Owner owner * @return red if they cannot */ -SpriteID TileZoneCheckBuildEvaluation(TileIndex tile, Owner owner) { +SpriteID TileZoneCheckBuildEvaluation(TileIndex tile, Owner owner) +{ /* Let's first check for the obvious things you cannot build on */ - switch ( GetTileType(tile) ) { + switch (GetTileType(tile)) { case MP_INDUSTRY: - case MP_UNMOVABLE: + case MP_OBJECT: case MP_STATION: case MP_HOUSE: - case MP_TUNNELBRIDGE: return SPR_PALETTE_ZONING_RED; + case MP_TUNNELBRIDGE: + return SPR_ZONING_INNER_HIGHLIGHT_RED; + /* There are only two things you can own (or some else * can own) that you can still build on. i.e. roads and * railways. @@ -117,15 +131,18 @@ SpriteID TileZoneCheckBuildEvaluation(TileIndex tile, Owner owner) { * While that being said, it should also check if it * is not possible to build railway/road on someone * else's/your own road/railway (e.g. the railway track - * is curved or a cross).*/ + * is curved or a cross). + */ case MP_ROAD: - case MP_RAILWAY: { - if ( GetTileOwner(tile) != owner ) - return SPR_PALETTE_ZONING_RED; - else - return INVALID_SPRITE_ID; - } - default: return INVALID_SPRITE_ID; + case MP_RAILWAY: + if (GetTileOwner(tile) != owner) { + return SPR_ZONING_INNER_HIGHLIGHT_RED; + } else { + return ZONING_INVALID_SPRITE_ID; + } + + default: + return ZONING_INVALID_SPRITE_ID; } } @@ -134,96 +151,60 @@ SpriteID TileZoneCheckBuildEvaluation(TileIndex tile, Owner owner) { * * @param TileIndex tile * @param Owner owner - * @return black if no opinion, orange if bad, + * @return black if no opinion, orange if bad, * light blue if good or invalid if no town */ -SpriteID TileZoneCheckOpinionEvaluation(TileIndex tile, Owner owner) { +SpriteID TileZoneCheckOpinionEvaluation(TileIndex tile, Owner owner) +{ int opinion = 0; // 0: no town, 1: no opinion, 2: bad, 3: good Town *town = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); - if ( town !=NULL ) { - if ( HasBit(town->have_ratings, owner) ) { - opinion = ( town->ratings[owner] > 0 ) ? 3 : 2; + if (town != NULL) { + if (HasBit(town->have_ratings, owner)) { + opinion = (town->ratings[owner] > 0) ? 3 : 2; } else { opinion = 1; } } - switch ( opinion ) { - case 1: return SPR_PALETTE_ZONING_BLACK; // no opinion - case 2: return SPR_PALETTE_ZONING_ORANGE; // bad - case 3: return SPR_PALETTE_ZONING_LIGHT_BLUE; // good - default: return INVALID_SPRITE_ID; // no town + switch (opinion) { + case 1: return SPR_ZONING_INNER_HIGHLIGHT_BLACK; // no opinion + case 2: return SPR_ZONING_INNER_HIGHLIGHT_ORANGE; // bad + case 3: return SPR_ZONING_INNER_HIGHLIGHT_LIGHT_BLUE; // good + default: return ZONING_INVALID_SPRITE_ID; // no town } } -/** - * Detect whether the tile is within the 'catchment' zone of an industry. - * - * @param TileIndex tile - * @param Owner owner - * @return The colour depends on the distance to the industry: - * 1-3 White (lorry/bus) - * 4 Blue (train station/some airports) - * 5 Green (docks/some airports) - * 6 Yellow (some airports) - * 7-9 Light blue (international airport) - */ -SpriteID TileZoneCheckIndustryCatchmentEvaluation(TileIndex tile, Owner owner) { - - // TODO: Implement this! - - return INVALID_SPRITE_ID; -} - /** * Detect whether the tile is within the catchment zone of a station. * * @param TileIndex tile * @param Owner owner - * @return black if within, light blue if only in acceptance zone + * @return black if within, light blue if only in acceptance zone * and nothing if no nearby station. */ -SpriteID TileZoneCheckStationCatchmentEvaluation(TileIndex tile, Owner owner) { - - //TODO: Actually check owner. +SpriteID TileZoneCheckStationCatchmentEvaluation(TileIndex tile, Owner owner) +{ + // TODO: Actually check owner. // Never on a station. - if ( IsTileType(tile, MP_STATION) ) - return INVALID_SPRITE_ID; - - // For provided goods - - StationFinder stations(TileArea(tile, 1, 1)); - - if ( stations.GetStations()->Length() > 0 ) { - return SPR_PALETTE_ZONING_BLACK; + if (IsTileType(tile, MP_STATION)) { + return ZONING_INVALID_SPRITE_ID; } - - // For accepted goods - - if ( IsTileWithinAcceptanceZoneOfStation(tile, owner) ) - return SPR_PALETTE_ZONING_LIGHT_BLUE; - - return INVALID_SPRITE_ID; -} -/** - * Detect whether a tile is within the 'catchment' zone of a building. - * - * @param TileIndex tile - * @param Owner owner - * @return The colour depends on the distance to the building: - * 1-3 White (lorry/bus) - * 4 Blue (train station/some airports) - * 5 Green (docks/some airports) - * 6 Yellow (some airports) - * 7-9 Light blue (international airport) - */ -SpriteID TileZoneCheckBuildingCatchmentEvaluation(TileIndex tile, Owner owner) { - // TODO: Implement this! - - return INVALID_SPRITE_ID; + // For provided goods + StationFinder stations(TileArea(tile, 1, 1)); + + if (stations.GetStations()->Length() > 0) { + return SPR_ZONING_INNER_HIGHLIGHT_BLACK; + } + + // For accepted goods + if (IsTileWithinAcceptanceZoneOfStation(tile, owner)) { + return SPR_ZONING_INNER_HIGHLIGHT_LIGHT_BLUE; + } + + return ZONING_INVALID_SPRITE_ID; } /** @@ -234,33 +215,42 @@ SpriteID TileZoneCheckBuildingCatchmentEvaluation(TileIndex tile, Owner owner) { * @return red if unserved, orange if only accepting, nothing if served or not * a building */ -SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner) { +SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner) +{ + // TODO: Actually use owner. - //TODO: Actually use owner. - - CargoArray dat; - - if ( IsTileType (tile, MP_HOUSE) - && ( ( memset(&dat, 0, sizeof(dat)), AddAcceptedCargo(tile, dat, NULL), (dat[CT_MAIL] + dat[CT_PASSENGERS] > 0) ) - || ( memset(&dat, 0, sizeof(dat)), AddProducedCargo(tile, dat), (dat[CT_MAIL] + dat[CT_PASSENGERS] > 0) ) ) ) { - StationFinder stations(TileArea(tile, 1, 1)); - - if ( stations.GetStations()->Length() > 0 ) { - return INVALID_SPRITE_ID; - } - - // For accepted goods - - if ( IsTileWithinAcceptanceZoneOfStation(tile, owner) ) - return SPR_PALETTE_ZONING_ORANGE; - - //TODO: Check for stations that does not accept mail/passengers, - //which is currently only truck stops. - - return SPR_PALETTE_ZONING_RED; + if (!IsTileType(tile, MP_HOUSE)) { + return ZONING_INVALID_SPRITE_ID; } - - return INVALID_SPRITE_ID; + + CargoArray dat; + + memset(&dat, 0, sizeof(dat)); + AddAcceptedCargo(tile, dat, NULL); + if (dat[CT_MAIL] + dat[CT_PASSENGERS] == 0) { + // nothing is accepted, so now test if cargo is produced + AddProducedCargo(tile, dat); + if (dat[CT_MAIL] + dat[CT_PASSENGERS] == 0) { + // total is still 0, so give up + return ZONING_INVALID_SPRITE_ID; + } + } + + StationFinder stations(TileArea(tile, 1, 1)); + + if (stations.GetStations()->Length() > 0) { + return ZONING_INVALID_SPRITE_ID; + } + + // For accepted goods + if (IsTileWithinAcceptanceZoneOfStation(tile, owner)) { + return SPR_ZONING_INNER_HIGHLIGHT_ORANGE; + } + + // TODO: Check for stations that does not accept mail/passengers, + // which is currently only truck stops. + + return SPR_ZONING_INNER_HIGHLIGHT_RED; } /** @@ -271,30 +261,30 @@ SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner) { * @return red if unserved, orange if only accepting, nothing if served or not * a building */ -SpriteID TileZoneCheckUnservedIndustriesEvaluation(TileIndex tile, Owner owner) { +SpriteID TileZoneCheckUnservedIndustriesEvaluation(TileIndex tile, Owner owner) +{ + // TODO: Actually use owner. - //TODO: Actually use owner. - - if ( IsTileType(tile, MP_INDUSTRY) ) { + if (IsTileType(tile, MP_INDUSTRY)) { Industry *ind = Industry::GetByTile(tile); StationFinder stations(ind->location); - - if ( stations.GetStations()->Length() > 0 ) { - return INVALID_SPRITE_ID; + + if (stations.GetStations()->Length() > 0) { + return ZONING_INVALID_SPRITE_ID; } - + // For accepted goods - - if ( IsAreaWithinAcceptanceZoneOfStation(ind->location, owner) ) - return SPR_PALETTE_ZONING_ORANGE; - - //TODO: Check for stations that only accepts mail/passengers, - //which is currently only bus stops. - - return SPR_PALETTE_ZONING_RED; + if (IsAreaWithinAcceptanceZoneOfStation(ind->location, owner)) { + return SPR_ZONING_INNER_HIGHLIGHT_ORANGE; + } + + // TODO: Check for stations that only accepts mail/passengers, + // which is currently only bus stops. + + return SPR_ZONING_INNER_HIGHLIGHT_RED; } - - return INVALID_SPRITE_ID; + + return ZONING_INVALID_SPRITE_ID; } /** @@ -305,74 +295,39 @@ SpriteID TileZoneCheckUnservedIndustriesEvaluation(TileIndex tile, Owner owner) * Tile to be evaluated. * @param Owner owner * The current player - * @param EvaluationMode ev_mode + * @param ZoningEvaluationMode ev_mode * The current evaluation mode. * @return The colour returned by the evaluation functions (none if no ev_mode). */ -SpriteID TileZoningSpriteEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode) { - switch ( ev_mode ) { - case CHECKBUILD: return TileZoneCheckBuildEvaluation(tile, owner); - case CHECKOPINION: return TileZoneCheckOpinionEvaluation(tile, owner); - case CHECKINDCATCH: return TileZoneCheckIndustryCatchmentEvaluation(tile, owner); - case CHECKSTACATCH: return TileZoneCheckStationCatchmentEvaluation(tile, owner); - case CHECKBULCATCH: return TileZoneCheckBuildingCatchmentEvaluation(tile, owner); - case CHECKBULUNSER: return TileZoneCheckUnservedBuildingsEvaluation(tile, owner); - case CHECKINDUNSER: return TileZoneCheckUnservedIndustriesEvaluation(tile, owner); - default: return INVALID_SPRITE_ID; +SpriteID TileZoningSpriteEvaluation(TileIndex tile, Owner owner, ZoningEvaluationMode ev_mode) +{ + switch (ev_mode) { + case ZEM_CAN_BUILD: return TileZoneCheckBuildEvaluation(tile, owner); + case ZEM_AUTHORITY: return TileZoneCheckOpinionEvaluation(tile, owner); + case ZEM_STA_CATCH: return TileZoneCheckStationCatchmentEvaluation(tile, owner); + case ZEM_BUL_UNSER: return TileZoneCheckUnservedBuildingsEvaluation(tile, owner); + case ZEM_IND_UNSER: return TileZoneCheckUnservedIndustriesEvaluation(tile, owner); + default: return ZONING_INVALID_SPRITE_ID; } } -/** - * Same as above, but not return an integer instead of sprite. However, it - * has so far not yet seem a real purpose, so therefore has not been implemented. - * - * @param TileIndex tile - * Tile to be evaluated. - * @param Owner owner - * The current player - * @param EvaluationMode ev_mode - * The current evaluation mode. - * @return Probably an integer based on the evaluation mode. - */ -int TileZoningEvaluation(TileIndex tile, Owner owner, EvaluationMode ev_mode) { - return 0; -} - /** * Draw the the zoning on the tile. * * @param TileInfo ti * the tile to draw on. */ -void DrawTileZoning(const TileInfo *ti) { - if ( IsTileType(ti->tile, MP_VOID) - || _game_mode != GM_NORMAL ) +void DrawTileZoning(const TileInfo *ti) +{ + if (IsTileType(ti->tile, MP_VOID) || _game_mode != GM_NORMAL) { return; - - if ( _zoning.outer != CHECKNOTHING ) - DrawZoningSprites(SPR_SELECT_TILE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.outer), ti); - - if ( _zoning.inner != CHECKNOTHING ) - DrawZoningSprites(SPR_INNER_HIGHLIGHT_BASE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.inner), ti); -} + } -/** - * Get the evaluation mode depending on an integer. Though, this may be better - * implemented so the code does not need to be updated several places everything - * a new type of evaluation is added. - * - * @param int ev_mode - * @return EvaluationMode - */ -EvaluationMode GetEvaluationModeFromInt(int ev_mode) { - switch ( ev_mode ) { - case 1: return CHECKOPINION; - case 2: return CHECKBUILD; - case 3: return CHECKSTACATCH; - case 4: return CHECKINDCATCH; - case 5: return CHECKBULCATCH; - case 6: return CHECKBULUNSER; - case 7: return CHECKINDUNSER; - default: return CHECKNOTHING; + if (_zoning.outer != ZEM_NOTHING) { + DrawZoningSprites(SPR_SELECT_TILE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.outer), ti); + } + + if (_zoning.inner != ZEM_NOTHING) { + DrawZoningSprites(SPR_ZONING_INNER_HIGHLIGHT_BASE, TileZoningSpriteEvaluation(ti->tile, _local_company, _zoning.inner), ti); } } diff --git a/src/zoning_gui.cpp b/src/zoning_gui.cpp index 42161d1036..74be21b8f6 100644 --- a/src/zoning_gui.cpp +++ b/src/zoning_gui.cpp @@ -1,3 +1,11 @@ +/* $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 . + */ /** @file zoning_gui.cpp */ @@ -5,12 +13,10 @@ #include "openttd.h" #include "widgets/dropdown_func.h" #include "widget_type.h" -#include "functions.h" #include "window_func.h" #include "gui.h" #include "viewport_func.h" #include "sound_func.h" -#include "variables.h" #include "table/sprites.h" #include "table/strings.h" #include "strings_func.h" @@ -21,66 +27,113 @@ enum ZoningToolbarWidgets { ZTW_OUTER = 4, - ZTW_OUTER_DROPDOWN, + ZTW_OUTER_DROPDOWN, ZTW_INNER, ZTW_INNER_DROPDOWN, ZTW_CAPTION }; -const StringID _zone_types[] = { STR_ZONING_NO_ZONING, STR_ZONING_AUTHORITY, STR_ZONING_CAN_BUILD, STR_ZONING_STA_CATCH, STR_ZONING_IND_CATCH, STR_ZONING_BUL_CATCH, STR_ZONING_BUL_UNSER, STR_ZONING_IND_UNSER, INVALID_STRING_ID }; +static const StringID _zone_type_strings[] = { + STR_ZONING_NO_ZONING, + STR_ZONING_AUTHORITY, + STR_ZONING_CAN_BUILD, + STR_ZONING_STA_CATCH, + STR_ZONING_BUL_UNSER, + STR_ZONING_IND_UNSER, + INVALID_STRING_ID +}; + +static const ZoningEvaluationMode _zone_type_modes[] = { + ZEM_NOTHING, + ZEM_AUTHORITY, + ZEM_CAN_BUILD, + ZEM_STA_CATCH, + ZEM_BUL_UNSER, + ZEM_IND_UNSER, +}; + +static ZoningEvaluationMode DropDownIndexToZoningEvaluationMode(int index) +{ + if (index < 0 || index >= (int) lengthof(_zone_type_modes)) { + return ZEM_NOTHING; + } + return _zone_type_modes[index]; +} + +static int ZoningEvaluationModeToDropDownIndex(ZoningEvaluationMode ev_mode) +{ + for (int i = 0; i < (int) lengthof(_zone_type_modes); i++) { + if (_zone_type_modes[i] == ev_mode) return i; + } + NOT_REACHED(); +} struct ZoningWindow : public Window { - - ZoningWindow(const WindowDesc *desc, int window_number) : Window() { - this->InitNested(desc, window_number); - this->InvalidateData(); + + ZoningWindow(WindowDesc *desc, int window_number) + : Window(desc) + { + this->InitNested(window_number); + this->InvalidateData(); } - - virtual void OnPaint() { + + virtual void OnPaint() + { this->DrawWidgets(); } - - virtual void OnClick(Point pt, int widget, int click_count) { - switch ( widget ) { + + virtual void OnClick(Point pt, int widget, int click_count) + { + switch (widget) { case ZTW_OUTER_DROPDOWN: - ShowDropDownMenu(this, _zone_types, _zoning.outer_val, ZTW_OUTER_DROPDOWN, 0, 0); + ShowDropDownMenu(this, _zone_type_strings, ZoningEvaluationModeToDropDownIndex(_zoning.outer), ZTW_OUTER_DROPDOWN, 0, 0); break; + case ZTW_INNER_DROPDOWN: - ShowDropDownMenu(this, _zone_types, _zoning.inner_val, ZTW_INNER_DROPDOWN, 0, 0); + ShowDropDownMenu(this, _zone_type_strings, ZoningEvaluationModeToDropDownIndex(_zoning.inner), ZTW_INNER_DROPDOWN, 0, 0); break; - } + } } - - virtual void OnDropdownSelect(int widget, int index) { + + virtual void OnDropdownSelect(int widget, int index) + { switch(widget) { case ZTW_OUTER_DROPDOWN: - _zoning.outer_val = index; - _zoning.outer = GetEvaluationModeFromInt(_zoning.outer_val); + _zoning.outer = DropDownIndexToZoningEvaluationMode(index); break; + case ZTW_INNER_DROPDOWN: - _zoning.inner_val = index; - _zoning.inner = GetEvaluationModeFromInt(_zoning.inner_val); + _zoning.inner = DropDownIndexToZoningEvaluationMode(index); break; } this->InvalidateData(); MarkWholeScreenDirty(); } - - virtual void SetStringParameters(int widget) const { - switch ( widget ) { - case ZTW_OUTER_DROPDOWN: SetDParam(0, _zone_types[_zoning.outer]); break; - case ZTW_INNER_DROPDOWN: SetDParam(0, _zone_types[_zoning.inner]); break; + + virtual void SetStringParameters(int widget) const + { + switch (widget) { + case ZTW_OUTER_DROPDOWN: + SetDParam(0, _zone_type_strings[ZoningEvaluationModeToDropDownIndex(_zoning.outer)]); + break; + + case ZTW_INNER_DROPDOWN: + SetDParam(0, _zone_type_strings[ZoningEvaluationModeToDropDownIndex(_zoning.inner)]); + break; } } - - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { + + virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + { const StringID *strs = NULL; - switch ( widget ) { - case ZTW_OUTER_DROPDOWN: strs = _zone_types; break; - case ZTW_INNER_DROPDOWN: strs = _zone_types; break; + switch (widget) { + case ZTW_OUTER_DROPDOWN: + case ZTW_INNER_DROPDOWN: + strs = _zone_type_strings; + break; } - if ( strs != NULL ) { - while ( *strs != INVALID_STRING_ID ) { + if (strs != NULL) { + while (*strs != INVALID_STRING_ID) { *size = maxdim(*size, GetStringBoundingBox(*strs++)); } } @@ -96,9 +149,9 @@ static const NWidgetPart _nested_zoning_widgets[] = { NWidget(WWT_SHADEBOX, COLOUR_GREY), NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), - + NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL, COLOUR_GREY), SetPIP(10, 3, 10), + NWidget(NWID_HORIZONTAL, COLOUR_GREY), SetPIP(10, 3, 10), NWidget(NWID_VERTICAL, COLOUR_GREY), SetPadding(5, 0, 5, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_ZONING_OUTER, STR_NULL), SetResize(1, 0), SetPadding(1, 6, 1, 6), NWidget(WWT_TEXT, COLOUR_GREY, ZTW_OUTER), @@ -115,13 +168,14 @@ static const NWidgetPart _nested_zoning_widgets[] = { EndContainer() }; -static const WindowDesc _zoning_desc ( - WDP_CENTER, 0, 0, +static WindowDesc _zoning_desc ( + WDP_CENTER, "zoning_gui", 0, 0, WC_ZONING_TOOLBAR, WC_NONE, 0, _nested_zoning_widgets, lengthof(_nested_zoning_widgets) ); -void ShowZoningToolbar() { +void ShowZoningToolbar() +{ AllocateWindowDescFront(&_zoning_desc, 0); } From 74bccb5d500852b35220aa80c889faccf3ef520e Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 2 Aug 2015 13:09:30 +0100 Subject: [PATCH 3/3] Zoning: Implement ownership checks, and station facility checks for industries. --- src/zoning_cmd.cpp | 57 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/zoning_cmd.cpp b/src/zoning_cmd.cpp index 9edcba8dd8..5f9240d76c 100644 --- a/src/zoning_cmd.cpp +++ b/src/zoning_cmd.cpp @@ -52,19 +52,20 @@ void DrawZoningSprites(SpriteID image, SpriteID colour, const TileInfo *ti) * the area to search by * @param Owner owner * the owner of the stations which we need to match again + * @param StationFacility facility_mask + * one or more facilities in the mask must be present for a station to be used * @return true if a station is found */ -bool IsAreaWithinAcceptanceZoneOfStation(TileArea area, Owner owner) +bool IsAreaWithinAcceptanceZoneOfStation(TileArea area, Owner owner, StationFacility facility_mask) { - // TODO: Actually do owner check. - int catchment = _settings_game.station.station_spread + (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); StationFinder morestations(TileArea(TileXY(TileX(area.tile) - (catchment / 2), TileY(area.tile) - (catchment / 2)), TileX(area.tile) + area.w + catchment, TileY(area.tile) + area.h + catchment)); for (Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter) { - Station *st = *st_iter; + const Station *st = *st_iter; + if (st->owner != owner || !(st->facilities & facility_mask)) continue; Rect rect = st->GetCatchmentRect(); return TileArea(TileXY(rect.left, rect.top), TileXY(rect.right, rect.bottom)).Intersects(area); } @@ -79,19 +80,20 @@ bool IsAreaWithinAcceptanceZoneOfStation(TileArea area, Owner owner) * the tile to search by * @param Owner owner * the owner of the stations + * @param StationFacility facility_mask + * one or more facilities in the mask must be present for a station to be used * @return true if a station is found */ -bool IsTileWithinAcceptanceZoneOfStation(TileIndex tile, Owner owner) +bool IsTileWithinAcceptanceZoneOfStation(TileIndex tile, Owner owner, StationFacility facility_mask) { - // TODO: Actually do owner check. - int catchment = _settings_game.station.station_spread + (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); StationFinder morestations(TileArea(TileXY(TileX(tile) - (catchment / 2), TileY(tile) - (catchment / 2)), catchment, catchment)); for (Station * const *st_iter = morestations.GetStations()->Begin(); st_iter != morestations.GetStations()->End(); ++st_iter) { - Station *st = *st_iter; + const Station *st = *st_iter; + if (st->owner != owner || !(st->facilities & facility_mask)) continue; Rect rect = st->GetCatchmentRect(); if ((uint)rect.left <= TileX(tile) && TileX(tile) <= (uint)rect.right && (uint)rect.top <= TileY(tile) && TileY(tile) <= (uint)rect.bottom) { @@ -185,8 +187,6 @@ SpriteID TileZoneCheckOpinionEvaluation(TileIndex tile, Owner owner) */ SpriteID TileZoneCheckStationCatchmentEvaluation(TileIndex tile, Owner owner) { - // TODO: Actually check owner. - // Never on a station. if (IsTileType(tile, MP_STATION)) { return ZONING_INVALID_SPRITE_ID; @@ -195,12 +195,15 @@ SpriteID TileZoneCheckStationCatchmentEvaluation(TileIndex tile, Owner owner) // For provided goods StationFinder stations(TileArea(tile, 1, 1)); - if (stations.GetStations()->Length() > 0) { - return SPR_ZONING_INNER_HIGHLIGHT_BLACK; + for (Station * const *st_iter = stations.GetStations()->Begin(); st_iter != stations.GetStations()->End(); ++st_iter) { + const Station *st = *st_iter; + if (st->owner == owner) { + return SPR_ZONING_INNER_HIGHLIGHT_BLACK; + } } // For accepted goods - if (IsTileWithinAcceptanceZoneOfStation(tile, owner)) { + if (IsTileWithinAcceptanceZoneOfStation(tile, owner, ~FACIL_NONE)) { return SPR_ZONING_INNER_HIGHLIGHT_LIGHT_BLUE; } @@ -217,8 +220,6 @@ SpriteID TileZoneCheckStationCatchmentEvaluation(TileIndex tile, Owner owner) */ SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner) { - // TODO: Actually use owner. - if (!IsTileType(tile, MP_HOUSE)) { return ZONING_INVALID_SPRITE_ID; } @@ -238,18 +239,18 @@ SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner) StationFinder stations(TileArea(tile, 1, 1)); - if (stations.GetStations()->Length() > 0) { - return ZONING_INVALID_SPRITE_ID; + for (Station * const *st_iter = stations.GetStations()->Begin(); st_iter != stations.GetStations()->End(); ++st_iter) { + const Station *st = *st_iter; + if (st->owner == owner) { + return ZONING_INVALID_SPRITE_ID; + } } // For accepted goods - if (IsTileWithinAcceptanceZoneOfStation(tile, owner)) { + if (IsTileWithinAcceptanceZoneOfStation(tile, owner, ~FACIL_NONE)) { return SPR_ZONING_INNER_HIGHLIGHT_ORANGE; } - // TODO: Check for stations that does not accept mail/passengers, - // which is currently only truck stops. - return SPR_ZONING_INNER_HIGHLIGHT_RED; } @@ -263,24 +264,22 @@ SpriteID TileZoneCheckUnservedBuildingsEvaluation(TileIndex tile, Owner owner) */ SpriteID TileZoneCheckUnservedIndustriesEvaluation(TileIndex tile, Owner owner) { - // TODO: Actually use owner. - if (IsTileType(tile, MP_INDUSTRY)) { Industry *ind = Industry::GetByTile(tile); StationFinder stations(ind->location); - if (stations.GetStations()->Length() > 0) { - return ZONING_INVALID_SPRITE_ID; + for (Station * const *st_iter = stations.GetStations()->Begin(); st_iter != stations.GetStations()->End(); ++st_iter) { + const Station *st = *st_iter; + if (st->owner == owner && st->facilities & (~FACIL_BUS_STOP)) { + return ZONING_INVALID_SPRITE_ID; + } } // For accepted goods - if (IsAreaWithinAcceptanceZoneOfStation(ind->location, owner)) { + if (IsAreaWithinAcceptanceZoneOfStation(ind->location, owner, ~FACIL_BUS_STOP)) { return SPR_ZONING_INNER_HIGHLIGHT_ORANGE; } - // TODO: Check for stations that only accepts mail/passengers, - // which is currently only bus stops. - return SPR_ZONING_INNER_HIGHLIGHT_RED; }