haxis/Plugins/SkillTree/Source/SkillTreeEditor/Private/SkillTreeEditorViewportClie...

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