添加背包配置中的背包预览UI
This commit is contained in:
parent
faddbbe338
commit
1aeaa662a9
@ -6,6 +6,8 @@
|
|||||||
#include "PropertyCustomizationHelpers.h"
|
#include "PropertyCustomizationHelpers.h"
|
||||||
#include "Framework/Notifications/NotificationManager.h"
|
#include "Framework/Notifications/NotificationManager.h"
|
||||||
#include "ProjectFish/DataAsset/BagShapeAsset.h"
|
#include "ProjectFish/DataAsset/BagShapeAsset.h"
|
||||||
|
#include "Widgets/BagConfigGridWidget.h"
|
||||||
|
#include "Widgets/BagShapeGridWidget.h"
|
||||||
#include "Widgets/Notifications/SNotificationList.h"
|
#include "Widgets/Notifications/SNotificationList.h"
|
||||||
|
|
||||||
|
|
||||||
@ -15,12 +17,12 @@ void SBagConfigEditorWidget::Construct(const FArguments& InArgs)
|
|||||||
SelectedSkillAsset = nullptr;
|
SelectedSkillAsset = nullptr;
|
||||||
bIsPlacingSkill = false;
|
bIsPlacingSkill = false;
|
||||||
SelectedSkillIndex = -1;
|
SelectedSkillIndex = -1;
|
||||||
|
|
||||||
ChildSlot
|
ChildSlot
|
||||||
[
|
[
|
||||||
SNew(SVerticalBox)
|
SNew(SVerticalBox)
|
||||||
|
|
||||||
// BagShapeAsset 选择器
|
// 背包选择器
|
||||||
+ SVerticalBox::Slot()
|
+ SVerticalBox::Slot()
|
||||||
.AutoHeight()
|
.AutoHeight()
|
||||||
.Padding(5.0f)
|
.Padding(5.0f)
|
||||||
@ -88,140 +90,191 @@ void SBagConfigEditorWidget::Construct(const FArguments& InArgs)
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
// // 工具栏
|
// 技能按钮
|
||||||
// + SVerticalBox::Slot()
|
+ SVerticalBox::Slot()
|
||||||
// .AutoHeight()
|
.AutoHeight()
|
||||||
// .Padding(5.0f)
|
.Padding(5.0f)
|
||||||
// [
|
[
|
||||||
// SNew(SHorizontalBox)
|
SNew(SHorizontalBox)
|
||||||
//
|
|
||||||
// + SHorizontalBox::Slot()
|
+ SHorizontalBox::Slot()
|
||||||
// .AutoWidth()
|
.AutoWidth()
|
||||||
// .Padding(2.0f)
|
.Padding(2.0f)
|
||||||
// [
|
[
|
||||||
// SNew(SButton)
|
SNew(SButton)
|
||||||
// .Text(FText::FromString(TEXT("Add Skill")))
|
.Text(FText::FromString(TEXT("点击后,单击背包添加当前选中的技能")))
|
||||||
// .OnClicked(this, &SBagClassEditor::OnAddSkillClicked)
|
.OnClicked(this, &SBagConfigEditorWidget::OnAddSkillClicked)
|
||||||
// .IsEnabled_Lambda([this]() { return BagClass.IsValid() && BagClass->BagShapeAsset != nullptr && SelectedSkillObject.IsValid(); })
|
.IsEnabled_Lambda([this]() { return BagConfig.IsValid() && BagConfig->BagShapeAsset != nullptr && SelectedSkillAsset.IsValid(); })
|
||||||
// ]
|
]
|
||||||
//
|
|
||||||
// + SHorizontalBox::Slot()
|
+ SHorizontalBox::Slot()
|
||||||
// .AutoWidth()
|
.AutoWidth()
|
||||||
// .Padding(2.0f)
|
.Padding(2.0f)
|
||||||
// [
|
[
|
||||||
// SNew(SButton)
|
SNew(SButton)
|
||||||
// .Text(FText::FromString(TEXT("Remove Selected")))
|
.Text(FText::FromString(TEXT("点击后,单击背包移除当前选中的技能")))
|
||||||
// .OnClicked(this, &SBagClassEditor::OnRemoveSkillClicked)
|
.OnClicked(this, &SBagConfigEditorWidget::OnRemoveSkillClicked)
|
||||||
// .IsEnabled_Lambda([this]() { return SelectedSkillObject.IsValid(); })
|
.IsEnabled_Lambda([this]() { return SelectedSkillAsset.IsValid(); })
|
||||||
// ]
|
]
|
||||||
//
|
|
||||||
// + SHorizontalBox::Slot()
|
+ SHorizontalBox::Slot()
|
||||||
// .AutoWidth()
|
.AutoWidth()
|
||||||
// .Padding(2.0f)
|
.Padding(2.0f)
|
||||||
// [
|
[
|
||||||
// SNew(SButton)
|
SNew(SButton)
|
||||||
// .Text(FText::FromString(TEXT("Clear All")))
|
.Text(FText::FromString(TEXT("移除所有技能")))
|
||||||
// .OnClicked(this, &SBagClassEditor::OnClearAllSkillsClicked)
|
.OnClicked(this, &SBagConfigEditorWidget::OnClearAllSkillsClicked)
|
||||||
// .IsEnabled_Lambda([this]() { return BagClass.IsValid() && BagClass->GetSkillCount() > 0; })
|
.IsEnabled_Lambda([this]() { return BagConfig.IsValid() && BagConfig->GetSkillCount() > 0; })
|
||||||
// ]
|
]
|
||||||
// ]
|
]
|
||||||
//
|
|
||||||
// // 主编辑区域
|
// 主编辑区域
|
||||||
// + SVerticalBox::Slot()
|
+ SVerticalBox::Slot()
|
||||||
// .FillHeight(1.0f)
|
.FillHeight(1.0f)
|
||||||
// [
|
[
|
||||||
// SNew(SSplitter)
|
SNew(SSplitter)
|
||||||
// .Orientation(Orient_Horizontal)
|
.Orientation(Orient_Horizontal)
|
||||||
//
|
|
||||||
// // 左侧:背包格子视图
|
// 左侧:背包格子视图
|
||||||
// + SSplitter::Slot()
|
+ SSplitter::Slot()
|
||||||
// .Value(0.7f)
|
.Value(0.7f)
|
||||||
// [
|
[
|
||||||
// SNew(SBox)
|
SNew(SBox)
|
||||||
// .HAlign(HAlign_Center)
|
.HAlign(HAlign_Center)
|
||||||
// .VAlign(VAlign_Center)
|
.VAlign(VAlign_Center)
|
||||||
// .Padding(10.0f)
|
.Padding(10.0f)
|
||||||
// [
|
[
|
||||||
// SNew(SVerticalBox)
|
SNew(SVerticalBox)
|
||||||
//
|
|
||||||
// + SVerticalBox::Slot()
|
+ SVerticalBox::Slot()
|
||||||
// .AutoHeight()
|
.AutoHeight()
|
||||||
// .HAlign(HAlign_Center)
|
.HAlign(HAlign_Center)
|
||||||
// .Padding(0, 0, 0, 10)
|
.Padding(0, 0, 0, 10)
|
||||||
// [
|
[
|
||||||
// SNew(STextBlock)
|
SNew(STextBlock)
|
||||||
// .Text_Lambda([this]()
|
.Text_Lambda([this]()
|
||||||
// {
|
{
|
||||||
// if (!BagClass.IsValid())
|
if (!BagConfig.IsValid())
|
||||||
// {
|
{
|
||||||
// return FText::FromString(TEXT("No Bag Class"));
|
return FText::FromString(TEXT("No Bag Class"));
|
||||||
// }
|
}
|
||||||
// else if (!BagClass->BagShapeAsset)
|
else if (!BagConfig->BagShapeAsset)
|
||||||
// {
|
{
|
||||||
// return FText::FromString(TEXT("Please select a Bag Shape Asset above"));
|
return FText::FromString(TEXT("Please select a Bag Shape Asset above"));
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// {
|
{
|
||||||
// return FText::FromString(FString::Printf(TEXT("Bag: %s (%dx%d)"),
|
return FText::FromString(FString::Printf(TEXT("Bag: %s (%dx%d)"),
|
||||||
// *BagClass->BagShapeAsset->GetName(),
|
*BagConfig->BagShapeAsset->GetName(),
|
||||||
// BagClass->BagShapeAsset->BagWidth,
|
BagConfig->BagShapeAsset->BagWidth,
|
||||||
// BagClass->BagShapeAsset->BagHeight));
|
BagConfig->BagShapeAsset->BagHeight));
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// .Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
|
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
|
||||||
// .ColorAndOpacity_Lambda([this]()
|
.ColorAndOpacity_Lambda([this]()
|
||||||
// {
|
{
|
||||||
// return (!BagClass.IsValid() || !BagClass->BagShapeAsset) ?
|
return (!BagConfig.IsValid() || !BagConfig->BagShapeAsset) ?
|
||||||
// FSlateColor(FLinearColor::Red) : FSlateColor(FLinearColor::White);
|
FSlateColor(FLinearColor::Red) : FSlateColor(FLinearColor::White);
|
||||||
// })
|
})
|
||||||
// ]
|
]
|
||||||
//
|
|
||||||
// + SVerticalBox::Slot()
|
+ SVerticalBox::Slot()
|
||||||
// .AutoHeight()
|
.AutoHeight()
|
||||||
// .HAlign(HAlign_Center)
|
.HAlign(HAlign_Center)
|
||||||
// [
|
[
|
||||||
// SAssignNew(BagGridWidget, SBagGridWidget)
|
SAssignNew(BagGridWidget, SBagConfigGridWidget)
|
||||||
// .BagClass(BagClass.Get())
|
.BagConfig(BagConfig.Get())
|
||||||
// .OnGridCellClicked(this, &SBagClassEditor::OnGridCellClicked)
|
.OnGridCellClicked(this, &SBagConfigEditorWidget::OnGridCellClicked)
|
||||||
// .Visibility_Lambda([this]()
|
.Visibility_Lambda([this]()
|
||||||
// {
|
{
|
||||||
// return (BagClass.IsValid() && BagClass->BagShapeAsset) ?
|
return (BagConfig.IsValid() && BagConfig->BagShapeAsset) ?
|
||||||
// EVisibility::Visible : EVisibility::Hidden;
|
EVisibility::Visible : EVisibility::Hidden;
|
||||||
// })
|
})
|
||||||
// ]
|
]
|
||||||
// ]
|
]
|
||||||
// ]
|
]
|
||||||
//
|
|
||||||
// // 右侧:技能列表
|
// // 右侧:技能列表
|
||||||
// + SSplitter::Slot()
|
// + SSplitter::Slot()
|
||||||
// .Value(0.3f)
|
// .Value(0.3f)
|
||||||
// [
|
// [
|
||||||
// SNew(SVerticalBox)
|
// SNew(SVerticalBox)
|
||||||
//
|
//
|
||||||
// + SVerticalBox::Slot()
|
// + SVerticalBox::Slot()
|
||||||
// .AutoHeight()
|
// .AutoHeight()
|
||||||
// .Padding(5.0f)
|
// .Padding(5.0f)
|
||||||
// [
|
// [
|
||||||
// SNew(STextBlock)
|
// SNew(STextBlock)
|
||||||
// .Text(FText::FromString(TEXT("Placed Skills:")))
|
// .Text(FText::FromString(TEXT("Placed Skills:")))
|
||||||
// .Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
|
// .Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
|
||||||
// ]
|
// ]
|
||||||
//
|
//
|
||||||
// + SVerticalBox::Slot()
|
// + SVerticalBox::Slot()
|
||||||
// .FillHeight(1.0f)
|
// .FillHeight(1.0f)
|
||||||
// .Padding(5.0f)
|
// .Padding(5.0f)
|
||||||
// [
|
// [
|
||||||
// SAssignNew(SkillListWidget, SSkillListWidget)
|
// SAssignNew(SkillListWidget, SSkillListWidget)
|
||||||
// .BagClass(BagClass.Get())
|
// .BagClass(BagClass.Get())
|
||||||
// .OnSkillSelected(this, &SBagClassEditor::OnSkillSelected)
|
// .OnSkillSelected(this, &SBagClassEditor::OnSkillSelected)
|
||||||
// ]
|
// ]
|
||||||
// ]
|
// ]
|
||||||
//]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
RefreshUI();
|
RefreshUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FReply SBagConfigEditorWidget::OnAddSkillClicked()
|
||||||
|
{
|
||||||
|
if (!BagConfig.IsValid() || !BagConfig->BagShapeAsset || !SelectedSkillAsset.IsValid())
|
||||||
|
{
|
||||||
|
ShowWarningMessage(TEXT("Please select a bag shape asset and a skill object first!"));
|
||||||
|
return FReply::Handled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进入放置模式
|
||||||
|
bIsPlacingSkill = true;
|
||||||
|
ShowWarningMessage(TEXT("Click on the grid to place the skill"));
|
||||||
|
|
||||||
|
return FReply::Handled();
|
||||||
|
}
|
||||||
|
|
||||||
|
FReply SBagConfigEditorWidget::OnRemoveSkillClicked()
|
||||||
|
{
|
||||||
|
if (!BagConfig.IsValid() || SelectedSkillIndex < 0)
|
||||||
|
{
|
||||||
|
return FReply::Handled();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BagConfig->RemoveSkill(SelectedSkillIndex))
|
||||||
|
{
|
||||||
|
SelectedSkillIndex = -1;
|
||||||
|
RefreshUI();
|
||||||
|
|
||||||
|
// 标记资源为已修改
|
||||||
|
BagConfig->MarkPackageDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return FReply::Handled();
|
||||||
|
}
|
||||||
|
|
||||||
|
FReply SBagConfigEditorWidget::OnClearAllSkillsClicked()
|
||||||
|
{
|
||||||
|
if (!BagConfig.IsValid())
|
||||||
|
{
|
||||||
|
return FReply::Handled();
|
||||||
|
}
|
||||||
|
|
||||||
|
BagConfig->ClearAllSkills();
|
||||||
|
SelectedSkillIndex = -1;
|
||||||
|
RefreshUI();
|
||||||
|
|
||||||
|
// 标记资源为已修改
|
||||||
|
BagConfig->MarkPackageDirty();
|
||||||
|
|
||||||
|
return FReply::Handled();
|
||||||
|
}
|
||||||
|
|
||||||
void SBagConfigEditorWidget::OnBagShapeAssetChanged(const FAssetData& AssetData)
|
void SBagConfigEditorWidget::OnBagShapeAssetChanged(const FAssetData& AssetData)
|
||||||
{
|
{
|
||||||
if (!BagConfig.IsValid())
|
if (!BagConfig.IsValid())
|
||||||
@ -267,13 +320,58 @@ void SBagConfigEditorWidget::OnSkillAssetChanged(const FAssetData& AssetData)
|
|||||||
SelectedSkillAsset = Cast<USkillAsset>(AssetData.GetAsset());
|
SelectedSkillAsset = Cast<USkillAsset>(AssetData.GetAsset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SBagConfigEditorWidget::OnGridCellClicked(int32 X, int32 Y)
|
||||||
|
{
|
||||||
|
if (!BagConfig.IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bIsPlacingSkill && SelectedSkillAsset.IsValid())
|
||||||
|
{
|
||||||
|
// 尝试在指定位置放置技能
|
||||||
|
if (BagConfig->CanPlaceSkill(SelectedSkillAsset.Get(), X, Y))
|
||||||
|
{
|
||||||
|
if (BagConfig->AddSkill(SelectedSkillAsset.Get(), X, Y))
|
||||||
|
{
|
||||||
|
BagConfig->MarkPackageDirty();
|
||||||
|
RefreshUI();
|
||||||
|
ShowWarningMessage(FString::Printf(TEXT("Successfully placed skill '%s' at (%d,%d)"),
|
||||||
|
*SelectedSkillAsset->SkillName.ToString(), X, Y));
|
||||||
|
|
||||||
|
// 退出放置模式
|
||||||
|
bIsPlacingSkill = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShowWarningMessage(TEXT("Failed to place skill!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShowWarningMessage(TEXT("Cannot place skill at this position!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// // 选择现有技能
|
||||||
|
// int32 SkillIndex = BagConfig->GetSkillAtPosition(X, Y);
|
||||||
|
// SelectedSkillIndex = SkillIndex;
|
||||||
|
//
|
||||||
|
// if (SkillListWidget.IsValid())
|
||||||
|
// {
|
||||||
|
// SkillListWidget->SetSelectedSkill(SkillIndex);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SBagConfigEditorWidget::RefreshUI()
|
void SBagConfigEditorWidget::RefreshUI()
|
||||||
{
|
{
|
||||||
// if (BagGridWidget.IsValid())
|
if (BagGridWidget.IsValid())
|
||||||
// {
|
{
|
||||||
// BagGridWidget->RefreshGrid();
|
BagGridWidget->RefreshGrid();
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// if (SkillListWidget.IsValid())
|
// if (SkillListWidget.IsValid())
|
||||||
// {
|
// {
|
||||||
// SkillListWidget->RefreshSkillList();
|
// SkillListWidget->RefreshSkillList();
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "Widgets/BagConfigGridWidget.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SBagConfigGridWidget::Construct(const FArguments& InArgs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBagConfigGridWidget::RefreshGrid()
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -34,13 +34,13 @@ private:
|
|||||||
int32 SelectedSkillIndex;
|
int32 SelectedSkillIndex;
|
||||||
|
|
||||||
// UI组件
|
// UI组件
|
||||||
TSharedPtr<class SBagShapeGridWidget> BagGridWidget;
|
TSharedPtr<class SBagConfigGridWidget> BagGridWidget;
|
||||||
//TSharedPtr<class SSkillListWidget> SkillListWidget;
|
//TSharedPtr<class SSkillListWidget> SkillListWidget;
|
||||||
|
|
||||||
// // 回调函数
|
// 回调函数
|
||||||
// FReply OnAddSkillClicked();
|
FReply OnAddSkillClicked();
|
||||||
// FReply OnRemoveSkillClicked();
|
FReply OnRemoveSkillClicked();
|
||||||
// FReply OnClearAllSkillsClicked();
|
FReply OnClearAllSkillsClicked();
|
||||||
|
|
||||||
// BagShapeAsset选择回调
|
// BagShapeAsset选择回调
|
||||||
void OnBagShapeAssetChanged(const FAssetData& AssetData);
|
void OnBagShapeAssetChanged(const FAssetData& AssetData);
|
||||||
@ -51,8 +51,8 @@ private:
|
|||||||
// // 技能选择回调
|
// // 技能选择回调
|
||||||
// void OnSkillSelected(int32 SkillIndex);
|
// void OnSkillSelected(int32 SkillIndex);
|
||||||
//
|
//
|
||||||
// // 格子点击回调
|
// 格子点击回调
|
||||||
// void OnGridCellClicked(int32 X, int32 Y);
|
void OnGridCellClicked(int32 X, int32 Y);
|
||||||
|
|
||||||
// 刷新UI
|
// 刷新UI
|
||||||
void RefreshUI();
|
void RefreshUI();
|
||||||
@ -62,3 +62,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "ProjectFish/DataAsset/BagConfigAsset.h"
|
||||||
|
|
||||||
|
DECLARE_DELEGATE_TwoParams(FOnGridCellClicked, int32, int32);
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class PROJECTFISHEDITOR_API SBagConfigGridWidget : public SCompoundWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLATE_BEGIN_ARGS(SBagConfigGridWidget) {}
|
||||||
|
SLATE_ARGUMENT(UBagConfigAsset*, BagConfig)
|
||||||
|
SLATE_EVENT(FOnGridCellClicked, OnGridCellClicked)
|
||||||
|
SLATE_END_ARGS()
|
||||||
|
|
||||||
|
void Construct(const FArguments& InArgs);
|
||||||
|
|
||||||
|
// // 设置背包类
|
||||||
|
// void UpdateBagConfig(UBagConfigAsset* InBagClass);
|
||||||
|
//
|
||||||
|
// // 设置预览技能(用于显示放置预览)
|
||||||
|
// void SetPreviewSkill(USkillAsset* InPreviewSkill, int32 PreviewX, int32 PreviewY);
|
||||||
|
//
|
||||||
|
// // 清除预览
|
||||||
|
// void ClearPreview();
|
||||||
|
//
|
||||||
|
// 刷新显示
|
||||||
|
void RefreshGrid();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// // Slate重写函数
|
||||||
|
// virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
|
||||||
|
// virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
|
||||||
|
// virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect,
|
||||||
|
// FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
|
||||||
|
//
|
||||||
|
// virtual FVector2D ComputeDesiredSize(float) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 背包类引用
|
||||||
|
TWeakObjectPtr<UBagConfigAsset> BagClass;
|
||||||
|
|
||||||
|
// 回调委托
|
||||||
|
FOnGridCellClicked OnGridCellClicked;
|
||||||
|
|
||||||
|
// 预览数据
|
||||||
|
TWeakObjectPtr<USkillAsset> PreviewSkill;
|
||||||
|
int32 PreviewX;
|
||||||
|
int32 PreviewY;
|
||||||
|
|
||||||
|
// UI参数
|
||||||
|
static const float CellSize;
|
||||||
|
static const float CellSpacing;
|
||||||
|
|
||||||
|
// // 工具函数
|
||||||
|
// FVector2D GetCellPosition(int32 X, int32 Y) const;
|
||||||
|
// FVector2D GetGridCellFromPosition(const FVector2D& Position) const;
|
||||||
|
// bool IsValidGridPosition(int32 X, int32 Y) const;
|
||||||
|
// FLinearColor GetCellColor(int32 X, int32 Y) const;
|
||||||
|
// int32 GetSkillAtPosition(int32 X, int32 Y) const;
|
||||||
|
};
|
||||||
Loading…
x
Reference in New Issue
Block a user