241 lines
6.9 KiB
C++
241 lines
6.9 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "cppGI.h"
|
|
#include "Kismet/GameplayStatics.h"
|
|
#include "Misc/paths.h"
|
|
#include "Engine/levelstreamingdynamic.h"
|
|
#include "cppFuncLibrary.h"
|
|
|
|
/*for working tarray::Contains*/
|
|
|
|
bool operator==(const Fcppcoords& c1, const Fcppcoords& c2) {
|
|
return c1.flat == c2.flat &&
|
|
c1.floor == c2.floor &&
|
|
c1.house == c2.house &&
|
|
c1.section == c2.section &&
|
|
c1.type == c2.type &&
|
|
c1.zone == c2.zone;
|
|
}
|
|
/*for working tarray::Contains*/
|
|
bool operator==(const FcppLevelStruct& c1, const FcppLevelStruct& c2) {
|
|
return c1.anotherLvl == c2.anotherLvl &&
|
|
c1.coords == c2.coords &&
|
|
c1.dontUnload == c2.dontUnload &&
|
|
c1.path == c2.path &&
|
|
c1.uniqName == c2.uniqName &&
|
|
c1.Z == c2.Z;
|
|
}
|
|
|
|
TArray<ULevelStreaming*> UcppGI::cppLvlManage(UObject* WorldContextObject, Fcppcoords currentCoords, uint8 currentState)
|
|
{
|
|
TArray<ULevelStreaming*> outStruct;
|
|
bool loadthis;
|
|
auto is3DTour = currentState == 11;
|
|
/*for 3Dtour only*/
|
|
if (is3DTour) {
|
|
auto temp = Fcppcoords();
|
|
temp.house = -2;
|
|
temp.section = -2;
|
|
temp.floor = 1;
|
|
cppLoadList.AddUnique(temp);
|
|
}
|
|
|
|
cppLoadList.AddUnique(currentCoords);
|
|
|
|
for (const auto& lvl : cppLevels)
|
|
{
|
|
loadthis = 0;
|
|
|
|
if (cppBlackList.Contains(lvl));
|
|
else if (cppWhiteList.Contains(lvl)) loadthis = true;
|
|
else {
|
|
bool ceq[7];
|
|
for (const auto& crd : cppLoadList) // here is filter code
|
|
{
|
|
cppCoordsEq(crd, lvl.coords, true, false, ceq[0], ceq[1], ceq[2], ceq[3], ceq[4], ceq[5], ceq[6]);
|
|
if (
|
|
(
|
|
(
|
|
(ceq[0] || !is3DTour || lvl.coords.flat == -1) && ceq[5]
|
|
)
|
|
|| (is3DTour ? lvl.anotherLvl >= 1 && lvl.anotherLvl == crd.flat : lvl.anotherLvl >= 1 && lvl.anotherLvl == crd.flat && lvl.coords.floor < crd.floor)
|
|
)
|
|
&& ceq[3] && ceq[4] && ceq[2]
|
|
) loadthis = true; //load all on floor and under 2-floor flat, and full 2-floor flat in 3d tour
|
|
|
|
//if (ceq[6]) loadthis = true; //classic load with parallax
|
|
}
|
|
}
|
|
|
|
if (loadthis) {
|
|
if (cppCreatedList.Contains(lvl.uniqName)) { /*if already created level*/
|
|
ULevelStreaming* outlvl_ = nullptr;
|
|
if ((outlvl_ = UGameplayStatics::GetStreamingLevel(WorldContextObject, lvl.uniqName)) != nullptr) {
|
|
outlvl_->SetShouldBeLoaded(true);
|
|
outlvl_->SetShouldBeVisible(true);
|
|
cpploadedList.Add(lvl.uniqName);
|
|
outStruct.Add(outlvl_);
|
|
}
|
|
}
|
|
else { /*load new level instance*/
|
|
|
|
bool b;
|
|
if (ULevelStreamingDynamic* newlvl = ULevelStreamingDynamic::LoadLevelInstance(WorldContextObject, lvl.path, FVector(0, 0, lvl.Z), FRotator(0), b, lvl.uniqName.ToString())) {
|
|
newlvl->SetPriority(lvl.coords.flat == -1 ? 1 : 0);
|
|
newlvl->bShouldBlockOnLoad = lvl.dontUnload;
|
|
cppCreatedList.Add(lvl.uniqName);
|
|
cpploadedList.Add(lvl.uniqName);
|
|
outStruct.Add(newlvl);
|
|
}
|
|
|
|
}
|
|
}
|
|
else if (cppCreatedList.Contains(lvl.uniqName)) {
|
|
ULevelStreaming* outlvl_ = nullptr;
|
|
if ((outlvl_ = UGameplayStatics::GetStreamingLevel(WorldContextObject, lvl.uniqName)) != nullptr) {
|
|
//if (lvl.path.EndsWith("refl")) outlvl_->bShouldBlockOnUnload = true;
|
|
outlvl_->SetShouldBeLoaded(lvl.dontUnload);
|
|
outlvl_->SetShouldBeVisible(false);
|
|
cpploadedList.Remove(lvl.uniqName);
|
|
outStruct.Add(outlvl_);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
cppWhiteList.Empty();
|
|
cppBlackList.Empty();
|
|
cppLoadList.Empty();
|
|
return outStruct;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UcppGI::cppCoordsEq(Fcppcoords coords, Fcppcoords coords1, bool relevantMinus2, bool fastEq, bool& flat_, bool& type_, bool& zone_, bool& house_, bool& section_, bool& floor_, bool& fullEq)
|
|
{
|
|
bool* outLvl[6] = { &flat_, &type_, &zone_, &house_, §ion_, &floor_ };
|
|
int32 c1[6] = { coords.flat,coords.type, coords.zone, coords.house, coords.section, coords.floor };
|
|
int32 c2[6] = { coords1.flat,coords1.type, coords1.zone, coords1.house, coords1.section, coords1.floor };
|
|
int32 mins[6] = { 0,0,1,1,1,0 };
|
|
if (fastEq) {
|
|
for (int8 i = 0; i < 6; i++)
|
|
{
|
|
*outLvl[i] = (c1[i] == c2[i]);
|
|
}
|
|
}
|
|
else {
|
|
for (int8 i = 0; i < 6; i++) {
|
|
*outLvl[i] = ((c1[i] < mins[i]) && (c2[i] < mins[i])) || (c1[i] == c2[i]) || ((c1[i] == -2) && relevantMinus2) || ((c2[i] == -2) && relevantMinus2);
|
|
}
|
|
}
|
|
fullEq = true;
|
|
for (const auto var : outLvl)
|
|
{
|
|
if (!*var)fullEq = false;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
TArray<FcppflatStruct> UcppGI::getFlatArr_(Fcppcoords coords, int& len)
|
|
{
|
|
auto output = TArray<FcppflatStruct>();
|
|
for (auto& flat : flatArray) {
|
|
auto flatcoords = Fcppcoords();
|
|
flatcoords.flat = coords.flat < 0 ? -2 : flat.FlatId; //ignore flat
|
|
flatcoords.floor = coords.floor < 0 ? -2 : flat.Floor;
|
|
flatcoords.house = coords.house < 1 ? -2 : flat.House;
|
|
flatcoords.section = coords.section < 1 ? -2 : flat.Section;
|
|
flatcoords.type = coords.type < 0 ? -2 : flat.flatType;
|
|
flatcoords.zone = coords.zone < 1 ? -2 : flat.Zone;
|
|
bool dummy[6];
|
|
bool eq;
|
|
cppCoordsEq(coords, flatcoords, true, false, dummy[0], dummy[1], dummy[2], dummy[3], dummy[4], dummy[5], eq);
|
|
if (eq) output.Add(flat);
|
|
}
|
|
len = output.Num();
|
|
return output;
|
|
}
|
|
|
|
FcppflatStruct UcppGI::findFlatByCoords_(Fcppcoords coords, bool& success)
|
|
{
|
|
success = false;
|
|
if (coords.flat < 0) return FcppflatStruct();
|
|
int len;
|
|
auto tt = getFlatArr_(coords, len);
|
|
if (len > 1) UE_LOG(LogCore, Warning, TEXT("UcppGI::findFlatByCoords: found more than one flat: GP%d-S%d-F%d-A%d"), coords.house, coords.section, coords.floor, coords.flat);
|
|
if (len == 0) return FcppflatStruct();
|
|
success = true;
|
|
return tt[0];
|
|
}
|
|
|
|
FcppflatStruct UcppGI::findFlatByN_(Fcppcoords filter, int num, bool& success)
|
|
{
|
|
success = false;
|
|
filter.flat = -2;
|
|
auto output = FcppflatStruct();
|
|
|
|
auto arr = getFlatArr_(filter, intDummy);
|
|
for (auto& flat : arr) {
|
|
if (flat.FlatN == num) {
|
|
if (!success) output = flat;
|
|
else UE_LOG(LogCore, Warning, TEXT("UcppGI::findFlatByN_: found more than one flat"));
|
|
success = true;
|
|
}
|
|
}
|
|
|
|
|
|
return output;
|
|
}
|
|
|
|
void UcppGI::countFreeApartments(Fcppcoords coords, int& free, int& all, float& minPrice)
|
|
{
|
|
int len;
|
|
free = 0;
|
|
minPrice = 0;
|
|
bool temp = false;
|
|
for (auto& flat : getFlatArr_(coords, len)) {
|
|
if (flat.available) {
|
|
if (!temp) {
|
|
minPrice = flat.Price;
|
|
temp = true;
|
|
}
|
|
free++;
|
|
if (flat.Price < minPrice) minPrice = flat.Price;
|
|
}
|
|
}
|
|
minPrice /= 1000000;
|
|
all = len;
|
|
return;
|
|
}
|
|
|
|
void UcppGI::cppFlatTocppCoords(FcppflatStruct flat, Fcppcoords& coords)
|
|
{
|
|
coords.flat = flat.FlatId;
|
|
coords.floor = flat.Floor;
|
|
coords.house = flat.House;
|
|
coords.section = flat.Section;
|
|
coords.type = flat.flatType;
|
|
coords.zone = flat.Zone;
|
|
}
|
|
|
|
void UcppGI::cppCoordsToCppFlat(UObject* WorldContextObject, Fcppcoords coords, FcppflatStruct& flat, bool onlyCoords)
|
|
{
|
|
if (onlyCoords) {
|
|
flat.FlatId = coords.flat;
|
|
flat.Floor = coords.floor;
|
|
flat.House = coords.house;
|
|
flat.Section = coords.section;
|
|
flat.flatType = coords.type;
|
|
flat.Zone = coords.zone;
|
|
return;
|
|
}
|
|
bool dum;
|
|
|
|
flat = StaticCastPtr<UcppGI, UGameInstance>(UGameplayStatics::GetGameInstance(WorldContextObject))->findFlatByCoords_(coords, dum);
|
|
|
|
|
|
} |