Files
integration/Source/Integration/TangibleManager.cpp

153 lines
3.9 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "TangibleManager.h"
#include "Tangible.h"
#include "DebugPrint.h"
#include "IntegrationGameModeBase.h"
using namespace DebugPrint;
using TanArray = UlxTangibleManager::TanArray;
using IdArray = UlxTangibleManager::IdArray;
UFunction *UlxTangibleManager::GetAnimationQueueChanged(UClass *uclass) {
UFunction *result = uclass->FindFunctionByName(FName(TEXT("Animation Queue Changed")));
if (result == nullptr) return nullptr;
if (result->ParmsSize != 0) return nullptr;
return result;
}
UClass *UlxTangibleManager::GetTangibleClass(const FString &name) {
if (name.IsEmpty()) {
return nullptr;
}
if (name == TEXT("unknown")) {
return nullptr;
}
FString path(TEXT("/Game/Tangibles/"));
path += name;
path += TCHAR('.');
path += name;
path += TCHAR('_');
path += TCHAR('C');
UClass *result = LoadObject<UClass>(nullptr, *path);
if (result == nullptr) {
UE_LOG(LogBlueprint, Error, TEXT("No such UClass: %s"), *path);
return nullptr;
}
if (!result->IsChildOf(AActor::StaticClass())) {
UE_LOG(LogBlueprint, Error, TEXT("UClass is not an actor: %s"), *path);
return nullptr;
}
UFunction *aqchanged = GetAnimationQueueChanged(result);
if (aqchanged == nullptr) {
UE_LOG(LogBlueprint, Error, TEXT("UClass does not have 'Animation Queue Changed' function: %s"), *path);
return nullptr;
}
return result;
}
UlxTangibleManager::UlxTangibleManager() {
World = nullptr;
PossessedTangible = nullptr;
}
void UlxTangibleManager::Init(UWorld* world, AIntegrationGameModeBase *gamemode) {
World = world;
GameMode = gamemode;
}
UlxTangible* UlxTangibleManager::GetTangible(int64 id) const {
UlxTangible*const* p = IdToTangible.Find(id);
if (p == nullptr) {
return nullptr;
} else {
return *p;
}
}
#pragma optimize("", off)
UlxTangible* UlxTangibleManager::MakeTangible(int64 id) {
check(id > 0);
UlxTangible*& t = IdToTangible.FindOrAdd(id);
if (t == nullptr) {
t = NewObject<UlxTangible>();
t->Init(this, id);
}
return t;
}
void UlxTangibleManager::DeleteTangible(int64 id) {
// IMPLEMENT ME
}
TanArray UlxTangibleManager::GetAllTangibles() const {
TanArray result;
result.SetNum(IdToTangible.Num());
int next = 0;
for (auto& pair : IdToTangible) {
result[next++] = pair.Value;
}
return result;
}
#pragma optimize("", off)
void UlxTangibleManager::UpdateNearAccordingToLuprex(IdView near) {
// Clear all the 'NearAccordingToLuprex' flags.
for (const auto& pair : IdToTangible) {
pair.Value->NearAccordingToLuprex = false;
}
// For every ID on the list, create it if it doesn't exist,
// mark it, and return it.
for (int64 id : near) {
UlxTangible* tan = MakeTangible(id);
tan->NearAccordingToLuprex = true;
}
}
#pragma optimize("", off)
void UlxTangibleManager::RecalcNearAccordingToUnreal(int64 player, double radius) {
UlxTangible *p = GetTangible(player);
check (p != nullptr);
FVector playerpos = p->CurrentActor->GetActorLocation();
FName playerplane = p->Plane;
double radiussq = radius * radius;
for (const auto& pair : IdToTangible) {
UlxTangible *tan = pair.Value;
if (tan->Plane != playerplane) {
tan->NearAccordingToUnreal = false;
} else {
FVector pos = tan->GetLocation();
double distsq = FVector::DistSquared(pos, playerpos);
tan->NearAccordingToUnreal = (distsq <= radiussq);
}
}
}
void UlxTangibleManager::DeleteFarawayTangibles() {
// Make a list of tangibles that need to be deleted.
TanArray faraway;
for (const auto& pair : IdToTangible) {
UlxTangible *tan = pair.Value;
if (!(tan->NearAccordingToLuprex || tan->NearAccordingToUnreal)) {
faraway.Add(tan);
}
}
for (UlxTangible *tan : faraway) {
IdToTangible.Remove(tan->TangibleId);
tan->Destroy(); // Remove the actor from the scene.
}
}
IdArray UlxTangibleManager::GetIds(const TanArray &arr) {
IdArray result;
result.SetNum(arr.Num());
for (int i = 0; i < arr.Num(); i++) {
result[i] = arr[i]->TangibleId;
}
return result;
}