mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
3 Commits
207f1279cc
...
67bb5fc5c5
Author | SHA1 | Date |
---|---|---|
|
67bb5fc5c5 | |
|
a8650c6b06 | |
|
7bb4940ebd |
|
@ -454,6 +454,7 @@ add_files(
|
|||
spritecache.cpp
|
||||
spritecache.h
|
||||
spritecache_internal.h
|
||||
spritecache_type.h
|
||||
station.cpp
|
||||
station_base.h
|
||||
station_cmd.cpp
|
||||
|
|
|
@ -83,7 +83,7 @@ void AIInstance::Died()
|
|||
|
||||
void AIInstance::LoadDummyScript()
|
||||
{
|
||||
ScriptAllocatorScope alloc_scope(this->engine);
|
||||
ScriptAllocatorScope alloc_scope(this->engine.get());
|
||||
Script_CreateDummy(this->engine->GetVM(), STR_ERROR_AI_NO_AI_FOUND, "AI");
|
||||
}
|
||||
|
||||
|
|
|
@ -3689,10 +3689,15 @@ STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}Town gro
|
|||
STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}Town is {RED}not{BLACK} growing
|
||||
STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA}
|
||||
STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centre the main view on town location. Ctrl+Click to open a new viewport on town location
|
||||
STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Local Authority
|
||||
STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}Show information on local authority
|
||||
STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Change town name
|
||||
|
||||
STR_TOWN_VIEW_INFO :Information
|
||||
STR_TOWN_VIEW_INFO_TOOLTIP :Switch to town information tab
|
||||
STR_TOWN_VIEW_RATINGS :Ratings
|
||||
STR_TOWN_VIEW_RATINGS_TOOLTIP :Switch to local authority ratings tab
|
||||
STR_TOWN_VIEW_ACTIONS :Actions
|
||||
STR_TOWN_VIEW_ACTIONS_TOOLTIP :Switch to local authority actions tab
|
||||
|
||||
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Expand
|
||||
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Increase size of town
|
||||
STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Expand buildings
|
||||
|
@ -3704,8 +3709,6 @@ STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Delete t
|
|||
|
||||
STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Rename Town
|
||||
|
||||
# Town local authority window
|
||||
STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} local authority
|
||||
STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone
|
||||
STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Show zone within local authority boundaries
|
||||
STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transport company ratings:
|
||||
|
|
|
@ -605,7 +605,7 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlags flags)
|
|||
if (flags.Test(DoCommandFlag::Execute)) {
|
||||
Town *town = o->town;
|
||||
town->statues.Reset(GetTileOwner(tile));
|
||||
SetWindowDirty(WC_TOWN_AUTHORITY, town->index);
|
||||
SetWindowDirty(WC_TOWN_VIEW, town->index);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -888,7 +888,7 @@ static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_ow
|
|||
do_clear = true;
|
||||
}
|
||||
|
||||
SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
|
||||
SetWindowDirty(WC_TOWN_VIEW, t->index);
|
||||
} else {
|
||||
do_clear = true;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ static ScriptStorage &GetStorage()
|
|||
|
||||
/* static */ ScriptInstance *ScriptObject::ActiveInstance::active = nullptr;
|
||||
|
||||
ScriptObject::ActiveInstance::ActiveInstance(ScriptInstance &instance) : alc_scope(instance.engine)
|
||||
ScriptObject::ActiveInstance::ActiveInstance(ScriptInstance &instance) : alc_scope(instance.engine.get())
|
||||
{
|
||||
this->last_active = ScriptObject::ActiveInstance::active;
|
||||
ScriptObject::ActiveInstance::active = &instance;
|
||||
|
@ -230,8 +230,8 @@ ScriptObject::DisableDoCommandScope::DisableDoCommandScope()
|
|||
|
||||
/* static */ bool ScriptObject::CanSuspend()
|
||||
{
|
||||
Squirrel *squirrel = ScriptObject::GetActiveInstance().engine;
|
||||
return GetStorage().allow_do_command && squirrel->CanSuspend();
|
||||
Squirrel &squirrel = *ScriptObject::GetActiveInstance().engine;
|
||||
return GetStorage().allow_do_command && squirrel.CanSuspend();
|
||||
}
|
||||
|
||||
/* static */ ScriptEventQueue &ScriptObject::GetEventQueue()
|
||||
|
|
|
@ -50,8 +50,8 @@ static void PrintFunc(bool error_msg, std::string_view message)
|
|||
|
||||
ScriptInstance::ScriptInstance(std::string_view api_name)
|
||||
{
|
||||
this->storage = new ScriptStorage();
|
||||
this->engine = new Squirrel(api_name);
|
||||
this->storage = std::make_unique<ScriptStorage>();
|
||||
this->engine = std::make_unique<Squirrel>(api_name);
|
||||
this->engine->SetPrintFunction(&PrintFunc);
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,10 @@ void ScriptInstance::Initialize(const std::string &main_script, const std::strin
|
|||
{
|
||||
ScriptObject::ActiveInstance active(*this);
|
||||
|
||||
this->controller = new ScriptController(company);
|
||||
this->controller = std::make_unique<ScriptController>(company);
|
||||
|
||||
/* Register the API functions and classes */
|
||||
this->engine->SetGlobalPointer(this->engine);
|
||||
this->engine->SetGlobalPointer(this->engine.get());
|
||||
this->RegisterAPI();
|
||||
if (this->IsDead()) {
|
||||
/* Failed to register API; a message has already been logged. */
|
||||
|
@ -81,12 +81,11 @@ void ScriptInstance::Initialize(const std::string &main_script, const std::strin
|
|||
}
|
||||
|
||||
/* Create the main-class */
|
||||
this->instance = new SQObject();
|
||||
if (!this->engine->CreateClassInstance(instance_name, this->controller, this->instance)) {
|
||||
this->instance = std::make_unique<SQObject>();
|
||||
if (!this->engine->CreateClassInstance(instance_name, this->controller.get(), this->instance.get())) {
|
||||
/* If CreateClassInstance has returned false instance has not been
|
||||
* registered with squirrel, so avoid trying to Release it by clearing it now */
|
||||
delete this->instance;
|
||||
this->instance = nullptr;
|
||||
this->instance.reset();
|
||||
this->Died();
|
||||
return;
|
||||
}
|
||||
|
@ -158,11 +157,10 @@ ScriptInstance::~ScriptInstance()
|
|||
ScriptObject::ActiveInstance active(*this);
|
||||
this->in_shutdown = true;
|
||||
|
||||
if (instance != nullptr) this->engine->ReleaseObject(this->instance);
|
||||
if (engine != nullptr) delete this->engine;
|
||||
delete this->storage;
|
||||
delete this->controller;
|
||||
delete this->instance;
|
||||
if (instance != nullptr) this->engine->ReleaseObject(this->instance.get());
|
||||
|
||||
/* Engine must be reset explicitly in scope of the active instance. */
|
||||
this->engine.reset();
|
||||
}
|
||||
|
||||
void ScriptInstance::Continue()
|
||||
|
@ -179,11 +177,9 @@ void ScriptInstance::Died()
|
|||
|
||||
this->last_allocated_memory = this->GetAllocatedMemory(); // Update cache
|
||||
|
||||
if (this->instance != nullptr) this->engine->ReleaseObject(this->instance);
|
||||
delete this->instance;
|
||||
delete this->engine;
|
||||
this->instance = nullptr;
|
||||
this->engine = nullptr;
|
||||
if (this->instance != nullptr) this->engine->ReleaseObject(this->instance.get());
|
||||
this->engine.reset();
|
||||
this->instance.reset();
|
||||
}
|
||||
|
||||
void ScriptInstance::GameLoop()
|
||||
|
|
|
@ -256,7 +256,7 @@ public:
|
|||
void ReleaseSQObject(HSQOBJECT *obj);
|
||||
|
||||
protected:
|
||||
class Squirrel *engine = nullptr; ///< A wrapper around the squirrel vm.
|
||||
std::unique_ptr<class Squirrel> engine; ///< A wrapper around the squirrel vm.
|
||||
std::string api_version{}; ///< Current API used by this script.
|
||||
|
||||
/**
|
||||
|
@ -288,9 +288,9 @@ protected:
|
|||
virtual void LoadDummyScript() = 0;
|
||||
|
||||
private:
|
||||
class ScriptController *controller = nullptr; ///< The script main class.
|
||||
class ScriptStorage *storage = nullptr; ///< Some global information for each running script.
|
||||
SQObject *instance = nullptr; ///< Squirrel-pointer to the script main class.
|
||||
std::unique_ptr<class ScriptStorage> storage; ///< Some global information for each running script.
|
||||
std::unique_ptr<class ScriptController> controller; ///< The script main class.
|
||||
std::unique_ptr<SQObject> instance; ///< Squirrel-pointer to the script main class.
|
||||
|
||||
bool is_started = false; ///< Is the scripts constructor executed?
|
||||
bool is_dead = false; ///< True if the script has been stopped.
|
||||
|
|
|
@ -535,7 +535,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty
|
|||
|
||||
struct GrfSpriteOffset {
|
||||
size_t file_pos;
|
||||
uint8_t control_flags;
|
||||
SpriteCacheCtrlFlags control_flags{};
|
||||
};
|
||||
|
||||
/** Map from sprite numbers to position in the GRF file. */
|
||||
|
@ -565,7 +565,7 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
|
|||
size_t old_pos = file.GetPos();
|
||||
file.SeekTo(data_offset, SEEK_CUR);
|
||||
|
||||
GrfSpriteOffset offset = { 0, 0 };
|
||||
GrfSpriteOffset offset{0};
|
||||
|
||||
/* Loop over all sprite section entries and store the file
|
||||
* offset for each newly encountered ID. */
|
||||
|
@ -574,7 +574,6 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
|
|||
if (id != prev_id) {
|
||||
_grf_sprite_offsets[prev_id] = offset;
|
||||
offset.file_pos = file.GetPos() - 4;
|
||||
offset.control_flags = 0;
|
||||
}
|
||||
prev_id = id;
|
||||
uint length = file.ReadDword();
|
||||
|
@ -585,11 +584,11 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
|
|||
uint8_t zoom = file.ReadByte();
|
||||
length--;
|
||||
if (colour.Any() && zoom == 0) { // ZoomLevel::Normal (normal zoom)
|
||||
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL);
|
||||
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
|
||||
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal);
|
||||
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
|
||||
}
|
||||
if (colour.Any() && zoom == 2) { // ZoomLevel::In2x (2x zoomed in)
|
||||
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
|
||||
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -621,7 +620,7 @@ bool LoadNextSprite(SpriteID load_index, SpriteFile &file, uint file_sprite_id)
|
|||
uint8_t grf_type = file.ReadByte();
|
||||
|
||||
SpriteType type;
|
||||
uint8_t control_flags = 0;
|
||||
SpriteCacheCtrlFlags control_flags;
|
||||
if (grf_type == 0xFF) {
|
||||
/* Some NewGRF files have "empty" pseudo-sprites which are 1
|
||||
* byte long. Catch these so the sprites won't be displayed. */
|
||||
|
|
|
@ -11,24 +11,9 @@
|
|||
#define SPRITECACHE_H
|
||||
|
||||
#include "gfx_type.h"
|
||||
#include "spritecache_type.h"
|
||||
#include "spriteloader/spriteloader.hpp"
|
||||
|
||||
/** Data structure describing a sprite. */
|
||||
struct Sprite {
|
||||
uint16_t height; ///< Height of the sprite.
|
||||
uint16_t width; ///< Width of the sprite.
|
||||
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
|
||||
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
|
||||
std::byte data[]; ///< Sprite data.
|
||||
};
|
||||
|
||||
enum SpriteCacheCtrlFlags : uint8_t {
|
||||
SCCF_ALLOW_ZOOM_MIN_1X_PAL = 0, ///< Allow use of sprite min zoom setting at 1x in palette mode.
|
||||
SCCF_ALLOW_ZOOM_MIN_1X_32BPP = 1, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
|
||||
SCCF_ALLOW_ZOOM_MIN_2X_PAL = 2, ///< Allow use of sprite min zoom setting at 2x in palette mode.
|
||||
SCCF_ALLOW_ZOOM_MIN_2X_32BPP = 3, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
|
||||
};
|
||||
|
||||
extern uint _sprite_cache_size;
|
||||
|
||||
/** SpriteAllocator that allocates memory via a unique_ptr array. */
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "core/math_func.hpp"
|
||||
#include "gfx_type.h"
|
||||
#include "spritecache_type.h"
|
||||
#include "spriteloader/spriteloader.hpp"
|
||||
|
||||
#include "table/sprites.h"
|
||||
|
@ -27,7 +28,7 @@ struct SpriteCache {
|
|||
uint32_t lru = 0;
|
||||
SpriteType type = SpriteType::Invalid; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
|
||||
bool warned = false; ///< True iff the user has been warned about incorrect use of this sprite
|
||||
uint8_t control_flags = 0; ///< Control flags, see SpriteCacheCtrlFlags
|
||||
SpriteCacheCtrlFlags control_flags{}; ///< Control flags, see SpriteCacheCtrlFlags
|
||||
|
||||
void ClearSpriteData();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file spritecache_type.h Types related to the sprite cache. */
|
||||
|
||||
#ifndef SPRITECACHE_TYPE_H
|
||||
#define SPRITECACHE_TYPE_H
|
||||
|
||||
#include "core/enum_type.hpp"
|
||||
|
||||
/** Data structure describing a sprite. */
|
||||
struct Sprite {
|
||||
uint16_t height; ///< Height of the sprite.
|
||||
uint16_t width; ///< Width of the sprite.
|
||||
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
|
||||
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
|
||||
std::byte data[]; ///< Sprite data.
|
||||
};
|
||||
|
||||
enum class SpriteCacheCtrlFlag : uint8_t {
|
||||
AllowZoomMin1xPal, ///< Allow use of sprite min zoom setting at 1x in palette mode.
|
||||
AllowZoomMin1x32bpp, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
|
||||
AllowZoomMin2xPal, ///< Allow use of sprite min zoom setting at 2x in palette mode.
|
||||
AllowZoomMin2x32bpp, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
|
||||
};
|
||||
|
||||
using SpriteCacheCtrlFlags = EnumBitSet<SpriteCacheCtrlFlag, uint8_t>;
|
||||
|
||||
#endif /* SPRITECACHE_TYPE_H */
|
|
@ -256,7 +256,7 @@ static ZoomLevels LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFil
|
|||
return {};
|
||||
}
|
||||
|
||||
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||
{
|
||||
static const ZoomLevel zoom_lvl_map[6] = {ZoomLevel::Normal, ZoomLevel::In4x, ZoomLevel::In2x, ZoomLevel::Out2x, ZoomLevel::Out4x, ZoomLevel::Out8x};
|
||||
|
||||
|
@ -295,11 +295,11 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
|
|||
is_wanted_zoom_lvl = true;
|
||||
ZoomLevel zoom_min = sprite_type == SpriteType::Font ? ZoomLevel::Min : _settings_client.gui.sprite_zoom_min;
|
||||
if (zoom_min >= ZoomLevel::In2x &&
|
||||
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl < ZoomLevel::In2x) {
|
||||
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal) && zoom_lvl < ZoomLevel::In2x) {
|
||||
is_wanted_zoom_lvl = false;
|
||||
}
|
||||
if (zoom_min >= ZoomLevel::Normal &&
|
||||
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl < ZoomLevel::Normal) {
|
||||
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal) && zoom_lvl < ZoomLevel::Normal) {
|
||||
is_wanted_zoom_lvl = false;
|
||||
}
|
||||
} else {
|
||||
|
@ -359,7 +359,7 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
|
|||
return loaded_sprites;
|
||||
}
|
||||
|
||||
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||
{
|
||||
if (this->container_ver >= 2) {
|
||||
return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, control_flags, avail_8bpp, avail_32bpp);
|
||||
|
|
|
@ -17,7 +17,7 @@ class SpriteLoaderGrf : public SpriteLoader {
|
|||
uint8_t container_ver;
|
||||
public:
|
||||
SpriteLoaderGrf(uint8_t container_ver) : container_ver(container_ver) {}
|
||||
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
||||
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
||||
};
|
||||
|
||||
#endif /* SPRITELOADER_GRF_HPP */
|
||||
|
|
|
@ -48,7 +48,7 @@ static void Convert32bppTo8bpp(SpriteLoader::Sprite &sprite)
|
|||
}
|
||||
}
|
||||
|
||||
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
|
||||
{
|
||||
ZoomLevels avail = this->baseloader.LoadSprite(sprite, file, file_pos, sprite_type, true, control_flags, avail_8bpp, avail_32bpp);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ class SpriteLoaderMakeIndexed : public SpriteLoader {
|
|||
SpriteLoader &baseloader;
|
||||
public:
|
||||
SpriteLoaderMakeIndexed(SpriteLoader &baseloader) : baseloader(baseloader) {}
|
||||
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
||||
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
|
||||
};
|
||||
|
||||
#endif /* SPRITELOADER_MAKEINDEXED_H */
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "../core/alloc_type.hpp"
|
||||
#include "../core/enum_type.hpp"
|
||||
#include "../gfx_type.h"
|
||||
#include "../spritecache_type.h"
|
||||
#include "sprite_file_type.hpp"
|
||||
|
||||
struct Sprite;
|
||||
|
@ -94,7 +95,7 @@ public:
|
|||
* @param[out] avail_32bpp Available 32bpp sprites.
|
||||
* @return Available sprites matching \a load_32bpp.
|
||||
*/
|
||||
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
|
||||
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
|
||||
|
||||
virtual ~SpriteLoader() = default;
|
||||
};
|
||||
|
|
|
@ -147,7 +147,7 @@ def = true
|
|||
str = STR_CONFIG_SETTING_BRIBE
|
||||
strhelp = STR_CONFIG_SETTING_BRIBE_HELPTEXT
|
||||
help_cb = SettingHelpWallclock
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); }
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_VIEW); }
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_BOOL]
|
||||
|
@ -157,7 +157,7 @@ def = true
|
|||
str = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE
|
||||
strhelp = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT
|
||||
help_cb = SettingHelpWallclock
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); }
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_VIEW); }
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_BOOL]
|
||||
|
@ -166,7 +166,7 @@ from = SLV_165
|
|||
def = true
|
||||
str = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS
|
||||
strhelp = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); }
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_VIEW); }
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_BOOL]
|
||||
|
@ -175,7 +175,7 @@ from = SLV_160
|
|||
def = true
|
||||
str = STR_CONFIG_SETTING_ALLOW_FUND_ROAD
|
||||
strhelp = STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); }
|
||||
post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_VIEW); }
|
||||
cat = SC_BASIC
|
||||
|
||||
[SDT_BOOL]
|
||||
|
|
|
@ -33,7 +33,7 @@ static bool MockLoadNextSprite(SpriteID load_index)
|
|||
sc->id = 0;
|
||||
sc->type = is_mapgen ? SpriteType::MapGen : SpriteType::Normal;
|
||||
sc->warned = false;
|
||||
sc->control_flags = 0;
|
||||
sc->control_flags = {};
|
||||
|
||||
/* Fill with empty sprites up until the default sprite count. */
|
||||
return load_index < SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;
|
||||
|
|
|
@ -3195,7 +3195,7 @@ CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID compan
|
|||
int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
|
||||
if (flags.Test(DoCommandFlag::Execute)) {
|
||||
t->ratings[company_id] = new_rating;
|
||||
InvalidateWindowData(WC_TOWN_AUTHORITY, town_id);
|
||||
InvalidateWindowData(WC_TOWN_VIEW, town_id);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
|
@ -3591,7 +3591,7 @@ static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
|
|||
*/
|
||||
if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
|
||||
t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
|
||||
SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
|
||||
SetWindowDirty(WC_TOWN_VIEW, t->index);
|
||||
}
|
||||
} else {
|
||||
ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
|
||||
|
@ -3692,7 +3692,7 @@ CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction act
|
|||
if (ret.Failed()) return ret;
|
||||
|
||||
if (flags.Test(DoCommandFlag::Execute)) {
|
||||
SetWindowDirty(WC_TOWN_AUTHORITY, town_id);
|
||||
SetWindowDirty(WC_TOWN_VIEW, town_id);
|
||||
}
|
||||
|
||||
return cost;
|
||||
|
@ -3745,7 +3745,7 @@ static void UpdateTownRating(Town *t)
|
|||
t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
|
||||
}
|
||||
|
||||
SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
|
||||
SetWindowDirty(WC_TOWN_VIEW, t->index);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4017,7 +4017,7 @@ void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
|
|||
} else {
|
||||
t->have_ratings.Set(_current_company);
|
||||
t->ratings[_current_company] = rating;
|
||||
SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
|
||||
InvalidateWindowData(WC_TOWN_VIEW, t->index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
547
src/town_gui.cpp
547
src/town_gui.cpp
|
@ -57,36 +57,21 @@ TownKdtree _town_local_authority_kdtree{};
|
|||
|
||||
typedef GUIList<const Town*, const bool &> GUITownList;
|
||||
|
||||
static constexpr NWidgetPart _nested_town_authority_widgets[] = {
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
|
||||
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TA_CAPTION),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TA_ZONE_BUTTON), SetMinimalSize(50, 0), SetStringTip(STR_LOCAL_AUTHORITY_ZONE, STR_LOCAL_AUTHORITY_ZONE_TOOLTIP),
|
||||
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
|
||||
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
|
||||
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_RATING_INFO), SetMinimalSize(317, 92), SetResize(1, 1), EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_COMMAND_LIST), SetMinimalSize(317, 52), SetResize(1, 0), SetToolTip(STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP), 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), SetStringTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
|
||||
EndContainer()
|
||||
};
|
||||
|
||||
/** Town authority window. */
|
||||
struct TownAuthorityWindow : Window {
|
||||
/* Town view window. */
|
||||
struct TownViewWindow : Window {
|
||||
private:
|
||||
Town *town = nullptr; ///< Town being displayed.
|
||||
Town *town = nullptr; ///< Town displayed by the window.
|
||||
TownAction sel_action = TownAction::End; ///< Currently selected town action, TownAction::End means no action selected.
|
||||
TownActions displayed_actions_on_previous_painting{}; ///< Actions that were available on the previous call to OnPaint()
|
||||
TownActions enabled_actions{}; ///< Actions that are enabled in settings.
|
||||
TownActions available_actions{}; ///< Actions that are available to execute for the current company.
|
||||
std::array<StringID, to_underlying(TownAction::End)> action_tooltips{};
|
||||
|
||||
Dimension icon_size{}; ///< Dimensions of company icon
|
||||
Dimension exclusive_size{}; ///< Dimensions of exclusive icon
|
||||
uint rating_line_height = 0;
|
||||
|
||||
static inline uint initial_visible_pane = 0;
|
||||
uint visible_pane = 0;
|
||||
|
||||
/**
|
||||
* Gets all town authority actions enabled in settings.
|
||||
|
@ -107,10 +92,17 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
TownAuthorityWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
|
||||
static const int WID_TV_HEIGHT_NORMAL = 150;
|
||||
|
||||
TownViewWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
|
||||
{
|
||||
this->visible_pane = TownViewWindow::initial_visible_pane;
|
||||
|
||||
this->CreateNestedTree();
|
||||
|
||||
this->town = Town::Get(window_number);
|
||||
this->enabled_actions = GetEnabledActions();
|
||||
this->available_actions = GetMaskOfTownActions(_local_company, this->town);
|
||||
|
||||
auto realtime = TimerGameEconomy::UsingWallclockUnits();
|
||||
this->action_tooltips[0] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING;
|
||||
|
@ -122,238 +114,7 @@ public:
|
|||
this->action_tooltips[6] = realtime ? STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT_MINUTES : STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT_MONTHS;
|
||||
this->action_tooltips[7] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE;
|
||||
|
||||
this->InitNested(window_number);
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
|
||||
this->exclusive_size = GetSpriteSize(SPR_EXCLUSIVE_TRANSPORT);
|
||||
}
|
||||
|
||||
void OnPaint() override
|
||||
{
|
||||
this->available_actions = GetMaskOfTownActions(_local_company, this->town);
|
||||
if (this->available_actions != displayed_actions_on_previous_painting) this->SetDirty();
|
||||
displayed_actions_on_previous_painting = this->available_actions;
|
||||
|
||||
this->SetWidgetLoweredState(WID_TA_ZONE_BUTTON, this->town->show_zone);
|
||||
this->SetWidgetDisabledState(WID_TA_EXECUTE, (this->sel_action == TownAction::End) || !this->available_actions.Test(this->sel_action));
|
||||
|
||||
this->DrawWidgets();
|
||||
if (!this->IsShaded())
|
||||
{
|
||||
this->DrawRatings();
|
||||
this->DrawActions();
|
||||
}
|
||||
}
|
||||
|
||||
StringID GetRatingString(int rating) const
|
||||
{
|
||||
if (rating > RATING_EXCELLENT) return STR_CARGO_RATING_OUTSTANDING;
|
||||
if (rating > RATING_VERYGOOD) return STR_CARGO_RATING_EXCELLENT;
|
||||
if (rating > RATING_GOOD) return STR_CARGO_RATING_VERY_GOOD;
|
||||
if (rating > RATING_MEDIOCRE) return STR_CARGO_RATING_GOOD;
|
||||
if (rating > RATING_POOR) return STR_CARGO_RATING_MEDIOCRE;
|
||||
if (rating > RATING_VERYPOOR) return STR_CARGO_RATING_POOR;
|
||||
if (rating > RATING_APPALLING) return STR_CARGO_RATING_VERY_POOR;
|
||||
return STR_CARGO_RATING_APPALLING;
|
||||
}
|
||||
|
||||
/** Draw the contents of the ratings panel. May request a resize of the window if the contents does not fit. */
|
||||
void DrawRatings()
|
||||
{
|
||||
Rect r = this->GetWidget<NWidgetBase>(WID_TA_RATING_INFO)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
|
||||
|
||||
int text_y_offset = (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2;
|
||||
int icon_y_offset = (this->resize.step_height - this->icon_size.height) / 2;
|
||||
int exclusive_y_offset = (this->resize.step_height - this->exclusive_size.height) / 2;
|
||||
|
||||
DrawString(r.left, r.right, r.top + text_y_offset, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
|
||||
r.top += this->resize.step_height;
|
||||
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
Rect icon = r.WithWidth(this->icon_size.width, rtl);
|
||||
Rect exclusive = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(this->exclusive_size.width, rtl);
|
||||
Rect text = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal + this->exclusive_size.width + WidgetDimensions::scaled.hsep_normal, rtl);
|
||||
|
||||
/* Draw list of companies */
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if ((this->town->have_ratings.Test(c->index) || this->town->exclusivity == c->index)) {
|
||||
DrawCompanyIcon(c->index, icon.left, text.top + icon_y_offset);
|
||||
|
||||
if (this->town->exclusivity == c->index) {
|
||||
DrawSprite(SPR_EXCLUSIVE_TRANSPORT, GetCompanyPalette(c->index), exclusive.left, text.top + exclusive_y_offset);
|
||||
}
|
||||
|
||||
int rating = this->town->ratings[c->index];
|
||||
DrawString(text.left, text.right, text.top + text_y_offset, GetString(STR_LOCAL_AUTHORITY_COMPANY_RATING, c->index, c->index, GetRatingString(rating)));
|
||||
text.top += this->resize.step_height;
|
||||
}
|
||||
}
|
||||
|
||||
text.bottom = text.top - 1;
|
||||
if (text.bottom > r.bottom) {
|
||||
/* If the company list is too big to fit, mark ourself dirty and draw again. */
|
||||
ResizeWindow(this, 0, text.bottom - r.bottom, false);
|
||||
}
|
||||
}
|
||||
|
||||
/** Draws the contents of the actions panel. May re-initialise window to resize panel, if the list does not fit. */
|
||||
void DrawActions()
|
||||
{
|
||||
Rect r = this->GetWidget<NWidgetBase>(WID_TA_COMMAND_LIST)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
|
||||
|
||||
DrawString(r, STR_LOCAL_AUTHORITY_ACTIONS_TITLE);
|
||||
r.top += GetCharacterHeight(FS_NORMAL);
|
||||
|
||||
/* Draw list of actions */
|
||||
for (TownAction i = {}; i != TownAction::End; ++i) {
|
||||
/* Don't show actions if disabled in settings. */
|
||||
if (!this->enabled_actions.Test(i)) continue;
|
||||
|
||||
/* Set colour of action based on ability to execute and if selected. */
|
||||
TextColour action_colour = TC_GREY | TC_NO_SHADE;
|
||||
if (this->available_actions.Test(i)) action_colour = TC_ORANGE;
|
||||
if (this->sel_action == i) action_colour = TC_WHITE;
|
||||
|
||||
DrawString(r, STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + to_underlying(i), action_colour);
|
||||
r.top += GetCharacterHeight(FS_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
|
||||
{
|
||||
if (widget == WID_TA_CAPTION) return GetString(STR_LOCAL_AUTHORITY_CAPTION, this->window_number);
|
||||
|
||||
return this->Window::GetWidgetString(widget, stringid);
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TA_ACTION_INFO:
|
||||
if (this->sel_action != TownAction::End) {
|
||||
Money action_cost = _price[PR_TOWN_ACTION] * GetTownActionCost(this->sel_action) >> 8;
|
||||
bool affordable = Company::IsValidID(_local_company) && action_cost < GetAvailableMoney(_local_company);
|
||||
|
||||
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect),
|
||||
GetString(this->action_tooltips[to_underlying(this->sel_action)], action_cost),
|
||||
affordable ? TC_YELLOW : TC_RED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TA_ACTION_INFO: {
|
||||
assert(size.width > padding.width && size.height > padding.height);
|
||||
Dimension d = {0, 0};
|
||||
for (TownAction i = {}; i != TownAction::End; ++i) {
|
||||
Money price = _price[PR_TOWN_ACTION] * GetTownActionCost(i) >> 8;
|
||||
d = maxdim(d, GetStringMultiLineBoundingBox(GetString(this->action_tooltips[to_underlying(i)], price), size));
|
||||
}
|
||||
d.width += padding.width;
|
||||
d.height += padding.height;
|
||||
size = maxdim(size, d);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TA_COMMAND_LIST:
|
||||
size.height = (to_underlying(TownAction::End) + 1) * GetCharacterHeight(FS_NORMAL) + padding.height;
|
||||
size.width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width;
|
||||
for (TownAction i = {}; i != TownAction::End; ++i) {
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + to_underlying(i)).width + padding.width);
|
||||
}
|
||||
size.width += padding.width;
|
||||
break;
|
||||
|
||||
case WID_TA_RATING_INFO:
|
||||
fill.height = resize.height = std::max({this->icon_size.height + WidgetDimensions::scaled.vsep_normal, this->exclusive_size.height + WidgetDimensions::scaled.vsep_normal, (uint)GetCharacterHeight(FS_NORMAL)});
|
||||
size.height = 9 * resize.height + padding.height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TA_ZONE_BUTTON: {
|
||||
bool new_show_state = !this->town->show_zone;
|
||||
TownID index = this->town->index;
|
||||
|
||||
new_show_state ? _town_local_authority_kdtree.Insert(index) : _town_local_authority_kdtree.Remove(index);
|
||||
|
||||
this->town->show_zone = new_show_state;
|
||||
this->SetWidgetLoweredState(widget, new_show_state);
|
||||
MarkWholeScreenDirty();
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TA_COMMAND_LIST: {
|
||||
int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, GetCharacterHeight(FS_NORMAL)) - 1;
|
||||
|
||||
auto action = this->enabled_actions.GetNthSetBit(y);
|
||||
if (!action.has_value()) break;
|
||||
|
||||
this->sel_action = *action;
|
||||
this->SetDirty();
|
||||
|
||||
/* When double-clicking, continue */
|
||||
if (click_count == 1 || !this->available_actions.Test(this->sel_action)) break;
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
||||
case WID_TA_EXECUTE:
|
||||
Command<CMD_DO_TOWN_ACTION>::Post(STR_ERROR_CAN_T_DO_THIS, this->town->xy, static_cast<TownID>(this->window_number), this->sel_action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Redraw the whole window on a regular interval. */
|
||||
const IntervalTimer<TimerWindow> redraw_interval = {std::chrono::seconds(3), [this](auto) {
|
||||
this->SetDirty();
|
||||
}};
|
||||
|
||||
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
|
||||
this->enabled_actions = this->GetEnabledActions();
|
||||
if (!this->enabled_actions.Test(this->sel_action)) {
|
||||
this->sel_action = TownAction::End;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static WindowDesc _town_authority_desc(
|
||||
WDP_AUTO, "view_town_authority", 317, 222,
|
||||
WC_TOWN_AUTHORITY, WC_NONE,
|
||||
{},
|
||||
_nested_town_authority_widgets
|
||||
);
|
||||
|
||||
static void ShowTownAuthorityWindow(uint town)
|
||||
{
|
||||
AllocateWindowDescFront<TownAuthorityWindow>(_town_authority_desc, town);
|
||||
}
|
||||
|
||||
|
||||
/* Town view window. */
|
||||
struct TownViewWindow : Window {
|
||||
private:
|
||||
Town *town = nullptr; ///< Town displayed by the window.
|
||||
|
||||
public:
|
||||
static const int WID_TV_HEIGHT_NORMAL = 150;
|
||||
|
||||
TownViewWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
|
||||
{
|
||||
this->CreateNestedTree();
|
||||
|
||||
this->town = Town::Get(window_number);
|
||||
this->SetPaneState();
|
||||
|
||||
this->FinishInitNested(window_number);
|
||||
|
||||
|
@ -365,6 +126,23 @@ public:
|
|||
this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !_network_server);
|
||||
}
|
||||
|
||||
void SetPaneState()
|
||||
{
|
||||
if (auto *nwid = this->GetWidget<NWidgetStacked>(WID_TV_PANE_SEL); nwid != nullptr) {
|
||||
nwid->SetDisplayedPlane(this->visible_pane);
|
||||
this->SetWidgetLoweredState(WID_TV_PANE_INFO, this->visible_pane == 0);
|
||||
this->SetWidgetLoweredState(WID_TV_PANE_RATINGS, this->visible_pane == 1);
|
||||
this->SetWidgetLoweredState(WID_TV_PANE_ACTIONS, this->visible_pane == 2);
|
||||
}
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
this->icon_size = GetScaledSpriteSize(SPR_COMPANY_ICON);
|
||||
this->exclusive_size = GetScaledSpriteSize(SPR_EXCLUSIVE_TRANSPORT);
|
||||
this->rating_line_height = std::max({this->icon_size.height, this->exclusive_size.height, (uint)GetCharacterHeight(FS_NORMAL)});
|
||||
}
|
||||
|
||||
void Close([[maybe_unused]] int data = 0) override
|
||||
{
|
||||
SetViewportCatchmentTown(Town::Get(this->window_number), false);
|
||||
|
@ -382,14 +160,24 @@ public:
|
|||
{
|
||||
extern const Town *_viewport_highlight_town;
|
||||
this->SetWidgetLoweredState(WID_TV_CATCHMENT, _viewport_highlight_town == this->town);
|
||||
|
||||
this->SetWidgetLoweredState(WID_TV_ZONE, this->town->show_zone);
|
||||
this->SetWidgetDisabledState(WID_TV_EXECUTE, this->visible_pane != 2 || this->sel_action == TownAction::End || !this->available_actions.Test(this->sel_action));
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
if (widget != WID_TV_INFO) return;
|
||||
switch (widget) {
|
||||
case WID_TV_INFO: this->DrawInfo(r); break;
|
||||
case WID_TV_RATING_INFO: this->DrawRatings(r); break;
|
||||
case WID_TV_COMMAND_LIST: this->DrawActions(r); break;
|
||||
case WID_TV_ACTION_INFO: this->DrawActionInfo(r); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawInfo(const Rect &r) const
|
||||
{
|
||||
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
|
||||
|
||||
DrawString(tr, GetString(STR_TOWN_VIEW_POPULATION_HOUSES, this->town->cache.population, this->town->cache.num_houses));
|
||||
|
@ -465,6 +253,86 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
static StringID GetRatingString(int rating)
|
||||
{
|
||||
if (rating > RATING_EXCELLENT) return STR_CARGO_RATING_OUTSTANDING;
|
||||
if (rating > RATING_VERYGOOD) return STR_CARGO_RATING_EXCELLENT;
|
||||
if (rating > RATING_GOOD) return STR_CARGO_RATING_VERY_GOOD;
|
||||
if (rating > RATING_MEDIOCRE) return STR_CARGO_RATING_GOOD;
|
||||
if (rating > RATING_POOR) return STR_CARGO_RATING_MEDIOCRE;
|
||||
if (rating > RATING_VERYPOOR) return STR_CARGO_RATING_POOR;
|
||||
if (rating > RATING_APPALLING) return STR_CARGO_RATING_VERY_POOR;
|
||||
return STR_CARGO_RATING_APPALLING;
|
||||
}
|
||||
|
||||
/** Draw the contents of the ratings panel. May request a resize of the window if the contents does not fit. */
|
||||
void DrawRatings(const Rect &r) const
|
||||
{
|
||||
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
|
||||
|
||||
int text_y_offset = (this->rating_line_height - GetCharacterHeight(FS_NORMAL)) / 2;
|
||||
int icon_y_offset = (this->rating_line_height - this->icon_size.height) / 2;
|
||||
int exclusive_y_offset = (this->rating_line_height - this->exclusive_size.height) / 2;
|
||||
|
||||
DrawString(tr.left, tr.right, tr.top + text_y_offset, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
|
||||
tr.top += this->rating_line_height;
|
||||
|
||||
bool rtl = _current_text_dir == TD_RTL;
|
||||
Rect icon = tr.WithWidth(this->icon_size.width, rtl);
|
||||
Rect exclusive = tr.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(this->exclusive_size.width, rtl);
|
||||
Rect text = tr.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal + this->exclusive_size.width + WidgetDimensions::scaled.hsep_normal, rtl);
|
||||
|
||||
/* Draw list of companies */
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if ((this->town->have_ratings.Test(c->index) || this->town->exclusivity == c->index)) {
|
||||
DrawCompanyIcon(c->index, icon.left, text.top + icon_y_offset);
|
||||
|
||||
if (this->town->exclusivity == c->index) {
|
||||
DrawSprite(SPR_EXCLUSIVE_TRANSPORT, GetCompanyPalette(c->index), exclusive.left, text.top + exclusive_y_offset);
|
||||
}
|
||||
|
||||
int rating = this->town->ratings[c->index];
|
||||
DrawString(text.left, text.right, text.top + text_y_offset, GetString(STR_LOCAL_AUTHORITY_COMPANY_RATING, c->index, c->index, GetRatingString(rating)));
|
||||
text.top += this->rating_line_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Draws the contents of the actions panel. May re-initialise window to resize panel, if the list does not fit. */
|
||||
void DrawActions(const Rect &r) const
|
||||
{
|
||||
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
|
||||
|
||||
DrawString(tr, STR_LOCAL_AUTHORITY_ACTIONS_TITLE);
|
||||
tr.top += GetCharacterHeight(FS_NORMAL);
|
||||
|
||||
/* Draw list of actions */
|
||||
for (TownAction i = {}; i != TownAction::End; ++i) {
|
||||
/* Don't show actions if disabled in settings. */
|
||||
if (!this->enabled_actions.Test(i)) continue;
|
||||
|
||||
/* Set colour of action based on ability to execute and if selected. */
|
||||
TextColour action_colour = TC_GREY | TC_NO_SHADE;
|
||||
if (this->available_actions.Test(i)) action_colour = TC_ORANGE;
|
||||
if (this->sel_action == i) action_colour = TC_WHITE;
|
||||
|
||||
DrawString(tr, STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + to_underlying(i), action_colour);
|
||||
tr.top += GetCharacterHeight(FS_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawActionInfo(const Rect &r) const
|
||||
{
|
||||
if (this->sel_action == TownAction::End) return;
|
||||
|
||||
Money action_cost = _price[PR_TOWN_ACTION] * GetTownActionCost(this->sel_action) >> 8;
|
||||
bool affordable = Company::IsValidID(_local_company) && action_cost < GetAvailableMoney(_local_company);
|
||||
|
||||
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect),
|
||||
GetString(this->action_tooltips[to_underlying(this->sel_action)], action_cost),
|
||||
affordable ? TC_YELLOW : TC_RED);
|
||||
}
|
||||
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
|
@ -476,10 +344,6 @@ public:
|
|||
}
|
||||
break;
|
||||
|
||||
case WID_TV_SHOW_AUTHORITY: // town authority
|
||||
ShowTownAuthorityWindow(this->window_number);
|
||||
break;
|
||||
|
||||
case WID_TV_CHANGE_NAME: // rename
|
||||
ShowQueryString(GetString(STR_TOWN_NAME, this->window_number), STR_TOWN_VIEW_RENAME_TOWN_BUTTON, MAX_LENGTH_TOWN_NAME_CHARS, this, CS_ALPHANUMERAL, {QueryStringFlag::EnableDefault, QueryStringFlag::LengthIsInChars});
|
||||
break;
|
||||
|
@ -503,14 +367,68 @@ public:
|
|||
case WID_TV_DELETE: // delete town - only available on Scenario editor
|
||||
Command<CMD_DELETE_TOWN>::Post(STR_ERROR_TOWN_CAN_T_DELETE, static_cast<TownID>(this->window_number));
|
||||
break;
|
||||
|
||||
case WID_TV_ZONE: {
|
||||
bool new_show_state = !this->town->show_zone;
|
||||
TownID index = this->town->index;
|
||||
|
||||
new_show_state ? _town_local_authority_kdtree.Insert(index) : _town_local_authority_kdtree.Remove(index);
|
||||
|
||||
this->town->show_zone = new_show_state;
|
||||
this->SetWidgetLoweredState(widget, new_show_state);
|
||||
MarkWholeScreenDirty();
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TV_COMMAND_LIST: {
|
||||
int y = this->GetRowFromWidget(pt.y, widget, WidgetDimensions::scaled.framerect.top, GetCharacterHeight(FS_NORMAL)) - 1;
|
||||
|
||||
auto action = this->enabled_actions.GetNthSetBit(y);
|
||||
if (!action.has_value()) break;
|
||||
|
||||
this->sel_action = *action;
|
||||
this->SetDirty();
|
||||
|
||||
/* When double-clicking, continue */
|
||||
if (click_count == 1 || !this->available_actions.Test(this->sel_action)) break;
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
||||
case WID_TV_EXECUTE:
|
||||
Command<CMD_DO_TOWN_ACTION>::Post(STR_ERROR_CAN_T_DO_THIS, this->town->xy, static_cast<TownID>(this->window_number), this->sel_action);
|
||||
break;
|
||||
|
||||
case WID_TV_PANE_INFO:
|
||||
TownViewWindow::initial_visible_pane = this->visible_pane = 0;
|
||||
this->ResizePanes();
|
||||
break;
|
||||
|
||||
case WID_TV_PANE_RATINGS:
|
||||
TownViewWindow::initial_visible_pane = this->visible_pane = 1;
|
||||
this->ResizePanes();
|
||||
break;
|
||||
|
||||
case WID_TV_PANE_ACTIONS:
|
||||
TownViewWindow::initial_visible_pane = this->visible_pane = 2;
|
||||
this->ResizePanes();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_TV_INFO:
|
||||
size.height = GetDesiredInfoHeight(size.width) + padding.height;
|
||||
case WID_TV_COMMAND_LIST:
|
||||
if (this->visible_pane != 2) {
|
||||
size.height = 0;
|
||||
} else {
|
||||
size.height = (to_underlying(TownAction::End) + 1) * GetCharacterHeight(FS_NORMAL) + padding.height;
|
||||
size.width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width;
|
||||
for (TownAction i = {}; i != TownAction::End; ++i) {
|
||||
size.width = std::max(size.width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + to_underlying(i)).width + padding.width);
|
||||
}
|
||||
size.width += padding.width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -521,6 +439,7 @@ public:
|
|||
*/
|
||||
uint GetDesiredInfoHeight(int width) const
|
||||
{
|
||||
width -= WidgetDimensions::scaled.framerect.Horizontal();
|
||||
uint aimed_height = static_cast<uint>(1 + CargoSpec::town_production_cargoes[TPE_PASSENGERS].size() + CargoSpec::town_production_cargoes[TPE_MAIL].size()) * GetCharacterHeight(FS_NORMAL);
|
||||
|
||||
bool first = true;
|
||||
|
@ -540,23 +459,76 @@ public:
|
|||
if (_settings_game.economy.station_noise_level) aimed_height += GetCharacterHeight(FS_NORMAL);
|
||||
|
||||
if (!this->town->text.empty()) {
|
||||
aimed_height += GetStringHeight(this->town->text.GetDecodedString(), width - WidgetDimensions::scaled.framerect.Horizontal());
|
||||
aimed_height += GetStringHeight(this->town->text.GetDecodedString(), width);
|
||||
}
|
||||
|
||||
return aimed_height;
|
||||
return aimed_height + WidgetDimensions::scaled.framerect.Vertical();
|
||||
}
|
||||
|
||||
void ResizeWindowAsNeeded()
|
||||
uint GetDesiredRatingHeight(int) const
|
||||
{
|
||||
const NWidgetBase *nwid_info = this->GetWidget<NWidgetBase>(WID_TV_INFO);
|
||||
uint aimed_height = GetDesiredInfoHeight(nwid_info->current_x);
|
||||
if (aimed_height > nwid_info->current_y || (aimed_height < nwid_info->current_y && nwid_info->current_y > nwid_info->smallest_y)) {
|
||||
this->ReInit();
|
||||
int lines = 1;
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if ((this->town->have_ratings.Test(c->index) || this->town->exclusivity == c->index)) {
|
||||
++lines;
|
||||
}
|
||||
}
|
||||
return this->rating_line_height * std::max(3, lines) + WidgetDimensions::scaled.framerect.Vertical();
|
||||
}
|
||||
|
||||
uint GetDesiredActionInfoHeight(int width) const
|
||||
{
|
||||
width -= WidgetDimensions::scaled.framerect.Horizontal();
|
||||
int height = 0;
|
||||
for (TownAction i = {}; i != TownAction::End; ++i) {
|
||||
Money price = _price[PR_TOWN_ACTION] * GetTownActionCost(i) >> 8;
|
||||
height = std::max(height, GetStringHeight(GetString(this->action_tooltips[to_underlying(i)], price), width));
|
||||
}
|
||||
return height + WidgetDimensions::scaled.framerect.Vertical();
|
||||
}
|
||||
|
||||
bool UpdatePaneSizes()
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
auto *sel = this->GetWidget<NWidgetStacked>(WID_TV_PANE_SEL);
|
||||
if (sel != nullptr) {
|
||||
if (auto *nwid = this->GetWidget<NWidgetCore>(WID_TV_INFO); nwid != nullptr) {
|
||||
uint y = this->visible_pane == 0 ? GetDesiredInfoHeight(nwid->current_x) : 0;
|
||||
changed |= nwid->UpdateVerticalSize(y);
|
||||
}
|
||||
|
||||
if (auto *nwid = this->GetWidget<NWidgetCore>(WID_TV_RATING_INFO); nwid != nullptr) {
|
||||
uint y = this->visible_pane == 1 ? GetDesiredRatingHeight(nwid->current_x) : 0;
|
||||
changed |= nwid->UpdateVerticalSize(y);
|
||||
}
|
||||
|
||||
if (auto *nwid = this->GetWidget<NWidgetCore>(WID_TV_ACTION_INFO); nwid != nullptr) {
|
||||
uint y = this->visible_pane == 2 ? GetDesiredActionInfoHeight(nwid->current_x) : 0;
|
||||
changed |= nwid->UpdateVerticalSize(y);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void ResizePanes()
|
||||
{
|
||||
this->SetPaneState();
|
||||
|
||||
/* We want to resize the window while maintaining the size of the viewport. */
|
||||
auto *nwid = this->GetWidget<NWidgetViewport>(WID_TV_VIEWPORT);
|
||||
int old_y = static_cast<int>(nwid->current_y);
|
||||
this->OnResize();
|
||||
int new_y = static_cast<int>(nwid->current_y);
|
||||
|
||||
if (old_y != new_y) ResizeWindow(this, 0, old_y - new_y, false, false);
|
||||
}
|
||||
|
||||
void OnResize() override
|
||||
{
|
||||
if (this->UpdatePaneSizes()) this->ReInit(0, 0);
|
||||
|
||||
if (this->viewport != nullptr) {
|
||||
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_TV_VIEWPORT);
|
||||
nvp->UpdateViewportCoordinates(this);
|
||||
|
@ -573,6 +545,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/** Redraw the whole window on a regular interval. */
|
||||
const IntervalTimer<TimerWindow> redraw_interval = {std::chrono::seconds(3), [this](auto) {
|
||||
this->SetDirty();
|
||||
}};
|
||||
|
||||
/**
|
||||
* Some data on this window has become invalid.
|
||||
* @param data Information about the changed data.
|
||||
|
@ -581,9 +558,16 @@ public:
|
|||
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
|
||||
{
|
||||
if (!gui_scope) return;
|
||||
|
||||
/* Called when setting station noise or required cargoes have changed, in order to resize the window */
|
||||
this->enabled_actions = GetEnabledActions();
|
||||
this->available_actions = GetMaskOfTownActions(_local_company, this->town);
|
||||
if (!this->enabled_actions.Test(this->sel_action)) {
|
||||
this->sel_action = TownAction::End;
|
||||
}
|
||||
|
||||
this->SetDirty(); // refresh display for current size. This will allow to avoid glitches when downgrading
|
||||
this->ResizeWindowAsNeeded();
|
||||
this->ResizePanes();
|
||||
}
|
||||
|
||||
void OnQueryTextFinished(std::optional<std::string> str) override
|
||||
|
@ -614,10 +598,23 @@ static constexpr NWidgetPart _nested_town_game_view_widgets[] = {
|
|||
NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_TV_VIEWPORT), SetMinimalSize(254, 86), SetFill(1, 0), SetResize(1, 1),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_INFO), SetMinimalSize(260, 32), SetResize(1, 0), SetFill(1, 0), EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_SHOW_AUTHORITY), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_PANE_INFO), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_INFO, STR_TOWN_VIEW_INFO_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_PANE_RATINGS), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_RATINGS, STR_TOWN_VIEW_RATINGS_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_PANE_ACTIONS), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_ACTIONS, STR_TOWN_VIEW_ACTIONS_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TV_PANE_SEL),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_INFO), SetResize(1, 0), SetFill(1, 1), EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_RATING_INFO), SetResize(1, 0), SetFill(1, 1), EndContainer(),
|
||||
NWidget(NWID_VERTICAL),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_COMMAND_LIST), SetResize(1, 0), SetFill(1, 1), SetToolTip(STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP), EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_ACTION_INFO), SetResize(1, 0), SetFill(1, 0), EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXECUTE), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_ZONE), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_LOCAL_AUTHORITY_ZONE, STR_LOCAL_AUTHORITY_ZONE_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
|
||||
EndContainer(),
|
||||
};
|
||||
|
|
|
@ -21,30 +21,27 @@ enum TownDirectoryWidgets : WidgetID {
|
|||
WID_TD_WORLD_POPULATION, ///< The world's population.
|
||||
};
|
||||
|
||||
/** Widgets of the #TownAuthorityWindow class. */
|
||||
enum TownAuthorityWidgets : WidgetID {
|
||||
WID_TA_CAPTION, ///< Caption of window.
|
||||
WID_TA_ZONE_BUTTON, ///< Turn on/off showing local authority zone.
|
||||
WID_TA_RATING_INFO, ///< Overview with ratings for each company.
|
||||
WID_TA_COMMAND_LIST, ///< List of commands for the player.
|
||||
WID_TA_SCROLLBAR, ///< Scrollbar of the list of commands.
|
||||
WID_TA_ACTION_INFO, ///< Additional information about the action.
|
||||
WID_TA_EXECUTE, ///< Do-it button.
|
||||
};
|
||||
|
||||
/** Widgets of the #TownViewWindow class. */
|
||||
enum TownViewWidgets : WidgetID {
|
||||
WID_TV_CAPTION, ///< Caption of window.
|
||||
WID_TV_VIEWPORT, ///< View of the center of the town.
|
||||
WID_TV_INFO, ///< General information about the town.
|
||||
WID_TV_CENTER_VIEW, ///< Center the main view on this town.
|
||||
WID_TV_SHOW_AUTHORITY, ///< Show the town authority window.
|
||||
WID_TV_CHANGE_NAME, ///< Change the name of this town.
|
||||
WID_TV_CATCHMENT, ///< Toggle catchment area highlight.
|
||||
WID_TV_EXPAND, ///< Expand this town (scenario editor only).
|
||||
WID_TV_EXPAND_BUILDINGS, ///< Expand number of buildings this town (scenario editor only).
|
||||
WID_TV_EXPAND_ROADS, ///< Expand roads of this town (scenario editor only).
|
||||
WID_TV_DELETE, ///< Delete this town (scenario editor only).
|
||||
WID_TV_PANE_SEL,
|
||||
WID_TV_PANE_INFO,
|
||||
WID_TV_PANE_RATINGS,
|
||||
WID_TV_PANE_ACTIONS,
|
||||
WID_TV_RATING_INFO, ///< Overview with ratings for each company.
|
||||
WID_TV_COMMAND_LIST, ///< List of commands for the player.
|
||||
WID_TV_ACTION_INFO, ///< Additional information about the action.
|
||||
WID_TV_EXECUTE, ///< Do-it button.
|
||||
WID_TV_ZONE, ///< Turn on/off showing local authority zone.
|
||||
};
|
||||
|
||||
/** Widgets of the #FoundTownWindow class. */
|
||||
|
|
|
@ -189,12 +189,6 @@ enum WindowClass : uint16_t {
|
|||
WC_TEXTFILE,
|
||||
|
||||
|
||||
/**
|
||||
* Town authority; %Window numbers:
|
||||
* - #TownID = #TownAuthorityWidgets
|
||||
*/
|
||||
WC_TOWN_AUTHORITY,
|
||||
|
||||
/**
|
||||
* Vehicle details; %Window numbers:
|
||||
* - #VehicleID = #VehicleDetailsWidgets
|
||||
|
|
Loading…
Reference in New Issue