mirror of https://github.com/OpenTTD/OpenTTD
(svn r19855) [1.0] -Backport from trunk:
- Fix: [NewGRF] Possible divide-by-zero if a NewGRF checked industry var 42 while the production level was 0 (r19749) - Fix: Do not recenter usually centered windows when resizing main window or changing language, if they have been moved/resized before [FS#3675] (r19746) - Fix: The GUI is controlled by _local_company, not _current_company (r19745) - Fix: NewGRFs could access map bits of not yet constructed industries and houses during construction callbacks (r19748, r19743) - Fix: Check for industry availability more thoroughly and cancel object placement when selecting not available industries [FS#3787] (r19701)release/1.0
parent
530d904f84
commit
1e5d35634d
|
@ -14,6 +14,7 @@
|
||||||
#include "../../command_type.h"
|
#include "../../command_type.h"
|
||||||
#include "../../strings_func.h"
|
#include "../../strings_func.h"
|
||||||
#include "../../industry.h"
|
#include "../../industry.h"
|
||||||
|
#include "../../newgrf_industries.h"
|
||||||
#include "../../core/random_func.hpp"
|
#include "../../core/random_func.hpp"
|
||||||
|
|
||||||
/* static */ bool AIIndustryType::IsValidIndustryType(IndustryType industry_type)
|
/* static */ bool AIIndustryType::IsValidIndustryType(IndustryType industry_type)
|
||||||
|
@ -88,6 +89,8 @@
|
||||||
/* static */ bool AIIndustryType::CanBuildIndustry(IndustryType industry_type)
|
/* static */ bool AIIndustryType::CanBuildIndustry(IndustryType industry_type)
|
||||||
{
|
{
|
||||||
if (!IsValidIndustryType(industry_type)) return false;
|
if (!IsValidIndustryType(industry_type)) return false;
|
||||||
|
|
||||||
|
if (!::CheckIfCallBackAllowsAvailability(industry_type, IACT_USERCREATION)) return false;
|
||||||
if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return true;
|
if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return true;
|
||||||
|
|
||||||
/* raw_industry_construction == 1 means "Build as other industries" */
|
/* raw_industry_construction == 1 means "Build as other industries" */
|
||||||
|
@ -97,7 +100,9 @@
|
||||||
/* static */ bool AIIndustryType::CanProspectIndustry(IndustryType industry_type)
|
/* static */ bool AIIndustryType::CanProspectIndustry(IndustryType industry_type)
|
||||||
{
|
{
|
||||||
if (!IsValidIndustryType(industry_type)) return false;
|
if (!IsValidIndustryType(industry_type)) return false;
|
||||||
|
|
||||||
if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return false;
|
if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return false;
|
||||||
|
if (!::CheckIfCallBackAllowsAvailability(industry_type, IACT_USERCREATION)) return false;
|
||||||
|
|
||||||
/* raw_industry_construction == 2 means "prospect" */
|
/* raw_industry_construction == 2 means "prospect" */
|
||||||
return _settings_game.construction.raw_industry_construction == 2;
|
return _settings_game.construction.raw_industry_construction == 2;
|
||||||
|
|
|
@ -1736,6 +1736,10 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_game_mode != GM_EDITOR && !CheckIfCallBackAllowsAvailability(it, IACT_USERCREATION)) {
|
||||||
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
const Industry *ind = NULL;
|
const Industry *ind = NULL;
|
||||||
if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry()) {
|
if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry()) {
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
|
|
|
@ -406,8 +406,10 @@ public:
|
||||||
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
|
|
||||||
if ((_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indsp != NULL && indsp->IsRawIndustry()) ||
|
if (GetCallbackWnd() == this &&
|
||||||
this->selected_type == INVALID_INDUSTRYTYPE) {
|
((_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indsp != NULL && indsp->IsRawIndustry()) ||
|
||||||
|
this->selected_type == INVALID_INDUSTRYTYPE ||
|
||||||
|
!this->enabled[this->selected_index])) {
|
||||||
/* Reset the button state if going to prospecting or "build many industries" */
|
/* Reset the button state if going to prospecting or "build many industries" */
|
||||||
this->RaiseButtons();
|
this->RaiseButtons();
|
||||||
ResetObjectToPlace();
|
ResetObjectToPlace();
|
||||||
|
|
|
@ -99,20 +99,25 @@ void DecreaseBuildingCount(Town *t, HouseID house_id)
|
||||||
|
|
||||||
static uint32 HouseGetRandomBits(const ResolverObject *object)
|
static uint32 HouseGetRandomBits(const ResolverObject *object)
|
||||||
{
|
{
|
||||||
const TileIndex tile = object->u.house.tile;
|
/* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
|
||||||
return (tile == INVALID_TILE || !IsTileType(tile, MP_HOUSE)) ? 0 : GetHouseRandomBits(tile);
|
TileIndex tile = object->u.house.tile;
|
||||||
|
assert(IsValidTile(tile) && (object->u.house.not_yet_constructed || IsTileType(tile, MP_HOUSE)));
|
||||||
|
return object->u.house.not_yet_constructed ? 0 : GetHouseRandomBits(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 HouseGetTriggers(const ResolverObject *object)
|
static uint32 HouseGetTriggers(const ResolverObject *object)
|
||||||
{
|
{
|
||||||
const TileIndex tile = object->u.house.tile;
|
/* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
|
||||||
return (tile == INVALID_TILE || !IsTileType(tile, MP_HOUSE)) ? 0 : GetHouseTriggers(tile);
|
TileIndex tile = object->u.house.tile;
|
||||||
|
assert(IsValidTile(tile) && (object->u.house.not_yet_constructed || IsTileType(tile, MP_HOUSE)));
|
||||||
|
return object->u.house.not_yet_constructed ? 0 : GetHouseTriggers(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HouseSetTriggers(const ResolverObject *object, int triggers)
|
static void HouseSetTriggers(const ResolverObject *object, int triggers)
|
||||||
{
|
{
|
||||||
const TileIndex tile = object->u.house.tile;
|
TileIndex tile = object->u.house.tile;
|
||||||
if (IsTileType(tile, MP_HOUSE)) SetHouseTriggers(tile, triggers);
|
assert(!object->u.house.not_yet_constructed && IsValidTile(tile) && IsTileType(tile, MP_HOUSE));
|
||||||
|
SetHouseTriggers(tile, triggers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 GetNumHouses(HouseID house_id, const Town *town)
|
static uint32 GetNumHouses(HouseID house_id, const Town *town)
|
||||||
|
@ -370,6 +375,7 @@ static void NewHouseResolver(ResolverObject *res, HouseID house_id, TileIndex ti
|
||||||
res->u.house.tile = tile;
|
res->u.house.tile = tile;
|
||||||
res->u.house.town = town;
|
res->u.house.town = town;
|
||||||
res->u.house.house_id = house_id;
|
res->u.house.house_id = house_id;
|
||||||
|
res->u.house.not_yet_constructed = false;
|
||||||
|
|
||||||
res->callback = CBID_NO_CALLBACK;
|
res->callback = CBID_NO_CALLBACK;
|
||||||
res->callback_param1 = 0;
|
res->callback_param1 = 0;
|
||||||
|
@ -383,15 +389,18 @@ static void NewHouseResolver(ResolverObject *res, HouseID house_id, TileIndex ti
|
||||||
res->grffile = (hs != NULL ? hs->grffile : NULL);
|
res->grffile = (hs != NULL ? hs->grffile : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile)
|
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed)
|
||||||
{
|
{
|
||||||
ResolverObject object;
|
ResolverObject object;
|
||||||
const SpriteGroup *group;
|
const SpriteGroup *group;
|
||||||
|
|
||||||
|
assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
|
||||||
|
|
||||||
NewHouseResolver(&object, house_id, tile, town);
|
NewHouseResolver(&object, house_id, tile, town);
|
||||||
object.callback = callback;
|
object.callback = callback;
|
||||||
object.callback_param1 = param1;
|
object.callback_param1 = param1;
|
||||||
object.callback_param2 = param2;
|
object.callback_param2 = param2;
|
||||||
|
object.u.house.not_yet_constructed = not_yet_constructed;
|
||||||
|
|
||||||
group = SpriteGroup::Resolve(HouseSpec::Get(house_id)->spritegroup, &object);
|
group = SpriteGroup::Resolve(HouseSpec::Get(house_id)->spritegroup, &object);
|
||||||
if (group == NULL) return CALLBACK_FAILED;
|
if (group == NULL) return CALLBACK_FAILED;
|
||||||
|
|
|
@ -44,7 +44,7 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id);
|
||||||
void AnimateNewHouseTile(TileIndex tile);
|
void AnimateNewHouseTile(TileIndex tile);
|
||||||
void ChangeHouseAnimationFrame(const struct GRFFile *file, TileIndex tile, uint16 callback_result);
|
void ChangeHouseAnimationFrame(const struct GRFFile *file, TileIndex tile, uint16 callback_result);
|
||||||
|
|
||||||
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile);
|
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed = false);
|
||||||
|
|
||||||
bool CanDeleteHouse(TileIndex tile);
|
bool CanDeleteHouse(TileIndex tile);
|
||||||
|
|
||||||
|
|
|
@ -201,6 +201,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
|
||||||
uint16 callback = indspec->callback_mask;
|
uint16 callback = indspec->callback_mask;
|
||||||
if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) {
|
if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) {
|
||||||
if ((indspec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) {
|
if ((indspec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) {
|
||||||
|
if (industry->prod_level == 0) return 0;
|
||||||
return min(industry->incoming_cargo_waiting[variable - 0x40] / industry->prod_level, (uint16)0xFFFF);
|
return min(industry->incoming_cargo_waiting[variable - 0x40] / industry->prod_level, (uint16)0xFFFF);
|
||||||
} else {
|
} else {
|
||||||
return min(industry->incoming_cargo_waiting[variable - 0x40], (uint16)0xFFFF);
|
return min(industry->incoming_cargo_waiting[variable - 0x40], (uint16)0xFFFF);
|
||||||
|
@ -342,18 +343,21 @@ static const SpriteGroup *IndustryResolveReal(const ResolverObject *object, cons
|
||||||
|
|
||||||
static uint32 IndustryGetRandomBits(const ResolverObject *object)
|
static uint32 IndustryGetRandomBits(const ResolverObject *object)
|
||||||
{
|
{
|
||||||
return object->u.industry.ind == NULL ? 0 : object->u.industry.ind->random;
|
const Industry *ind = object->u.industry.ind;
|
||||||
|
return ind != NULL ? ind->random: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 IndustryGetTriggers(const ResolverObject *object)
|
static uint32 IndustryGetTriggers(const ResolverObject *object)
|
||||||
{
|
{
|
||||||
return object->u.industry.ind == NULL ? 0 : object->u.industry.ind->random_triggers;
|
const Industry *ind = object->u.industry.ind;
|
||||||
|
return ind != NULL ? ind->random_triggers : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IndustrySetTriggers(const ResolverObject *object, int triggers)
|
static void IndustrySetTriggers(const ResolverObject *object, int triggers)
|
||||||
{
|
{
|
||||||
if (object->u.industry.ind == NULL) return;
|
Industry *ind = object->u.industry.ind;
|
||||||
object->u.industry.ind->random_triggers = triggers;
|
assert(ind != NULL && ind->index != INVALID_INDUSTRY);
|
||||||
|
ind->random_triggers = triggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
|
static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
|
||||||
|
|
|
@ -118,26 +118,35 @@ static const SpriteGroup *IndustryTileResolveReal(const ResolverObject *object,
|
||||||
static uint32 IndustryTileGetRandomBits(const ResolverObject *object)
|
static uint32 IndustryTileGetRandomBits(const ResolverObject *object)
|
||||||
{
|
{
|
||||||
const TileIndex tile = object->u.industry.tile;
|
const TileIndex tile = object->u.industry.tile;
|
||||||
if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
|
const Industry *ind = object->u.industry.ind;
|
||||||
return (object->scope == VSG_SCOPE_SELF) ? GetIndustryRandomBits(tile) : Industry::GetByTile(tile)->random;
|
assert(ind != NULL && IsValidTile(tile));
|
||||||
|
assert(ind->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
|
||||||
|
|
||||||
|
return (object->scope == VSG_SCOPE_SELF) ?
|
||||||
|
(ind->index != INVALID_INDUSTRY ? GetIndustryRandomBits(tile) : 0) :
|
||||||
|
ind->random;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32 IndustryTileGetTriggers(const ResolverObject *object)
|
static uint32 IndustryTileGetTriggers(const ResolverObject *object)
|
||||||
{
|
{
|
||||||
const TileIndex tile = object->u.industry.tile;
|
const TileIndex tile = object->u.industry.tile;
|
||||||
if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
|
const Industry *ind = object->u.industry.ind;
|
||||||
return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : Industry::GetByTile(tile)->random_triggers;
|
assert(ind != NULL && IsValidTile(tile));
|
||||||
|
assert(ind->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
|
||||||
|
if (ind->index == INVALID_INDUSTRY) return 0;
|
||||||
|
return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : ind->random_triggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
|
static void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
|
||||||
{
|
{
|
||||||
const TileIndex tile = object->u.industry.tile;
|
const TileIndex tile = object->u.industry.tile;
|
||||||
if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return;
|
Industry *ind = object->u.industry.ind;
|
||||||
|
assert(ind != NULL && ind->index != INVALID_INDUSTRY && IsValidTile(tile) && IsTileType(tile, MP_INDUSTRY));
|
||||||
|
|
||||||
if (object->scope == VSG_SCOPE_SELF) {
|
if (object->scope == VSG_SCOPE_SELF) {
|
||||||
SetIndustryTriggers(tile, triggers);
|
SetIndustryTriggers(tile, triggers);
|
||||||
} else {
|
} else {
|
||||||
Industry::GetByTile(tile)->random_triggers = triggers;
|
ind->random_triggers = triggers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +203,9 @@ uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2
|
||||||
ResolverObject object;
|
ResolverObject object;
|
||||||
const SpriteGroup *group;
|
const SpriteGroup *group;
|
||||||
|
|
||||||
|
assert(industry != NULL && IsValidTile(tile));
|
||||||
|
assert(industry->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
|
||||||
|
|
||||||
NewIndustryTileResolver(&object, gfx_id, tile, industry);
|
NewIndustryTileResolver(&object, gfx_id, tile, industry);
|
||||||
object.callback = callback;
|
object.callback = callback;
|
||||||
object.callback_param1 = param1;
|
object.callback_param1 = param1;
|
||||||
|
@ -385,6 +397,8 @@ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, I
|
||||||
{
|
{
|
||||||
ResolverObject object;
|
ResolverObject object;
|
||||||
|
|
||||||
|
assert(IsValidTile(tile) && IsTileType(tile, MP_INDUSTRY));
|
||||||
|
|
||||||
IndustryGfx gfx = GetIndustryGfx(tile);
|
IndustryGfx gfx = GetIndustryGfx(tile);
|
||||||
const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
|
const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,7 @@ struct ResolverObject {
|
||||||
TileIndex tile;
|
TileIndex tile;
|
||||||
Town *town;
|
Town *town;
|
||||||
HouseID house_id;
|
HouseID house_id;
|
||||||
|
bool not_yet_constructed; ///< True for construction check
|
||||||
} house;
|
} house;
|
||||||
struct {
|
struct {
|
||||||
TileIndex tile;
|
TileIndex tile;
|
||||||
|
|
|
@ -2164,7 +2164,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
|
if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
|
||||||
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile);
|
uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, true);
|
||||||
if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue;
|
if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1776,7 +1776,7 @@ static bool CheckClickOnStation(const ViewPort *vp, int x, int y)
|
||||||
static bool CheckClickOnSign(const ViewPort *vp, int x, int y)
|
static bool CheckClickOnSign(const ViewPort *vp, int x, int y)
|
||||||
{
|
{
|
||||||
/* Signs are turned off, or they are transparent and invisibility is ON, or company is a spectator */
|
/* Signs are turned off, or they are transparent and invisibility is ON, or company is a spectator */
|
||||||
if (!HasBit(_display_opt, DO_SHOW_SIGNS) || IsInvisibilitySet(TO_SIGNS) || _current_company == COMPANY_SPECTATOR) return false;
|
if (!HasBit(_display_opt, DO_SHOW_SIGNS) || IsInvisibilitySet(TO_SIGNS) || _local_company == COMPANY_SPECTATOR) return false;
|
||||||
|
|
||||||
const Sign *si;
|
const Sign *si;
|
||||||
FOR_ALL_SIGNS(si) {
|
FOR_ALL_SIGNS(si) {
|
||||||
|
|
|
@ -830,22 +830,22 @@ static void BringWindowToFront(Window *w)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the data (except the position and initial size) of a new Window.
|
* Initializes the data (except the position and initial size) of a new Window.
|
||||||
* @param cls Class of the window, used for identification and grouping. @see WindowClass
|
* @param desc Window description.
|
||||||
* @param window_number Number being assigned to the new window
|
* @param window_number Number being assigned to the new window
|
||||||
* @param desc_flags Window flags. @see WindowDefaultFlag
|
|
||||||
* @return Window pointer of the newly created window
|
* @return Window pointer of the newly created window
|
||||||
* @pre If nested widgets are used (\a widget is \c NULL), #nested_root and #nested_array_size must be initialized.
|
* @pre If nested widgets are used (\a widget is \c NULL), #nested_root and #nested_array_size must be initialized.
|
||||||
* In addition, #nested_array is either \c NULL, or already initialized.
|
* In addition, #nested_array is either \c NULL, or already initialized.
|
||||||
*/
|
*/
|
||||||
void Window::InitializeData(WindowClass cls, int window_number, uint32 desc_flags)
|
void Window::InitializeData(const WindowDesc *desc, WindowNumber window_number)
|
||||||
{
|
{
|
||||||
/* Set up window properties; some of them are needed to set up smallest size below */
|
/* Set up window properties; some of them are needed to set up smallest size below */
|
||||||
this->window_class = cls;
|
this->window_class = desc->cls;
|
||||||
this->flags4 |= WF_WHITE_BORDER_MASK; // just opened windows have a white border
|
this->flags4 |= WF_WHITE_BORDER_MASK; // just opened windows have a white border
|
||||||
|
if (desc->default_pos == WDP_CENTER) this->flags4 |= WF_CENTERED;
|
||||||
this->owner = INVALID_OWNER;
|
this->owner = INVALID_OWNER;
|
||||||
this->nested_focus = NULL;
|
this->nested_focus = NULL;
|
||||||
this->window_number = window_number;
|
this->window_number = window_number;
|
||||||
this->desc_flags = desc_flags;
|
this->desc_flags = desc->flags;
|
||||||
|
|
||||||
this->OnInit();
|
this->OnInit();
|
||||||
/* Initialize nested widget tree. */
|
/* Initialize nested widget tree. */
|
||||||
|
@ -1230,7 +1230,7 @@ void Window::CreateNestedTree(const WindowDesc *desc, bool fill_nested)
|
||||||
*/
|
*/
|
||||||
void Window::FinishInitNested(const WindowDesc *desc, WindowNumber window_number)
|
void Window::FinishInitNested(const WindowDesc *desc, WindowNumber window_number)
|
||||||
{
|
{
|
||||||
this->InitializeData(desc->cls, window_number, desc->flags);
|
this->InitializeData(desc, window_number);
|
||||||
Point pt = this->OnInitialPosition(desc, this->nested_root->smallest_x, this->nested_root->smallest_y, window_number);
|
Point pt = this->OnInitialPosition(desc, this->nested_root->smallest_x, this->nested_root->smallest_y, window_number);
|
||||||
this->InitializePositionSize(pt.x, pt.y, this->nested_root->smallest_x, this->nested_root->smallest_y);
|
this->InitializePositionSize(pt.x, pt.y, this->nested_root->smallest_x, this->nested_root->smallest_y);
|
||||||
this->FindWindowPlacementAndResize(desc->default_width, desc->default_height);
|
this->FindWindowPlacementAndResize(desc->default_width, desc->default_height);
|
||||||
|
@ -1697,6 +1697,7 @@ static bool HandleWindowDragging()
|
||||||
static void StartWindowDrag(Window *w)
|
static void StartWindowDrag(Window *w)
|
||||||
{
|
{
|
||||||
w->flags4 |= WF_DRAGGING;
|
w->flags4 |= WF_DRAGGING;
|
||||||
|
w->flags4 &= ~WF_CENTERED;
|
||||||
_dragging_window = true;
|
_dragging_window = true;
|
||||||
|
|
||||||
_drag_delta.x = w->left - _cursor.pos.x;
|
_drag_delta.x = w->left - _cursor.pos.x;
|
||||||
|
@ -1714,6 +1715,7 @@ static void StartWindowDrag(Window *w)
|
||||||
static void StartWindowSizing(Window *w, bool to_left)
|
static void StartWindowSizing(Window *w, bool to_left)
|
||||||
{
|
{
|
||||||
w->flags4 |= to_left ? WF_SIZING_LEFT : WF_SIZING_RIGHT;
|
w->flags4 |= to_left ? WF_SIZING_LEFT : WF_SIZING_RIGHT;
|
||||||
|
w->flags4 &= ~WF_CENTERED;
|
||||||
_dragging_window = true;
|
_dragging_window = true;
|
||||||
|
|
||||||
_drag_delta.x = _cursor.pos.x;
|
_drag_delta.x = _cursor.pos.x;
|
||||||
|
@ -2556,13 +2558,6 @@ void RelocateAllWindows(int neww, int newh)
|
||||||
left = PositionMainToolbar(w); // changes toolbar orientation
|
left = PositionMainToolbar(w); // changes toolbar orientation
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WC_SELECT_GAME:
|
|
||||||
case WC_GAME_OPTIONS:
|
|
||||||
case WC_NETWORK_WINDOW:
|
|
||||||
top = (newh - w->height) >> 1;
|
|
||||||
left = (neww - w->width) >> 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WC_NEWS_WINDOW:
|
case WC_NEWS_WINDOW:
|
||||||
top = newh - w->height;
|
top = newh - w->height;
|
||||||
left = (neww - w->width) >> 1;
|
left = (neww - w->width) >> 1;
|
||||||
|
@ -2585,6 +2580,12 @@ void RelocateAllWindows(int neww, int newh)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
if (w->flags4 & WF_CENTERED) {
|
||||||
|
top = (newh - w->height) >> 1;
|
||||||
|
left = (neww - w->width) >> 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
left = w->left;
|
left = w->left;
|
||||||
if (left + (w->width >> 1) >= neww) left = neww - w->width;
|
if (left + (w->width >> 1) >= neww) left = neww - w->width;
|
||||||
if (left < 0) left = 0;
|
if (left < 0) left = 0;
|
||||||
|
|
|
@ -334,7 +334,7 @@ struct Window : ZeroedMemoryAllocator {
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void InitializeData(WindowClass cls, int window_number, uint32 desc_flags);
|
void InitializeData(const WindowDesc *desc, WindowNumber window_number);
|
||||||
void InitializePositionSize(int x, int y, int min_width, int min_height);
|
void InitializePositionSize(int x, int y, int min_width, int min_height);
|
||||||
void FindWindowPlacementAndResize(int def_width, int def_height);
|
void FindWindowPlacementAndResize(int def_width, int def_height);
|
||||||
|
|
||||||
|
@ -842,6 +842,8 @@ enum WindowFlags {
|
||||||
|
|
||||||
WF_WHITE_BORDER_ONE = 1 << 13,
|
WF_WHITE_BORDER_ONE = 1 << 13,
|
||||||
WF_WHITE_BORDER_MASK = 1 << 14 | WF_WHITE_BORDER_ONE,
|
WF_WHITE_BORDER_MASK = 1 << 14 | WF_WHITE_BORDER_ONE,
|
||||||
|
|
||||||
|
WF_CENTERED = 1 << 15, ///< Window is centered and shall stay centered after ReInit
|
||||||
};
|
};
|
||||||
|
|
||||||
Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
|
Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
|
||||||
|
|
Loading…
Reference in New Issue