第一次提交
This commit is contained in:
@@ -0,0 +1,297 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "GIS_CoreStructLibray.h"
|
||||
#include "GIS_CurrencyEntry.h"
|
||||
#include "Items/GIS_ItemInfo.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "GIS_CraftingStructLibrary.generated.h"
|
||||
|
||||
/**
|
||||
* Struct for querying item ingredients required for crafting.
|
||||
* 用于查询合成所需道具材料的结构体。
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FGIS_ItemIngredient
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FGIS_ItemIngredient()
|
||||
: NeedAmounts(0)
|
||||
{
|
||||
}
|
||||
|
||||
FGIS_ItemIngredient(int32 InNeedAmounts, const TArray<FGIS_ItemInfo>& InHoldItemAmounts)
|
||||
: NeedAmounts(InNeedAmounts)
|
||||
, HoldItemAmounts(InHoldItemAmounts)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition of the item required for crafting.
|
||||
* 合成所需道具的定义。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
TSoftObjectPtr<UGIS_ItemDefinition> ItemDefinition;
|
||||
|
||||
/**
|
||||
* Required amount of the item for crafting.
|
||||
* 合成所需道具的数量。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
int32 NeedAmounts;
|
||||
|
||||
/**
|
||||
* List of held items and their amounts.
|
||||
* 持有道具及其数量的列表。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
TArray<FGIS_ItemInfo> HoldItemAmounts;
|
||||
|
||||
/**
|
||||
* Calculates the total amount of held items.
|
||||
* 计算持有道具的总量。
|
||||
* @return The total amount of held items. 持有道具的总量。
|
||||
*/
|
||||
FORCEINLINE int32 GetHoldAmount() const
|
||||
{
|
||||
int32 Count = 0;
|
||||
for (const auto& ItemInfo : HoldItemAmounts)
|
||||
{
|
||||
Count += ItemInfo.Amount;
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Struct for querying currency ingredients required for crafting.
|
||||
* 用于查询合成所需货币材料的结构体。
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FGIS_CurrencyIngredient
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FGIS_CurrencyIngredient()
|
||||
: NeedAmounts(0)
|
||||
{
|
||||
}
|
||||
|
||||
FGIS_CurrencyIngredient(TObjectPtr<const UGIS_CurrencyDefinition> InCurrencyDefinition, int32 InNeedAmounts, FGIS_CurrencyEntry InHoldAmounts)
|
||||
: CurrencyDefinition(InCurrencyDefinition)
|
||||
, NeedAmounts(InNeedAmounts)
|
||||
, HoldCurrencyInfo(InHoldAmounts)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition of the currency required for crafting.
|
||||
* 合成所需货币的定义。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
TObjectPtr<const UGIS_CurrencyDefinition> CurrencyDefinition;
|
||||
|
||||
/**
|
||||
* Required amount of the currency for crafting.
|
||||
* 合成所需货币的数量。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
int32 NeedAmounts;
|
||||
|
||||
/**
|
||||
* Information about the held currency.
|
||||
* 持有货币的信息。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FGIS_CurrencyEntry HoldCurrencyInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Struct defining the cost data for crafting or enhancing items.
|
||||
* 定义合成或强化道具的消耗数据的结构体。
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FGIS_CraftItemCostData
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FGIS_CraftItemCostData() : bCostItem(false), bCostCurrency(true), bCostTime(false), Days(1)
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if items are consumed during crafting.
|
||||
* 确定合成时是否消耗道具。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Crafting")
|
||||
bool bCostItem;
|
||||
|
||||
/**
|
||||
* List of items consumed during crafting.
|
||||
* 合成时消耗的道具列表。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(EditCondition="bCostItem"), Category="Crafting", meta=(TitleProperty="Definition"))
|
||||
TArray<FGIS_ItemDefinitionAmount> CostItems;
|
||||
|
||||
/**
|
||||
* Determines if currencies are consumed during crafting.
|
||||
* 确定合成时是否消耗货币。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Crafting")
|
||||
bool bCostCurrency;
|
||||
|
||||
/**
|
||||
* List of currencies consumed during crafting.
|
||||
* 合成时消耗的货币列表。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(EditCondition="bCostCurrency"), Category="Crafting")
|
||||
TArray<FGIS_CurrencyEntry> CostCurrencies;
|
||||
|
||||
/**
|
||||
* Determines if time is consumed during crafting.
|
||||
* 确定合成时是否消耗时间。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Crafting")
|
||||
bool bCostTime;
|
||||
|
||||
/**
|
||||
* Time consumed for crafting, in days.
|
||||
* 合成消耗的时间(以天为单位)。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(EditCondition="bCostTime"), Category="Crafting")
|
||||
float Days;
|
||||
};
|
||||
|
||||
/**
|
||||
* Data table struct for item crafting recipes.
|
||||
* 道具合成配方的数据表结构体。
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FGIS_CraftingItemData : public FTableRowBase
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
/**
|
||||
* Gameplay tag defining the crafting item.
|
||||
* 定义合成道具的游戏标签。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FGameplayTag CraftingItemDefinition;
|
||||
|
||||
/**
|
||||
* Definition of the crafting item.
|
||||
* 合成道具的定义。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
TSoftObjectPtr<const UGIS_ItemDefinition> CraftingDefinition;
|
||||
|
||||
/**
|
||||
* Type of crafting operation.
|
||||
* 合成操作的类型。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FGameplayTag CraftingItemType;
|
||||
|
||||
/**
|
||||
* Cost data for the crafting operation.
|
||||
* 合成操作的消耗数据。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FGIS_CraftItemCostData CraftItemCost;
|
||||
|
||||
/**
|
||||
* Definition of the output item produced by crafting.
|
||||
* 合成产出的道具定义。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="GIS")
|
||||
TSoftObjectPtr<const UGIS_ItemDefinition> OutputItemDefinition;
|
||||
};
|
||||
|
||||
/**
|
||||
* Data table struct for item enhancement data.
|
||||
* 道具强化数据的数据表结构体。
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct FGIS_ItemEnhancedData : public FTableRowBase
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
FGIS_ItemEnhancedData() : EnhancedLevel(1), bDestroy(false), Downgrading(false)
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* Set of item types that can use this enhancement data.
|
||||
* 可以使用此强化数据的道具类型集合。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FGameplayTagContainer ItemTypeSet;
|
||||
|
||||
/**
|
||||
* Tag query for items eligible for this enhancement.
|
||||
* 适用于此强化的道具标签查询。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FGameplayTagQuery ItemTagQuery;
|
||||
|
||||
/**
|
||||
* Level of enhancement applied to the item.
|
||||
* 应用于道具的强化等级。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
int32 EnhancedLevel;
|
||||
|
||||
/**
|
||||
* Prefix added to the item name after enhancement.
|
||||
* 强化后添加到道具名称的前缀。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FName EnhancedNamePrefix;
|
||||
|
||||
/**
|
||||
* Cost data for the enhancement operation.
|
||||
* 强化操作的消耗数据。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GIS")
|
||||
FGIS_CraftItemCostData EnhancedItemCost;
|
||||
|
||||
/**
|
||||
* Constant attribute bonuses applied by the enhancement.
|
||||
* 强化应用的常量属性加成。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="GIS")
|
||||
TMap<FGameplayTag, float> AdditionAttributes;
|
||||
|
||||
/**
|
||||
* Multiplier attribute bonuses applied by the enhancement.
|
||||
* 强化应用的系数属性加成。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="GIS")
|
||||
TMap<FGameplayTag, float> MultiplierAttributes;
|
||||
|
||||
/**
|
||||
* Success rate of the enhancement operation.
|
||||
* 强化操作的成功率。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="GIS", meta=(ClampMin = 0.f, ClampMax = 1.f))
|
||||
float SuccessRate = 1.f;
|
||||
|
||||
/**
|
||||
* Determines if the item is destroyed on enhancement failure (deprecated).
|
||||
* 确定强化失败时道具是否销毁(已弃用)。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="GIS", meta=(DeprecatedProperty))
|
||||
bool bDestroy;
|
||||
|
||||
/**
|
||||
* Level reduction on enhancement failure (deprecated).
|
||||
* 强化失败时的等级降低(已弃用)。
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="GIS", meta=(EditCondition="!bDestroy", DeprecatedProperty))
|
||||
int32 Downgrading;
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GIS_CraftingStructLibrary.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "GIS_CraftingSystemComponent.generated.h"
|
||||
|
||||
class UGIS_ItemFragment_CraftingRecipe;
|
||||
class UGIS_CurrencySystemComponent;
|
||||
class UGIS_CraftingRecipe;
|
||||
|
||||
/**
|
||||
* Actor component for handling crafting functionality in the inventory system.
|
||||
* 用于在库存系统中处理制作功能的演员组件。
|
||||
*/
|
||||
UCLASS(ClassGroup=(GIS), meta=(BlueprintSpawnableComponent))
|
||||
class GENERICINVENTORYSYSTEM_API UGIS_CraftingSystemComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor for the crafting system component.
|
||||
* 制作系统组件的构造函数。
|
||||
*/
|
||||
UGIS_CraftingSystemComponent();
|
||||
|
||||
/**
|
||||
* Attempts to craft items using a recipe.
|
||||
* 尝试使用配方制作道具。
|
||||
* @param Recipe The item definition containing recipe data. 包含配方数据的道具定义。
|
||||
* @param Inventory The inventory that pays the crafting cost. 用于支付制作成本的库存。
|
||||
* @param Quantity The multiplier for crafting output. 制作输出的倍率。
|
||||
* @return True if crafting succeeds, false otherwise. 如果制作成功返回true,否则返回false。
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="GIS|CraftingSystem")
|
||||
bool Craft(const UGIS_ItemDefinition* Recipe, UGIS_InventorySystemComponent* Inventory, int32 Quantity = 1);
|
||||
|
||||
/**
|
||||
* Checks if the parameters are valid for crafting an item.
|
||||
* 检查参数是否满足制作道具的条件。
|
||||
* @param RecipeDefinition The item definition with recipe data. 包含配方数据的道具定义。
|
||||
* @param Inventory The inventory containing the items. 包含道具的库存。
|
||||
* @param Quantity The amount to craft. 要制作的数量。
|
||||
* @return True if crafting is possible, false otherwise. 如果可以制作则返回true,否则返回false。
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category="GIS|CraftingSystem")
|
||||
bool CanCraft(const UGIS_ItemDefinition* RecipeDefinition, UGIS_InventorySystemComponent* Inventory, int32 Quantity = 1);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Internal function to check if crafting is possible.
|
||||
* 内部函数,检查是否可以制作。
|
||||
* @param RecipeDefinition The item definition with recipe data. 包含配方数据的道具定义。
|
||||
* @param Inventory The inventory containing the items. 包含道具的库存。
|
||||
* @param Quantity The amount to craft. 要制作的数量。
|
||||
* @return True if crafting is possible, false otherwise. 如果可以制作则返回true,否则返回false。
|
||||
*/
|
||||
virtual bool CanCraftInternal(const UGIS_ItemDefinition* RecipeDefinition, UGIS_InventorySystemComponent* Inventory, int32 Quantity = 1);
|
||||
|
||||
/**
|
||||
* Internal function to perform crafting.
|
||||
* 内部函数,执行制作。
|
||||
* @param RecipeDefinition The item definition with recipe data. 包含配方数据的道具定义。
|
||||
* @param Inventory The inventory that pays the crafting cost. 用于支付制作成本的库存。
|
||||
* @param Quantity The multiplier for crafting output. 制作输出的倍率。
|
||||
* @return True if crafting succeeds, false otherwise. 如果制作成功返回true,否则返回false。
|
||||
*/
|
||||
virtual bool CraftInternal(const UGIS_ItemDefinition* RecipeDefinition, UGIS_InventorySystemComponent* Inventory, int32 Quantity = 1);
|
||||
|
||||
/**
|
||||
* Produces crafting output for the inventory, adding output items by default.
|
||||
* 为库存生成制作输出,默认将输出道具添加到库存。
|
||||
* @details Override to implement custom logic, such as a crafting queue.
|
||||
* @细节 可覆写以实现自定义逻辑,例如制作队列(延迟获得结果)。
|
||||
* @param RecipeDefinition The item definition with recipe data. 包含配方数据的道具定义。
|
||||
* @param Inventory The inventory to receive the output. 接收输出的库存。
|
||||
* @param Quantity The multiplier for crafting output. 制作输出的倍率。
|
||||
*/
|
||||
virtual void ProduceCraftingOutput(const UGIS_ItemDefinition* RecipeDefinition, UGIS_InventorySystemComponent* Inventory, int32 Quantity = 1);
|
||||
|
||||
/**
|
||||
* Checks if the recipe definition is valid (contains valid crafting data).
|
||||
* 检查配方定义是否有效(包含有效的制作数据)。
|
||||
* @details Override to apply custom validation rules, such as checking for specific fragments.
|
||||
* @细节 可覆写以应用自定义验证规则,例如检查特定道具片段是否存在。
|
||||
* @param RecipeDefinition The item definition to validate. 要验证的道具定义。
|
||||
* @return True if the recipe is valid, false otherwise. 如果配方有效则返回true,否则返回false。
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category="GIS|CraftingSystem")
|
||||
bool IsValidRecipe(const UGIS_ItemDefinition* RecipeDefinition) const;
|
||||
|
||||
/**
|
||||
* Gets the recipe fragment for the default crafting implementation.
|
||||
* 获取默认制作实现所需的配方片段。
|
||||
* @param RecipeDefinition The item definition to retrieve data from. 要从中获取数据的道具定义。
|
||||
* @return The crafting recipe fragment, or nullptr if not found. 制作配方片段,如果未找到则返回nullptr。
|
||||
*/
|
||||
const UGIS_ItemFragment_CraftingRecipe* GetRecipeFragment(const UGIS_ItemDefinition* RecipeDefinition) const;
|
||||
|
||||
/**
|
||||
* Selects the maximum number of item infos for required item ingredients from the inventory.
|
||||
* 从库存中选择满足道具成分需求的最大道具信息。
|
||||
* @param Inventory The inventory to select items from. 要从中选择道具的库存。
|
||||
* @param ItemIngredients The required item ingredients. 所需的道具成分。
|
||||
* @param Quantity The amount to craft. 要制作的数量。
|
||||
* @return True if sufficient items are selected, false otherwise. 如果选择了足够的道具则返回true,否则返回false。
|
||||
*/
|
||||
virtual bool SelectItemForIngredients(const UGIS_InventorySystemComponent* Inventory, const TArray<FGIS_ItemDefinitionAmount>& ItemIngredients, int32 Quantity);
|
||||
|
||||
/**
|
||||
* Checks if selected items are sufficient for the required item ingredients.
|
||||
* 检查已选道具是否足以满足道具成分需求。
|
||||
* @param ItemIngredients The required item ingredients. 所需的道具成分。
|
||||
* @param Quantity The amount to craft. 要制作的数量。
|
||||
* @param SelectedItems The selected items from the inventory. 从库存中选择的道具。
|
||||
* @param ItemsToIgnore Items to ignore during checking. 检查时要忽略的道具。
|
||||
* @param NumOfItemsToIgnore Number of items to ignore (output). 要忽略的道具数量(输出)。
|
||||
* @return True if the selected items are sufficient, false otherwise. 如果选择的道具足够则返回true,否则返回false。
|
||||
*/
|
||||
virtual bool CheckIfEnoughItemIngredients(const TArray<FGIS_ItemDefinitionAmount>& ItemIngredients,
|
||||
int32 Quantity, const TArray<FGIS_ItemInfo>& SelectedItems, TArray<FGIS_ItemInfo>& ItemsToIgnore, int32& NumOfItemsToIgnore);
|
||||
|
||||
/**
|
||||
* Removes item ingredients from the inventory's default collection one by one.
|
||||
* 从库存的默认集合中逐一移除道具成分。
|
||||
* @param Inventory The inventory to remove items from. 要从中移除道具的库存。
|
||||
* @param ItemIngredients The item ingredients to remove. 要移除的道具成分。
|
||||
* @return True if all items were successfully removed, false otherwise. 如果所有道具移除成功则返回true,否则返回false。
|
||||
*/
|
||||
virtual bool RemoveItemIngredients(UGIS_InventorySystemComponent* Inventory, const TArray<FGIS_ItemInfo>& ItemIngredients);
|
||||
|
||||
/**
|
||||
* Cache for selected items during crafting.
|
||||
* 制作过程中选择的道具缓存。
|
||||
*/
|
||||
TArray<FGIS_ItemInfo> SelectedItemsCache;
|
||||
|
||||
/**
|
||||
* Number of selected items in the cache.
|
||||
* 缓存中选择的道具数量。
|
||||
*/
|
||||
int32 NumOfSelectedItemsCache;
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GIS_CoreStructLibray.h"
|
||||
#include "GIS_CurrencyEntry.h"
|
||||
#include "GIS_ItemFragment.h"
|
||||
#include "GIS_ItemFragment_CraftingRecipe.generated.h"
|
||||
|
||||
/**
|
||||
* Item fragment defining a crafting recipe for producing items.
|
||||
* 定义用于生产道具的合成配方的道具片段。
|
||||
* @details Specifies input items, currencies, and output items for crafting.
|
||||
* @细节 指定用于合成的输入道具、货币和输出道具。
|
||||
*/
|
||||
UCLASS(DisplayName="Crafting Recipe Settings", Category="BuiltIn")
|
||||
class GENERICINVENTORYSYSTEM_API UGIS_ItemFragment_CraftingRecipe : public UGIS_ItemFragment
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* List of required items and their quantities for crafting.
|
||||
* 合成所需的道具及其数量列表。
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Crafting", meta=(TitleProperty="{Definition}->{Amount}"))
|
||||
TArray<FGIS_ItemDefinitionAmount> InputItems;
|
||||
|
||||
/**
|
||||
* List of required currencies and their amounts for crafting.
|
||||
* 合成所需的货币及其数量列表。
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Ingredients", meta=(TitleProperty="{Tag}->{Amount}"))
|
||||
TArray<FGIS_CurrencyEntry> InputCurrencies;
|
||||
|
||||
/**
|
||||
* List of items produced by the crafting recipe.
|
||||
* 合成配方产出的道具列表。
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Crafting", meta=(TitleProperty="EditorFriendlyName"))
|
||||
TArray<FGIS_ItemDefinitionAmount> OutputItems;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual void PreSave(FObjectPreSaveContext SaveContext) override;
|
||||
#endif
|
||||
};
|
||||
Reference in New Issue
Block a user