mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Allow overriding town settings on a per-town basis
Add a setting for whether this is allowed for non-privileged multiplayer clients
This commit is contained in:
parent
e1defedb2a
commit
a8361cd608
@ -155,6 +155,7 @@ CommandProc CmdFoundTown;
|
||||
CommandProc CmdRenameTown;
|
||||
CommandProc CmdRenameTownNonAdmin;
|
||||
CommandProc CmdDoTownAction;
|
||||
CommandProc CmdOverrideTownSetting;
|
||||
CommandProc CmdTownGrowthRate;
|
||||
CommandProc CmdTownRating;
|
||||
CommandProc CmdTownCargoGoal;
|
||||
@ -401,6 +402,7 @@ static const Command _command_proc_table[] = {
|
||||
DEF_CMD(CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN
|
||||
DEF_CMD(CmdRenameTownNonAdmin, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_TOWN_NON_ADMIN
|
||||
DEF_CMD(CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DO_TOWN_ACTION
|
||||
DEF_CMD(CmdOverrideTownSetting, 0, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_SETTING_OVERRIDE
|
||||
DEF_CMD(CmdTownCargoGoal, CMD_LOG_AUX | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_CARGO_GOAL
|
||||
DEF_CMD(CmdTownGrowthRate, CMD_LOG_AUX | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_GROWTH_RATE
|
||||
DEF_CMD(CmdTownRating, CMD_LOG_AUX | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_RATING
|
||||
|
@ -347,6 +347,7 @@ enum Commands {
|
||||
CMD_RENAME_TOWN, ///< rename a town
|
||||
CMD_RENAME_TOWN_NON_ADMIN, ///< rename a town, non-admin command
|
||||
CMD_DO_TOWN_ACTION, ///< do a action from the town detail window (like advertises or bribe)
|
||||
CMD_TOWN_SETTING_OVERRIDE, ///< override a town setting
|
||||
CMD_TOWN_CARGO_GOAL, ///< set the goal of a cargo for a town
|
||||
CMD_TOWN_GROWTH_RATE, ///< set the town growth rate
|
||||
CMD_TOWN_RATING, ///< set rating of a company in a town
|
||||
|
@ -1332,6 +1332,8 @@ STR_CONFIG_SETTING_MONEY_CHEAT_MULTIPLAYER :Allow multiplay
|
||||
STR_CONFIG_SETTING_MONEY_CHEAT_MULTIPLAYER_HELPTEXT :If enabled, non-admin multiplayer clients can use the money cheat. The money cheat is always available in single-player mode, and to the multiplayer server admin.
|
||||
STR_CONFIG_SETTING_RENAME_TOWNS_MULTIPLAYER :Allow multiplayer clients to rename towns: {STRING2}
|
||||
STR_CONFIG_SETTING_RENAME_TOWNS_MULTIPLAYER_HELPTEXT :If enabled, non-admin multiplayer clients which are not spectating can rename towns. Renaming towns is always available in single-player mode, and to the multiplayer server admin.
|
||||
STR_CONFIG_SETTING_OVERRIDE_TOWN_SETTINGS_MULTIPLAYER :Allow multiplayer clients to override town settings: {STRING2}
|
||||
STR_CONFIG_SETTING_OVERRIDE_TOWN_SETTINGS_MULTIPLAYER_HELPTEXT :If enabled, non-admin multiplayer clients which are not spectating can override town settings, on a per-town basis. Overriding individual town settings is always available in single-player mode, and to the multiplayer server admin.
|
||||
|
||||
STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Map height limit: {STRING2}
|
||||
STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Set the maximum height of the map terrain. With "(auto)" a good value will be picked after terrain generation
|
||||
@ -4478,6 +4480,17 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Fund th
|
||||
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations.{}Cost: {CURRENCY_LONG}
|
||||
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}Cost: {CURRENCY_LONG}
|
||||
|
||||
###length 4
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_ALLOW_ROADS :Allowed to build roads
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_ALLOW_LEVEL_CROSSINGS :Allowed to level crossings
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_TUNNELS :Allowed to build tunnels
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_MAX_ROAD_SLOPE :Limit building continuous inclined roads
|
||||
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_DEFAULT :Default ({STRING1})
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_STR :{STRING}: {PUSH_COLOUR}{YELLOW}{STRING2}{POP_COLOUR}
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_TEXT :{YELLOW}Override the following setting for this individual town:{}{STRING}{}{STRING}
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_TOOLTIP :{BLACK}Change setting override
|
||||
|
||||
# Goal window
|
||||
STR_GOALS_CAPTION :{WHITE}{COMPANY} Goals
|
||||
STR_GOALS_SPECTATOR_CAPTION :{WHITE}Global Goals
|
||||
|
@ -175,6 +175,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_INDUSTRY_ANIM_MASK, XSCF_IGNORABLE_ALL, 1, 1, "industry_anim_mask", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_NEW_SIGNAL_STYLES, XSCF_NULL, 2, 2, "new_signal_styles", nullptr, nullptr, "XBST,NSID" },
|
||||
{ XSLFI_NO_TREE_COUNTER, XSCF_IGNORABLE_ALL, 1, 1, "no_tree_counter", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TOWN_SETTING_OVERRIDE, XSCF_NULL, 1, 1, "town_setting_override", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_U64_TICK_COUNTER, XSCF_NULL, 1, 1, "u64_tick_counter", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
||||
|
@ -128,6 +128,7 @@ enum SlXvFeatureIndex {
|
||||
XSLFI_INDUSTRY_ANIM_MASK, ///< Industry tile animation masking
|
||||
XSLFI_NEW_SIGNAL_STYLES, ///< New signal styles
|
||||
XSLFI_NO_TREE_COUNTER, ///< No tree counter
|
||||
XSLFI_TOWN_SETTING_OVERRIDE, ///< Town setting overrides
|
||||
|
||||
XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
|
||||
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER
|
||||
|
@ -243,6 +243,11 @@ static const SaveLoad _town_desc[] = {
|
||||
SLE_CONDNULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), ///< cargo_produced, no longer in use
|
||||
SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), ///< cargo_produced, no longer in use
|
||||
SLE_CONDNULL(30, SLV_2, SLV_REMOVE_TOWN_CARGO_CACHE), ///< old reserved space
|
||||
|
||||
SLE_CONDVAR_X(Town, override_flags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TOWN_SETTING_OVERRIDE)),
|
||||
SLE_CONDVAR_X(Town, override_values, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TOWN_SETTING_OVERRIDE)),
|
||||
SLE_CONDVAR_X(Town, build_tunnels, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TOWN_SETTING_OVERRIDE)),
|
||||
SLE_CONDVAR_X(Town, max_road_slope, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TOWN_SETTING_OVERRIDE)),
|
||||
};
|
||||
|
||||
static const SaveLoad _town_supplied_desc[] = {
|
||||
|
@ -1465,6 +1465,11 @@ static void DifficultyRenameTownsMultiplayerChange(int32 new_value)
|
||||
SetWindowClassesDirty(WC_TOWN_VIEW);
|
||||
}
|
||||
|
||||
static void DifficultyOverrideTownSettingsMultiplayerChange(int32 new_value)
|
||||
{
|
||||
SetWindowClassesDirty(WC_TOWN_AUTHORITY);
|
||||
}
|
||||
|
||||
static void MaxNoAIsChange(int32 new_value)
|
||||
{
|
||||
if (GetGameSettings().difficulty.max_no_competitors != 0 &&
|
||||
|
@ -2283,6 +2283,7 @@ static SettingsContainer &GetSettingsTree()
|
||||
ai->Add(new SettingEntry("economy.min_years_for_shares"));
|
||||
ai->Add(new SettingEntry("difficulty.money_cheat_in_multiplayer"));
|
||||
ai->Add(new SettingEntry("difficulty.rename_towns_in_multiplayer"));
|
||||
ai->Add(new SettingEntry("difficulty.override_town_settings_in_multiplayer"));
|
||||
}
|
||||
|
||||
SettingsPage *scenario = main->Add(new SettingsPage(STR_CONFIG_SETTING_SCENARIO_EDITOR));
|
||||
|
@ -97,6 +97,7 @@ struct DifficultySettings {
|
||||
byte town_council_tolerance; ///< minimum required town ratings to be allowed to demolish stuff
|
||||
bool money_cheat_in_multiplayer; ///< is the money cheat permitted for non-admin multiplayer clients
|
||||
bool rename_towns_in_multiplayer; ///< is renaming towns permitted for non-admin multiplayer clients
|
||||
bool override_town_settings_in_multiplayer; ///< is overriding town settings permitted for non-admin multiplayer clients
|
||||
};
|
||||
|
||||
/** Settings relating to viewport/smallmap scrolling. */
|
||||
|
@ -27,6 +27,7 @@ static bool TownCouncilToleranceAdjust(int32 &new_value);
|
||||
static void DifficultyNoiseChange(int32 new_value);
|
||||
static void DifficultyMoneyCheatMultiplayerChange(int32 new_value);
|
||||
static void DifficultyRenameTownsMultiplayerChange(int32 new_value);
|
||||
static void DifficultyOverrideTownSettingsMultiplayerChange(int32 new_value);
|
||||
static void MaxNoAIsChange(int32 new_value);
|
||||
static bool CheckRoadSide(int32 &new_value);
|
||||
static void RoadSideChanged(int32 new_value);
|
||||
@ -476,6 +477,15 @@ post_cb = DifficultyRenameTownsMultiplayerChange
|
||||
cat = SC_EXPERT
|
||||
patxname = ""cheat.difficulty.rename_towns_in_multiplayer""
|
||||
|
||||
[SDT_BOOL]
|
||||
var = difficulty.override_town_settings_in_multiplayer
|
||||
def = false
|
||||
str = STR_CONFIG_SETTING_OVERRIDE_TOWN_SETTINGS_MULTIPLAYER
|
||||
strhelp = STR_CONFIG_SETTING_OVERRIDE_TOWN_SETTINGS_MULTIPLAYER_HELPTEXT
|
||||
post_cb = DifficultyOverrideTownSettingsMultiplayerChange
|
||||
cat = SC_EXPERT
|
||||
patxname = ""cheat.difficulty.override_town_settings_in_multiplayer""
|
||||
|
||||
[SDTG_VAR]
|
||||
name = ""diff_level""
|
||||
var = _old_diff_level
|
||||
|
34
src/town.h
34
src/town.h
@ -59,6 +59,14 @@ struct TownCache {
|
||||
BuildingCounts<uint16> building_counts; ///< The number of each type of building in the town
|
||||
};
|
||||
|
||||
/** Town setting override flags */
|
||||
enum TownSettingOverrideFlags {
|
||||
TSOF_OVERRIDE_BUILD_ROADS = 0,
|
||||
TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS = 1,
|
||||
TSOF_OVERRIDE_BUILD_TUNNELS = 2,
|
||||
TSOF_OVERRIDE_BUILD_INCLINED_ROADS = 3,
|
||||
};
|
||||
|
||||
/** Town data structure. */
|
||||
struct Town : TownPool::PoolItem<&_town_pool> {
|
||||
TileIndex xy; ///< town center tile
|
||||
@ -73,6 +81,12 @@ struct Town : TownPool::PoolItem<&_town_pool> {
|
||||
mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the town, if not using a custom town name
|
||||
|
||||
byte flags; ///< See #TownFlags.
|
||||
|
||||
byte override_flags; ///< Bitmask of enabled flag overrides. See #TownSettingOverrideFlags.
|
||||
byte override_values; ///< Bitmask of flag override values. See #TownSettingOverrideFlags.
|
||||
TownTunnelMode build_tunnels; ///< If/when towns are allowed to build road tunnels (if TSOF_OVERRIDE_BUILD_TUNNELS set in override_flags)
|
||||
uint8 max_road_slope; ///< Maximum number of consecutive sloped road tiles which towns are allowed to build (if TSOF_OVERRIDE_BUILD_INCLINED_ROADS set in override_flags)
|
||||
|
||||
uint16 church_count; ///< Number of church buildings in the town.
|
||||
uint16 stadium_count; ///< Number of stadium buildings in the town.
|
||||
|
||||
@ -173,6 +187,26 @@ struct Town : TownPool::PoolItem<&_town_pool> {
|
||||
return this->cached_name.c_str();
|
||||
}
|
||||
|
||||
inline bool GetAllowBuildRoads() const
|
||||
{
|
||||
return HasBit(this->override_flags, TSOF_OVERRIDE_BUILD_ROADS) ? HasBit(this->override_values, TSOF_OVERRIDE_BUILD_ROADS) : _settings_game.economy.allow_town_roads;
|
||||
}
|
||||
|
||||
inline bool GetAllowBuildLevelCrossings() const
|
||||
{
|
||||
return HasBit(this->override_flags, TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS) ? HasBit(this->override_values, TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS) : _settings_game.economy.allow_town_level_crossings;
|
||||
}
|
||||
|
||||
inline TownTunnelMode GetBuildTunnelMode() const
|
||||
{
|
||||
return HasBit(this->override_flags, TSOF_OVERRIDE_BUILD_TUNNELS) ? this->build_tunnels : _settings_game.economy.town_build_tunnels;
|
||||
}
|
||||
|
||||
inline uint8 GetBuildMaxRoadSlope() const
|
||||
{
|
||||
return HasBit(this->override_flags, TSOF_OVERRIDE_BUILD_INCLINED_ROADS) ? this->max_road_slope : _settings_game.economy.town_max_road_slope;
|
||||
}
|
||||
|
||||
static inline Town *GetByTile(TileIndex tile)
|
||||
{
|
||||
return Town::Get(GetTownIndex(tile));
|
||||
|
@ -67,7 +67,7 @@ static Rect _record_house_rect;
|
||||
TownPool _town_pool("Town");
|
||||
INSTANTIATE_POOL_METHODS(Town)
|
||||
|
||||
static bool CanFollowRoad(TileIndex tile, DiagDirection dir);
|
||||
static bool CanFollowRoad(const Town *t, TileIndex tile, DiagDirection dir);
|
||||
|
||||
TownKdtree _town_kdtree(&Kdtree_TownXYFunc);
|
||||
|
||||
@ -1311,7 +1311,7 @@ static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, con
|
||||
|
||||
/* If the next tile is a railroad track, check if towns are allowed to build level crossings.
|
||||
* If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
|
||||
if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
|
||||
if (IsTileType(next_tile, MP_RAILWAY) && !t->GetAllowBuildLevelCrossings()) return false;
|
||||
|
||||
/* If a road tile can be built, the construction is allowed. */
|
||||
return DoCommand(next_tile, rcmd | (rt << 4), t->index, DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Succeeded();
|
||||
@ -1452,7 +1452,8 @@ static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDi
|
||||
{
|
||||
assert(tunnel_dir < DIAGDIR_END);
|
||||
|
||||
if (_settings_game.economy.town_build_tunnels == TTM_FORBIDDEN) return false;
|
||||
const TownTunnelMode tunnel_mode = t->GetBuildTunnelMode();
|
||||
if (tunnel_mode == TTM_FORBIDDEN) return false;
|
||||
|
||||
Slope slope = GetTileSlope(tile);
|
||||
|
||||
@ -1467,7 +1468,7 @@ static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDi
|
||||
|
||||
/* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
|
||||
if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
|
||||
if (_settings_game.economy.town_build_tunnels != TTM_ALLOWED) return false;
|
||||
if (tunnel_mode != TTM_ALLOWED) return false;
|
||||
|
||||
/* Only tunnel under a mountain if the slope is continuous for at least 4 tiles. We want tunneling to be a last resort for large hills. */
|
||||
TileIndex slope_tile = tile;
|
||||
@ -1571,8 +1572,8 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
* to say that this is the last iteration. */
|
||||
_grow_town_result = GROWTH_SEARCH_STOPPED;
|
||||
|
||||
if (!_settings_game.economy.allow_town_roads && !_generating_world) return;
|
||||
if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, MP_RAILWAY)) return;
|
||||
if (!t1->GetAllowBuildRoads() && !_generating_world) return;
|
||||
if (!t1->GetAllowBuildLevelCrossings() && IsTileType(tile, MP_RAILWAY)) return;
|
||||
if (!MayTownModifyRoad(tile)) return;
|
||||
|
||||
/* Remove hills etc */
|
||||
@ -1618,7 +1619,8 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
break;
|
||||
}
|
||||
|
||||
if (_settings_game.economy.town_max_road_slope > 0 && ((rcmd == ROAD_X) || (rcmd == ROAD_Y))) {
|
||||
const uint8 max_road_slope = t1->GetBuildMaxRoadSlope();
|
||||
if (max_road_slope > 0 && ((rcmd == ROAD_X) || (rcmd == ROAD_Y))) {
|
||||
/* Limit consecutive sloped road tiles */
|
||||
|
||||
auto get_road_slope = [rcmd](TileIndex t) -> Slope {
|
||||
@ -1633,7 +1635,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
const int delta = TileOffsByDiagDir(ReverseDiagDir(target_dir));
|
||||
bool ok = false;
|
||||
TileIndex t = tile;
|
||||
for (uint i = 0; i < _settings_game.economy.town_max_road_slope; i++) {
|
||||
for (uint i = 0; i < max_road_slope; i++) {
|
||||
t += delta;
|
||||
if (!IsValidTile(t) || !IsNormalRoadTile(t) || GetRoadBits(t, RTT_ROAD) != rcmd || get_road_slope(t) != slope) {
|
||||
ok = true;
|
||||
@ -1653,7 +1655,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
* the fitting RoadBits */
|
||||
_grow_town_result = GROWTH_SEARCH_STOPPED;
|
||||
|
||||
if (!_settings_game.economy.allow_town_roads && !_generating_world) return;
|
||||
if (!t1->GetAllowBuildRoads() && !_generating_world) return;
|
||||
|
||||
switch (t1->layout) {
|
||||
default: NOT_REACHED();
|
||||
@ -1691,7 +1693,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
target_bits = DiagDirToRoadBits(target_dir);
|
||||
} while (!(cur_rb & target_bits));
|
||||
cur_rb &= ~target_bits;
|
||||
} while (!(target_dir == GetTunnelBridgeDirection(tile) || CanFollowRoad(tile, target_dir)));
|
||||
} while (!(target_dir == GetTunnelBridgeDirection(tile) || CanFollowRoad(t1, tile, target_dir)));
|
||||
if (target_dir == GetTunnelBridgeDirection(tile)) {
|
||||
/* cross the bridge */
|
||||
*tile_ptr = GetOtherTunnelBridgeEnd(tile);
|
||||
@ -1746,7 +1748,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
|
||||
if (!IsValidTile(house_tile)) return;
|
||||
|
||||
if (target_dir != DIAGDIR_END && (_settings_game.economy.allow_town_roads || _generating_world)) {
|
||||
if (target_dir != DIAGDIR_END && (t1->GetAllowBuildRoads() || _generating_world)) {
|
||||
switch (t1->layout) {
|
||||
default: NOT_REACHED();
|
||||
|
||||
@ -1811,18 +1813,19 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t
|
||||
/**
|
||||
* Checks whether a road can be followed or is a dead end, that can not be extended to the next tile.
|
||||
* This only checks trivial but often cases.
|
||||
* @param t Town doing the following
|
||||
* @param tile Start tile for road.
|
||||
* @param dir Direction for road to follow or build.
|
||||
* @return true If road is or can be connected in the specified direction.
|
||||
*/
|
||||
static bool CanFollowRoad(TileIndex tile, DiagDirection dir)
|
||||
static bool CanFollowRoad(const Town *t, TileIndex tile, DiagDirection dir)
|
||||
{
|
||||
TileIndex target_tile = tile + TileOffsByDiagDir(dir);
|
||||
if (!IsValidTile(target_tile)) return false;
|
||||
if (HasTileWaterGround(target_tile)) return false;
|
||||
|
||||
RoadBits target_rb = GetTownRoadBits(target_tile);
|
||||
if (_settings_game.economy.allow_town_roads || _generating_world) {
|
||||
if (t->GetAllowBuildRoads() || _generating_world) {
|
||||
/* Check whether a road connection exists or can be build. */
|
||||
switch (GetTileType(target_tile)) {
|
||||
case MP_ROAD:
|
||||
@ -1922,7 +1925,7 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
target_bits = DiagDirToRoadBits(target_dir);
|
||||
} while (!(cur_rb & target_bits));
|
||||
cur_rb &= ~target_bits;
|
||||
} while (!CanFollowRoad(tile, target_dir));
|
||||
} while (!CanFollowRoad(t, tile, target_dir));
|
||||
}
|
||||
tile = TileAddByDiagDir(tile, target_dir);
|
||||
|
||||
@ -2001,7 +2004,7 @@ static bool GrowTown(Town *t)
|
||||
|
||||
/* No road available, try to build a random road block by
|
||||
* clearing some land and then building a road there. */
|
||||
if (_settings_game.economy.allow_town_roads || _generating_world) {
|
||||
if (t->GetAllowBuildRoads() || _generating_world) {
|
||||
tile = t->xy;
|
||||
for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
|
||||
/* Only work with plain land that not already has a house */
|
||||
@ -2789,7 +2792,7 @@ static inline CommandCost IsAnotherHouseTypeAllowedInTown(Town *t, HouseID house
|
||||
static inline bool TownLayoutAllowsHouseHere(Town *t, const TileArea &ta)
|
||||
{
|
||||
/* Allow towns everywhere when we don't build roads */
|
||||
if (!_settings_game.economy.allow_town_roads && !_generating_world) return true;
|
||||
if (!t->GetAllowBuildRoads() && !_generating_world) return true;
|
||||
|
||||
TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, ta.tile);
|
||||
|
||||
@ -3792,6 +3795,67 @@ CommandCost CmdDoTownAction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override a town setting
|
||||
* @param tile unused
|
||||
* @param flags type of operation
|
||||
* @param p1 town to do the action at
|
||||
* @param p2 various bitstuffed elements
|
||||
* - p2 = (bit 0 - 7) - what setting to change
|
||||
* - p2 = (bit 8 - 15) - the data to modify
|
||||
* - p2 = (bit 16) - whether to override the value, or use the default
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdOverrideTownSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||
{
|
||||
if (_networking && !_settings_game.difficulty.override_town_settings_in_multiplayer) return CMD_ERROR;
|
||||
|
||||
Town *t = Town::GetIfValid(p1);
|
||||
if (t == nullptr) return CMD_ERROR;
|
||||
|
||||
const uint8 setting = GB(p2, 0, 8);
|
||||
const bool is_override = HasBit(p2, 16);
|
||||
const uint8 value = GB(p2, 8, 8);
|
||||
switch (setting) {
|
||||
case TSOF_OVERRIDE_BUILD_ROADS:
|
||||
case TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS:
|
||||
if (is_override && value != 0 && value != 1) return CMD_ERROR;
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_TUNNELS:
|
||||
if (is_override && value >= TTM_END) return CMD_ERROR;
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_INCLINED_ROADS:
|
||||
if (is_override && value > 8) return CMD_ERROR;
|
||||
break;
|
||||
default:
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
SB(t->override_flags, setting, 1, is_override ? 1 : 0);
|
||||
if (is_override) {
|
||||
switch (setting) {
|
||||
case TSOF_OVERRIDE_BUILD_ROADS:
|
||||
case TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS:
|
||||
SB(t->override_values, setting, 1, value & 1);
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_TUNNELS:
|
||||
t->build_tunnels = (TownTunnelMode)value;
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_INCLINED_ROADS:
|
||||
t->max_road_slope = value;
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
SetWindowDirty(WC_TOWN_AUTHORITY, p1);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
static void ForAllStationsNearTown(Town *t, Func func)
|
||||
{
|
||||
|
189
src/town_gui.cpp
189
src/town_gui.cpp
@ -68,7 +68,10 @@ static const NWidgetPart _nested_town_authority_widgets[] = {
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_ACTION_INFO), SetMinimalSize(317, 52), SetResize(1, 0), EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TA_EXECUTE), SetMinimalSize(317, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP),
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TA_BTN_SEL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TA_EXECUTE), SetMinimalSize(317, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_TA_SETTING), SetMinimalSize(317, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BLACK_STRING1, STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
|
||||
EndContainer()
|
||||
};
|
||||
@ -101,6 +104,14 @@ private:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool ChangeSettingsDisabled()
|
||||
{
|
||||
return _networking && !(_network_server || _network_settings_access) &&
|
||||
!(_local_company != COMPANY_SPECTATOR && _settings_game.difficulty.override_town_settings_in_multiplayer);
|
||||
}
|
||||
|
||||
static const uint SETTING_OVERRIDE_COUNT = 4;
|
||||
|
||||
public:
|
||||
TownAuthorityWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), sel_index(-1), displayed_actions_on_previous_painting(0)
|
||||
{
|
||||
@ -114,17 +125,20 @@ public:
|
||||
{
|
||||
int numact;
|
||||
uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town);
|
||||
numact += SETTING_OVERRIDE_COUNT;
|
||||
if (buttons != displayed_actions_on_previous_painting) this->SetDirty();
|
||||
displayed_actions_on_previous_painting = buttons;
|
||||
|
||||
this->vscroll->SetCount(numact + 1);
|
||||
|
||||
if (this->sel_index != -1 && !HasBit(buttons, this->sel_index)) {
|
||||
if (this->sel_index != -1 && this->sel_index < 0x100 && !HasBit(buttons, this->sel_index)) {
|
||||
this->sel_index = -1;
|
||||
}
|
||||
|
||||
this->SetWidgetLoweredState(WID_TA_ZONE_BUTTON, this->town->show_zone);
|
||||
this->SetWidgetDisabledState(WID_TA_EXECUTE, this->sel_index == -1);
|
||||
this->SetWidgetDisabledState(WID_TA_EXECUTE, this->sel_index == -1 || this->sel_index >= 0x100);
|
||||
this->SetWidgetDisabledState(WID_TA_SETTING, ChangeSettingsDisabled());
|
||||
this->GetWidget<NWidgetStacked>(WID_TA_BTN_SEL)->SetDisplayedPlane(this->sel_index >= 0x100 ? 1 : 0);
|
||||
|
||||
this->DrawWidgets();
|
||||
if (!this->IsShaded()) this->DrawRatings();
|
||||
@ -193,7 +207,31 @@ public:
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
{
|
||||
if (widget == WID_TA_CAPTION) SetDParam(0, this->window_number);
|
||||
if (widget == WID_TA_CAPTION) {
|
||||
SetDParam(0, this->window_number);
|
||||
} else if (widget == WID_TA_SETTING) {
|
||||
SetDParam(0, STR_EMPTY);
|
||||
if (this->sel_index >= 0x100 && this->sel_index < (int)(0x100 + SETTING_OVERRIDE_COUNT)) {
|
||||
if (!HasBit(this->town->override_flags, this->sel_index - 0x100)) {
|
||||
SetDParam(0, STR_COLOUR_DEFAULT);
|
||||
} else {
|
||||
int idx = this->sel_index - 0x100;
|
||||
switch (idx) {
|
||||
case TSOF_OVERRIDE_BUILD_ROADS:
|
||||
case TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS:
|
||||
SetDParam(0, HasBit(this->town->override_values, idx) ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_TUNNELS:
|
||||
SetDParam(0, STR_CONFIG_SETTING_TOWN_TUNNELS_FORBIDDEN + this->town->build_tunnels);
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_INCLINED_ROADS:
|
||||
SetDParam(0, STR_CONFIG_SETTING_TOWN_MAX_ROAD_SLOPE_VALUE + ((this->town->max_road_slope == 0) ? 1 : 0));
|
||||
SetDParam(1, this->town->max_road_slope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
@ -201,14 +239,36 @@ public:
|
||||
switch (widget) {
|
||||
case WID_TA_ACTION_INFO:
|
||||
if (this->sel_index != -1) {
|
||||
SetDParam(0, _price[PR_TOWN_ACTION] * _town_action_costs[this->sel_index] >> 8);
|
||||
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM,
|
||||
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING + this->sel_index);
|
||||
StringID text = STR_NULL;
|
||||
if (this->sel_index >= 0x100) {
|
||||
SetDParam(1, STR_EMPTY);
|
||||
switch (this->sel_index - 0x100) {
|
||||
case TSOF_OVERRIDE_BUILD_ROADS:
|
||||
SetDParam(1, STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT);
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS:
|
||||
SetDParam(1, STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT);
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_TUNNELS:
|
||||
SetDParam(1, STR_CONFIG_SETTING_TOWN_TUNNELS_HELPTEXT);
|
||||
break;
|
||||
case TSOF_OVERRIDE_BUILD_INCLINED_ROADS:
|
||||
SetDParam(1, STR_CONFIG_SETTING_TOWN_MAX_ROAD_SLOPE_HELPTEXT);
|
||||
break;
|
||||
}
|
||||
text = STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_TEXT;
|
||||
SetDParam(0, STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_ALLOW_ROADS + this->sel_index - 0x100);
|
||||
} else {
|
||||
text = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING + this->sel_index;
|
||||
SetDParam(0, _price[PR_TOWN_ACTION] * _town_action_costs[this->sel_index] >> 8);
|
||||
}
|
||||
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, text);
|
||||
}
|
||||
break;
|
||||
case WID_TA_COMMAND_LIST: {
|
||||
int numact;
|
||||
uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town);
|
||||
numact += SETTING_OVERRIDE_COUNT;
|
||||
int y = r.top + WD_FRAMERECT_TOP;
|
||||
int pos = this->vscroll->GetPosition();
|
||||
|
||||
@ -218,14 +278,47 @@ public:
|
||||
}
|
||||
|
||||
for (int i = 0; buttons; i++, buttons >>= 1) {
|
||||
if (pos <= -5) break; ///< Draw only the 5 fitting lines
|
||||
|
||||
if ((buttons & 1) && --pos < 0) {
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y,
|
||||
STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i, this->sel_index == i ? TC_WHITE : TC_ORANGE);
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < (int)SETTING_OVERRIDE_COUNT; i++) {
|
||||
if (--pos < 0) {
|
||||
const bool disabled = ChangeSettingsDisabled();
|
||||
const bool selected = (this->sel_index == (0x100 + i));
|
||||
const TextColour tc = disabled ? (TC_NO_SHADE | (selected ? TC_SILVER : TC_GREY)) : (selected ? TC_WHITE : TC_ORANGE);
|
||||
const bool overriden = HasBit(this->town->override_flags, i);
|
||||
SetDParam(0, STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_ALLOW_ROADS + i);
|
||||
SetDParam(1, overriden ? STR_JUST_STRING1 : STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_DEFAULT);
|
||||
switch (i) {
|
||||
case TSOF_OVERRIDE_BUILD_ROADS:
|
||||
SetDParam(2, this->town->GetAllowBuildRoads() ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
|
||||
break;
|
||||
|
||||
case TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS:
|
||||
SetDParam(2, this->town->GetAllowBuildLevelCrossings() ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
|
||||
break;
|
||||
|
||||
case TSOF_OVERRIDE_BUILD_TUNNELS: {
|
||||
TownTunnelMode tunnel_mode = this->town->GetBuildTunnelMode();
|
||||
SetDParam(2, STR_CONFIG_SETTING_TOWN_TUNNELS_FORBIDDEN + tunnel_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
case TSOF_OVERRIDE_BUILD_INCLINED_ROADS: {
|
||||
uint8 max_slope = this->town->GetBuildMaxRoadSlope();
|
||||
SetDParam(2, STR_CONFIG_SETTING_TOWN_MAX_ROAD_SLOPE_VALUE + ((max_slope == 0) ? 1 : 0));
|
||||
SetDParam(3, max_slope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y,
|
||||
STR_LOCAL_AUTHORITY_SETTING_OVERRIDE_STR, tc);
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -250,7 +343,7 @@ public:
|
||||
}
|
||||
|
||||
case WID_TA_COMMAND_LIST:
|
||||
size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
|
||||
size->height = WD_FRAMERECT_TOP + (5 + SETTING_OVERRIDE_COUNT) * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
|
||||
size->width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width;
|
||||
for (uint i = 0; i < TACT_COUNT; i++ ) {
|
||||
size->width = std::max(size->width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i).width);
|
||||
@ -283,10 +376,16 @@ public:
|
||||
|
||||
case WID_TA_COMMAND_LIST: {
|
||||
int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, FONT_HEIGHT_NORMAL);
|
||||
if (!IsInsideMM(y, 0, 5)) return;
|
||||
if (!IsInsideMM(y, 0, 5 + SETTING_OVERRIDE_COUNT)) return;
|
||||
|
||||
y = GetNthSetBit(GetMaskOfTownActions(nullptr, _local_company, this->town), y + this->vscroll->GetPosition() - 1);
|
||||
if (y >= 0) {
|
||||
const uint setting_override_offset = 32 - SETTING_OVERRIDE_COUNT;
|
||||
|
||||
y = GetNthSetBit(GetMaskOfTownActions(nullptr, _local_company, this->town) | (UINT32_MAX << setting_override_offset), y + this->vscroll->GetPosition() - 1);
|
||||
if (y >= (int)setting_override_offset) {
|
||||
this->sel_index = y + 0x100 - setting_override_offset;
|
||||
this->SetDirty();
|
||||
break;
|
||||
} else if (y >= 0) {
|
||||
this->sel_index = y;
|
||||
this->SetDirty();
|
||||
}
|
||||
@ -298,9 +397,71 @@ public:
|
||||
case WID_TA_EXECUTE:
|
||||
DoCommandP(this->town->xy, this->window_number, this->sel_index, CMD_DO_TOWN_ACTION | CMD_MSG(STR_ERROR_CAN_T_DO_THIS));
|
||||
break;
|
||||
|
||||
case WID_TA_SETTING: {
|
||||
uint8 idx = this->sel_index - 0x100;
|
||||
switch (idx) {
|
||||
case TSOF_OVERRIDE_BUILD_ROADS:
|
||||
case TSOF_OVERRIDE_BUILD_LEVEL_CROSSINGS: {
|
||||
int value = HasBit(this->town->override_flags, idx) ? (HasBit(this->town->override_values, idx) ? 2 : 1) : 0;
|
||||
const StringID names[] = {
|
||||
STR_COLOUR_DEFAULT,
|
||||
STR_CONFIG_SETTING_OFF,
|
||||
STR_CONFIG_SETTING_ON,
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
ShowDropDownMenu(this, names, value, WID_TA_SETTING, 0, 0);
|
||||
break;
|
||||
}
|
||||
case TSOF_OVERRIDE_BUILD_TUNNELS: {
|
||||
const StringID names[] = {
|
||||
STR_COLOUR_DEFAULT,
|
||||
STR_CONFIG_SETTING_TOWN_TUNNELS_FORBIDDEN,
|
||||
STR_CONFIG_SETTING_TOWN_TUNNELS_ALLOWED_OBSTRUCTION,
|
||||
STR_CONFIG_SETTING_TOWN_TUNNELS_ALLOWED,
|
||||
INVALID_STRING_ID
|
||||
};
|
||||
ShowDropDownMenu(this, names, HasBit(this->town->override_flags, idx) ? this->town->build_tunnels + 1 : 0, WID_TA_SETTING, 0, 0);
|
||||
break;
|
||||
}
|
||||
case TSOF_OVERRIDE_BUILD_INCLINED_ROADS:
|
||||
DropDownList dlist;
|
||||
dlist.emplace_back(new DropDownListStringItem(STR_COLOUR_DEFAULT, 0, false));
|
||||
dlist.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TOWN_MAX_ROAD_SLOPE_ZERO, 1, false));
|
||||
for (int i = 1; i <= 8; i++) {
|
||||
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_CONFIG_SETTING_TOWN_MAX_ROAD_SLOPE_VALUE, i + 1, false);
|
||||
item->SetParam(0, i);
|
||||
dlist.emplace_back(item);
|
||||
}
|
||||
ShowDropDownList(this, std::move(dlist), HasBit(this->town->override_flags, idx) ? this->town->max_road_slope + 1 : 0, WID_TA_SETTING);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TA_SETTING: {
|
||||
if (index < 0) break;
|
||||
uint32 p2 = this->sel_index - 0x100;
|
||||
if (index > 0) {
|
||||
SetBit(p2, 16);
|
||||
p2 |= (index - 1) << 8;
|
||||
}
|
||||
DoCommandP(this->town->xy, this->window_number, p2, CMD_TOWN_SETTING_OVERRIDE | CMD_MSG(STR_ERROR_CAN_T_DO_THIS));
|
||||
break;
|
||||
}
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
void OnHundredthTick() override
|
||||
{
|
||||
this->SetDirty();
|
||||
@ -477,7 +638,7 @@ public:
|
||||
/* Warn the user if towns are not allowed to build roads, but do this only once per OpenTTD run. */
|
||||
static bool _warn_town_no_roads = false;
|
||||
|
||||
if (!_settings_game.economy.allow_town_roads && !_warn_town_no_roads) {
|
||||
if (!Town::Get(this->window_number)->GetAllowBuildRoads() && !_warn_town_no_roads) {
|
||||
ShowErrorMessage(STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS, INVALID_STRING_ID, WL_WARNING);
|
||||
_warn_town_no_roads = true;
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ enum TownAuthorityWidgets {
|
||||
WID_TA_SCROLLBAR, ///< Scrollbar of the list of commands.
|
||||
WID_TA_ACTION_INFO, ///< Additional information about the action.
|
||||
WID_TA_EXECUTE, ///< Do-it button.
|
||||
WID_TA_SETTING, ///< Setting drop-down.
|
||||
WID_TA_BTN_SEL, ///< Button selector.
|
||||
};
|
||||
|
||||
/** Widgets of the #TownViewWindow class. */
|
||||
|
Loading…
Reference in New Issue
Block a user