haxis/Source/UnrealProject/GUI/SkillTree/SkillWidget.cpp

844 lines
23 KiB
C++

// Project Lab - NHTV Igad
#include "UnrealProject.h"
#include "SkillWidget.h"
#include "BaseSkillObject.h"
#include "SkillTreeObject.h"
#include "HexagonTile.h"
#include "CanvasPanel.h"
#include "Border.h"
#include "SkillTreeWidget.h"
#include "HexagonTile.h"
#include "WidgetLayoutLibrary.h"
#include "AbilityInfo.h"
#include "SizeBorder.h"
#include "MenuScreenBase.h"
int32 roundToNearestOdd(float a_in)
{
return 2 * FMath::FloorToInt(a_in / 2) + 1;
}
int32 roundToNearestEven(float a_in)
{
return 2 * FMath::FloorToInt(a_in / 2);
}
//Convert from Odd-q coordinate system to Cube.
FIntVector Oddq2Cube( FIntPoint in )
{
int32 x = in.X;
int32 z = int32( float( in.Y ) - float( in.X - ( in.X & 1 ) ) / 2.0f );
int32 y = -x - z;
return FIntVector( x, y, z );
}
//Convert from Cube coordinate system to Odd-q.
FIntPoint Cube2Oddq( FIntVector in )
{
int32 x = in.X;
int32 y = int32( float( in.Z ) + float( in.X - ( in.X & 1 ) ) / 2.0f );
return FIntPoint( x, y );
}
//Convert from Even-q coordinate system to Cube.
FIntVector Evenq2Cube( FIntPoint in )
{
int32 x = in.X;
int32 z = int32( float( in.Y ) - float( in.X + ( in.X & 1 ) ) / 2.0f );
int32 y = -x - z;
return FIntVector( x, y, z );
}
//Convert from Cube coordinate system to Even-q.
FIntPoint Cube2Evenq( FIntVector in )
{
int32 x = in.X;
int32 y = int32( float( in.Z ) + float( in.X + ( in.X & 1 ) ) / 2.0f );
return FIntPoint( x, y );
}
//Rotates a hexoganal position by the angle.
//The position must be in Cube coordinates.
//The angle must be in degrees.
FIntVector RotateHexPos( FIntVector in, float angle )
{
while ( angle < 0 )
{
angle += 360;
}
while ( angle > 360 )
{
angle -= 360;
}
int32 steps = FMath::FloorToInt( angle / 60 );
FIntVector result = in;
for ( int32 i = 0; i < steps; i++ )
{
FIntVector tmp = FIntVector( -result.Z, -result.X, -result.Y );
result = tmp;
}
return result;
}
//Rotates a hexoganal position by the angle.
//The position must be in Odd-q or Even-q coordinates.
//The OddQ boolean decides what coordinate system is used.
//The angle must be in degrees.
FIntPoint RotateHexPos( FIntPoint in, float angle, bool oddq )
{
FIntVector cubeIn;
if ( oddq )
cubeIn = Oddq2Cube( in );
else
cubeIn = Evenq2Cube( in );
FIntVector cubeOut = RotateHexPos( cubeIn, angle );
FIntPoint Out;
if ( oddq )
Out = Cube2Oddq( cubeOut );
else
Out = Cube2Evenq( cubeOut );
return Out;
}
void USkillWidget::PlaceOnGridIndex(FVector2D index)
{
m_lastGridIndex = index /*+ FVector2D(1.5, 4) * RenderTransform.Scale.X*/;
UCanvasPanelSlot* tmpSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(parent->GetCanvas());
float viewportScale = UWidgetLayoutLibrary::GetViewportScale(parent);
FVector2D topLeft = GetSkillTreePos();
float scale = 32.0f * (RenderTransform.Scale.X / 2);
float XScale = (scale * 1.73205f);
float YScale = scale;
if(tmpSlot)
{
FVector2D result;
result.X = index.X * XScale;
result.X += topLeft.X;
//result.X -= 2;
result.Y = index.Y * YScale;
result.Y += topLeft.Y;
//result.Y += 14.5f;
UCanvasPanelSlot* selfSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(this);
selfSlot->SetPosition(result);
placedPoints.SetNum(0);
CheckPosition(m_lastGridIndex, &placedPoints);
ChangeColor(GetShapeTypeColor());
}
}
void USkillWidget::SetPlaced()
{
m_dragable = true;
m_placed = true;
}
void USkillWidget::UpdateSkill()
{
m_hexagons.Empty();
if ( !skillAsset )
{
//YWARNING( "No Skill Asset assigned to the Skill Widget." );
SetVisibility( ESlateVisibility::Hidden );
return;
}
SetVisibility(ESlateVisibility::SelfHitTestInvisible);
TArray<UWidget*> widgets;
WidgetTree->GetAllWidgets( widgets );
UCanvasPanel* canvasPanel = NULL;
FLinearColor color = GetShapeTypeColor();
for ( int32 i = 0; i < widgets.Num(); i++ )
{
UHexagonTile* tmp = Cast<UHexagonTile>( widgets[i] );
UCanvasPanel* tmpPanel = Cast<UCanvasPanel>( widgets[i] );
if ( tmpPanel ) canvasPanel = tmpPanel;
if ( !tmp ) continue;
bool test = skillAsset->hexMap.Get( tmp->x, tmp->y );
//tmp->SetColorAndOpacity( skillColor );
m_hexagons.Push( tmp );
if ( !test )
{
tmp->SetVisibility(ESlateVisibility::Hidden);
}
else
{
tmp->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}
}
if (!m_dragable)
{
UpdateLevel(0);
}
if ( canvasPanel )
{
m_canvasPanel = canvasPanel;
UCanvasPanelSlot* slot = Cast<UCanvasPanelSlot>( canvasPanel->Slot );
if ( slot )
{
m_slot = slot;
float offset = 1.0f;
float width = ( skillAsset->hexMap.width * 27.7128f ) + 4.2871f;
FVector2D newSize = FVector2D(width, ( (skillAsset->hexMap.height * 32.0f) - offset ));
m_slot->SetSize(newSize);
//GWPRINT(L"Size of " + skillAsset->GetName() + L"(placed=" + m_placed + L") = " + newSize);
}
if ( m_dragable )
{
FVector2D transformPivot;
transformPivot.X = ( float( skillAsset->pivot.X ) + 0.5f ) / float( skillAsset->hexMap.width );
transformPivot.Y = ( float( skillAsset->pivot.Y ) + ( ( skillAsset->pivot.X & 1 ) ? 1.0f : 0.5f ) ) / float( skillAsset->hexMap.height );
canvasPanel->SetRenderTransformPivot( transformPivot );
//YPRINT( "Pivot: X=" + transformPivot.X + ", Y=" + transformPivot.Y );
}
}
UCanvasPanel* mainCanvas = WidgetTree->FindWidget<UCanvasPanel>("Main_Canvas");
if ( m_dragable )
{
//m_spacer->SetVisibility( ESlateVisibility::Hidden );
SetRenderScale( parent->WidgetTree->FindWidget<UCanvasPanel>("Main_SkillTree")->RenderTransform.Scale );
}
else
{
//m_spacer->SetVisibility( ESlateVisibility::Visible );
SetRenderScale( FVector2D( 1, 1 ) );
}
//float scale = RenderTransform.Scale.X - 1.0f;
//float alignment = ( m_dragable ) ? (-scale * 0.5f) : 0.5f;
//FVector2D alignment2D ( alignment, alignment );
//tmpSlot->SetAlignment( alignment2D );
if ( m_dragable && !m_controller )
{
FVector2D mousePos;
UWidgetLayoutLibrary::GetMousePositionScaledByDPI( GetOwningPlayer(), mousePos.X, mousePos.Y );
FVector2D skillPos;
skillPos = mousePos - ( m_slot->GetSize() / 2 );
UCanvasPanelSlot* tmpSlot2 = Cast<UCanvasPanelSlot>( Slot );
if ( tmpSlot2 )
{
tmpSlot2->SetPosition( skillPos );
}
if(!m_placed)
StartDragging();
else
{
FVector2D position = GetViewportPos();
FVector2D mousePos;
UWidgetLayoutLibrary::GetMousePositionScaledByDPI(GetOwningPlayer(), mousePos.X, mousePos.Y);
m_offset = position - mousePos;
}
m_offset = -( ( m_slot->GetSize() * (RenderTransform.Scale.X / 2) ) / 2);
}
else if (m_controller)
{
StartDragging();
}
// Update color of hexagons
UpdateSkillIcon();
ChangeColor(color);
}
void USkillWidget::NativeConstruct()
{
selectedEffect = -1;
hovered = false;
UpdateSkill();
FIntPoint point( 0, 1 );
FIntPoint a = RotateHexPos( point, 60, false );
//YPRINT( "60: X:" + a.X + ", Y:" + a.Y );
/*
FIntPoint b = RotateHexPos( point, 120 );
YPRINT( "120: X:" + b.X + ", Y:" + b.Y );
FIntPoint c = RotateHexPos( point, 180 );
YPRINT( "180: X:" + c.X + ", Y:" + c.Y );
FIntPoint d = RotateHexPos( point, 240 );
YPRINT( "240: X:" + d.X + ", Y:" + d.Y );
FIntPoint e = RotateHexPos( point, 300 );
YPRINT( "300: X:" + e.X + ", Y:" + e.Y );
FIntPoint f = RotateHexPos( point, -60 );
YPRINT( "-60: X:" + f.X + ", Y:" + f.Y );
FIntPoint g = RotateHexPos( point, -120 );
YPRINT( "-120: X:" + g.X + ", Y:" + g.Y );
FIntPoint h = RotateHexPos( point, -180 );
YPRINT( "-180: X:" + h.X + ", Y:" + h.Y );
*/
//m_border = WidgetTree->FindWidget<UBorder>("Border");
//m_border->SetVisibility(ESlateVisibility::Hidden);
Super::NativeConstruct();
}
void USkillWidget::NativeDestruct()
{
Super::NativeDestruct();
}
void USkillWidget::UpdateSkillColor()
{
FLinearColor color;
if(m_dragging)
{
bool hover = CheckPosition(m_lastGridIndex);
if(hover)
{
m_hovering = true;
color = FLinearColor(0, 1, 0, 1);
if(!GetSelectedEffectAbility())
color = FLinearColor::Yellow;
}
else
{
m_hovering = false;
color = FLinearColor(1, 0, 0, 1);
}
}
else
{
color = GetShapeTypeColor();
}
ChangeColor(color);
}
void USkillWidget::UpdateSkillIcon()
{
for(int32 i = 0; i < m_hexagons.Num(); i++)
{
if(m_hexagons[i]->material)
{
m_hexagons[i]->material->SetTextureParameterValue("Skill_Texture", m_skillIcon);
}
}
}
void USkillWidget::SetSelectedEffect(int32 effect)
{
//UpdateSkill();
if(effect >= 0 && effect < skillAsset->abilityEffects.Num())
{
selectedEffect = effect;
// Set icon on hexagons
UAbilityInfo* ability = skillAsset->abilityEffects[selectedEffect];
if(ability)
{
m_skillIcon = ability->icon;
}
}
// Update material
UpdateSkillIcon();
UpdateSkillColor();
}
class UAbilityInfo* USkillWidget::GetSelectedEffectAbility() const
{
if(selectedEffect >= 0 && selectedEffect < skillAsset->abilityEffects.Num())
{
return skillAsset->abilityEffects[selectedEffect];
}
return nullptr;
}
void USkillWidget::Select()
{
//if ( !m_spacer ) return;
//m_spacer->SetBrushColor( FLinearColor( 1, 1, 1, 0.68f ) );
//parent->DeselectOther( this );
//m_selected = true;
//UWidgetLayoutLibrary::GetMousePositionScaledByDPI( GetOwningPlayer(), m_mousedownPos.X, m_mousedownPos.Y );
}
void USkillWidget::Deselect()
{
//if ( !m_spacer ) return;
//m_spacer->SetBrushColor( FLinearColor( 0, 0, 0, 0.68f ) );
//m_selected = false;
}
void USkillWidget::Remove()
{
parent->RemoveSkill(this, placedPoints);
}
bool USkillWidget::RestartDragging()
{
if (parent->draggingWidget)
return false;
parent->RemoveSkill(this, placedPoints);
SetDragable(true, true);
SetUserFocus(GetOwningPlayer());
parent->draggingWidget = this;
m_hovering = true;
ChangeColor(FLinearColor(0, 1, 0, 1));
return true;
}
void USkillWidget::StartDragging()
{
if(!m_dragging && parent->draggingWidget == nullptr && parent->IsInteractive())
{
m_dragging = true;
FVector2D position = GetViewportPos();
FVector2D mousePos;
UWidgetLayoutLibrary::GetMousePositionScaledByDPI(GetOwningPlayer(), mousePos.X, mousePos.Y);
m_offset = position - mousePos;
if(m_placed) parent->RemoveSkill(this, placedPoints);
m_placed = false;
parent->StartDragging(this);
OnStartDragging();
}
//YPRINT( "Start... (X: " + position.X + ", Y: " + position.Y + ")" );
}
bool USkillWidget::PlaceSkill()
{
// Check if we have selected a valid effect
bool canPlace = true;
bool effectAssigned = GetSelectedEffectAbility() != nullptr;
//if(m_controller && !effectAssigned)
// canPlace = false;
if(skillAsset->abilityEffects.Num() == 0)
{
GERROR("Skill has no ability effects assigned, " + skillAsset->GetName());
canPlace = false;
}
TArray<FIntPoint> points;
placedPoints.Empty();
if(!CheckPosition(m_lastGridIndex, &points))
canPlace = false;
if(canPlace)
{
placedPoints = points;
parent->AddSkill(this, points);
m_placed = true;
ChangeColor(GetShapeTypeColor());
parent->StopDragging(this);
if(m_controller)
{
GetScreen()->CloseSubMenu(this);
}
m_dragging = false;
if(!effectAssigned)
{
OnRequireSkillEffect();
}
OnPlaceDone(true);
return true;
}
else if(!m_controller)
{
// Using mouse
parent->CancelSkill(this);
parent->StopDragging(this);
OnPlaceDone(false);
return false;
}
else
{
OnPlaceDone(false);
return false;
}
}
void USkillWidget::StopDragging()
{
if(m_dragging)
{
FVector2D mousePos;
UWidgetLayoutLibrary::GetMousePositionScaledByDPI(GetOwningPlayer(), mousePos.X, mousePos.Y);
FVector2D newPos = mousePos + m_offset;
FVector4 gridresult = GetGridPos(newPos);
FVector2D gridPos = FVector2D(gridresult.X, gridresult.Y);
FVector2D gridIndex = FVector2D(gridresult.Z, gridresult.W);
m_dragging = false;
PlaceSkill();
}
}
FVector2D USkillWidget::GetPositionFromIndex(FIntPoint in)
{
FVector2D result;
UCanvasPanelSlot* tmpSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(parent->GetCanvas());
float viewportScale = UWidgetLayoutLibrary::GetViewportScale(parent);
FVector2D topLeft = GetSkillTreePos();
float scale = 32.0f * ( RenderTransform.Scale.X / 2);
float XScale = (scale * 1.73205f);
float YScale = scale;
//FVector2D magicOffset = FVector2D(1.5, 4) * RenderTransform.Scale.X;
float XIndex = (float)in.X;// -magicOffset.X;
float YIndex = (float)in.Y;// -magicOffset.Y;
result.X = XIndex * XScale + topLeft.X;
result.Y = YIndex * YScale + topLeft.Y;
return result;
}
FVector2D USkillWidget::GetSkillTreePos()
{
UCanvasPanelSlot* tmpSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(parent->GetCanvas());
float viewportScale = UWidgetLayoutLibrary::GetViewportScale(parent->GetCanvas());
FVector2D topLeft;
if (tmpSlot)
{
FVector2D screenTopRight = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY().X * tmpSlot->GetAnchors().Minimum.X, GEngine->GameViewport->Viewport->GetSizeXY().Y * tmpSlot->GetAnchors().Minimum.Y);
FVector2D offset = tmpSlot->GetPosition() * viewportScale;
FVector2D widgetTopLeft = ((tmpSlot->GetSize() * RenderTransform.Scale.X * viewportScale) / 2) ;
topLeft = screenTopRight + offset - widgetTopLeft;
topLeft /= viewportScale;
//topLeft.X -= 16.0f;
}
return topLeft;
}
FVector2D USkillWidget::GetViewportPos()
{
FVector2D result;
FVector2D position;
UCanvasPanelSlot* tmpSlot = Cast<UCanvasPanelSlot>( Slot );
if ( tmpSlot )
{
position = tmpSlot->GetPosition( );
}
result.X = position.X;
result.Y = position.Y;
return result;
}
FVector4 USkillWidget::GetGridPos( FVector2D in )
{
FVector2D result;
FVector2D topLeft = GetSkillTreePos();
float scale = 32.0f * (RenderTransform.Scale.X / 2);
float XScale = (scale * 1.73205f);
float YScale = scale;
int32 XIndex = FMath::FloorToInt( ( in.X - topLeft.X ) / XScale );
int32 YIndex = FMath::FloorToInt( ( in.Y - topLeft.Y ) / YScale );
if ( XIndex % 2 == 0 )
YIndex = roundToNearestOdd( YIndex );
else
YIndex = roundToNearestEven(YIndex);
result.X = XIndex * XScale;
result.X += topLeft.X;
result.Y = YIndex * YScale;
result.Y += topLeft.Y;
m_lastGridIndex = FVector2D(XIndex, YIndex) - FVector2D(1, 0);// Store last grid position
return FVector4(result.X , result.Y , XIndex, YIndex);
}
bool USkillWidget::CheckPosition(FVector2D in, TArray<FIntPoint>* points)
{
bool result = true;
TArray<FIntPoint> localPoints;
//Check if positions are valid and available.
for ( int32 x1 = 0; x1 < skillAsset->hexMap.width; x1++ )
{
for ( int32 y1 = 0; y1 < skillAsset->hexMap.height; y1++ )
{
if ( skillAsset->hexMap.Get( x1, y1 ) )
{
int32 x2 = FMath::FloorToInt( in.X );
int32 y2;
int32 angle = FMath::FloorToInt( m_canvasPanel->RenderTransform.Angle );
FIntPoint pos1 = RotateHexPos( FIntPoint( x1 - skillAsset->pivot.X, y1 - skillAsset->pivot.Y ), angle, !(skillAsset->pivot.X & 1) );
pos1.X += skillAsset->pivot.X;
pos1.Y += skillAsset->pivot.Y;
if ( FMath::FloorToInt( in.X ) % 2 != 0 && pos1.X % 2 != 0 )
y2 = FMath::FloorToInt( ( in.Y + 1 ) / 2 );
else
y2 = FMath::FloorToInt( in.Y / 2 );
FIntPoint pos2 = pos1 + FIntPoint( x2, y2 );
localPoints.Push( pos2 );
if (pos2.X < 0 || pos2.X >= 13 || pos2.Y < 0 || pos2.Y >= ( (pos2.X & 1) ? 15 : 16 ) || parent->skillTreeAsset->hexMap.Get(pos2.X, pos2.Y) || parent->placedSkillHexMap->Get(pos2.X, pos2.Y))
{
result = false;
if ( !points )
{
break;
}
}
}
}
if ( !result && !points ) break;
}
if ( points ) ( *points ) = localPoints;
/*
for ( int32 i = 0; i < parent->tiles.Num(); i++ )
{
bool test = true;
for ( int32 j = 0; j < points.Num(); j++ )
{
if ( parent->tiles[i]->x == points[j].X && parent->tiles[i]->y == points[j].Y )
{
parent->tiles[i]->SetColorAndOpacity( FLinearColor::Yellow );
parent->tiles[i]->SetVisibility( ESlateVisibility::Visible );
test = false;
break;
}
}
if ( test )
{
if ( !parent->skillTreeAsset->hexMap.Get( parent->tiles[i]->x, parent->tiles[i]->y ) )
{
parent->tiles[i]->SetColorAndOpacity( FLinearColor::White );
parent->tiles[i]->SetVisibility( ESlateVisibility::Visible );
}
else
{
parent->tiles[i]->SetColorAndOpacity( FLinearColor::White );
parent->tiles[i]->SetVisibility( ESlateVisibility::Hidden );
}
}
}
*/
return result;
}
void USkillWidget::SetSkillRotation(float angle)
{
if(m_canvasPanel) m_canvasPanel->SetRenderAngle(angle);
else YWARNING("No canvas panel found!");
NativeOnSkillMove();
OnRotate();
}
void USkillWidget::MoveSkill(FVector2D offset)
{
//Check if odd
FVector2D tmpOffset = offset;
if (((int32)m_lastGridIndex.X) & 1 && tmpOffset.X != 0) tmpOffset.Y -= 1;
if (!(((int32)m_lastGridIndex.X) & 1) && tmpOffset.X != 0) tmpOffset.Y += 1;
m_lastGridIndex += tmpOffset;
if(parent->lastGridIndex != m_lastGridIndex)
{
parent->lastGridIndex = m_lastGridIndex; // Store last index
NativeOnSkillMove();
}
}
void USkillWidget::MoveSkillAbsolute(FVector2D gridIndex)
{
m_lastGridIndex = gridIndex;
parent->lastGridIndex = m_lastGridIndex; // Store last index
NativeOnSkillMove();
}
void USkillWidget::ChangeColor(FLinearColor color)
{
for ( int32 i = 0; i < m_hexagons.Num(); i++ )
{
if (m_hexagons[i]->material) m_hexagons[i]->material->SetVectorParameterValue("Skill_Color", color);
}
}
void USkillWidget::UpdateLevel( float level )
{
if (!m_dragable) return;
for (int32 i = 0; i < m_hexagons.Num(); i++)
{
if( m_hexagons[i]->material ) m_hexagons[i]->material->SetScalarParameterValue("Skill_Level", level);
}
float offset = 1.0f - level;
float skillHeight = 13.0f * offset;
float height = FMath::CeilToFloat(skillHeight);
int32 hexcount = 0;
for (int32 i = 0; i < placedPoints.Num(); i++)
{
float YPos = ( placedPoints[i].X & 1 ) ? (float(placedPoints[i].Y) + 0.5f) : (float(placedPoints[i].Y));
if ( YPos < height ) hexcount++;
}
m_power = float(placedPoints.Num()) / float(hexcount);
}
void USkillWidget::UpdateInfo(float skilltreeHeight, float skilltreeOffset)
{
for (int32 i = 0; i < m_hexagons.Num(); i++)
{
if (m_hexagons[i]->material)
{
m_hexagons[i]->material->SetScalarParameterValue("Skill_Tree_Height", skilltreeHeight);
m_hexagons[i]->material->SetScalarParameterValue("Skill_Offset", skilltreeOffset);
}
}
}
TArray<USkillWidget*> USkillWidget::ConnectedSkills(TArray<FIntPoint>& points)
{
//Check if surrounding positions contain another skill.
//if ( !PointsCointainsRoot(localPoints))
//{
TArray<USkillWidget*> result;
const FIntPoint offsets[2][6]{
{ FIntPoint(0, -1), FIntPoint(1, -1), FIntPoint(1, 0), FIntPoint(0, 1), FIntPoint(-1, 0), FIntPoint(-1, -1) },
{ FIntPoint(0, -1), FIntPoint(1, 0), FIntPoint(1, 1), FIntPoint(0, 1), FIntPoint(-1, 1), FIntPoint(-1, 0) } };
for (int32 i = 0; i < points.Num(); i++)
{
int32 k = points[i].X & 1;
for (int32 j = 0; j < 6; j++)
{
FIntPoint checkPoint = points[i] + offsets[k][j];
if ( points.Contains( checkPoint ) ) continue;
if (parent->skillTreeAsset->hexMap.Get(checkPoint.X, checkPoint.Y)) continue;
if (parent->placedSkillHexMap->Get(checkPoint.X, checkPoint.Y))
{
USkillWidget* widget = *parent->tileMap.Find(checkPoint);
if (result.Contains(widget)) continue;
result.Push(widget);
}
}
}
return result;
//}
}
bool USkillWidget::ContainsRoot(TArray<FIntPoint>& points)
{
return PointsCointainsRoot(points);
}
TArray<FIntPoint> USkillWidget::GetPoints()
{
TArray<FIntPoint> points;
CheckPosition(m_lastGridIndex, &points);
return points;
}
bool USkillWidget::PointsCointainsRoot( TArray<FIntPoint>& points )
{
for ( int32 i = 0; i < points.Num(); i++ )
{
if ( points[i] == parent->rootPoint ) return true;
}
return false;
}
void USkillWidget::NativeOnSkillMove()
{
UpdateSkillColor();
OnMove();
}
void USkillWidget::NativeTick( const FGeometry& geometry, float deltaTime )
{
FVector2D mousePos;
UWidgetLayoutLibrary::GetMousePositionScaledByDPI(GetOwningPlayer(), mousePos.X, mousePos.Y);
if ( m_dragging && !m_controller )
{
FVector2D newPos = mousePos + m_offset;
UCanvasPanelSlot* tmpSlot = Cast<UCanvasPanelSlot>( Slot );
if ( tmpSlot )
{
FVector4 gridresult = GetGridPos( newPos );
FVector2D gridPos = FVector2D( gridresult.X, gridresult.Y );
FVector2D gridIndex = FVector2D( gridresult.Z, gridresult.W );
if(gridPos != m_lastGridPos)
{
NativeOnSkillMove();
m_lastGridPos = gridPos;
}
}
else
YWARNING( "Couldn't get Slot." );
}
else if( !m_dragging )
{
if (hovered)
{
ChangeColor(GetShapeTypeColor() * 2.0f);
}
else
{
ChangeColor(GetShapeTypeColor() * 0.5f);
}
if(parent->draggingWidget == this)
parent->StopDragging(this);
}
if ( m_selected && m_enabled)
{
FVector2D mousePos;
UWidgetLayoutLibrary::GetMousePositionScaledByDPI( GetOwningPlayer(), mousePos.X, mousePos.Y );
FVector2D distanceVect = mousePos - m_mousedownPos;
if ( distanceVect.SizeSquared() > 100 )
{
parent->NewSkill( this );
m_selected = false;
}
}
UCanvasPanelSlot* tmpSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(parent->GetCanvas());
if (m_dragable)
{
float scale = 32.0f * (RenderTransform.Scale.X / 2);
float XScale = (scale * 1.73205f);
float YScale = scale;
FVector2D topLeft = GetSkillTreePos();
FVector2D result;
result.X = (m_lastGridIndex.X) * XScale;
result.X += topLeft.X;
result.Y = (m_lastGridIndex.Y) * YScale;
result.Y += topLeft.Y;
UCanvasPanelSlot* selfSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(this);
if (selfSlot)
{
selfSlot->SetPosition(result);
}
}
Super::NativeTick( geometry, deltaTime );
}
FLinearColor USkillWidget::GetShapeTypeColor() const
{
if(selectedEffect == -1)
return FLinearColor(1.0f, 1.0f, 1.0f) * 1.0f; // Hwhite
static FLinearColor shapeTypeColors[] =
{
FLinearColor(0.1f, 1.0f, 0.3f) * 0.75f, // Green
FLinearColor(1.0f, 0.3f, 0.1f) * 0.6f, // Red-Ish
FLinearColor(0.0f, 0.0f, 1.0f) * 0.6f, // Blue
};
int32 idx = 0;
if(skillAsset)
{
idx = (int32)skillAsset->abilityEffects[selectedEffect]->abilityCategory;
}
idx = FMath::Clamp(idx, 0, 2);
return FLinearColor(shapeTypeColors[idx].R, shapeTypeColors[idx].G, shapeTypeColors[idx].B, 1.0f);
}
void USkillWidget::SetDragable(bool dragable, bool controller /*= false */)
{
m_controller = controller;
m_dragable = dragable;
UpdateSkill();
}