(Feat) Add Animation Fps Charater
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "InventoryScreenWidget.h"
|
||||
|
||||
#include "Components/Button.h"
|
||||
#include "Components/TextBlock.h"
|
||||
#include "Components/WidgetSwitcher.h"
|
||||
#include "CraftingWidget.h"
|
||||
#include "FpsPlayer.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "InventoryDragDropOperation.h"
|
||||
#include "InventoryWidget.h"
|
||||
#include "StorageContainer.h"
|
||||
|
||||
void UInventoryScreenWidget::NativeConstruct()
|
||||
{
|
||||
Super::NativeConstruct();
|
||||
|
||||
if (InventoryTabButton)
|
||||
{
|
||||
InventoryTabButton->OnClicked.AddDynamic(this, &UInventoryScreenWidget::HandleInventoryTabClicked);
|
||||
}
|
||||
|
||||
if (CraftingTabButton)
|
||||
{
|
||||
CraftingTabButton->OnClicked.AddDynamic(this, &UInventoryScreenWidget::HandleCraftingTabClicked);
|
||||
}
|
||||
|
||||
if (StoreAllButton)
|
||||
{
|
||||
StoreAllButton->OnClicked.AddDynamic(this, &UInventoryScreenWidget::HandleStoreAllClicked);
|
||||
}
|
||||
|
||||
if (TakeAllButton)
|
||||
{
|
||||
TakeAllButton->OnClicked.AddDynamic(this, &UInventoryScreenWidget::HandleTakeAllClicked);
|
||||
}
|
||||
|
||||
// La grille de coffre n'affiche jamais de detail : c'est le meme
|
||||
// WBP_Inventory que le sac, elle en porte donc un exemplaire qu'on coupe une
|
||||
// fois pour toutes ici plutot que de compter sur une case a cocher.
|
||||
if (StorageGrid)
|
||||
{
|
||||
StorageGrid->SetItemDetailsEnabled(false);
|
||||
}
|
||||
|
||||
// Le panneau de coffre ne se montre qu'a l'ouverture d'un coffre. On le
|
||||
// masque en C++ plutot que de dependre de ce qui a ete regle dans la
|
||||
// Designer : un panneau laisse Visible par erreur afficherait une grille
|
||||
// vide en permanence a cote du sac.
|
||||
HideStorage();
|
||||
|
||||
ShowInventoryTab();
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::BindToOwningPawn()
|
||||
{
|
||||
if (InventoryPage)
|
||||
{
|
||||
InventoryPage->BindToOwningPawn();
|
||||
}
|
||||
|
||||
if (CraftingPage)
|
||||
{
|
||||
CraftingPage->BindToOwningPawn();
|
||||
}
|
||||
}
|
||||
|
||||
bool UInventoryScreenWidget::IsInventoryTabActive() const
|
||||
{
|
||||
return TabSwitcher && InventoryPage && TabSwitcher->GetActiveWidget() == InventoryPage;
|
||||
}
|
||||
|
||||
int32 UInventoryScreenWidget::GetHoveredSlotIndex() const
|
||||
{
|
||||
if (!InventoryPage || !IsInventoryTabActive())
|
||||
{
|
||||
return INDEX_NONE;
|
||||
}
|
||||
|
||||
return InventoryPage->GetHoveredSlotIndex();
|
||||
}
|
||||
|
||||
bool UInventoryScreenWidget::GetHoveredSlot(UInventoryComponent*& OutInventory, int32& OutIndex) const
|
||||
{
|
||||
// Le coffre en premier : c'est le panneau le plus a droite, donc celui que
|
||||
// le curseur survole quand les deux sont affiches.
|
||||
if (bStorageVisible && StorageGrid && StorageGrid->GetHoveredSlot(OutInventory, OutIndex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (InventoryPage && IsInventoryTabActive() && InventoryPage->GetHoveredSlot(OutInventory, OutIndex))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
OutInventory = nullptr;
|
||||
OutIndex = INDEX_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::NotifyExternalSlotHovered(UInventoryComponent* Inventory, int32 SlotIndex, bool bHovered)
|
||||
{
|
||||
// Rien a faire sous l'onglet Fabrication : le panneau est parti avec la
|
||||
// page, et la barre rapide y est de toute facon masquee.
|
||||
if (InventoryPage && IsInventoryTabActive())
|
||||
{
|
||||
InventoryPage->NotifyExternalSlotHovered(Inventory, SlotIndex, bHovered);
|
||||
}
|
||||
}
|
||||
|
||||
UInventoryComponent* UInventoryScreenWidget::GetPlayerInventory() const
|
||||
{
|
||||
const APlayerController* OwningController = GetOwningPlayer();
|
||||
AFpsPlayer* PlayerPawn = OwningController ? Cast<AFpsPlayer>(OwningController->GetPawn()) : nullptr;
|
||||
return PlayerPawn ? PlayerPawn->GetInventoryComponent() : nullptr;
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::ShowStorage(AStorageContainer* Container)
|
||||
{
|
||||
UInventoryComponent* Contents = Container ? Container->GetStorage() : nullptr;
|
||||
if (!Contents)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("UInventoryScreenWidget::ShowStorage : coffre nul ou sans inventaire."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!StoragePanel || !StorageGrid)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("UInventoryScreenWidget : 'StoragePanel' ou 'StorageGrid' manque dans WBP_InventoryScreen, le coffre ne s'affichera pas."));
|
||||
return;
|
||||
}
|
||||
|
||||
BoundStorage = Contents;
|
||||
bStorageVisible = true;
|
||||
|
||||
StorageGrid->SetColumnCount(Container->GetColumnCount());
|
||||
StorageGrid->BindToInventory(Contents);
|
||||
|
||||
// Le clic droit envoie d'un cote a l'autre. Le pawn a pu changer depuis la
|
||||
// derniere ouverture (respawn), d'ou la relecture plutot qu'une valeur
|
||||
// gardee en cache.
|
||||
StorageGrid->SetQuickTransferTarget(GetPlayerInventory());
|
||||
if (InventoryPage)
|
||||
{
|
||||
InventoryPage->SetQuickTransferTarget(Contents);
|
||||
|
||||
// Le detail disparait en mode coffre : l'ecran passe deja a deux grilles
|
||||
// cote a cote, une troisieme colonne le rendrait illisible.
|
||||
InventoryPage->SetItemDetailsEnabled(false);
|
||||
}
|
||||
|
||||
if (StorageTitle)
|
||||
{
|
||||
StorageTitle->SetText(Container->GetDisplayName());
|
||||
}
|
||||
|
||||
StoragePanel->SetVisibility(ESlateVisibility::Visible);
|
||||
|
||||
// Un coffre ouvert sous l'onglet Fabrication n'aurait aucun sens : on force
|
||||
// l'onglet Inventaire, et ShowPage grise le bouton Fabrication tant que
|
||||
// bStorageVisible est vrai.
|
||||
ShowInventoryTab();
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::HideStorage()
|
||||
{
|
||||
BoundStorage.Reset();
|
||||
bStorageVisible = false;
|
||||
|
||||
// On coupe les transferts rapides AVANT de debrancher : une case qui garde
|
||||
// un coffre en memoire y enverrait encore des objets au prochain clic droit,
|
||||
// panneau ferme.
|
||||
if (InventoryPage)
|
||||
{
|
||||
InventoryPage->SetQuickTransferTarget(nullptr);
|
||||
|
||||
// Le sac retrouve son panneau. Repose a chaque fermeture, y compris a la
|
||||
// construction : c'est l'etat par defaut de l'ecran, il ne doit dependre
|
||||
// ni de la Designer ni de ce qu'a laisse la session precedente.
|
||||
InventoryPage->SetItemDetailsEnabled(true);
|
||||
}
|
||||
|
||||
if (StorageGrid)
|
||||
{
|
||||
StorageGrid->SetQuickTransferTarget(nullptr);
|
||||
StorageGrid->BindToInventory(nullptr);
|
||||
}
|
||||
|
||||
if (StoragePanel)
|
||||
{
|
||||
StoragePanel->SetVisibility(ESlateVisibility::Collapsed);
|
||||
}
|
||||
|
||||
// Rend la main a l'onglet Fabrication, que ShowPage avait grise.
|
||||
if (CraftingTabButton)
|
||||
{
|
||||
CraftingTabButton->SetIsEnabled(IsInventoryTabActive());
|
||||
}
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::HandleStoreAllClicked()
|
||||
{
|
||||
UInventoryComponent* PlayerInventory = GetPlayerInventory();
|
||||
if (!PlayerInventory || !BoundStorage.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// A partir de la grille seulement : la barre rapide porte les outils qu'on
|
||||
// vient d'utiliser, et les ranger a chaque retour d'expedition serait une
|
||||
// punition deguisee en confort.
|
||||
PlayerInventory->TransferAllTo(BoundStorage.Get(), PlayerInventory->GetBackpackStartIndex());
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::HandleTakeAllClicked()
|
||||
{
|
||||
UInventoryComponent* PlayerInventory = GetPlayerInventory();
|
||||
if (!PlayerInventory || !BoundStorage.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Depuis l'index 0 : un coffre n'a pas de barre rapide. Ce qui ne rentre
|
||||
// pas dans le sac reste dans le coffre.
|
||||
BoundStorage->TransferAllTo(PlayerInventory, 0);
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::ShowInventoryTab()
|
||||
{
|
||||
ShowPage(InventoryPage);
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::ShowCraftingTab()
|
||||
{
|
||||
ShowPage(CraftingPage);
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::HandleInventoryTabClicked()
|
||||
{
|
||||
ShowPage(InventoryPage);
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::HandleCraftingTabClicked()
|
||||
{
|
||||
ShowPage(CraftingPage);
|
||||
}
|
||||
|
||||
void UInventoryScreenWidget::ShowPage(UWidget* Page)
|
||||
{
|
||||
if (!TabSwitcher || !Page)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TabSwitcher->SetActiveWidget(Page);
|
||||
|
||||
// Le bouton de l'onglet courant est desactive : il sert d'indicateur de
|
||||
// position autant que de garde-fou contre un clic sans effet.
|
||||
const bool bInventoryActive = (Page == InventoryPage);
|
||||
|
||||
if (InventoryTabButton)
|
||||
{
|
||||
InventoryTabButton->SetIsEnabled(!bInventoryActive);
|
||||
}
|
||||
|
||||
if (CraftingTabButton)
|
||||
{
|
||||
// Grise aussi tant qu'un coffre est ouvert : ses ressources ne comptent
|
||||
// pas encore dans les recettes, et un clic dont le resultat serait
|
||||
// incomprehensible vaut mieux etre rendu impossible.
|
||||
CraftingTabButton->SetIsEnabled(bInventoryActive && !bStorageVisible);
|
||||
}
|
||||
|
||||
OnTabChanged.Broadcast(bInventoryActive);
|
||||
}
|
||||
|
||||
bool UInventoryScreenWidget::NativeOnDrop(const FGeometry& InGeometry, const FDragDropEvent& InDragDropEvent, UDragDropOperation* InOperation)
|
||||
{
|
||||
Super::NativeOnDrop(InGeometry, InDragDropEvent, InOperation);
|
||||
|
||||
// On n'arrive ici que si ni une case ni la page d'inventaire n'ont traite le
|
||||
// depot : les enfants sont consultes en premier et arretent la propagation.
|
||||
const UInventoryDragDropOperation* Payload = Cast<UInventoryDragDropOperation>(InOperation);
|
||||
if (!Payload || Payload->SourceSlotIndex == INDEX_NONE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Depuis l'inventaire SOURCE et non celui du joueur : sortir une pile du
|
||||
// coffre en la lachant dans le vide doit la retirer du coffre.
|
||||
if (const APlayerController* OwningController = GetOwningPlayer())
|
||||
{
|
||||
if (AFpsPlayer* PlayerPawn = Cast<AFpsPlayer>(OwningController->GetPawn()))
|
||||
{
|
||||
PlayerPawn->DropFromInventory(Payload->SourceInventory.Get(), Payload->SourceSlotIndex, Payload->Quantity);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user