333 lines
10 KiB
C++
333 lines
10 KiB
C++
// Project Lab - NHTV IGAD
|
|
//////////////////////////////////////////
|
|
// Author: Yoshi van Belkom - 130118
|
|
//////////////////////////////////////////
|
|
|
|
#include "SkillTreeEditorPrivatePCH.h"
|
|
#include "SkillTreeEditorViewportClient.h"
|
|
#include "SceneViewport.h"
|
|
|
|
#include "PreviewScene.h"
|
|
#include "ScopedTransaction.h"
|
|
#include "Runtime/Engine/Public/ComponentReregisterContext.h"
|
|
|
|
#include "AssetToolsModule.h"
|
|
#include "AssetRegistryModule.h"
|
|
#include "CanvasTypes.h"
|
|
#include "CanvasItem.h"
|
|
|
|
#include "PhysicsEngine/BodySetup2D.h"
|
|
#include "SEditorViewport.h"
|
|
|
|
#include "SNotificationList.h"
|
|
#include "NotificationManager.h"
|
|
|
|
#include "SkillTreeFactory.h"
|
|
#include "SkillTreeObject.h"
|
|
#include "SkillObject.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "SkillTreeEditor"
|
|
|
|
FSkillTreeEditorViewportClient::FSkillTreeEditorViewportClient( TWeakPtr<FSkillTreeEditorViewport> a_skillTreeEditor, TWeakPtr<class SEditorViewport> a_skillTreeEditorViewportPtr )
|
|
: FEditorViewportClient( new FAssetEditorModeManager(), nullptr, a_skillTreeEditorViewportPtr )
|
|
, m_skillTreeEditorPtr( a_skillTreeEditor )
|
|
, m_skillTreeEditorViewportPtr( a_skillTreeEditorViewportPtr )
|
|
{
|
|
check( m_skillTreeEditorPtr.IsValid() && m_skillTreeEditorViewportPtr.IsValid() );
|
|
|
|
// The tile map editor fully supports mode tools and isn't doing any incompatible stuff with the Widget
|
|
Widget->SetUsesEditorModeTools( ModeTools );
|
|
|
|
PreviewScene = &m_ownedPreviewScene;
|
|
((FAssetEditorModeManager*)ModeTools)->SetPreviewScene( PreviewScene );
|
|
|
|
SetRealtime( true );
|
|
|
|
DrawHelper.bDrawGrid = false;
|
|
|
|
EngineShowFlags.DisableAdvancedFeatures();
|
|
EngineShowFlags.CompositeEditorPrimitives = false; //REMINDER: Turned off.
|
|
}
|
|
|
|
void FSkillTreeEditorViewportClient::Draw( const FSceneView* a_view, FPrimitiveDrawInterface* a_drawInterface )
|
|
{
|
|
FEditorViewportClient::Draw( a_view, a_drawInterface );
|
|
}
|
|
|
|
void FSkillTreeEditorViewportClient::DrawCanvas( FViewport& a_viewport, FSceneView& a_view, FCanvas& a_canvas )
|
|
{
|
|
const bool isHitTesting = a_canvas.IsHitTesting();
|
|
if ( !isHitTesting )
|
|
{
|
|
a_canvas.SetHitProxy( nullptr );
|
|
}
|
|
|
|
if ( !m_skillTreeEditorPtr.IsValid() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_screenSize = a_viewport.GetSizeXY();
|
|
|
|
USkillTreeObject* skillTree = m_skillTreeEditorPtr.Pin()->GetSkillTreeBeingEdited();
|
|
USkillObject* skill = m_skillTreeEditorPtr.Pin()->GetSkillBeingEdited();
|
|
|
|
int offsetY = -m_hexSize;
|
|
int height;
|
|
int maxY;
|
|
int width;
|
|
|
|
if ( m_state )
|
|
{
|
|
height = skill->hexMap.height;
|
|
if ( height % 2 != 0 ) offsetY = m_hexSize;
|
|
width = skill->hexMap.width;
|
|
maxY = height - 1;
|
|
}
|
|
else
|
|
{
|
|
height = 16;
|
|
width = 13;
|
|
maxY = 15;
|
|
}
|
|
|
|
FLinearColor enabledColor = FLinearColor( 0.43f, 0.43f, 0.43f );
|
|
FLinearColor disabledColor = FLinearColor( 0.10f, 0.10f, 0.10f );
|
|
|
|
for ( float x = 0; x < width; x++ )
|
|
{
|
|
maxY = (maxY == (height - 1) ? height : (height - 1));
|
|
offsetY = (offsetY == -m_hexSize ? 0 : -m_hexSize);
|
|
for ( int y = 0; y < maxY; y++ )
|
|
{
|
|
bool test;
|
|
if ( m_state )
|
|
{
|
|
test = skill->hexMap.Get( x, y );
|
|
}
|
|
else
|
|
{
|
|
test = skillTree->hexMap.Get( x, y );
|
|
}
|
|
FLinearColor hexColor = enabledColor;
|
|
if ( !test )
|
|
{
|
|
hexColor = disabledColor;
|
|
}
|
|
float X = (x - (((float)width) / 2.0f)) * m_hexSize * 2;
|
|
float Y = ((y - (maxY / 2)) * m_hexSize * 2) + offsetY;
|
|
FCanvasNGonItem hexagonBorder( FVector2D( ( m_screenSize.X / 2 ) + X, ( m_screenSize.Y / 2 ) + Y ), FVector2D( m_hexSize, m_hexSize ), 6, hexColor );
|
|
hexagonBorder.Draw( &a_canvas );
|
|
|
|
if ( m_state )
|
|
{
|
|
FCanvasTextItem TextItem( FVector2D( ( m_screenSize.X / 2 ) + X, ( m_screenSize.Y / 2 ) + Y ), FText::Format( LOCTEXT( "PositionStr", "{0},{1}" ), FText::AsNumber( x ), FText::AsNumber( y ) ), GEngine->GetSmallFont(), FLinearColor::White );
|
|
TextItem.EnableShadow( FLinearColor::Black );
|
|
TextItem.bCentreX = true;
|
|
|
|
TextItem.Draw( &a_canvas );
|
|
}
|
|
}
|
|
}
|
|
|
|
float hexmapWidth = ( m_screenSize.X / 2 ) + ( ( ( width - 1 ) - ( ( (float)width ) / 2.0f ) ) * m_hexSize * 2 );
|
|
hexmapWidth += m_hexSize;
|
|
int boxWidth = ( ( m_screenSize.X - hexmapWidth ) );
|
|
boxWidth = FMath::Clamp( boxWidth, 0, 150 );
|
|
if ( !m_state )
|
|
{
|
|
for ( int i = 0, y = 50; i < skillTree->skills.Num(); i++, y += 20 )
|
|
{
|
|
if ( !skillTree->skills[i] ) continue;
|
|
if ( m_hoverY == i || m_skillTreeEditorPtr.Pin()->selectedY == i )
|
|
{
|
|
int minboxX = m_screenSize.X - boxWidth;
|
|
int minboxY = y;
|
|
FCanvasBoxItem boxItem( FVector2D( minboxX, minboxY ), FVector2D( boxWidth, 20) );
|
|
if ( m_hoverY == i ) boxItem.SetColor( FLinearColor::Black );
|
|
if ( m_skillTreeEditorPtr.Pin()->selectedY == i ) boxItem.SetColor( FLinearColor::White );
|
|
boxItem.Draw( &a_canvas );
|
|
}
|
|
FFormatNamedArguments args;
|
|
args.Add( TEXT( "DirtyState" ), skillTree->skills[i]->GetOutermost()->IsDirty() ? FText::FromString( TEXT( "*" ) ) : FText::GetEmpty() );
|
|
args.Add( TEXT( "SkillName" ), FText::AsCultureInvariant( skillTree->skills[i]->GetName() ) );
|
|
const FText assetName = FText::Format( LOCTEXT( "SkillName", "{SkillName}{DirtyState}" ), args );
|
|
FCanvasTextItem TextItem( FVector2D( m_screenSize.X - ( ( m_screenSize.X - hexmapWidth ) / 2 ), y ), assetName, GEngine->GetSmallFont(), FLinearColor::White );
|
|
TextItem.EnableShadow( FLinearColor::Black );
|
|
TextItem.bCentreX = true;
|
|
|
|
TextItem.Draw( &a_canvas );
|
|
}
|
|
}
|
|
|
|
int minboxX = 0;
|
|
int minboxY = 50;
|
|
FCanvasTileItem enabledColorSquare( FVector2D( 0, 50 ), FVector2D( boxWidth, 20 ), enabledColor );
|
|
FCanvasTileItem disabledColorSquare( FVector2D( 0, 70 ), FVector2D( boxWidth, 20 ), disabledColor );
|
|
enabledColorSquare.Draw( &a_canvas );
|
|
disabledColorSquare.Draw( &a_canvas );
|
|
|
|
FCanvasTextItem enabledTextItem( FVector2D( boxWidth / 2, 50 ), FText::FromString( TEXT( "Solid" ) ), GEngine->GetSmallFont(), FLinearColor::White );
|
|
enabledTextItem.EnableShadow( FLinearColor::Black );
|
|
enabledTextItem.bCentreX = true;
|
|
enabledTextItem.Draw( &a_canvas );
|
|
|
|
FCanvasTextItem disabledTextItem( FVector2D( boxWidth / 2, 70 ), FText::FromString( TEXT( "Empty" ) ), GEngine->GetSmallFont(), FLinearColor::White );
|
|
disabledTextItem.EnableShadow( FLinearColor::Black );
|
|
disabledTextItem.bCentreX = true;
|
|
disabledTextItem.Draw( &a_canvas );
|
|
|
|
FEditorViewportClient::DrawCanvas( a_viewport, a_view, a_canvas );
|
|
}
|
|
|
|
void FSkillTreeEditorViewportClient::MouseMove( FViewport* a_viewport, int32 a_mouseX, int32 a_mouseY )
|
|
{
|
|
if ( m_state ) return;
|
|
USkillTreeObject* skillTree = m_skillTreeEditorPtr.Pin()->GetSkillTreeBeingEdited();
|
|
int width = 13;
|
|
|
|
float hexmapWidth = ( m_screenSize.X / 2 ) + ( ( ( width - 1 ) - ( ( (float)width ) / 2.0f ) ) * m_hexSize * 2 );
|
|
hexmapWidth += m_hexSize;
|
|
|
|
int minboxX = m_screenSize.X - ( ( m_screenSize.X - hexmapWidth ) );
|
|
int maxboxX = m_screenSize.X;
|
|
for ( int i = 0, y = 50; i < skillTree->skills.Num(); i++, y += 20 )
|
|
{
|
|
int minboxY = y;
|
|
int maxboxY = y + 20;
|
|
if ( !skillTree->skills[i] ) continue;
|
|
if ( a_mouseX >= minboxX && a_mouseX <= maxboxX && a_mouseY >= minboxY && a_mouseY <= maxboxY )
|
|
{
|
|
m_hoverY = i;
|
|
FEditorViewportClient::MouseMove( a_viewport, a_mouseX, a_mouseY );
|
|
return;
|
|
}
|
|
}
|
|
m_hoverY = -1;
|
|
|
|
FEditorViewportClient::MouseMove( a_viewport, a_mouseX, a_mouseY );
|
|
}
|
|
|
|
void FSkillTreeEditorViewportClient::InternalActivateNewMode( )
|
|
{
|
|
//m_currentMode = a_newMode;
|
|
Viewport->InvalidateHitProxy();
|
|
}
|
|
|
|
FLinearColor FSkillTreeEditorViewportClient::GetBackgroundColor() const
|
|
{
|
|
return FLinearColor( 0.20f, 0.22f, 0.22f );
|
|
}
|
|
|
|
void FSkillTreeEditorViewportClient::ActivateEditMode()
|
|
{
|
|
// Activate the skill tree edit mode
|
|
ModeTools->SetToolkitHost( m_skillTreeEditorPtr.Pin()->GetToolkitHost() );
|
|
ModeTools->ActivateDefaultMode();
|
|
}
|
|
|
|
void FSkillTreeEditorViewportClient::Tick( float a_deltaSeconds )
|
|
{
|
|
FEditorViewportClient::Tick( a_deltaSeconds );
|
|
|
|
m_skillTreeEditorPtr.Pin()->UpdateSkills();
|
|
|
|
if ( !GIntraFrameDebuggingGameThread )
|
|
{
|
|
m_ownedPreviewScene.GetWorld()->Tick( LEVELTICK_All, a_deltaSeconds );
|
|
}
|
|
}
|
|
|
|
void FSkillTreeEditorViewportClient::ProcessClick( FSceneView& a_view, HHitProxy* a_hitProxy, FKey a_key, EInputEvent a_event, uint32 a_hitX, uint32 a_hitY )
|
|
{
|
|
bool handled = false;
|
|
USkillTreeObject* skillTree = m_skillTreeEditorPtr.Pin()->GetSkillTreeBeingEdited();
|
|
USkillObject* skill = m_skillTreeEditorPtr.Pin()->GetSkillBeingEdited();
|
|
|
|
int offsetY = -m_hexSize;
|
|
int height;
|
|
int maxY;
|
|
int width;
|
|
|
|
if ( m_state )
|
|
{
|
|
height = skill->hexMap.height;
|
|
width = skill->hexMap.width;
|
|
if ( height % 2 != 0 ) offsetY = m_hexSize;
|
|
maxY = height-1;
|
|
}
|
|
else
|
|
{
|
|
height = 16;
|
|
width = 13;
|
|
maxY = 15;
|
|
}
|
|
|
|
FVector2D mpos( a_hitX, a_hitY );
|
|
|
|
for ( float x = 0; x < width; x++ )
|
|
{
|
|
maxY = (maxY == (height - 1) ? height : (height - 1));
|
|
offsetY = ( offsetY == -m_hexSize ? 0 : -m_hexSize );
|
|
for ( int y = 0; y < maxY; y++ )
|
|
{
|
|
float X = ( x - ( ( (float)width ) / 2.0f ) ) * m_hexSize * 2;
|
|
float Y = ( ( y - ( maxY / 2 ) ) * m_hexSize * 2 ) + offsetY;
|
|
FVector2D pos( ( m_screenSize.X / 2 ) + X, ( m_screenSize.Y / 2 ) + Y );
|
|
float dist = FVector2D::Distance( pos, mpos );
|
|
if ( dist <= m_hexSize )
|
|
{
|
|
if ( !m_state )
|
|
{
|
|
skillTree->hexMap.Invert( x, y );
|
|
skillTree->Modify();
|
|
skillTree->MarkPackageDirty();
|
|
skillTree->PostEditChange();
|
|
}
|
|
else
|
|
{
|
|
skill->hexMap.Invert( x, y );
|
|
skill->Modify();
|
|
skill->MarkPackageDirty();
|
|
skill->PostEditChange();
|
|
}
|
|
handled = true;
|
|
Invalidate();
|
|
break;
|
|
}
|
|
}
|
|
if ( handled )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( !handled && !m_state )
|
|
{
|
|
float hexmapWidth = ( m_screenSize.X / 2 ) + ( ( ( width - 1 ) - ( ( (float)width ) / 2.0f ) ) * m_hexSize * 2 );
|
|
hexmapWidth += m_hexSize;
|
|
|
|
uint32 minboxX = m_screenSize.X - ( ( m_screenSize.X - hexmapWidth ) );
|
|
uint32 maxboxX = m_screenSize.X;
|
|
for ( int i = 0, y = 50; i < skillTree->skills.Num(); i++, y += 20 )
|
|
{
|
|
uint32 minboxY = y;
|
|
uint32 maxboxY = y + 20;
|
|
if ( !skillTree->skills[i] ) continue;
|
|
if ( a_hitX >= minboxX && a_hitX <= maxboxX && a_hitY >= minboxY && a_hitY <= maxboxY )
|
|
{
|
|
m_skillTreeEditorPtr.Pin()->selectedY = i;
|
|
handled = true;
|
|
USkillObject* tmpCast = skillTree->skills[i]->GetDefaultObject<USkillObject>();
|
|
if ( tmpCast != NULL ) m_skillTreeEditorPtr.Pin()->SetSkillBeingEdited( tmpCast );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !handled )
|
|
{
|
|
FEditorViewportClient::ProcessClick( a_view, a_hitProxy, a_key, a_event, a_hitX, a_hitY );
|
|
}
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE |