2016-01-20 23:45:09 +01:00
|
|
|
/*****************************************************************************
|
2024-01-01 12:52:28 +01:00
|
|
|
* Copyright (c) 2014-2024 OpenRCT2 developers
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* For a complete list of all authors, please refer to contributors.md
|
|
|
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
2016-05-04 19:24:41 +02:00
|
|
|
*****************************************************************************/
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2-ui/interface/Dropdown.h>
|
|
|
|
#include <openrct2-ui/interface/Widget.h>
|
2017-09-06 15:09:18 +02:00
|
|
|
#include <openrct2-ui/windows/Window.h>
|
2017-12-12 14:52:57 +01:00
|
|
|
#include <openrct2/Input.h>
|
Split actions hpp files into separate h and cpp files (#13548)
* Split up SmallSceneryPlace/Remove
Added undo function for Remove Scenery
* Refactor: Balloon and Banner actions hpp=>h/cpp
* Refactor: rename all action *.hpp files to *.cpp
This is preparation for separation in later commits. Note that without
the complete set of commits in this branch, the code will not build.
* Refactor Clear, Climate, Custom, and Footpath actions hpp=>h/cpp
* VSCode: add src subdirectories to includePath
* Refactor Guest actions hpp=>h/cpp
* Refactor Land actions hpp=>h/cpp
* Refactor LargeScenery actions hpp=>h/cpp
* Refactor Load, Maze, Network actions hpp=>h/cpp
* Refactor Park actions hpp=>h/cpp
* Refactor/style: move private function declarations in actions *.h
Previous action .h files included private function declarations with
private member variables, before public function declarations. This
commit re-orders the header files to the following order:
- public member variables
- private member variables
- public functions
- private functions
* Refactor Pause action hpp=>h/cpp
* Refactor Peep, Place, Player actions hpp=>h/cpp
* Refactor Ride actions hpp=>h/cpp
* Refactor Scenario, Set*, Sign* actions hpp=>h/cpp
* Refactor SmallScenerySetColourAction hpp=>h/cpp
* Refactor Staff actions hpp=>h/cpp
* Refactor Surface, Tile, Track* actions hpp=>h/cpp
* Refactor Wall and Water actions hpp=>h/cpp
* Fix various includes and other compile errors
Update includes for tests.
Move static function declarations to .h files
Add explicit includes to various files that were previously implicit
(the required header was a nested include in an action hpp file, and the
action .h file does not include that header)
Move RideSetStatus string enum to the cpp file to avoid unused imports
* Xcode: modify project file for actions refactor
* Cleanup whitespace and end-of-file newlines
Co-authored-by: duncanspumpkin <duncans_pumpkin@hotmail.co.uk>
2020-12-10 07:39:10 +01:00
|
|
|
#include <openrct2/actions/PlayerKickAction.h>
|
|
|
|
#include <openrct2/actions/PlayerSetGroupAction.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/drawing/Drawing.h>
|
2021-12-12 00:06:06 +01:00
|
|
|
#include <openrct2/localisation/Formatter.h>
|
2019-02-20 22:30:12 +01:00
|
|
|
#include <openrct2/network/NetworkAction.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/network/network.h>
|
2017-09-06 15:09:18 +02:00
|
|
|
#include <openrct2/sprites.h>
|
2017-12-13 13:02:24 +01:00
|
|
|
#include <openrct2/util/Util.h>
|
2021-08-16 23:42:39 +02:00
|
|
|
#include <utility>
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
namespace OpenRCT2::Ui::Windows
|
|
|
|
{
|
|
|
|
// clang-format off
|
2021-11-26 15:25:34 +01:00
|
|
|
enum WindowPlayerPage {
|
2017-06-06 23:24:18 +02:00
|
|
|
WINDOW_PLAYER_PAGE_OVERVIEW,
|
|
|
|
WINDOW_PLAYER_PAGE_STATISTICS,
|
2016-01-20 23:45:09 +01:00
|
|
|
};
|
|
|
|
|
2016-02-11 01:09:10 +01:00
|
|
|
#pragma region Widgets
|
|
|
|
|
2021-11-26 15:25:34 +01:00
|
|
|
enum WindowPlayerWidgetIdx {
|
2017-06-06 23:24:18 +02:00
|
|
|
WIDX_BACKGROUND,
|
|
|
|
WIDX_TITLE,
|
|
|
|
WIDX_CLOSE,
|
|
|
|
WIDX_PAGE_BACKGROUND,
|
|
|
|
WIDX_TAB_1,
|
|
|
|
WIDX_TAB_2,
|
|
|
|
|
|
|
|
WIDX_GROUP = 6,
|
|
|
|
WIDX_GROUP_DROPDOWN,
|
|
|
|
WIDX_LOCATE,
|
|
|
|
WIDX_KICK,
|
|
|
|
WIDX_VIEWPORT,
|
2016-01-20 23:45:09 +01:00
|
|
|
};
|
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
#define WINDOW_PLAYER_COMMON_WIDGETS \
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 0, 0}, {192, 157}, WindowWidgetType::Frame, WindowColour::Primary ), /* Panel / Background */ \
|
|
|
|
MakeWidget({ 1, 1}, {190, 14}, WindowWidgetType::Caption, WindowColour::Primary , STR_STRING, STR_WINDOW_TITLE_TIP), /* Title */ \
|
|
|
|
MakeWidget({179, 2}, { 11, 12}, WindowWidgetType::CloseBox, WindowColour::Primary , STR_CLOSE_X, STR_CLOSE_WINDOW_TIP), /* Close x button */ \
|
|
|
|
MakeWidget({ 0, 43}, {192, 114}, WindowWidgetType::Resize, WindowColour::Secondary ), /* Resize */ \
|
2020-08-29 04:31:31 +02:00
|
|
|
MakeTab ({ 3, 17} ), /* Tab 1 */ \
|
|
|
|
MakeTab ({ 34, 17} ) /* Tab 2 */
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2022-12-24 16:50:29 +01:00
|
|
|
static Widget window_player_overview_widgets[] = {
|
2017-06-06 23:24:18 +02:00
|
|
|
WINDOW_PLAYER_COMMON_WIDGETS,
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 3, 46}, {175, 12}, WindowWidgetType::DropdownMenu, WindowColour::Secondary ), // Permission group
|
|
|
|
MakeWidget({167, 47}, { 11, 10}, WindowWidgetType::Button, WindowColour::Secondary, STR_DROPDOWN_GLYPH ),
|
2022-12-24 17:47:22 +01:00
|
|
|
MakeWidget({179, 45}, { 12, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, ImageId(SPR_LOCATE), STR_LOCATE_PLAYER_TIP), // Locate button
|
|
|
|
MakeWidget({179, 69}, { 12, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, ImageId(SPR_DEMOLISH), STR_KICK_PLAYER_TIP ), // Kick button
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 3, 60}, {175, 61}, WindowWidgetType::Viewport, WindowColour::Secondary ), // Viewport
|
2024-03-09 15:15:45 +01:00
|
|
|
kWidgetsEnd,
|
2016-02-11 01:09:10 +01:00
|
|
|
};
|
|
|
|
|
2022-12-24 16:50:29 +01:00
|
|
|
static Widget window_player_statistics_widgets[] = {
|
2017-06-06 23:24:18 +02:00
|
|
|
WINDOW_PLAYER_COMMON_WIDGETS,
|
2024-03-09 15:15:45 +01:00
|
|
|
kWidgetsEnd,
|
2016-01-20 23:45:09 +01:00
|
|
|
};
|
|
|
|
|
2022-12-24 16:50:29 +01:00
|
|
|
static Widget *window_player_page_widgets[] = {
|
2017-06-06 23:24:18 +02:00
|
|
|
window_player_overview_widgets,
|
2021-10-17 15:31:56 +02:00
|
|
|
window_player_statistics_widgets,
|
2016-01-20 23:45:09 +01:00
|
|
|
};
|
|
|
|
|
2016-02-11 01:09:10 +01:00
|
|
|
#pragma endregion
|
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// clang-format on
|
2023-06-23 00:44:17 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
class PlayerWindow final : public Window
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
int16_t _previousRotation = -1;
|
|
|
|
bool _drawViewport = true;
|
2022-02-14 00:06:19 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
public:
|
|
|
|
void Init(const uint8_t id)
|
|
|
|
{
|
|
|
|
number = id;
|
|
|
|
InitScrollWidgets();
|
|
|
|
SetPage(WINDOW_PLAYER_PAGE_OVERVIEW);
|
|
|
|
}
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
#pragma region Events
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnOpen() override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
page = 0;
|
|
|
|
frame_no = 0;
|
|
|
|
list_information_type = 0;
|
|
|
|
min_width = 210;
|
|
|
|
min_height = 134;
|
|
|
|
max_width = 500;
|
|
|
|
max_height = 450;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
Invalidate();
|
|
|
|
|
|
|
|
widgets = window_player_page_widgets[WINDOW_PLAYER_PAGE_OVERVIEW];
|
|
|
|
hold_down_widgets = 0;
|
|
|
|
pressed_widgets = 0;
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnResize() override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (page)
|
|
|
|
{
|
|
|
|
case WINDOW_PLAYER_PAGE_OVERVIEW:
|
|
|
|
OnResizeOverview();
|
|
|
|
break;
|
2017-09-06 15:09:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
case WINDOW_PLAYER_PAGE_STATISTICS:
|
|
|
|
OnResizeStatistics();
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnUpdate() override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (page)
|
|
|
|
{
|
|
|
|
case WINDOW_PLAYER_PAGE_OVERVIEW:
|
|
|
|
OnUpdateOverview();
|
|
|
|
break;
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
case WINDOW_PLAYER_PAGE_STATISTICS:
|
|
|
|
OnUpdateStatistics();
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnPrepareDraw() override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (page)
|
|
|
|
{
|
|
|
|
case WINDOW_PLAYER_PAGE_OVERVIEW:
|
|
|
|
OnPrepareDrawOverview();
|
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
case WINDOW_PLAYER_PAGE_STATISTICS:
|
|
|
|
OnPrepareDrawStatistics();
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnDraw(DrawPixelInfo& dpi) override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (page)
|
|
|
|
{
|
|
|
|
case WINDOW_PLAYER_PAGE_OVERVIEW:
|
|
|
|
OnDrawOverview(dpi);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WINDOW_PLAYER_PAGE_STATISTICS:
|
|
|
|
OnDrawStatistics(dpi);
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnMouseDown(WidgetIndex widgetIndex) override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (page)
|
|
|
|
{
|
|
|
|
case WINDOW_PLAYER_PAGE_OVERVIEW:
|
|
|
|
OnMouseDownOverview(widgetIndex);
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnMouseUp(WidgetIndex widgetIndex) override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (widgetIndex)
|
|
|
|
{
|
|
|
|
case WIDX_CLOSE:
|
|
|
|
Close();
|
|
|
|
return;
|
|
|
|
case WIDX_TAB_1:
|
|
|
|
case WIDX_TAB_2:
|
|
|
|
SetPage(widgetIndex - WIDX_TAB_1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (page)
|
|
|
|
{
|
|
|
|
case WINDOW_PLAYER_PAGE_OVERVIEW:
|
|
|
|
OnMouseUpOverview(widgetIndex);
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnDropdown(WidgetIndex widgetIndex, int32_t selectedIndex) override
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (page)
|
|
|
|
{
|
|
|
|
case WINDOW_PLAYER_PAGE_OVERVIEW:
|
|
|
|
OnDropdownOverview(widgetIndex, selectedIndex);
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2023-03-29 23:00:06 +02:00
|
|
|
#pragma endregion
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
private:
|
|
|
|
void SetPage(int32_t newPage)
|
|
|
|
{
|
|
|
|
int32_t originalPage = page;
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
page = newPage;
|
|
|
|
frame_no = 0;
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
hold_down_widgets = 0;
|
|
|
|
pressed_widgets = 0;
|
|
|
|
widgets = window_player_page_widgets[newPage];
|
|
|
|
Invalidate();
|
|
|
|
OnResize();
|
|
|
|
OnPrepareDraw();
|
|
|
|
InitScrollWidgets();
|
|
|
|
Invalidate();
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
if (page == WINDOW_PLAYER_PAGE_OVERVIEW)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
if (viewport == nullptr)
|
|
|
|
{
|
|
|
|
const auto viewportFocus = Focus(TileCoordsXYZ(128, 128, 0).ToCoordsXYZ());
|
|
|
|
ViewportCreate(this, windowPos, width, height, viewportFocus);
|
|
|
|
flags |= WF_NO_SCROLLING;
|
|
|
|
OnPrepareDraw();
|
|
|
|
UpdateViewport(false);
|
|
|
|
}
|
|
|
|
else if (originalPage != page)
|
|
|
|
{
|
|
|
|
OnPrepareDraw();
|
|
|
|
UpdateViewport(false);
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2024-03-10 14:52:35 +01:00
|
|
|
else
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
RemoveViewport();
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void DrawTabImages(DrawPixelInfo& dpi)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
Widget* widget;
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// Tab 1
|
|
|
|
if (!IsWidgetDisabled(WIDX_TAB_1))
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
widget = &this->widgets[WIDX_TAB_1];
|
|
|
|
auto screenCoords = windowPos + ScreenCoordsXY{ widget->left, widget->top };
|
|
|
|
GfxDrawSprite(dpi, ImageId(SPR_PEEP_LARGE_FACE_NORMAL), screenCoords);
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// Tab 2
|
|
|
|
if (!IsWidgetDisabled(WIDX_TAB_2))
|
|
|
|
{
|
|
|
|
widget = &this->widgets[WIDX_TAB_2];
|
|
|
|
auto screenCoords = windowPos + ScreenCoordsXY{ widget->left, widget->top };
|
|
|
|
int32_t imageId = SPR_TAB_FINANCES_SUMMARY_0;
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
if (page == WINDOW_PLAYER_PAGE_STATISTICS)
|
|
|
|
{
|
|
|
|
imageId += (frame_no / 2) & 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
GfxDrawSprite(dpi, ImageId(imageId), screenCoords);
|
|
|
|
}
|
2019-05-01 17:54:12 +02:00
|
|
|
}
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void UpdateViewport(bool scroll)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
int32_t playerIndex = NetworkGetPlayerIndex(static_cast<uint8_t>(number));
|
|
|
|
if (playerIndex == -1)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
return;
|
|
|
|
}
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
if (viewport != nullptr)
|
|
|
|
{
|
|
|
|
auto coord = NetworkGetPlayerLastActionCoord(playerIndex);
|
|
|
|
if (coord.x != 0 || coord.y != 0 || coord.z != 0)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
auto centreLoc = centre_2d_coordinates(coord, viewport);
|
|
|
|
if (!centreLoc.has_value())
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Don't scroll if the view was originally undefined
|
|
|
|
if (!_drawViewport)
|
|
|
|
{
|
|
|
|
scroll = false;
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2024-03-10 14:52:35 +01:00
|
|
|
|
|
|
|
if (!scroll || savedViewPos != centreLoc.value())
|
|
|
|
{
|
|
|
|
flags |= WF_SCROLLING_TO_LOCATION;
|
|
|
|
savedViewPos = centreLoc.value();
|
|
|
|
if (!scroll)
|
|
|
|
{
|
|
|
|
viewport->viewPos = centreLoc.value();
|
|
|
|
}
|
|
|
|
InvalidateWidget(WIDX_VIEWPORT);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw the viewport
|
|
|
|
_drawViewport = true;
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2024-03-10 14:52:35 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Don't draw the viewport
|
|
|
|
_drawViewport = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void UpdateTitle()
|
|
|
|
{
|
|
|
|
auto ft = Formatter::Common();
|
|
|
|
int32_t player = NetworkGetPlayerIndex(static_cast<uint8_t>(number));
|
|
|
|
if (player != -1)
|
|
|
|
{
|
|
|
|
ft.Add<const char*>(NetworkGetPlayerName(player)); // set title caption to player name
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
ft.Add<const char*>("");
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
#pragma region Overview
|
|
|
|
|
|
|
|
void OnResizeOverview()
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
WindowSetResize(*this, 240, 170, 500, 300);
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnUpdateOverview()
|
|
|
|
{
|
|
|
|
frame_no++;
|
|
|
|
InvalidateWidget(WIDX_TAB_1 + page);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
if (NetworkGetPlayerIndex(static_cast<uint8_t>(number)) == -1)
|
|
|
|
{
|
|
|
|
Close();
|
|
|
|
return;
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// Update viewport
|
|
|
|
bool scroll = true;
|
2020-10-16 01:13:52 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// Use this spare window field for rotation check
|
|
|
|
if (_previousRotation != GetCurrentRotation())
|
|
|
|
{
|
|
|
|
_previousRotation = GetCurrentRotation();
|
|
|
|
scroll = false;
|
|
|
|
}
|
|
|
|
UpdateViewport(scroll);
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnPrepareDrawOverview()
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
int32_t playerIndex = NetworkGetPlayerIndex(static_cast<uint8_t>(number));
|
|
|
|
if (playerIndex == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
if (window_player_page_widgets[page] != widgets)
|
|
|
|
{
|
|
|
|
widgets = window_player_page_widgets[page];
|
|
|
|
InitScrollWidgets();
|
|
|
|
}
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
pressed_widgets &= ~(WIDX_TAB_1);
|
|
|
|
pressed_widgets &= ~(WIDX_TAB_2);
|
|
|
|
pressed_widgets |= 1uLL << (page + WIDX_TAB_1);
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
UpdateTitle();
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
ResizeFrameWithPage();
|
|
|
|
widgets[WIDX_LOCATE].right = width - 2;
|
|
|
|
widgets[WIDX_LOCATE].left = width - 25;
|
|
|
|
widgets[WIDX_KICK].right = width - 2;
|
|
|
|
widgets[WIDX_KICK].left = width - 25;
|
|
|
|
widgets[WIDX_VIEWPORT].right = width - 26;
|
|
|
|
widgets[WIDX_VIEWPORT].bottom = height - 14;
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
int32_t groupDropdownWidth = widgets[WIDX_GROUP].width();
|
|
|
|
widgets[WIDX_GROUP].left = (width - groupDropdownWidth) / 2;
|
|
|
|
widgets[WIDX_GROUP].right = widgets[WIDX_GROUP].left + groupDropdownWidth;
|
|
|
|
widgets[WIDX_GROUP_DROPDOWN].left = widgets[WIDX_GROUP].right - 10;
|
|
|
|
widgets[WIDX_GROUP_DROPDOWN].right = widgets[WIDX_GROUP].right;
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_2);
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
if (viewport != nullptr)
|
|
|
|
{
|
|
|
|
Widget* viewportWidget = &window_player_overview_widgets[WIDX_VIEWPORT];
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
viewport->pos = windowPos + ScreenCoordsXY{ viewportWidget->left, viewportWidget->top };
|
|
|
|
viewport->width = viewportWidget->width();
|
|
|
|
viewport->height = viewportWidget->height();
|
|
|
|
viewport->view_width = viewport->zoom.ApplyTo(viewport->width);
|
|
|
|
viewport->view_height = viewport->zoom.ApplyTo(viewport->height);
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// Only enable kick button for other players
|
|
|
|
const bool canKick = NetworkCanPerformAction(NetworkGetCurrentPlayerGroupIndex(), NetworkPermission::KickPlayer);
|
|
|
|
const bool isServer = NetworkGetPlayerFlags(playerIndex) & NETWORK_PLAYER_FLAG_ISSERVER;
|
|
|
|
const bool isOwnWindow = (NetworkGetCurrentPlayerId() == number);
|
|
|
|
WidgetSetEnabled(*this, WIDX_KICK, canKick && !isOwnWindow && !isServer);
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnDrawOverview(DrawPixelInfo& dpi)
|
|
|
|
{
|
|
|
|
DrawWidgets(dpi);
|
|
|
|
DrawTabImages(dpi);
|
2019-03-15 01:40:43 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
int32_t player = NetworkGetPlayerIndex(static_cast<uint8_t>(number));
|
|
|
|
if (player == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// Draw current group
|
|
|
|
int32_t groupindex = NetworkGetGroupIndex(NetworkGetPlayerGroup(player));
|
|
|
|
if (groupindex != -1)
|
|
|
|
{
|
|
|
|
Widget* widget = &window_player_overview_widgets[WIDX_GROUP];
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
thread_local std::string _buffer;
|
|
|
|
_buffer.assign("{WINDOW_COLOUR_2}");
|
|
|
|
_buffer += NetworkGetGroupName(groupindex);
|
|
|
|
auto ft = Formatter();
|
|
|
|
ft.Add<const char*>(_buffer.c_str());
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
DrawTextEllipsised(
|
|
|
|
dpi, windowPos + ScreenCoordsXY{ widget->midX() - 5, widget->top }, widget->width() - 8, STR_STRING, ft,
|
|
|
|
{ TextAlignment::CENTRE });
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
// Draw ping
|
|
|
|
auto screenCoords = windowPos + ScreenCoordsXY{ 90, 24 };
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
auto ft = Formatter();
|
|
|
|
ft.Add<StringId>(STR_PING);
|
|
|
|
DrawTextBasic(dpi, screenCoords, STR_WINDOW_COLOUR_2_STRINGID, ft);
|
|
|
|
char ping[64];
|
|
|
|
snprintf(ping, 64, "%d ms", NetworkGetPlayerPing(player));
|
|
|
|
GfxDrawString(dpi, screenCoords + ScreenCoordsXY(30, 0), ping, { colours[2] });
|
|
|
|
|
|
|
|
// Draw last action
|
|
|
|
screenCoords = windowPos + ScreenCoordsXY{ width / 2, height - 13 };
|
|
|
|
int32_t updatedWidth = this->width - 8;
|
|
|
|
int32_t lastaction = NetworkGetPlayerLastAction(player, 0);
|
|
|
|
ft = Formatter();
|
|
|
|
if (lastaction != -999)
|
|
|
|
{
|
|
|
|
ft.Add<StringId>(NetworkGetActionNameStringID(lastaction));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ft.Add<StringId>(STR_ACTION_NA);
|
|
|
|
}
|
|
|
|
DrawTextEllipsised(dpi, screenCoords, updatedWidth, STR_LAST_ACTION_RAN, ft, { TextAlignment::CENTRE });
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
if (viewport != nullptr && _drawViewport)
|
|
|
|
{
|
|
|
|
WindowDrawViewport(dpi, *this);
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2019-02-20 22:18:40 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnMouseDownOverview(WidgetIndex widgetIndex)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
auto* widget = &widgets[widgetIndex];
|
|
|
|
switch (widgetIndex)
|
|
|
|
{
|
|
|
|
case WIDX_GROUP_DROPDOWN:
|
|
|
|
ShowGroupDropdownOverview(widget);
|
|
|
|
break;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnMouseUpOverview(WidgetIndex widgetIndex)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
switch (widgetIndex)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
case WIDX_LOCATE:
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
WindowBase* mainWindow = WindowGetMain();
|
|
|
|
if (mainWindow != nullptr)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
int32_t player = NetworkGetPlayerIndex(static_cast<uint8_t>(number));
|
|
|
|
if (player == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
auto coord = NetworkGetPlayerLastActionCoord(player);
|
|
|
|
if (coord.x || coord.y || coord.z)
|
|
|
|
{
|
|
|
|
WindowScrollToLocation(*mainWindow, coord);
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
}
|
2024-03-10 14:52:35 +01:00
|
|
|
break;
|
|
|
|
case WIDX_KICK:
|
|
|
|
{
|
|
|
|
auto kickPlayerAction = PlayerKickAction(number);
|
|
|
|
GameActions::Execute(&kickPlayerAction);
|
|
|
|
}
|
|
|
|
break;
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
}
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnDropdownOverview(WidgetIndex widgetIndex, int32_t dropdownIndex)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
const auto playerId = static_cast<uint8_t>(number);
|
|
|
|
const auto playerIdx = NetworkGetPlayerIndex(playerId);
|
|
|
|
if (playerIdx == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (dropdownIndex == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const auto groupId = NetworkGetGroupID(dropdownIndex);
|
|
|
|
const auto windowHandle = std::make_pair(classification, number);
|
|
|
|
auto playerSetGroupAction = PlayerSetGroupAction(playerId, groupId);
|
|
|
|
playerSetGroupAction.SetCallback([windowHandle](const GameAction* ga, const GameActions::Result* result) {
|
|
|
|
if (result->Error == GameActions::Status::Ok)
|
|
|
|
{
|
|
|
|
WindowInvalidateByNumber(windowHandle.first, windowHandle.second);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
GameActions::Execute(&playerSetGroupAction);
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2024-03-10 14:52:35 +01:00
|
|
|
|
|
|
|
void ShowGroupDropdownOverview(Widget* widget)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
Widget* dropdownWidget;
|
|
|
|
int32_t numItems, i;
|
|
|
|
int32_t player = NetworkGetPlayerIndex(static_cast<uint8_t>(number));
|
|
|
|
if (player == -1)
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
return;
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
dropdownWidget = widget - 1;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
numItems = NetworkGetNumGroups();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
WindowDropdownShowTextCustomWidth(
|
|
|
|
{ windowPos.x + dropdownWidget->left, windowPos.y + dropdownWidget->top }, dropdownWidget->height() + 1,
|
|
|
|
colours[1], 0, 0, numItems, widget->right - dropdownWidget->left);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
for (i = 0; i < NetworkGetNumGroups(); i++)
|
|
|
|
{
|
|
|
|
gDropdownItems[i].Format = STR_OPTIONS_DROPDOWN_ITEM;
|
|
|
|
gDropdownItems[i].Args = reinterpret_cast<uintptr_t>(NetworkGetGroupName(i));
|
|
|
|
}
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
Dropdown::SetChecked(NetworkGetGroupIndex(NetworkGetPlayerGroup(player)), true);
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2023-03-29 23:00:06 +02:00
|
|
|
#pragma endregion
|
2016-11-13 20:17:49 +01:00
|
|
|
|
2023-03-29 23:00:06 +02:00
|
|
|
#pragma region Statistics
|
2016-02-11 01:09:10 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnResizeStatistics()
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
WindowSetResize(*this, 210, 80, 210, 80);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2016-01-20 23:45:09 +01:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnUpdateStatistics()
|
2023-03-29 23:00:06 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
frame_no++;
|
|
|
|
InvalidateWidget(WIDX_TAB_1 + page);
|
|
|
|
|
|
|
|
if (NetworkGetPlayerIndex(static_cast<uint8_t>(number)) == -1)
|
|
|
|
{
|
|
|
|
Close();
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
}
|
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnPrepareDrawStatistics()
|
|
|
|
{
|
|
|
|
if (window_player_page_widgets[page] != widgets)
|
|
|
|
{
|
|
|
|
widgets = window_player_page_widgets[page];
|
|
|
|
InitScrollWidgets();
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
pressed_widgets &= ~(WIDX_TAB_1);
|
|
|
|
pressed_widgets &= ~(WIDX_TAB_2);
|
|
|
|
pressed_widgets |= 1uLL << (page + WIDX_TAB_1);
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
UpdateTitle();
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
ResizeFrameWithPage();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_2);
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
void OnDrawStatistics(DrawPixelInfo& dpi)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
DrawWidgets(dpi);
|
|
|
|
DrawTabImages(dpi);
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
int32_t player = NetworkGetPlayerIndex(static_cast<uint8_t>(number));
|
|
|
|
if (player == -1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
auto screenCoords = windowPos
|
|
|
|
+ ScreenCoordsXY{ window_player_overview_widgets[WIDX_PAGE_BACKGROUND].left + 4,
|
|
|
|
window_player_overview_widgets[WIDX_PAGE_BACKGROUND].top + 4 };
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
auto ft = Formatter();
|
|
|
|
ft.Add<uint32_t>(NetworkGetPlayerCommandsRan(player));
|
|
|
|
DrawTextBasic(dpi, screenCoords, STR_COMMANDS_RAN, ft);
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-04-14 18:37:01 +02:00
|
|
|
screenCoords.y += kListRowHeight;
|
2024-03-10 14:52:35 +01:00
|
|
|
|
|
|
|
ft = Formatter();
|
|
|
|
ft.Add<uint32_t>(NetworkGetPlayerMoneySpent(player));
|
|
|
|
DrawTextBasic(dpi, screenCoords, STR_MONEY_SPENT, ft);
|
|
|
|
}
|
2016-04-20 08:16:17 +02:00
|
|
|
|
2023-03-29 23:00:06 +02:00
|
|
|
#pragma endregion
|
2024-03-10 14:52:35 +01:00
|
|
|
};
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-17 07:37:46 +01:00
|
|
|
WindowBase* PlayerOpen(uint8_t id)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2024-03-10 14:52:35 +01:00
|
|
|
auto* window = static_cast<PlayerWindow*>(WindowBringToFrontByNumber(WindowClass::Player, id));
|
|
|
|
if (window == nullptr)
|
|
|
|
{
|
|
|
|
window = WindowCreate<PlayerWindow>(WindowClass::Player, 240, 170, WF_RESIZABLE);
|
|
|
|
}
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
window->Init(id);
|
2023-03-29 23:00:06 +02:00
|
|
|
|
2024-03-10 14:52:35 +01:00
|
|
|
return window;
|
|
|
|
}
|
|
|
|
} // namespace OpenRCT2::Ui::Windows
|