844 lines
23 KiB
C++
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();
|
|
}
|