Skip to content

Commit

Permalink
Equipment Refactor
Browse files Browse the repository at this point in the history
Completely changing Equipment Interface ( #142 ) and Equipment Component ( #142 ).
Created new Equipment Slot ( #143 ) and helpers ( #146, #147 ).
  • Loading branch information
pavlicekdominik committed Nov 27, 2023
1 parent 11465ca commit d521de3
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "Interfaces/UI/MounteaEquipmentWBPInterface.h"
#include "Net/UnrealNetwork.h"
#include "Settings/MounteaInventoryEquipmentSettings.h"
#include "Settings/Config/MounteaDefaultsConfig.h"
#include "WBP/MounteaBaseUserWidget.h"

#define LOCTEXT_NAMESPACE "MounteaEquipmentComponent"
Expand Down Expand Up @@ -462,12 +463,6 @@ void UMounteaEquipmentComponent::PostItemUnequipped_Multicast_RequestUpdate(cons
OnSlotUnequipped_Multicast.Broadcast(UpdateContext);
}

/*===============================================================================
IN PROGRESS
Following functions are using being changed.
===============================================================================*/

bool UMounteaEquipmentComponent::IsItemEquipped_Implementation(const UMounteaInstancedItem* Item, const FText& SlotID) const
{
return EquipmentSlots.Contains(FMounteaEquipmentSlotCompare(Item, SlotID));
Expand All @@ -494,6 +489,37 @@ bool UMounteaEquipmentComponent::SetEquipmentUI_Implementation(UMounteaBaseUserW
return false;
}

void UMounteaEquipmentComponent::SetEquipmentUIClass_Implementation(TSubclassOf<UMounteaBaseUserWidget> NewWBPClass)
{
if (NewWBPClass == nullptr) return;

if (NewWBPClass->ImplementsInterface(UMounteaEquipmentWBPInterface::StaticClass()))
{
EquipmentUIClass = NewWBPClass;
}
}

TSubclassOf<UMounteaBaseUserWidget> UMounteaEquipmentComponent::GetEquipmentUIClass_Implementation() const
{
if (EquipmentUIClass != nullptr ) { return EquipmentUIClass; };

const UMounteaInventoryEquipmentSettings* Settings = UMounteaInventoryEquipmentBPF::GetSettings();

if (!Settings) return nullptr;

const UMounteaDefaultsConfig* DefaultsConfig = Settings->DefaultsConfig.LoadSynchronous();

if (!DefaultsConfig) return nullptr;

return DefaultsConfig->DefaultEquipmentClass.LoadSynchronous();
}

/*===============================================================================
IN PROGRESS
Following functions are using being changed.
===============================================================================*/

/*===============================================================================
SUBJECT OF CHANGE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@
#include "Settings/MounteaEquipmentConfigData.h"
#include "Settings/MounteaInventoryEquipmentSettings.h"

void UMounteaEquipmentSlotBaseWidget::UpdateSlotID(const FText& NewSlotID)
{
if (const UMounteaInventoryEquipmentSettings* const Settings = UMounteaInventoryEquipmentBPF::GetSettings())
{
if (!Settings->EquipmentConfigData.IsNull())
{
const auto IDs = Settings->EquipmentConfigData.LoadSynchronous()->EquipmentSlotIDs;
if (IDs.Contains(NewSlotID))
{
SlotID = NewSlotID;

return;
}
}
}

UE_LOG(LogTemp, Error, TEXT("[EquipmentSlot - UpdateSlotID] Slot %s is not supported!"), *NewSlotID.ToString())
}

TArray<FText> UMounteaEquipmentSlotBaseWidget::GetSlotIDOptions()
{
TArray<FText> Results;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ class MOUNTEAINVENTORYEQUIPMENT_API UMounteaEquipmentComponent : public UActorCo
virtual TArray<FEquipmentSlot> GetAllSlots_Implementation() const override;
virtual bool DoesHaveAuthority_Implementation() const override;

public:
virtual UMounteaBaseUserWidget* GetEquipmentUI_Implementation() const override;
virtual bool IsItemEquipped_Implementation(const UMounteaInstancedItem* Item, const FText& SlotID) const override;

virtual bool SetEquipmentUI_Implementation(UMounteaBaseUserWidget* NewUI) override;

virtual void SetEquipmentUIClass_Implementation(UPARAM(meta=(MustImplement="/Script/MounteaInventoryEquipment.MounteaEquipmentWBPInterface")) TSubclassOf<UMounteaBaseUserWidget> NewWBPClass) override;
virtual TSubclassOf<UMounteaBaseUserWidget> GetEquipmentUIClass_Implementation() const override;

/**
* Checks if the owning actor has a network role of either Authority or Autonomous Proxy.
Expand All @@ -62,21 +68,20 @@ class MOUNTEAINVENTORYEQUIPMENT_API UMounteaEquipmentComponent : public UActorCo
* @return True if the owning actor is either Authority or Autonomous Proxy, false otherwise.
*/
bool IsAuthorityOrAutonomousProxy() const;

/*===============================================================================
IN PROGRESS
Following functions are using being changed.
===============================================================================*/

virtual FInventoryUpdateResult EquipItem_Implementation(UMounteaInstancedItem* ItemToEquip, const FText& SlotID) override;

UFUNCTION(Server, Reliable, WithValidation)
void EquipItem_Server(UMounteaInstancedItem* ItemToEquip, const FText& SlotID);
virtual FInventoryUpdateResult EquipItem_Implementation(UMounteaInstancedItem* ItemToEquip, const FText& SlotID) override;
virtual FInventoryUpdateResult UnEquipItem_Implementation(UMounteaInstancedItem* Item, const FText& SlotID) override;

virtual bool CanEquipItem_Implementation(const UMounteaInstancedItem* ItemToEquip) const override;
virtual bool CanUnEquipItem_Implementation(const UMounteaInstancedItem* ItemToUnequip) const override;

protected:

UFUNCTION(Server, Reliable, WithValidation)
void EquipItem_Server(UMounteaInstancedItem* ItemToEquip, const FText& SlotID);
UFUNCTION(Server, Reliable, WithValidation)
void UnEquipItem_Server(UMounteaInstancedItem* Item, const FText& SlotID);

UFUNCTION(Server, Unreliable)
void PostEquipmentUpdated(const FInventoryUpdateResult& UpdateContext);
UFUNCTION(Server, Unreliable)
Expand Down Expand Up @@ -104,49 +109,57 @@ class MOUNTEAINVENTORYEQUIPMENT_API UMounteaEquipmentComponent : public UActorCo
void PostItemEquipped_Client_RequestUpdate(const FInventoryUpdateResult& UpdateContext);
UFUNCTION()
void PostItemUnequipped_Client_RequestUpdate(const FInventoryUpdateResult& UpdateContext);


UFUNCTION()
void PostEquipmentUpdated_Multicast_RequestUpdate(const FInventoryUpdateResult& UpdateContext);
UFUNCTION()
void PostItemEquipped_Multicast_RequestUpdate(const FInventoryUpdateResult& UpdateContext);
UFUNCTION()
void PostItemUnequipped_Multicast_RequestUpdate(const FInventoryUpdateResult& UpdateContext);

public:

virtual FOnEquipmentUpdated& GetEquipmentUpdatedHandle() override { return OnEquipmentUpdated; };
virtual FOnEquipmentUpdated& GetSlotEquippedHandle() override { return OnSlotEquipped; };
virtual FOnEquipmentUpdated& GetSlotUnEquippedHandle() override { return OnSlotUnequipped; }

/*===============================================================================
IN PROGRESS
Following functions are using being changed.
===============================================================================*/


/*===============================================================================
SUBJECT OF CHANGE
Following functions are using outdated, wrong class definitions and functions.
===============================================================================*/

virtual bool IsItemEquipped_Implementation(const UMounteaInstancedItem* Item, const FText& SlotID) const override;

virtual FInventoryUpdateResult UnEquipItem_Implementation(UMounteaInstancedItem* Item, const FText& SlotID) override;

UFUNCTION(Server, Reliable, WithValidation)
void UnEquipItem_Server(UMounteaInstancedItem* Item, const FText& SlotID);

virtual UMounteaBaseUserWidget* GetEquipmentUI_Implementation() const override;
virtual bool SetEquipmentUI_Implementation(UMounteaBaseUserWidget* NewUI) override;

virtual FOnEquipmentUpdated& GetEquipmentUpdatedHandle() override { return OnEquipmentUpdated; };
virtual FOnEquipmentUpdated& GetSlotEquippedHandle() override { return OnSlotEquipped; };
virtual FOnEquipmentUpdated& GetSlotUnEquippedHandle() override { return OnSlotUnequipped; }


protected:

UFUNCTION()
void OnRep_Equipment();

#if WITH_EDITOR
protected:

virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;

#endif

#pragma endregion

#pragma region VARIABLES

protected:

UPROPERTY(SaveGame, EditAnywhere, Category="1. Required", meta=(DisplayThumbnail=false, ShowOnlyInnerProperties, MustImplement="/Script/MounteaInventoryEquipment.MounteaEquipmentWBPInterface"))
TSubclassOf<UMounteaBaseUserWidget> EquipmentUIClass;

UPROPERTY(SaveGame, Category="1. Required", EditDefaultsOnly, BlueprintReadOnly, ReplicatedUsing=OnRep_Equipment)
TArray<FEquipmentSlot> EquipmentSlots;

private:

// Filled from RemoveFromItem to keep track of Items that were removed
Expand Down Expand Up @@ -189,12 +202,5 @@ class MOUNTEAINVENTORYEQUIPMENT_API UMounteaEquipmentComponent : public UActorCo
FOnEquipmentUpdated OnSlotUnequipped_Multicast;

#pragma endregion

#if WITH_EDITOR
protected:

virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;

#endif

};
Original file line number Diff line number Diff line change
Expand Up @@ -39,46 +39,123 @@ class MOUNTEAINVENTORYEQUIPMENT_API IMounteaEquipmentInterface

public:

/**
* Retrieves the actor that owns this equipment. For components it is common to return Owner, for Actors to return themselves.
* @return The owning actor of this equipment.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
AActor* GetOwningActor() const;
virtual AActor* GetOwningActor_Implementation() const = 0;

/**
* Finds a suitable slot for the given item based on the equipment's rules and configuration.
* @param Item The item for which a suitable slot needs to be found.
* @return The ID of the slot that can accommodate the item, or None if none is found.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
FText FindSlotForItem(const UMounteaInstancedItem* Item) const;
virtual FText FindSlotForItem_Implementation(const UMounteaInstancedItem* Item) const = 0;

/**
* Finds a slot by its ID within the equipment.
* @param SlotID The ID of the slot to find.
* @return The index of the slot if found, or -1 if not found.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
int32 FindSlotByID(const FText& SlotID) const;
virtual int32 FindSlotByID_Implementation(const FText& SlotID) const = 0;


/**
* Equips an item to the specified slot, updating the equipment state accordingly.
* @param ItemToEquip The item to equip.
* @param SlotID The ID of the slot where the item is to be equipped.
* @return A structure containing details about the outcome of the equip process.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
FInventoryUpdateResult EquipItem(UMounteaInstancedItem* ItemToEquip, const FText& SlotID);
virtual FInventoryUpdateResult EquipItem_Implementation(UMounteaInstancedItem* ItemToEquip,const FText& SlotID) = 0;

/**
* Unequips an item from the specified slot, updating the equipment state accordingly.
* @param ItemToEquip The item to unequip.
* @param SlotID The ID of the slot from which the item is to be unequipped.
* @return A structure containing details about the outcome of the unequip process.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
FInventoryUpdateResult UnEquipItem(UMounteaInstancedItem* ItemToEquip, const FText& SlotID);
virtual FInventoryUpdateResult UnEquipItem_Implementation(UMounteaInstancedItem* ItemToEquip, const FText& SlotID) = 0;

/**
* Checks if a specific item is currently equipped in a specified slot.
* @param ItemToEquip The item to check if it's equipped.
* @param SlotID The ID of the slot to check.
* @return True if the item is equipped in the specified slot, false otherwise.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
bool IsItemEquipped(const UMounteaInstancedItem* ItemToEquip, const FText& SlotID) const;
virtual bool IsItemEquipped_Implementation(const UMounteaInstancedItem* ItemToEquip, const FText& SlotID) const = 0;


/**
* Retrieves all the equipment slots available.
* @return An array of all equipment slots.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
TArray<FEquipmentSlot> GetAllSlots() const;
virtual TArray<FEquipmentSlot> GetAllSlots_Implementation() const = 0;

/**
* Checks if a specific item can be equipped.
* @param ItemToEquip The item to check.
* @return True if the item can be equipped, false otherwise.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
bool CanEquipItem(const UMounteaInstancedItem* ItemToEquip) const;
virtual bool CanEquipItem_Implementation(const UMounteaInstancedItem* ItemToEquip) const = 0;

/**
* Checks if a specific item can be unequipped.
* @param ItemToUnequip The item to check.
* @return True if the item can be unequipped, false otherwise.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
bool CanUnEquipItem(const UMounteaInstancedItem* ItemToUnequip) const;
virtual bool CanUnEquipItem_Implementation(const UMounteaInstancedItem* ItemToUnequip) const = 0;

/**
* Sets the UI widget for the equipment interface.
* @param NewUI The new UI widget to set.
* @return True if the UI was successfully set, false otherwise.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
UMounteaBaseUserWidget* GetEquipmentUI() const;
virtual UMounteaBaseUserWidget* GetEquipmentUI_Implementation() const = 0;

/**
* Retrieves the class type of the user interface associated with this equipment.
* This function returns the class type of the UI widget used for displaying and interacting with the equipment.
*
* @return The class type of the equipment UI.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
TSubclassOf<UMounteaBaseUserWidget> GetEquipmentUIClass() const;
virtual TSubclassOf<UMounteaBaseUserWidget> GetEquipmentUIClass_Implementation() const = 0;

/**
* Sets the class type for the equipment's user interface.
* This function allows for dynamically changing the UI widget used for the equipment interface.
* It can be used to customize or upgrade the equipment UI according to game requirements.
* New class must implement `MounteaEquipmentWBPInterface`.
*
* @param NewWBPClass The new widget blueprint class to set as the equipment UI class.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
void SetEquipmentUIClass(UPARAM(meta=(MustImplement="/Script/MounteaInventoryEquipment.MounteaEquipmentWBPInterface")) TSubclassOf<UMounteaBaseUserWidget> NewWBPClass);
virtual void SetEquipmentUIClass_Implementation(UPARAM(meta=(MustImplement="/Script/MounteaInventoryEquipment.MounteaEquipmentWBPInterface")) TSubclassOf<UMounteaBaseUserWidget> NewWBPClass) = 0;

/**
* Retrieves the UI widget associated with the equipment interface.
* @return The UI widget of the equipment interface.
*/
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Equipment")
bool SetEquipmentUI(UMounteaBaseUserWidget* NewUI);
virtual bool SetEquipmentUI_Implementation(UMounteaBaseUserWidget* NewUI) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class MOUNTEAINVENTORYEQUIPMENT_API UMounteaEquipmentSlotBaseWidget : public UMo

UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|EquipmentSlot")
FORCEINLINE FText GetSlotID() const { return SlotID; };

UFUNCTION()
void UpdateSlotID(const FText& NewSlotID);

protected:

Expand Down

0 comments on commit d521de3

Please sign in to comment.