添加库存系统组件
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
// Copyright 2026 PHY. All Rights Reserved.
|
||||
|
||||
#include "GameplayTags/PHYInventoryItemTags.h"
|
||||
|
||||
namespace PHYInventoryItemTags
|
||||
{
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_Type_Weapon, "GIS.Item.Type.Weapon", "Weapon item category");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_Type_Equipment, "GIS.Item.Type.Equipment", "Equipment item category");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_Type_Consumable, "GIS.Item.Type.Consumable", "Consumable item category");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_Type_Material, "GIS.Item.Type.Material", "Material item category");
|
||||
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_EquipSlot_MainHand, "GIS.Item.EquipSlot.MainHand", "Main hand slot");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_EquipSlot_OffHand, "GIS.Item.EquipSlot.OffHand", "Off hand slot");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_EquipSlot_Head, "GIS.Item.EquipSlot.Head", "Head slot");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_EquipSlot_Chest, "GIS.Item.EquipSlot.Chest", "Chest slot");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_EquipSlot_Legs, "GIS.Item.EquipSlot.Legs", "Legs slot");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_EquipSlot_Feet, "GIS.Item.EquipSlot.Feet", "Feet slot");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Item_EquipSlot_Accessory, "GIS.Item.EquipSlot.Accessory", "Accessory slot");
|
||||
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_Attack, "GIS.Attribute.Item.Attack", "Item Attack bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_Defense, "GIS.Attribute.Item.Defense", "Item Defense bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_CritRate, "GIS.Attribute.Item.CritRate", "Item CritRate bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_CritDamage, "GIS.Attribute.Item.CritDamage", "Item CritDamage bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_Hit, "GIS.Attribute.Item.Hit", "Item Hit bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_Dodge, "GIS.Attribute.Item.Dodge", "Item Dodge bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_Parry, "GIS.Attribute.Item.Parry", "Item Parry bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_ArmorPenetration, "GIS.Attribute.Item.ArmorPenetration", "Item ArmorPenetration bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_DamageReduction, "GIS.Attribute.Item.DamageReduction", "Item DamageReduction bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_LifeSteal, "GIS.Attribute.Item.LifeSteal", "Item LifeSteal bonus");
|
||||
UE_DEFINE_GAMEPLAY_TAG_COMMENT(Tag__GIS_Attribute_Item_Resilience, "GIS.Attribute.Item.Resilience", "Item Resilience bonus");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2026 PHY. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "NativeGameplayTags.h"
|
||||
|
||||
namespace PHYInventoryItemTags
|
||||
{
|
||||
// Item category tags
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_Type_Weapon);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_Type_Equipment);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_Type_Consumable);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_Type_Material);
|
||||
|
||||
// Equipment slot tags
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_EquipSlot_MainHand);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_EquipSlot_OffHand);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_EquipSlot_Head);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_EquipSlot_Chest);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_EquipSlot_Legs);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_EquipSlot_Feet);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Item_EquipSlot_Accessory);
|
||||
|
||||
// Common item attributes used by this project
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_Attack);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_Defense);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_CritRate);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_CritDamage);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_Hit);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_Dodge);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_Parry);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_ArmorPenetration);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_DamageReduction);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_LifeSteal);
|
||||
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag__GIS_Attribute_Item_Resilience);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2026 PHY. All Rights Reserved.
|
||||
|
||||
#include "Items/PHYItemBlueprintLibrary.h"
|
||||
|
||||
#include "GIS_ItemInstance.h"
|
||||
|
||||
const UPHYItemFragment_PropertySet* UPHYItemBlueprintLibrary::FindPropertyFragment(const UGIS_ItemInstance* ItemInstance)
|
||||
{
|
||||
if (!IsValid(ItemInstance))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ItemInstance->FindFragmentByClass<UPHYItemFragment_PropertySet>();
|
||||
}
|
||||
|
||||
EPHYItemArchetype UPHYItemBlueprintLibrary::GetItemArchetype(const UGIS_ItemInstance* ItemInstance)
|
||||
{
|
||||
if (const UPHYItemFragment_PropertySet* Fragment = FindPropertyFragment(ItemInstance))
|
||||
{
|
||||
return Fragment->ItemArchetype;
|
||||
}
|
||||
|
||||
return EPHYItemArchetype::Material;
|
||||
}
|
||||
|
||||
EPHYEquipSlotType UPHYItemBlueprintLibrary::GetEquipSlotType(const UGIS_ItemInstance* ItemInstance)
|
||||
{
|
||||
if (const UPHYItemFragment_PropertySet* Fragment = FindPropertyFragment(ItemInstance))
|
||||
{
|
||||
return Fragment->EquipSlot;
|
||||
}
|
||||
|
||||
return EPHYEquipSlotType::None;
|
||||
}
|
||||
|
||||
bool UPHYItemBlueprintLibrary::IsWeaponItem(const UGIS_ItemInstance* ItemInstance)
|
||||
{
|
||||
return GetItemArchetype(ItemInstance) == EPHYItemArchetype::Weapon;
|
||||
}
|
||||
|
||||
bool UPHYItemBlueprintLibrary::IsEquipmentItem(const UGIS_ItemInstance* ItemInstance)
|
||||
{
|
||||
const EPHYItemArchetype Archetype = GetItemArchetype(ItemInstance);
|
||||
return Archetype == EPHYItemArchetype::Weapon || Archetype == EPHYItemArchetype::Equipment;
|
||||
}
|
||||
|
||||
bool UPHYItemBlueprintLibrary::IsConsumableItem(const UGIS_ItemInstance* ItemInstance)
|
||||
{
|
||||
return GetItemArchetype(ItemInstance) == EPHYItemArchetype::Consumable;
|
||||
}
|
||||
|
||||
FPHYConsumablePayload UPHYItemBlueprintLibrary::GetConsumablePayload(const UGIS_ItemInstance* ItemInstance)
|
||||
{
|
||||
if (const UPHYItemFragment_PropertySet* Fragment = FindPropertyFragment(ItemInstance))
|
||||
{
|
||||
return Fragment->ConsumablePayload;
|
||||
}
|
||||
|
||||
return FPHYConsumablePayload();
|
||||
}
|
||||
|
||||
39
Source/PHYInventory/Private/Items/PHYItemBlueprintLibrary.h
Normal file
39
Source/PHYInventory/Private/Items/PHYItemBlueprintLibrary.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2026 PHY. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "Items/PHYItemFragment_PropertySet.h"
|
||||
#include "PHYItemBlueprintLibrary.generated.h"
|
||||
|
||||
class UGIS_ItemInstance;
|
||||
|
||||
UCLASS()
|
||||
class UPHYItemBlueprintLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
static EPHYItemArchetype GetItemArchetype(const UGIS_ItemInstance* ItemInstance);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
static EPHYEquipSlotType GetEquipSlotType(const UGIS_ItemInstance* ItemInstance);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
static bool IsWeaponItem(const UGIS_ItemInstance* ItemInstance);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
static bool IsEquipmentItem(const UGIS_ItemInstance* ItemInstance);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
static bool IsConsumableItem(const UGIS_ItemInstance* ItemInstance);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
static FPHYConsumablePayload GetConsumablePayload(const UGIS_ItemInstance* ItemInstance);
|
||||
|
||||
private:
|
||||
static const UPHYItemFragment_PropertySet* FindPropertyFragment(const UGIS_ItemInstance* ItemInstance);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2026 PHY. All Rights Reserved.
|
||||
|
||||
#include "Items/PHYItemFragment_PropertySet.h"
|
||||
|
||||
#include "GIS_ItemInstance.h"
|
||||
|
||||
void UPHYItemFragment_PropertySet::OnInstanceCreated(UGIS_ItemInstance* ItemInstance) const
|
||||
{
|
||||
if (!IsValid(ItemInstance))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (const FGIS_GameplayTagFloat& Modifier : BaseFloatModifiers)
|
||||
{
|
||||
if (Modifier.Tag.IsValid())
|
||||
{
|
||||
ItemInstance->SetFloatAttribute(Modifier.Tag, Modifier.Value);
|
||||
}
|
||||
}
|
||||
|
||||
for (const FGIS_GameplayTagInteger& Modifier : BaseIntegerModifiers)
|
||||
{
|
||||
if (Modifier.Tag.IsValid())
|
||||
{
|
||||
ItemInstance->SetIntegerAttribute(Modifier.Tag, Modifier.Value);
|
||||
}
|
||||
}
|
||||
|
||||
Super::OnInstanceCreated(ItemInstance);
|
||||
}
|
||||
|
||||
bool UPHYItemFragment_PropertySet::IsEquippable() const
|
||||
{
|
||||
return ItemArchetype == EPHYItemArchetype::Weapon || ItemArchetype == EPHYItemArchetype::Equipment;
|
||||
}
|
||||
|
||||
bool UPHYItemFragment_PropertySet::IsConsumable() const
|
||||
{
|
||||
return ItemArchetype == EPHYItemArchetype::Consumable;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
// Copyright 2026 PHY. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GIS_GameplayTagFloat.h"
|
||||
#include "GIS_GameplayTagInteger.h"
|
||||
#include "GIS_ItemFragment.h"
|
||||
#include "PHYItemFragment_PropertySet.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EPHYItemArchetype : uint8
|
||||
{
|
||||
Weapon,
|
||||
Equipment,
|
||||
Consumable,
|
||||
Material,
|
||||
Quest
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EPHYEquipSlotType : uint8
|
||||
{
|
||||
None,
|
||||
MainHand,
|
||||
OffHand,
|
||||
Head,
|
||||
Chest,
|
||||
Legs,
|
||||
Feet,
|
||||
Accessory
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FPHYConsumablePayload
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Consumable")
|
||||
float RestoreHealth = 0.0f;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Consumable")
|
||||
float RestoreInnerPower = 0.0f;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Consumable")
|
||||
float DurationSeconds = 0.0f;
|
||||
};
|
||||
|
||||
/**
|
||||
* 统一道具属性片段:
|
||||
* - 定义道具大类(武器/装备/药品...)
|
||||
* - 定义装备槽位
|
||||
* - 定义创建实例时写入的动态属性(可用于随机词条前的基础值)
|
||||
* - 定义药品基础效果载荷
|
||||
*/
|
||||
UCLASS(DisplayName="PHY Item Property Settings", Category="PHY")
|
||||
class UPHYItemFragment_PropertySet : public UGIS_ItemFragment
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Item")
|
||||
EPHYItemArchetype ItemArchetype = EPHYItemArchetype::Material;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Item")
|
||||
EPHYEquipSlotType EquipSlot = EPHYEquipSlotType::None;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Item", meta=(Categories="GIS.Item"))
|
||||
FGameplayTagContainer ExtraItemTags;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Attributes", meta=(TitleProperty="{Tag} -> {Value}", Categories="GIS.Attribute"))
|
||||
TArray<FGIS_GameplayTagFloat> BaseFloatModifiers;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Attributes", meta=(TitleProperty="{Tag} -> {Value}", Categories="GIS.Attribute"))
|
||||
TArray<FGIS_GameplayTagInteger> BaseIntegerModifiers;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Consumable")
|
||||
FPHYConsumablePayload ConsumablePayload;
|
||||
|
||||
virtual void OnInstanceCreated(UGIS_ItemInstance* ItemInstance) const override;
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
bool IsEquippable() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="PHY|Item")
|
||||
bool IsConsumable() const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user