Closed VoidPollo closed 1 month ago
I've approved this merge request. Thanks for putting in the time to finalize the item pickables list! Got a bit lazy since I had to work on a ton of other stuff at the same time.
I'm trying to fix the low-hanging fruits just for polishing while your mind is set on the upcoming features.
I'm trying to fix the low-hanging fruits just for polishing while your mind is set on the upcoming features.
I appreciate all of the contributions!
I'm almost finished with the gather all from the map, without moving. Having a slight issue getting the FSessionActorId
, and possibly getting that through the QueryManager ActorToSessionId
method.
It'll be figured out... Feel free to dig yourself. I've provided my current code below for it:
Method
void TryGatherItems() {
PaliaOverlay* Overlay = static_cast<PaliaOverlay*>(OverlayBase::Instance);
auto World = GetWorld();
if (!World) return;
UGameplayStatics* GameplayStatics = static_cast<UGameplayStatics*>(UGameplayStatics::StaticClass()->DefaultObject);
if (!GameplayStatics) return;
auto GameInstance = World->OwningGameInstance;
if (!GameInstance) return;
if (GameInstance->LocalPlayers.Num() == 0) return;
ULocalPlayer* LocalPlayer = GameInstance->LocalPlayers[0];
if (!LocalPlayer) return;
APlayerController* PlayerController = LocalPlayer->PlayerController;
if (!PlayerController) return;
AValeriaPlayerController* ValeriaController = static_cast<AValeriaPlayerController*>(PlayerController);
if (!ValeriaController) return;
AValeriaCharacter* ValeriaCharacter = static_cast<AValeriaCharacter*>(PlayerController->K2_GetPawn());
if (!ValeriaCharacter) return;
UQueryManager* QueryManager = static_cast<UQueryManager*>(UQueryManager::StaticClass()->DefaultObject);
if (!QueryManager) return;
SDK::TArray<SDK::AActor*> actors;
GameplayStatics->GetAllActorsOfClass(World, SDK::ABP_ValeriaGatherable_C::StaticClass(), &actors);
int gathered = 0;
for (int i = 0; i < actors.Num(); ++i) {
auto* actor = reinterpret_cast<SDK::ABP_ValeriaGatherable_C*>(actors[i]);
auto* GatherComponent = actor->Gatherable;
auto* InteractorComponent = actor->Interactable;
if (GatherComponent->CanBeGatheredBy(ValeriaCharacter) &&
!GatherComponent->bEquipmentRequiredToGather &&
GatherComponent->EquipmentRequiredItemTags.Num() == 0 &&
GatherComponent->EquipmentRequiredItemGameplayTags.GameplayTags.GameplayTags.Num() == 0 &&
GatherComponent->EquipmentRequiredItemGameplayTags.GameplayTags.ParentTags.Num() == 0 &&
PaliaOverlay::IsFree(GatherComponent) &&
InteractorComponent->IsInteractable(ValeriaCharacter) &&
InteractorComponent->InteractableRequirementsMet(ValeriaCharacter)) {
FSessionActorId GatherableId;
ValeriaController->RpcServer_GatherActorOrPlaceables(GatherableId, nullptr, false);
++gathered;
}
}
}
// COULD BE DONE SOMEWHAT LIKE THIS ALSO
FSessionActorId* SessionId = QueryManager->ActorToSessionId.Find(actor);
if (SessionId) {
ValeriaController->RpcServer_GatherActorOrPlaceables(*SessionId, nullptr, false);
++gathered;
}
Button (Movement & Teleport - Under pickable list)
if (ImGui::Button("Gather Actors")) {
TryGatherItems();
}
The code above works, but throws the no permission notification in-game, so the only thing we need to figure out is getting each iterated Gatherable's FSessionActorId to pick them up.
Time to poke around
Time to poke around
Tbh I'm not even sure that's the right way. I'm sure it'll have something to do with the Interactor and Gatherable, but after I've continued to tweak it, it doesn't seem right.
I'd think we'd be able to trigger the PrimaryInteractPressed()
which would lead us closer to the objects that'll handle gathering. It used to be RpcServer_GatherActor(); but that seems to have changed. It was old either way.
Here's some old code that might help. It's interesting, nonetheless. (source)
SDK::TArray<SDK::AActor*> actors;
gameplayStatics->GetAllActorsOfClass(GetWorld(),
SDK::ABP_ValeriaGatherable_C::StaticClass(), &actors);
for (int i = 0; i < actors.Num(); ++i) {
auto* actor = reinterpret_cast<SDK::ABP_ValeriaGatherable_C*>(actors[i]);
auto* gComp = actor->Gatherable;
auto* iComp = actor->Interactable;
if (gComp->CanBeGatheredBy(character) &&
!gComp->bEquipmentRequiredToGather &&
gComp->EquipmentRequiredItemTags.Num() == 0 &&
gComp->EquipmentRequiredItemGameplayTags.GameplayTags.GameplayTags.Num() == 0 &&
gComp->EquipmentRequiredItemGameplayTags.GameplayTags.ParentTags.Num() == 0 &&
IsFree(gComp) &&
iComp->IsInteractable(character) &&
iComp->InteractableRequirementsMet(character)) {
controller->RpcServer_GatherActor(actor);
++gathered;
}
}
bool IsFree(SDK::UGatherableComponent* comp) {
auto isFree = [](SDK::EVitalType type) {
return type != SDK::EVitalType::Coins &&
type != SDK::EVitalType::CommunityPoints &&
type != SDK::EVitalType::Health &&
type != SDK::EVitalType::MedalFishing &&
type != SDK::EVitalType::PremiumCurrency;
};
return isFree(comp->VitalRequired) && isFree(comp->Vital2Required);
}
The live debugger works in this game too... why didn't I even try this before.. so much easier to search and look for things.
The live debugger works in this game too... why didn't I even try this before.. so much easier to search and look for things.
LMFAO good to know. I've been hooking VS into it and just breakpointing some functions that way. This will speed some things up.
Ummh? So my thinking was, instead of sending to the server RpcServer_Gather-- I teleport the actors to me instead to see If I could pick them up manually first, but a Wardrobe that I can interact with got put on my location instead of gatherables..
Ummh? So my thinking was, instead of sending to the server RpcServer_Gather-- I teleport the actors to me instead to see If I could pick them up manually first, but a Wardrobe that I can interact with got put on my location instead of gatherables..
That was my worry also. I figured based on the AHousingOwnershipActor* that it could be a housing RPC. There's also a chance my start of the Interactable code would work instead. Here's that.
void SimulateGatherInteractables(UInteractorComponent* Interactor, TArray<FEntry>& CachedActors) {
for (auto& Entry : CachedActors) {
if (Entry.shouldAdd && (Entry.ActorType == EType::Forage || Entry.ActorType == EType::Loot)) {
UInteractableComponent* Interactable = static_cast<UInteractableComponent*>(Entry.Actor->GetComponentByClass(UInteractableComponent::StaticClass()));
if (Interactable) {
Interactable->SetPreventHideByRequirementsCheck(true);
while (Interactable->InteractionBlockerCount > 0) {
Interactable->RemoveInteractionBlocker();
}
FVAL_InteractorLockParams LockParams;
LockParams.Interactable = Interactable;
LockParams.bEnforceFacing = false;
LockParams.bEnforcePosition = false;
if (Interactor->LockPlayerToInteractable(LockParams)) {
FInteractEventParams Params;
Interactor->InteractWithHighlighted(Params);
Interactor->UnlockPlayerFromInteractable(LockParams);
}
}
}
}
}
~ Pickable List now populates from enabled Forageable ESP options. ~ Added a slight Z increase to the pickable list entries. ~ Changed the only 2 instances of K2_TeleportTo to K2_SetActorLocation, as the rest of the project uses it. (Commented it out this time, hehe)