mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
Add custom widget logic and network stats API
This commit is contained in:
31
distribution/openrct2.d.ts
vendored
31
distribution/openrct2.d.ts
vendored
@@ -1397,6 +1397,7 @@ declare global {
|
|||||||
readonly players: Player[];
|
readonly players: Player[];
|
||||||
readonly currentPlayer: Player;
|
readonly currentPlayer: Player;
|
||||||
defaultGroup: number;
|
defaultGroup: number;
|
||||||
|
readonly stats: NetworkStats;
|
||||||
|
|
||||||
getServerInfo(): ServerInfo;
|
getServerInfo(): ServerInfo;
|
||||||
addGroup(): void;
|
addGroup(): void;
|
||||||
@@ -1442,6 +1443,11 @@ declare global {
|
|||||||
readonly providerWebsite: string;
|
readonly providerWebsite: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface NetworkStats {
|
||||||
|
bytesReceived: number[];
|
||||||
|
bytesSent: number[];
|
||||||
|
}
|
||||||
|
|
||||||
type PermissionType =
|
type PermissionType =
|
||||||
"chat" |
|
"chat" |
|
||||||
"terraform" |
|
"terraform" |
|
||||||
@@ -1996,14 +2002,15 @@ declare global {
|
|||||||
* Represents the type of a widget, e.g. button or label.
|
* Represents the type of a widget, e.g. button or label.
|
||||||
*/
|
*/
|
||||||
type WidgetType =
|
type WidgetType =
|
||||||
"button" | "checkbox" | "colourpicker" | "dropdown" | "groupbox" |
|
"button" | "checkbox" | "colourpicker" | "custom" | "dropdown" | "groupbox" |
|
||||||
"label" | "listview" | "spinner" | "textbox" | "viewport";
|
"label" | "listview" | "spinner" | "textbox" | "viewport";
|
||||||
|
|
||||||
type Widget =
|
type Widget =
|
||||||
ButtonWidget | CheckboxWidget | ColourPickerWidget | DropdownWidget | GroupBoxWidget |
|
ButtonWidget | CheckboxWidget | ColourPickerWidget | CustomWidget | DropdownWidget | GroupBoxWidget |
|
||||||
LabelWidget | ListView | SpinnerWidget | TextBoxWidget | ViewportWidget;
|
LabelWidget | ListView | SpinnerWidget | TextBoxWidget | ViewportWidget;
|
||||||
|
|
||||||
interface WidgetBase {
|
interface WidgetBase {
|
||||||
|
readonly window?: Window;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
width: number;
|
width: number;
|
||||||
@@ -2040,6 +2047,11 @@ declare global {
|
|||||||
onChange?: (colour: number) => void;
|
onChange?: (colour: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CustomWidget extends WidgetBase {
|
||||||
|
type: 'custom';
|
||||||
|
onDraw?: (this: CustomWidget, g: GraphicsContext) => void;
|
||||||
|
}
|
||||||
|
|
||||||
interface DropdownWidget extends WidgetBase {
|
interface DropdownWidget extends WidgetBase {
|
||||||
type: 'dropdown';
|
type: 'dropdown';
|
||||||
items?: string[];
|
items?: string[];
|
||||||
@@ -2191,6 +2203,21 @@ declare global {
|
|||||||
scrollTo(position: CoordsXY | CoordsXYZ): void;
|
scrollTo(position: CoordsXY | CoordsXYZ): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API for drawing graphics.
|
||||||
|
*/
|
||||||
|
interface GraphicsContext {
|
||||||
|
stroke: number;
|
||||||
|
fill: number;
|
||||||
|
|
||||||
|
clear(): void;
|
||||||
|
clip(x: number, y: number, width: number, height: number): void;
|
||||||
|
line(x1: number, y1: number, x2: number, y2: number): void;
|
||||||
|
rect(x: number, y: number, width: number, height: number): void;
|
||||||
|
fillRect(x: number, y: number, width: number, height: number): void;
|
||||||
|
image(image: number, x: number, y: number): void;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens for incoming connections.
|
* Listens for incoming connections.
|
||||||
* Based on node.js net.Server, see https://nodejs.org/api/net.html for more information.
|
* Based on node.js net.Server, see https://nodejs.org/api/net.html for more information.
|
||||||
|
|||||||
@@ -632,8 +632,15 @@ void WindowDrawWidgets(rct_window* w, rct_drawpixelinfo* dpi)
|
|||||||
{
|
{
|
||||||
// Check if widget is outside the draw region
|
// Check if widget is outside the draw region
|
||||||
if (w->windowPos.x + widget->left < dpi->x + dpi->width && w->windowPos.x + widget->right >= dpi->x)
|
if (w->windowPos.x + widget->left < dpi->x + dpi->width && w->windowPos.x + widget->right >= dpi->x)
|
||||||
|
{
|
||||||
if (w->windowPos.y + widget->top < dpi->y + dpi->height && w->windowPos.y + widget->bottom >= dpi->y)
|
if (w->windowPos.y + widget->top < dpi->y + dpi->height && w->windowPos.y + widget->bottom >= dpi->y)
|
||||||
WidgetDraw(dpi, w, widgetIndex);
|
{
|
||||||
|
if (w->IsLegacy())
|
||||||
|
WidgetDraw(dpi, w, widgetIndex);
|
||||||
|
else
|
||||||
|
w->OnDrawWidget(widgetIndex, *dpi);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
widgetIndex++;
|
widgetIndex++;
|
||||||
}
|
}
|
||||||
@@ -681,6 +688,21 @@ void InvalidateAllWindowsAfterInput()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Window::IsLegacy()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::OnDraw(rct_drawpixelinfo& dpi)
|
||||||
|
{
|
||||||
|
WindowDrawWidgets(this, &dpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::OnDrawWidget(rct_widgetindex widgetIndex, rct_drawpixelinfo& dpi)
|
||||||
|
{
|
||||||
|
WidgetDraw(&dpi, this, widgetIndex);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::InvalidateWidget(rct_widgetindex widgetIndex)
|
void Window::InvalidateWidget(rct_widgetindex widgetIndex)
|
||||||
{
|
{
|
||||||
widget_invalidate(this, widgetIndex);
|
widget_invalidate(this, widgetIndex);
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
struct Window : rct_window
|
struct Window : rct_window
|
||||||
{
|
{
|
||||||
|
virtual bool IsLegacy() override;
|
||||||
|
virtual void OnDraw(rct_drawpixelinfo& dpi) override;
|
||||||
|
virtual void OnDrawWidget(rct_widgetindex widgetIndex, rct_drawpixelinfo& dpi) override;
|
||||||
|
|
||||||
void InvalidateWidget(rct_widgetindex widgetIndex);
|
void InvalidateWidget(rct_widgetindex widgetIndex);
|
||||||
bool IsWidgetDisabled(rct_widgetindex widgetIndex) const;
|
bool IsWidgetDisabled(rct_widgetindex widgetIndex) const;
|
||||||
bool IsWidgetPressed(rct_widgetindex widgetIndex) const;
|
bool IsWidgetPressed(rct_widgetindex widgetIndex) const;
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
<ClInclude Include="scripting\CustomListView.h" />
|
<ClInclude Include="scripting\CustomListView.h" />
|
||||||
<ClInclude Include="scripting\CustomMenu.h" />
|
<ClInclude Include="scripting\CustomMenu.h" />
|
||||||
<ClInclude Include="scripting\CustomWindow.h" />
|
<ClInclude Include="scripting\CustomWindow.h" />
|
||||||
|
<ClInclude Include="scripting\ScGraphicsContext.hpp" />
|
||||||
<ClInclude Include="scripting\ScTileSelection.hpp" />
|
<ClInclude Include="scripting\ScTileSelection.hpp" />
|
||||||
<ClInclude Include="scripting\ScTitleSequence.hpp" />
|
<ClInclude Include="scripting\ScTitleSequence.hpp" />
|
||||||
<ClInclude Include="scripting\ScUi.hpp" />
|
<ClInclude Include="scripting\ScUi.hpp" />
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
|
||||||
# include "../interface/Dropdown.h"
|
# include "../interface/Dropdown.h"
|
||||||
|
# include "../scripting/ScGraphicsContext.hpp"
|
||||||
|
# include "../scripting/ScWidget.hpp"
|
||||||
# include "CustomListView.h"
|
# include "CustomListView.h"
|
||||||
# include "ScUi.hpp"
|
# include "ScUi.hpp"
|
||||||
# include "ScWindow.hpp"
|
# include "ScWindow.hpp"
|
||||||
@@ -83,6 +85,7 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
// Event handlers
|
// Event handlers
|
||||||
DukValue OnClick;
|
DukValue OnClick;
|
||||||
DukValue OnChange;
|
DukValue OnChange;
|
||||||
|
DukValue OnDraw;
|
||||||
DukValue OnIncrement;
|
DukValue OnIncrement;
|
||||||
DukValue OnDecrement;
|
DukValue OnDecrement;
|
||||||
DukValue OnHighlight;
|
DukValue OnHighlight;
|
||||||
@@ -131,6 +134,10 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
}
|
}
|
||||||
result.OnChange = desc["onChange"];
|
result.OnChange = desc["onChange"];
|
||||||
}
|
}
|
||||||
|
else if (result.Type == "custom")
|
||||||
|
{
|
||||||
|
result.OnDraw = desc["onDraw"];
|
||||||
|
}
|
||||||
else if (result.Type == "dropdown")
|
else if (result.Type == "dropdown")
|
||||||
{
|
{
|
||||||
if (desc["items"].is_array())
|
if (desc["items"].is_array())
|
||||||
@@ -375,7 +382,7 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
static void InvokeEventHandler(
|
static void InvokeEventHandler(
|
||||||
const std::shared_ptr<Plugin>& owner, const DukValue& dukHandler, const std::vector<DukValue>& args);
|
const std::shared_ptr<Plugin>& owner, const DukValue& dukHandler, const std::vector<DukValue>& args);
|
||||||
|
|
||||||
class CustomWindow : public rct_window
|
class CustomWindow : public Window
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static rct_windownumber _nextWindowNumber;
|
static rct_windownumber _nextWindowNumber;
|
||||||
@@ -536,6 +543,37 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnDrawWidget(rct_widgetindex widgetIndex, rct_drawpixelinfo& dpi) override
|
||||||
|
{
|
||||||
|
const auto& widget = widgets[widgetIndex];
|
||||||
|
const auto& info = GetInfo(this);
|
||||||
|
const auto widgetDesc = info.GetCustomWidgetDesc(this, widgetIndex);
|
||||||
|
if (widgetDesc != nullptr && widgetDesc->Type == "custom")
|
||||||
|
{
|
||||||
|
auto& onDraw = widgetDesc->OnDraw;
|
||||||
|
if (onDraw.is_function())
|
||||||
|
{
|
||||||
|
rct_drawpixelinfo widgetDpi;
|
||||||
|
if (clip_drawpixelinfo(
|
||||||
|
&widgetDpi, &dpi, { windowPos.x + widget.left, windowPos.y + widget.top }, widget.width(),
|
||||||
|
widget.height()))
|
||||||
|
{
|
||||||
|
auto ctx = onDraw.context();
|
||||||
|
auto dukWidget = ScWidget::ToDukValue(ctx, this, widgetIndex);
|
||||||
|
auto dukG = GetObjectAsDukValue(ctx, std::make_shared<ScGraphicsContext>(ctx, widgetDpi));
|
||||||
|
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||||
|
scriptEngine.ExecutePluginCall(info.Owner, widgetDesc->OnDraw, dukWidget, { dukG }, false);
|
||||||
|
}
|
||||||
|
// auto widgetDpi = dpi.Crop(
|
||||||
|
// { windowPos.x + widget.left, windowPos.y + widget.top }, { widget.width(), widget.height() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Window::OnDrawWidget(widgetIndex, dpi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnMouseUp(rct_widgetindex widgetIndex) override
|
void OnMouseUp(rct_widgetindex widgetIndex) override
|
||||||
{
|
{
|
||||||
switch (widgetIndex)
|
switch (widgetIndex)
|
||||||
@@ -988,6 +1026,11 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
widget.image = GetColourButtonImage(desc.Colour);
|
widget.image = GetColourButtonImage(desc.Colour);
|
||||||
widgetList.push_back(widget);
|
widgetList.push_back(widget);
|
||||||
}
|
}
|
||||||
|
else if (desc.Type == "custom")
|
||||||
|
{
|
||||||
|
widget.type = WindowWidgetType::Custom;
|
||||||
|
widgetList.push_back(widget);
|
||||||
|
}
|
||||||
else if (desc.Type == "dropdown")
|
else if (desc.Type == "dropdown")
|
||||||
{
|
{
|
||||||
widget.type = WindowWidgetType::DropdownMenu;
|
widget.type = WindowWidgetType::DropdownMenu;
|
||||||
@@ -1101,6 +1144,8 @@ namespace OpenRCT2::Ui::Windows
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rct_windownumber CustomWindow::_nextWindowNumber;
|
||||||
|
|
||||||
rct_window* window_custom_open(std::shared_ptr<Plugin> owner, DukValue dukDesc)
|
rct_window* window_custom_open(std::shared_ptr<Plugin> owner, DukValue dukDesc)
|
||||||
{
|
{
|
||||||
auto desc = CustomWindowDesc::FromDukValue(dukDesc);
|
auto desc = CustomWindowDesc::FromDukValue(dukDesc);
|
||||||
|
|||||||
90
src/openrct2-ui/scripting/ScGraphicsContext.hpp
Normal file
90
src/openrct2-ui/scripting/ScGraphicsContext.hpp
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Copyright (c) 2014-2020 OpenRCT2 developers
|
||||||
|
*
|
||||||
|
* For a complete list of all authors, please refer to contributors.md
|
||||||
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||||
|
*
|
||||||
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
|
||||||
|
# include <openrct2/drawing/Drawing.h>
|
||||||
|
# include <openrct2/scripting/Duktape.hpp>
|
||||||
|
|
||||||
|
namespace OpenRCT2::Scripting
|
||||||
|
{
|
||||||
|
class ScGraphicsContext
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
duk_context* _ctx{};
|
||||||
|
rct_drawpixelinfo _dpi{};
|
||||||
|
|
||||||
|
uint8_t _stroke{};
|
||||||
|
uint8_t _fill{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScGraphicsContext(duk_context* ctx, const rct_drawpixelinfo& dpi)
|
||||||
|
: _ctx(ctx)
|
||||||
|
, _dpi(dpi)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(duk_context* ctx)
|
||||||
|
{
|
||||||
|
dukglue_register_property(ctx, &ScGraphicsContext::fill_get, &ScGraphicsContext::fill_set, "fill");
|
||||||
|
dukglue_register_property(ctx, &ScGraphicsContext::stroke_get, &ScGraphicsContext::stroke_set, "stroke");
|
||||||
|
dukglue_register_method(ctx, &ScGraphicsContext::clear, "clear");
|
||||||
|
dukglue_register_method(ctx, &ScGraphicsContext::clip, "clip");
|
||||||
|
dukglue_register_method(ctx, &ScGraphicsContext::line, "line");
|
||||||
|
dukglue_register_method(ctx, &ScGraphicsContext::fillRect, "fillRect");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t fill_get() const
|
||||||
|
{
|
||||||
|
return _fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_set(uint8_t value)
|
||||||
|
{
|
||||||
|
_fill = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t stroke_get() const
|
||||||
|
{
|
||||||
|
return _stroke;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stroke_set(uint8_t value)
|
||||||
|
{
|
||||||
|
_stroke = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
gfx_clear(&_dpi, _fill);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clip(int32_t x, int32_t y, int32_t width, int32_t height)
|
||||||
|
{
|
||||||
|
rct_drawpixelinfo newDpi;
|
||||||
|
clip_drawpixelinfo(&newDpi, &_dpi, { x, y }, width, height);
|
||||||
|
_dpi = newDpi;
|
||||||
|
}
|
||||||
|
|
||||||
|
void line(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
|
||||||
|
{
|
||||||
|
gfx_draw_line(&_dpi, { { x1, y1 }, { x2, y2 } }, _stroke);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillRect(int32_t x, int32_t y, int32_t width, int32_t height)
|
||||||
|
{
|
||||||
|
gfx_fill_rect(&_dpi, { x, y, x + width - 1, y + height - 1 }, _fill);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace OpenRCT2::Scripting
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
namespace OpenRCT2::Scripting
|
namespace OpenRCT2::Scripting
|
||||||
{
|
{
|
||||||
|
class ScWindow;
|
||||||
class ScWidget
|
class ScWidget
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@@ -43,6 +44,8 @@ namespace OpenRCT2::Scripting
|
|||||||
static DukValue ToDukValue(duk_context* ctx, rct_window* w, rct_widgetindex widgetIndex);
|
static DukValue ToDukValue(duk_context* ctx, rct_window* w, rct_widgetindex widgetIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<ScWindow> window_get() const;
|
||||||
|
|
||||||
std::string name_get() const
|
std::string name_get() const
|
||||||
{
|
{
|
||||||
auto w = GetWindow();
|
auto w = GetWindow();
|
||||||
@@ -376,7 +379,7 @@ namespace OpenRCT2::Scripting
|
|||||||
public:
|
public:
|
||||||
static void Register(duk_context* ctx)
|
static void Register(duk_context* ctx)
|
||||||
{
|
{
|
||||||
// Common
|
dukglue_register_property(ctx, &ScWidget::window_get, nullptr, "window");
|
||||||
dukglue_register_property(ctx, &ScWidget::name_get, &ScWidget::name_set, "name");
|
dukglue_register_property(ctx, &ScWidget::name_get, &ScWidget::name_set, "name");
|
||||||
dukglue_register_property(ctx, &ScWidget::type_get, nullptr, "type");
|
dukglue_register_property(ctx, &ScWidget::type_get, nullptr, "type");
|
||||||
dukglue_register_property(ctx, &ScWidget::x_get, &ScWidget::x_set, "x");
|
dukglue_register_property(ctx, &ScWidget::x_get, &ScWidget::x_set, "x");
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
# include "UiExtensions.h"
|
# include "UiExtensions.h"
|
||||||
|
|
||||||
# include "CustomMenu.h"
|
# include "CustomMenu.h"
|
||||||
|
# include "ScGraphicsContext.hpp"
|
||||||
# include "ScTileSelection.hpp"
|
# include "ScTileSelection.hpp"
|
||||||
# include "ScTitleSequence.hpp"
|
# include "ScTitleSequence.hpp"
|
||||||
# include "ScUi.hpp"
|
# include "ScUi.hpp"
|
||||||
@@ -29,6 +30,7 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
|
|||||||
dukglue_register_global(ctx, std::make_shared<ScTitleSequenceManager>(), "titleSequenceManager");
|
dukglue_register_global(ctx, std::make_shared<ScTitleSequenceManager>(), "titleSequenceManager");
|
||||||
dukglue_register_global(ctx, std::make_shared<ScUi>(scriptEngine), "ui");
|
dukglue_register_global(ctx, std::make_shared<ScUi>(scriptEngine), "ui");
|
||||||
|
|
||||||
|
ScGraphicsContext::Register(ctx);
|
||||||
ScTileSelection::Register(ctx);
|
ScTileSelection::Register(ctx);
|
||||||
ScTool::Register(ctx);
|
ScTool::Register(ctx);
|
||||||
ScUi::Register(ctx);
|
ScUi::Register(ctx);
|
||||||
@@ -54,4 +56,9 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
|
|||||||
InitialiseCustomMenuItems(scriptEngine);
|
InitialiseCustomMenuItems(scriptEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ScWindow> ScWidget::window_get() const
|
||||||
|
{
|
||||||
|
return std::make_shared<ScWindow>(_class, _number);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ enum class WindowWidgetType : uint8_t
|
|||||||
Scroll = 22,
|
Scroll = 22,
|
||||||
Checkbox = 23,
|
Checkbox = 23,
|
||||||
Placeholder = 25,
|
Placeholder = 25,
|
||||||
|
Custom = 28,
|
||||||
TextBox = 27,
|
TextBox = 27,
|
||||||
Last = 26,
|
Last = 26,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1532,7 +1532,7 @@ void window_event_scroll_mousedrag_call(rct_window* w, int32_t scrollIndex, cons
|
|||||||
{
|
{
|
||||||
if (w->event_handlers == nullptr)
|
if (w->event_handlers == nullptr)
|
||||||
w->OnScrollMouseDrag(scrollIndex, screenCoords);
|
w->OnScrollMouseDrag(scrollIndex, screenCoords);
|
||||||
else if (w->event_handlers->scroll_mouseover != nullptr)
|
else if (w->event_handlers->scroll_mousedrag != nullptr)
|
||||||
w->event_handlers->scroll_mousedrag(w, scrollIndex, screenCoords);
|
w->event_handlers->scroll_mousedrag(w, scrollIndex, screenCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ struct rct_window
|
|||||||
rct_window() = default;
|
rct_window() = default;
|
||||||
virtual ~rct_window() = default;
|
virtual ~rct_window() = default;
|
||||||
|
|
||||||
|
virtual bool IsLegacy()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
virtual void OnOpen()
|
virtual void OnOpen()
|
||||||
{
|
{
|
||||||
@@ -134,6 +139,9 @@ struct rct_window
|
|||||||
virtual void OnDraw(rct_drawpixelinfo& dpi)
|
virtual void OnDraw(rct_drawpixelinfo& dpi)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
virtual void OnDrawWidget(rct_widgetindex widgetIndex, rct_drawpixelinfo& dpi)
|
||||||
|
{
|
||||||
|
}
|
||||||
virtual OpenRCT2String OnTooltip(rct_widgetindex widgetIndex, rct_string_id fallback)
|
virtual OpenRCT2String OnTooltip(rct_widgetindex widgetIndex, rct_string_id fallback)
|
||||||
{
|
{
|
||||||
return { fallback, {} };
|
return { fallback, {} };
|
||||||
|
|||||||
@@ -369,6 +369,39 @@ namespace OpenRCT2::Scripting
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DukValue stats_get() const
|
||||||
|
{
|
||||||
|
# ifndef DISABLE_NETWORK
|
||||||
|
auto obj = OpenRCT2::Scripting::DukObject(_context);
|
||||||
|
auto networkStats = network_get_stats();
|
||||||
|
{
|
||||||
|
duk_push_array(_context);
|
||||||
|
duk_uarridx_t index = 0;
|
||||||
|
for (auto v : networkStats.bytesReceived)
|
||||||
|
{
|
||||||
|
duk_push_number(_context, v);
|
||||||
|
duk_put_prop_index(_context, -2, index);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
obj.Set("bytesReceived", DukValue::take_from_stack(_context));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
duk_push_array(_context);
|
||||||
|
duk_uarridx_t index = 0;
|
||||||
|
for (auto v : networkStats.bytesSent)
|
||||||
|
{
|
||||||
|
duk_push_number(_context, v);
|
||||||
|
duk_put_prop_index(_context, -2, index);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
obj.Set("bytesSent", DukValue::take_from_stack(_context));
|
||||||
|
}
|
||||||
|
return obj.Take();
|
||||||
|
# else
|
||||||
|
return ToDuk(_context, nullptr);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ScPlayerGroup> getGroup(int32_t index) const
|
std::shared_ptr<ScPlayerGroup> getGroup(int32_t index) const
|
||||||
{
|
{
|
||||||
# ifndef DISABLE_NETWORK
|
# ifndef DISABLE_NETWORK
|
||||||
@@ -490,6 +523,7 @@ namespace OpenRCT2::Scripting
|
|||||||
dukglue_register_property(ctx, &ScNetwork::players_get, nullptr, "players");
|
dukglue_register_property(ctx, &ScNetwork::players_get, nullptr, "players");
|
||||||
dukglue_register_property(ctx, &ScNetwork::currentPlayer_get, nullptr, "currentPlayer");
|
dukglue_register_property(ctx, &ScNetwork::currentPlayer_get, nullptr, "currentPlayer");
|
||||||
dukglue_register_property(ctx, &ScNetwork::defaultGroup_get, &ScNetwork::defaultGroup_set, "defaultGroup");
|
dukglue_register_property(ctx, &ScNetwork::defaultGroup_get, &ScNetwork::defaultGroup_set, "defaultGroup");
|
||||||
|
dukglue_register_property(ctx, &ScNetwork::stats_get, nullptr, "stats");
|
||||||
dukglue_register_method(ctx, &ScNetwork::addGroup, "addGroup");
|
dukglue_register_method(ctx, &ScNetwork::addGroup, "addGroup");
|
||||||
dukglue_register_method(ctx, &ScNetwork::getGroup, "getGroup");
|
dukglue_register_method(ctx, &ScNetwork::getGroup, "getGroup");
|
||||||
dukglue_register_method(ctx, &ScNetwork::removeGroup, "removeGroup");
|
dukglue_register_method(ctx, &ScNetwork::removeGroup, "removeGroup");
|
||||||
|
|||||||
@@ -691,17 +691,27 @@ std::future<void> ScriptEngine::Eval(const std::string& s)
|
|||||||
|
|
||||||
DukValue ScriptEngine::ExecutePluginCall(
|
DukValue ScriptEngine::ExecutePluginCall(
|
||||||
const std::shared_ptr<Plugin>& plugin, const DukValue& func, const std::vector<DukValue>& args, bool isGameStateMutable)
|
const std::shared_ptr<Plugin>& plugin, const DukValue& func, const std::vector<DukValue>& args, bool isGameStateMutable)
|
||||||
|
{
|
||||||
|
duk_push_undefined(_context);
|
||||||
|
auto dukUndefined = DukValue::take_from_stack(_context);
|
||||||
|
return ExecutePluginCall(plugin, func, dukUndefined, args, isGameStateMutable);
|
||||||
|
}
|
||||||
|
|
||||||
|
DukValue ScriptEngine::ExecutePluginCall(
|
||||||
|
const std::shared_ptr<Plugin>& plugin, const DukValue& func, const DukValue& thisValue, const std::vector<DukValue>& args,
|
||||||
|
bool isGameStateMutable)
|
||||||
{
|
{
|
||||||
DukStackFrame frame(_context);
|
DukStackFrame frame(_context);
|
||||||
if (func.is_function())
|
if (func.is_function())
|
||||||
{
|
{
|
||||||
ScriptExecutionInfo::PluginScope scope(_execInfo, plugin, isGameStateMutable);
|
ScriptExecutionInfo::PluginScope scope(_execInfo, plugin, isGameStateMutable);
|
||||||
func.push();
|
func.push();
|
||||||
|
thisValue.push();
|
||||||
for (const auto& arg : args)
|
for (const auto& arg : args)
|
||||||
{
|
{
|
||||||
arg.push();
|
arg.push();
|
||||||
}
|
}
|
||||||
auto result = duk_pcall(_context, static_cast<duk_idx_t>(args.size()));
|
auto result = duk_pcall_method(_context, static_cast<duk_idx_t>(args.size()));
|
||||||
if (result == DUK_EXEC_SUCCESS)
|
if (result == DUK_EXEC_SUCCESS)
|
||||||
{
|
{
|
||||||
return DukValue::take_from_stack(_context);
|
return DukValue::take_from_stack(_context);
|
||||||
|
|||||||
@@ -202,6 +202,9 @@ namespace OpenRCT2::Scripting
|
|||||||
DukValue ExecutePluginCall(
|
DukValue ExecutePluginCall(
|
||||||
const std::shared_ptr<Plugin>& plugin, const DukValue& func, const std::vector<DukValue>& args,
|
const std::shared_ptr<Plugin>& plugin, const DukValue& func, const std::vector<DukValue>& args,
|
||||||
bool isGameStateMutable);
|
bool isGameStateMutable);
|
||||||
|
DukValue ExecutePluginCall(
|
||||||
|
const std::shared_ptr<Plugin>& plugin, const DukValue& func, const DukValue& thisValue,
|
||||||
|
const std::vector<DukValue>& args, bool isGameStateMutable);
|
||||||
|
|
||||||
void LogPluginInfo(const std::shared_ptr<Plugin>& plugin, std::string_view message);
|
void LogPluginInfo(const std::shared_ptr<Plugin>& plugin, std::string_view message);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user