
// 인벤토리에서 아이템 클릭 시 ItemClick 함수 호출됨
// ItemClick 함수 바인딩 한 부분
mTileView->OnItemDoubleClicked().AddUObject(this, &UInventoryBase::ItemClick);
// CampFire Widget이 켜져있으면 인벤토리에서 해당 아이템 제거
// Craft 인벤토리에는 해당 아이템 추가
void UInventoryBase::ItemClick(UObject* Object)
{
APlayerController* Controller = GetOwningLocalPlayer()->GetPlayerController(GetWorld());
if (IsValid(Controller))
{
ALvPlayer* Character = Cast<ALvPlayer>(Controller->GetCharacter());
if (IsValid(Character))
{
UItemDataBase* pData = Cast<UItemDataBase>(Object);
if (IsValid(pData))
{
int ItemID = pData->GetItemID();
ALvPlayerController* LvPlayerController = Cast<ALvPlayerController>(Controller);
UCampFireBase* CampFireWidget = LvPlayerController->GetMainHUD()->GetCampFireWidget();
if (true == CampFireWidget->IsVisible())
{
Character->GetInventoryComponent()->ServerRemoveItem(ItemID);
Character->GetCraftComponent()->ServerAddItem(ItemID);
}
else
Character->GetInventoryComponent()->ServerUseItem(ItemID);
}
}
}
}
void UInventoryComponent::ServerRemoveItem_Implementation(int32 ItemID)
{
mItems.RemoveSingle(ItemID);
}
// 아이템 추가 시 제작 가능한 아이템이 있는지 체크
// AllMatch되는 아이템이 있으면 요리 시간 Timer 세팅
void UCraftComponent::ServerAddItem_Implementation(int32 ItemID)
{
mCraftItems.Add(ItemID);
mCraftedItemID = -1;
mProgressRatio = 0.f;
GetOwner()->GetWorldTimerManager().ClearTimer(AllMatchTimerHandle);
AllMatchTimerHandle.Invalidate();
mCraftItems.Sort();
UDataTable* Table = UInventory::GetInst(GetWorld())->GetCraftTable();
FString Str;
TArray<FCraftTable*> Rows;
Table->GetAllRows<FCraftTable>(Str, Rows);
for (FCraftTable* CraftTable : Rows)
{
if (mCraftItems.Num() != CraftTable->RequiredItemList.Num())
continue;
bool AllMatch = true;
for (int i = 0; i < CraftTable->RequiredItemList.Num(); i++)
{
if (mCraftItems[i] != CraftTable->RequiredItemList[i])
{
AllMatch = false;
}
}
if (true == AllMatch)
{
ServerSetAllMatchTimer(mCraftItems.Num(), FCString::Atoi(*(CraftTable->Name.ToString())));
}
}
}
void UCraftComponent::ServerSetAllMatchTimer(int32 IngredientCount, int32 ItemID)
{
mCookingTime = IngredientCount * 4.f;
GetOwner()->GetWorldTimerManager().SetTimer(AllMatchTimerHandle, FTimerDelegate::CreateUObject(this, &UCraftComponent::ServerOnAllMatchTimerExpired, ItemID), mCookingTime, false);
}
// 타이머가 종료되면 CraftedItem이 세팅되고 ProgressBar는 100%가 됨
void UCraftComponent::ServerOnAllMatchTimerExpired(int32 ItemID)
{
mCraftedItemID = ItemID;
mProgressRatio = 1.f;
GetOwner()->GetWorldTimerManager().ClearTimer(AllMatchTimerHandle);
AllMatchTimerHandle.Invalidate();
}
// CraftedItemID가 세팅되었으므로 OnRep_CraftID 함수 실행
void UCraftComponent::OnRep_CraftID()
{
OnCraftFinishedEvent.Broadcast(mCraftedItemID);
}
// 이벤트 구독 해 놓은 함수(OnCraftFinished) 실행
Component->OnCraftFinishedEvent.AddUObject(this, &UCampFireBase::OnCraftFinished);
// UI 표출
void UCampFireBase::OnCraftFinished(int32 ItemID)
{
mItemID = ItemID;
if (ItemID == -1)
{
GetResultImage()->SetBrushFromTexture(nullptr);
mCanGetCraftedItem = false;
}
else
{
mCanGetCraftedItem = true;
FItemTable* ItemTable = UInventory::GetInst(GetWorld())->GetInfoItem(ItemID);
UTexture2D* pTex2D = LoadObject<UTexture2D>(nullptr, *(ItemTable->TexturePath));
GetResultImage()->SetBrushFromTexture(pTex2D);
if(ItemTable->ItemType == EItemType::Food)
mEatImg->SetVisibility(ESlateVisibility::Visible);
}
}
// UI에 표출된 완성된 아이템을 클릭하면 OnClickedCraftItem 함수 호출
// 바인딩 한 부분
mResultBtn->OnClicked.AddDynamic(this, &UCampFireBase::OnClickedCraftItem);
// 아이템 획득 가능 상태면 인벤토리에 해당 아이템 추가
// 제작 인벤토리 ServerClear 함수 호출
void UCampFireBase::OnClickedCraftItem()
{
if (true == mCanGetCraftedItem)
{
mCanGetCraftedItem = false;
//FItemTable* Table = UInventory::GetInst(GetGameInstance())->GetInfoItem(mItemID);
//UItemDataBase* pNewData = NewObject<UItemDataBase>();
//pNewData->SetItemIconPath(Table->TexturePath);
//pNewData->SetItemID(ItemID);
APlayerController* Controller = GetOwningLocalPlayer()->GetPlayerController(GetWorld());
ALvPlayer* Character = Cast<ALvPlayer>(Controller->GetCharacter());
Character->GetInventoryComponent()->ServerAddItem(mItemID);
Character->GetCraftComponent()->ServerClear();
mEatImg->SetVisibility(ESlateVisibility::Collapsed);
}
}
// ServerClear
void UCraftComponent::ServerClear_Implementation()
{
mCraftItems.Empty();
mCraftedItemID = -1;
mProgressRatio = 0.f;
GetOwner()->GetWorldTimerManager().ClearTimer(AllMatchTimerHandle);
AllMatchTimerHandle.Invalidate();
}
// 구독한 부분
mCampFireTileView->OnItemClicked().AddUObject(this, &UCampFireBase::OnCancelCraftItem);
// 넣은 요리 재료를 클릭하면 제작 인벤토리에서 해당 아이템 제거
// 플레이어 인벤토리에 해당 아이템 추가
void UCampFireBase::OnCancelCraftItem(UObject* Object)
{
UItemDataBase* ItemInfo = Cast<UItemDataBase>(Object);
int32 ItemID = ItemInfo->GetItemID();
APlayerController* Controller = GetOwningLocalPlayer()->GetPlayerController(GetWorld());
ALvPlayer* PlayerCharacter = Cast<ALvPlayer>(Controller->GetCharacter());
if (IsValid(PlayerCharacter))
{
UCraftComponent* CraftComponent = Cast<UCraftComponent>(PlayerCharacter->GetCraftComponent());
if(IsValid(CraftComponent))
CraftComponent->ServerRemoveItem(ItemID);
UInventoryComponent* InventoryComponent = Cast<UInventoryComponent>(PlayerCharacter->GetInventoryComponent());
if (IsValid(InventoryComponent))
InventoryComponent->ServerAddItem(ItemID);
}
}
// 아이템 변화에 따른 UI 업데이트
void UCampFireBase::OnItemsChanged(TArray<int32> Items)
{
mCampFireTileView->ClearListItems();
for (int32 Item : Items)
{
FItemTable* Table = UInventory::GetInst(GetGameInstance())->GetInfoItem(Item);
UItemDataBase* pNewData = NewObject<UItemDataBase>();
pNewData->SetItemIconPath(Table->TexturePath);
pNewData->SetItemID(Item);
pNewData->SetItemType(Table->ItemType);
mCampFireTileView->AddItem(pNewData);
}
}
(Case 1) 요리 도중 움직였을 때
(Case 2) 완성된 요리를 가져가지 않은 채로 움직였을 때
void UMainHUDBase::NativeTick(const FGeometry& _geo, float _DeltaTime)
{
Super::NativeTick(_geo, _DeltaTime);
UCharacterMovementComponent* MovementComponent = Character->GetCharacterMovement();
bool isMoving = MovementComponent->Velocity.Size() > 0;
if (isMoving)
{
if (mCampFire->IsVisible())
{
TArray<int32> AllItems = Character->GetCraftComponent()->GetCraftItems();
for (int32 Item : AllItems)
{
Character->GetInventoryComponent()->ServerAddItem(Item);
}
Character->GetCraftComponent()->ServerClear();
mCampFire->SetVisibility(ESlateVisibility::Collapsed);
}
{
if (mSgtLakeVendor->IsVisible())
mSgtLakeVendor->SetVisibility(ESlateVisibility::Collapsed);
}
}
}
안녕하세요 롱빈터 모작 작업 진행하려고 하는데 혹시 캐릭터, 맵, 아이템 등 리소스들은 어떻게 구하셨는지 알려주실 수 있나요?