void InitializeInjectedNodes(UBehaviorTreeGraphNode* GraphNode, UBTCompositeNode* RootNode, uint16 ExecutionIndex, uint8 TreeDepth, int32 ChildIdx)
	{
		TMap<UBehaviorTreeGraphNode_CompositeDecorator*, FIntIntPair> CompositeMap;
		TArray<UBTDecorator*> DecoratorInstances;
		TArray<FBTDecoratorLogic> DecoratorOperations;

		for (int32 i = 0; i < GraphNode->Decorators.Num(); i++)
		{
			UBehaviorTreeGraphNode* MyNode = GraphNode->Decorators[i];
			if (MyNode == NULL || !MyNode->bInjectedNode)
			{
				continue;
			}

			UBehaviorTreeGraphNode_Decorator* MyDecoratorNode = Cast<UBehaviorTreeGraphNode_Decorator>(MyNode);
			UBehaviorTreeGraphNode_CompositeDecorator* MyCompositeNode = Cast<UBehaviorTreeGraphNode_CompositeDecorator>(MyNode);

			if (MyDecoratorNode)
			{
				MyDecoratorNode->CollectDecoratorData(DecoratorInstances, DecoratorOperations);
			}
			else if (MyCompositeNode)
			{
				MyCompositeNode->SetDecoratorData(RootNode, ChildIdx);

				FIntIntPair RangeData;
				RangeData.FirstIdx = DecoratorInstances.Num();

				MyCompositeNode->CollectDecoratorData(DecoratorInstances, DecoratorOperations);

				RangeData.LastIdx = DecoratorInstances.Num() - 1;
				CompositeMap.Add(MyCompositeNode, RangeData);
			}
		}

		for (int32 i = 0; i < DecoratorInstances.Num(); i++)
		{
			DecoratorInstances[i]->InitializeNode(RootNode, ExecutionIndex, 0, TreeDepth);
			DecoratorInstances[i]->InitializeDecorator(ChildIdx);
			ExecutionIndex++;
		}

		// initialize composite decorators
		for (TMap<UBehaviorTreeGraphNode_CompositeDecorator*, FIntIntPair>::TIterator It(CompositeMap); It; ++It)
		{
			UBehaviorTreeGraphNode_CompositeDecorator* Node = It.Key();
			const FIntIntPair& PairInfo = It.Value();

			if (DecoratorInstances.IsValidIndex(PairInfo.FirstIdx) &&
				DecoratorInstances.IsValidIndex(PairInfo.LastIdx))
			{
				Node->FirstExecutionIndex = DecoratorInstances[PairInfo.FirstIdx]->GetExecutionIndex();
				Node->LastExecutionIndex = DecoratorInstances[PairInfo.LastIdx]->GetExecutionIndex();
			}
		}
	}
void AZombieController::Possess(APawn* Pawn)
{
	Super::Possess(Pawn);

	AZombieCharacter* Zombie = Cast<AZombieCharacter>(Pawn);

	if (Zombie)
	{
		//Initialize blackboard
		if (Zombie->BehaviorTree->BlackboardAsset)
		{
			BlackboardComp->InitializeBlackboard(*(Zombie->BehaviorTree->BlackboardAsset));
		}

		//Get player and hold a reference of it
		TArray<AActor*> ActorsArray;
		UGameplayStatics::GetAllActorsOfClass(GetWorld(), ARoguelikeChar::StaticClass(), ActorsArray);

		if (ActorsArray.IsValidIndex(0))
		{
			ARoguelikeChar* Player = Cast<ARoguelikeChar>(ActorsArray[0]);
			if (Player)
			{
				BlackboardComp->SetValueAsObject(PlayerBlackboardKey, Player);
			}
			
		}
		//Start the tree
		BehaviorComp->StartTree(*Zombie->BehaviorTree);
	}
}
Example #3
0
void AppendPathPointsHelper(TArray<FNavPathPoint>& PathPoints, const TArray<FPathPointInfo>& SourcePoints, int32 Index)
{
	if (SourcePoints.IsValidIndex(Index) && SourcePoints[Index].Point.NodeRef != 0)
	{
		PathPoints.Add(SourcePoints[Index].Point);
	}
}
void UGISInventoryBaseComponent::PreLootAction(TArray<class AGISPickupActor*> PickupsIn)
{ 
	TArray<FGISPickupActorDistanceHelper> HelperStruct;
	FVector PawmLocation = PCOwner->GetPawn()->GetActorLocation();
	for (AGISPickupActor* Pickup : PickupsIn)
	{
		if (Pickup)
		{
			if (Pickup->ItemToLoot.Num() > 0)
			{
				float Distance = FVector::Dist(PawmLocation, Pickup->GetActorLocation());
				FGISPickupActorDistanceHelper helper(Distance, Pickup);
				HelperStruct.Add(helper);
			}
		}
	}
	HelperStruct.Sort();

	if (HelperStruct.IsValidIndex(0))
	{
		//don't need to check everything. If closest actor is to far, rest is as well.
		if (HelperStruct[0].Distance > MaxLootingDistance)
			StartLooting(HelperStruct[0].PickupActor.Get());
	}
}
FTrackInstancePropertyBindings::FPropertyAddress FTrackInstancePropertyBindings::FindPropertyRecursive( const UObject* Object, void* BasePointer, UStruct* InStruct, TArray<FString>& InPropertyNames, uint32 Index ) const
{
	UProperty* Property = FindField<UProperty>(InStruct, *InPropertyNames[Index]);
	
	FTrackInstancePropertyBindings::FPropertyAddress NewAddress;

	UStructProperty* StructProp = Cast<UStructProperty>( Property );
	if( StructProp )
	{
		NewAddress.Property = StructProp;
		NewAddress.Address = BasePointer;

		if( InPropertyNames.IsValidIndex(Index+1) )
		{
			void* StructContainer = StructProp->ContainerPtrToValuePtr<void>(BasePointer);
			return FindPropertyRecursive( Object, StructContainer, StructProp->Struct, InPropertyNames, Index+1 );
		}
		else
		{
			check( StructProp->GetName() == InPropertyNames[Index] );
		}
	}
	else if( Property )
	{
		NewAddress.Property = Property;
		NewAddress.Address = BasePointer;
	}

	return NewAddress;

}
FString FTextFormatData::Format_NoLock(const FPrivateTextFormatArguments& InFormatArgs)
{
	ConditionalCompile_NoLock();

	if (LexedExpression.Num() == 0)
	{
		return SourceExpression;
	}

	FString ResultString;
	ResultString.Reserve(BaseFormatStringLength + (InFormatArgs.EstimatedArgumentValuesLength * FormatArgumentEstimateMultiplier));

	int32 ArgumentIndex = 0;
	for (int32 TokenIndex = 0; TokenIndex < LexedExpression.Num(); ++TokenIndex)
	{
		const FExpressionToken& Token = LexedExpression[TokenIndex];

		if (const auto* Literal = Token.Node.Cast<TextFormatTokens::FStringLiteral>())
		{
			ResultString.AppendChars(Literal->StringStartPos, Literal->StringLen);
		}
		else if (auto* Escaped = Token.Node.Cast<TextFormatTokens::FEscapedCharacter>())
		{
			ResultString.AppendChar(Escaped->Character);
		}
		else if (const auto* ArgumentToken = Token.Node.Cast<TextFormatTokens::FArgumentTokenSpecifier>())
		{
			const FFormatArgumentValue* const PossibleArgumentValue = InFormatArgs.GetArgumentValue(*ArgumentToken, ArgumentIndex++);
			if (PossibleArgumentValue)
			{
				if (LexedExpression.IsValidIndex(TokenIndex + 1))
				{
					const FExpressionToken& NextToken = LexedExpression[TokenIndex + 1];

					// Peek to see if the next token is an argument modifier
					if (const auto* ArgumentModifierToken = NextToken.Node.Cast<TextFormatTokens::FArgumentModifierTokenSpecifier>())
					{
						ArgumentModifierToken->TextFormatArgumentModifier->Evaluate(*PossibleArgumentValue, InFormatArgs, ResultString);
						++TokenIndex; // walk over the argument token so that the next iteration will skip over the argument modifier
						continue;
					}
				}

				PossibleArgumentValue->ToFormattedString(InFormatArgs.bRebuildText, InFormatArgs.bRebuildAsSource, ResultString);
			}
			else
			{
				ResultString.AppendChar(TextFormatTokens::ArgStartChar);
				ResultString.AppendChars(ArgumentToken->ArgumentNameStartPos, ArgumentToken->ArgumentNameLen);
				ResultString.AppendChar(TextFormatTokens::ArgEndChar);
			}
		}
	}

	return ResultString;
}
Example #7
0
TArray<FVector> ULeapImage::LocateBlobs(TArray<FVector> blobArray1, TArray<FVector> blobArray2)
{
	TArray<FVector> BlobVectors;
	uint8 matchBlobs[200];
	FVector blobLocation, blob1, blob2, cameraOffset;;

	cameraOffset = FVector(-0.02f, 0.0f, 0.0f);

	//MATCH THE LEFT RAYS TO THE RIGHT RAYS
	//MAKE SURE RAYS ARE AT LEAST WITHIN 0.05 OF EACHOTHER
	//PICK PAIR THAT RESULTS IN LONGER DISTANCE TO AVOID ENTANGLEMENT
	for (int i = 0; blobArray1.IsValidIndex(i); i++) {
		matchBlobs[i] = 255;
	}

	float farthest;
	for (int i = 0; blobArray1.IsValidIndex(i); i++){

		farthest = 0.05f; //MUST BE FARTHER THAN THIS TO COUNT AT ALL
		for (int j = 0; blobArray2.IsValidIndex(j); j++){

			//TEST ALL FOR FARTHEST WORKING BLOB
			float intersectiondistance = _private->ClosestDistOfApproach(-cameraOffset, blobArray1[i], cameraOffset, blobArray2[j]);
			float distancefromleap = _private->ClosestTimeOfApproach(-cameraOffset, blobArray1[i], cameraOffset, blobArray2[j]);
			if (distancefromleap > farthest) {
				if (intersectiondistance < 0.02f) {
					farthest = distancefromleap;
					matchBlobs[i] = j;
				}
			}
		}
	}

	//ADD BLOB POSITIONS (RELATIVE TO PARENT) ONLY AT THE INTERSECTION OF THE MATCHED RAYS
	for (int i = 0; blobArray1.IsValidIndex(i); i++){
		if (matchBlobs[i] != 255){
			blobLocation = _private->ClosestPointOfApproach(-cameraOffset, blobArray1[i], cameraOffset, blobArray2[matchBlobs[i]]);
			BlobVectors.Add(blobLocation);
		}
	}

	return BlobVectors;
}
	FVector ExtractLocation(TSubclassOf<UEnvQueryItemType> ItemType, const TArray<uint8>& RawData, const TArray<FEnvQueryItem>& Items, int32 Index)
	{
		if (Items.IsValidIndex(Index) &&
			ItemType->IsChildOf(UEnvQueryItemType_VectorBase::StaticClass()))
		{
			UEnvQueryItemType_VectorBase* DefTypeOb = ItemType->GetDefaultObject<UEnvQueryItemType_VectorBase>();
			return DefTypeOb->GetItemLocation(RawData.GetData() + Items[Index].DataOffset);
		}
		return FVector::ZeroVector;
	}
void ASignDialogueHandler::LoadFile(FString fileName) {
	FXmlFile file(fileName);
	FXmlNode* root = file.GetRootNode();

	if (root != NULL) {
		TArray<FXmlNode*> rootChildren = root->GetChildrenNodes();

		// Run through the root's children
		for (int i = 0; i < rootChildren.Num(); i++) {
			if (rootChildren.IsValidIndex(i)) {
				TArray<FXmlNode*> children = rootChildren[i]->GetChildrenNodes();

				if (children.IsValidIndex(0) && children.IsValidIndex(1)
					&& SignArray.IsValidIndex(i)) {

					SignArray[i]->signInfo.signID = FCString::Atoi(*children[0]->GetContent());
					SignArray[i]->signInfo.line = children[1]->GetContent();
				}
			}
		}
	}
}
TValueOrError<FString, FExpressionError> FStringFormatter::FormatInternal(const TCHAR* InExpression, const TArray<FStringFormatArg>& Args, bool bStrict) const
{
	TValueOrError<TArray<FExpressionToken>, FExpressionError> Result = ExpressionParser::Lex(InExpression, bStrict ? StrictOrderedDefinitions : OrderedDefinitions);
	if (!Result.IsValid())
	{
		return MakeError(Result.StealError());
	}

	TArray<FExpressionToken>& Tokens = Result.GetValue();
	if (Tokens.Num() == 0)
	{
		return MakeValue(InExpression);
	}
	
	// This code deliberately tries to reallocate as little as possible
	FString Formatted;
	Formatted.Reserve(Tokens.Last().Context.GetTokenEndPos() - InExpression);
	for (auto& Token : Tokens)
	{
		if (const auto* Literal = Token.Node.Cast<FStringLiteral>())
		{
			Formatted.AppendChars(Literal->String.GetTokenStartPos(), Literal->Len);
		}
		else if (auto* Escaped = Token.Node.Cast<FEscapedCharacter>())
		{
			Formatted.AppendChar(Escaped->Character);
		}
		else if (const auto* IndexToken = Token.Node.Cast<FIndexSpecifier>())
		{
			if (Args.IsValidIndex(IndexToken->Index))
			{
				AppendToString(Args[IndexToken->Index], Formatted);
			}
			else if (bStrict)
			{
				return MakeError(FText::Format(LOCTEXT("InvalidArgumentIndex", "Invalid argument index: {0}"), FText::AsNumber(IndexToken->Index)));
			}
			else
			{
				// No replacement found, so just add the original token string
				const int32 Length = IndexToken->EntireToken.GetTokenEndPos() - IndexToken->EntireToken.GetTokenStartPos();
				Formatted.AppendChars(IndexToken->EntireToken.GetTokenStartPos(), Length);
			}
		}
	}

	return MakeValue(Formatted);
}
Example #11
0
void FBehaviorTreeDebugger::SetCompositeDecoratorRuntimeDescription(const TArray<FString>& RuntimeDescriptions, class UBehaviorTreeGraphNode_CompositeDecorator* Node)
{
	Node->DebuggerRuntimeDescription.Empty();
	for (int32 i = Node->FirstExecutionIndex; i <= Node->LastExecutionIndex; i++)
	{
		if (RuntimeDescriptions.IsValidIndex(i) && RuntimeDescriptions[i].Len())
		{
			if (Node->DebuggerRuntimeDescription.Len())
			{
				Node->DebuggerRuntimeDescription.AppendChar(TEXT('\n'));
			}

			Node->DebuggerRuntimeDescription += FString::Printf(TEXT("[%d] %s"), i, *RuntimeDescriptions[i].Replace(TEXT("\n"), TEXT(", ")));
		}
	}
}
Example #12
0
/**
 *			Called when a Controller is logout from the game or changes teams. If there is
 * 			atleast one teammate left on the team, then the team will continue to be in controll
 * 			of the leaving Controllers ControlPoints.If there is no other teammates left on the
 * 			team after the player changes teams/logout, then any ControlPoints controlled by the
 * 			Controller is set back to Neutral.
 * @param	PS	The Controller who is changing teams or is logout.
 */
void AUTDomGameMode::ClearControl(AUTPlayerState* PS)
{
	TArray<AUTPlayerState*> Pick;
	uint8 Num, i;

	// find a teammate
	if (PS == NULL)
	{
		return;
	}
	for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
	{
		AUTPlayerController* NextPlayer = Cast<AUTPlayerController>(*Iterator);
		AUTPlayerState* TestPS = NextPlayer ? Cast<AUTPlayerState>(NextPlayer->PlayerState) : NULL;
		if (TestPS != NULL && TestPS != PS && (PS->GetTeamNum() == TestPS->GetTeamNum()))
		{
			Pick.AddUnique(TestPS);
		}
	}

	if (Pick.Num() > 0)
	{
		Num = FMath::RandHelper(Pick.Num());
		if (Pick.IsValidIndex(Num) && Pick[Num] != NULL)
		{
			// Give random team mate control over leaving players control points
			for (i = 0; i < CDomPoints.Num(); i++)
			{
				if (CDomPoints[i]->TeamNum != 255 && CDomPoints[i]->ControllingPawn == PS)
				{
					CDomPoints[i]->ControllingPawn = Pick[Num];
					CDomPoints[i]->UpdateStatus();
				}
			}
			return;
		}
	}

	// No teammate found, so reset the point to X
	for (i = 0; i < CDomPoints.Num(); i++)
	{
		if (CDomPoints[i]->ControllingPawn == PS)
		{
			CDomPoints[i]->ResetPoint(true);
		}
	}
}
FString DataTableUtils::AssignStringToProperty(const FString& InString, const UProperty* InProp, uint8* InData)
{
	FStringOutputDevice ImportError;
	if(InProp && IsSupportedTableProperty(InProp))
	{
		if(InProp->ArrayDim == 1)
		{
			DataTableUtilsImpl::AssignStringToProperty(InString, InProp, InData, 0, PPF_None, ImportError);
		}
		else
		{
			if(InString.Len() >= 2 && InString[0] == '(' && InString[InString.Len() - 1] == ')')
			{
				// Trim the ( and )
				FString StringToSplit = InString.Mid(1, InString.Len() - 2);

				TArray<FString> Values;
				StringToSplit.ParseIntoArray(Values, TEXT(","), 1);

				if (InProp->ArrayDim != Values.Num())
				{
					UE_LOG(LogDataTable, Warning, TEXT("%s - Array is %d elements large, but we have %d values to import"), *InProp->GetName(), InProp->ArrayDim, Values.Num());
				}

				for (int32 Index = 0; Index < InProp->ArrayDim; ++Index)
				{
					if (Values.IsValidIndex(Index))
					{
						DataTableUtilsImpl::AssignStringToProperty(Values[Index], InProp, InData, Index, PPF_Delimited, ImportError);
					}
				}
			}
			else
			{
				UE_LOG(LogDataTable, Warning, TEXT("%s - Malformed array string. It must start with '(' and end with ')'"), *InProp->GetName());
			}
		}
	}

	FString Error = ImportError;
	return Error;
}
bool UColorPadActivator::DetermineIfPlayerOverlaps()
{
	TArray<AActor*> OverlappingActors;

	GetOwner()->GetOverlappingActors(
		OUT OverlappingActors,
		ADefaultPawn::StaticClass()
	);
	
	if (OverlappingActors.IsValidIndex(0))
	{
		//player is overlapping
		return true;
	}
	else
	{
		//player is not overlapping
		return false;
	}
}
int32 AHeliGameModeLobby::ChooseTeam(AHeliPlayerState* ForPlayerState) const
{
	// choose one of the teams that are least populated

	TArray<int32> TeamBalance;
	TeamBalance.AddZeroed(NumTeams);

	// get current team balance
	for (int32 i = 0; i < GameState->PlayerArray.Num(); i++)
	{
		AHeliPlayerState const* const TestPlayerState = Cast<AHeliPlayerState>(GameState->PlayerArray[i]);
		if (TestPlayerState && TestPlayerState != ForPlayerState && TeamBalance.IsValidIndex(TestPlayerState->GetTeamNumber()))
		{
			TeamBalance[TestPlayerState->GetTeamNumber()]++;
		}
	}

	// find least populated one
	int32 BestTeamScore = TeamBalance[0];
	for (int32 i = 1; i < TeamBalance.Num(); i++)
	{
		if (BestTeamScore > TeamBalance[i])
		{
			BestTeamScore = TeamBalance[i];
		}
	}

	// there could be more than one...
	TArray<int32> BestTeams;
	for (int32 i = 0; i < TeamBalance.Num(); i++)
	{
		if (TeamBalance[i] == BestTeamScore)
		{
			BestTeams.Add(i);
		}
	}

	// get random from best list
	const int32 RandomBestTeam = BestTeams[FMath::RandHelper(BestTeams.Num())];
	return RandomBestTeam;
}
bool FGameplayCueTranslationManager::BuildTagTranslationTable_r(const FName& TagName, const TArray<FName>& SplitNames)
{

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
	if (CVarGameplyCueTranslatorDebugTag->GetString().IsEmpty() == false && TagName.ToString().Contains(CVarGameplyCueTranslatorDebugTag->GetString()))
	{
		// 
		UE_LOG(LogGameplayCueTranslator, Log, TEXT("....."));
	}
#endif

	bool HasValidRootTag = false;

	TArray<FName> SwappedNames;
	SwappedNames.Reserve(10);

	// Every NameSwap Rule/Class that gave us data
	for (FNameSwapData& NameSwapData : AllNameSwaps)
	{
		// Avoid rule recursion
		{
			if (FGameplayCueTranslatorNode* ChildNode = GetTranslationNodeForName(TagName, false))
			{
				if (ChildNode->UsedTranslators.Contains(NameSwapData.ClassCDO))
				{
					continue;
				}
			}
		}

		// Every Swap that this Rule/Class gave us
		for (int32 SwapRuleIdx=0; SwapRuleIdx < NameSwapData.NameSwaps.Num(); ++SwapRuleIdx)
		{
			const FGameplayCueTranslationNameSwap& SwapRule = NameSwapData.NameSwaps[SwapRuleIdx];

#if WITH_EDITOR
			if (SwapRule.EditorData.Enabled == false)
			{
				continue;
			}
#endif

			// Walk through the original tag's elements
			for (int32 TagIdx=0; TagIdx < SplitNames.Num(); ++TagIdx)
			{
				// Walk through the potential new tag's elemnts
				for (int32 ToNameIdx=0; ToNameIdx < SwapRule.ToNames.Num() && TagIdx < SplitNames.Num(); ++ToNameIdx)
				{
					// If they match
					if (SwapRule.ToNames[ToNameIdx] == SplitNames[TagIdx])
					{
						// If we are at the end
						if (ToNameIdx == SwapRule.ToNames.Num()-1)
						{
							// *Possible* tag translation found! This tag can be derived from out name swapping rules, 
							// but we don't know if there actually is a tag that matches the tag which it would be translated *from*

							// Don't operator on SplitNames, since subsequent rules and name swaps use the same array
							SwappedNames = SplitNames;

							// Remove the "To Names" from the SwappedNames array, replace with the single "From Name"
							// E.g, GC.{Steel.Master} -> GC.{Hero}
							int32 NumRemoves = SwapRule.ToNames.Num(); // We are going to remove as many tags 
							int32 RemoveAtIdx = TagIdx - (SwapRule.ToNames.Num() - 1);
							check(SwappedNames.IsValidIndex(RemoveAtIdx));

							SwappedNames.RemoveAt(RemoveAtIdx, NumRemoves, false);
							SwappedNames.Insert(SwapRule.FromName, RemoveAtIdx);

							// Compose a string from the new name
							FString ComposedString = SwappedNames[0].ToString();							
							for (int32 ComposeIdx=1; ComposeIdx < SwappedNames.Num(); ++ ComposeIdx)
							{
								ComposedString += FString::Printf(TEXT(".%s"), *SwappedNames[ComposeIdx].ToString());
							}
								
							UE_LOG(LogGameplayCueTranslator, Log, TEXT("Found possible expanded tag. Original Child Tag: %s. Possible Parent Tag: %s"), *TagName.ToString(), *ComposedString);
							FName ComposedName = FName(*ComposedString);

							// Look for this tag - is it an actual real tag? If not, continue on
							{
								FGameplayTag ComposedTag = TagManager->RequestGameplayTag(ComposedName, false);
								if (ComposedTag.IsValid() == false)
								{
									UE_LOG(LogGameplayCueTranslator, Log, TEXT("   No tag match found, recursing..."));
									
									FGameplayCueTranslatorNodeIndex ParentIdx = GetTranslationIndexForName( ComposedName, false );
									if (ParentIdx.IsValid() == false)
									{
										ParentIdx = GetTranslationIndexForName( ComposedName, true );
										check(ParentIdx.IsValid());
										TranslationLUT[ParentIdx].UsedTranslators.Add( NameSwapData.ClassCDO );
																		
										HasValidRootTag |= BuildTagTranslationTable_r(ComposedName, SwappedNames);
									}
								}
								else
								{
									HasValidRootTag = true;
								}
							}

							if (HasValidRootTag)
							{
								// Add it to our data structures
								FGameplayCueTranslatorNodeIndex ParentIdx = GetTranslationIndexForName(ComposedName, true);
								check(ParentIdx.IsValid());
								
								UE_LOG(LogGameplayCueTranslator, Log, TEXT("   Matches real tags! Adding to translation tree"));

								FGameplayCueTranslatorNodeIndex ChildIdx = GetTranslationIndexForName(TagName, true);
								ensure(ChildIdx != INDEX_NONE);

								// Note: important to do this after getting ChildIdx since allocating idx can move TranslationMap memory around
								FGameplayCueTranslatorNode& ParentNode = TranslationLUT[ParentIdx];

								FGameplayCueTranslationLink& NewLink = ParentNode.FindOrCreateLink(NameSwapData.ClassCDO, NameSwapData.NameSwaps.Num());
										
								// Verify this link hasn't already been established
								ensure(NewLink.NodeLookup[SwapRuleIdx] != ChildIdx);

								// Setup the link
								NewLink.NodeLookup[SwapRuleIdx] = ChildIdx;

								// Now make sure we don't reapply this rule to this child node or any of its child nodes
								FGameplayCueTranslatorNode& ChildNode = TranslationLUT[ChildIdx];
								ChildNode.UsedTranslators.Append( ParentNode.UsedTranslators );
								ChildNode.UsedTranslators.Add( NameSwapData.ClassCDO );
							}
							else
							{
								UE_LOG(LogGameplayCueTranslator, Log, TEXT("   No tag match found after recursing. Dead end."));
							}

							break;
						}
						else
						{
							// Keep going, advance TagIdx
							TagIdx++;
							continue;
						}
					}
					else
					{
						// Match failed
						break;
					}
				}
			}
		}
	}

	return HasValidRootTag;
}
void UEnvQueryTest_Project::RunTest(FEnvQueryInstance& QueryInstance) const
{
	BoolValue.BindData(QueryInstance.Owner.Get(), QueryInstance.QueryID);
	bool bWantsProjected = BoolValue.GetValue();

	UEnvQueryItemType_Point* ItemTypeCDO = QueryInstance.ItemType->GetDefaultObject<UEnvQueryItemType_Point>();
	if (ItemTypeCDO == nullptr)
	{
		return;
	}

	if (ProjectionData.TraceMode == EEnvQueryTrace::Navigation)
	{
		const ANavigationData* NavData = FEQSHelpers::FindNavigationDataForQuery(QueryInstance);
		if (NavData)
		{
			TSharedPtr<const FNavigationQueryFilter> NavigationFilter = UNavigationQueryFilter::GetQueryFilter(*NavData, ProjectionData.NavigationFilter);
			TArray<FNavigationProjectionWork> Workload;
			Workload.Reserve(QueryInstance.Items.Num());

			const FVector VerticalOffset = (ProjectionData.ProjectDown == ProjectionData.ProjectUp) ?
				FVector::ZeroVector : FVector(0, 0, (ProjectionData.ProjectUp - ProjectionData.ProjectDown) / 2);

			for (int32 Idx = 0; Idx < QueryInstance.Items.Num(); Idx++)
			{
				if (QueryInstance.Items[Idx].IsValid())
				{
					const FVector& ItemLocation = GetItemLocation(QueryInstance, Idx);
					Workload.Add(FNavigationProjectionWork(ItemLocation + VerticalOffset));
				}
			}

			const FVector ProjectionExtent(ProjectionData.ExtentX, ProjectionData.ExtentX, (ProjectionData.ProjectDown + ProjectionData.ProjectUp) / 2);
			NavData->BatchProjectPoints(Workload, ProjectionExtent, NavigationFilter);

			int32 Idx = 0;
			for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It, Idx++)
			{
				const bool bProjected = Workload[Idx].bResult;
				if (bProjected)
				{
					ItemTypeCDO->SetItemNavLocation(It.GetItemData(), Workload[Idx].OutLocation);
				}

				It.SetScore(TestPurpose, FilterType, bProjected, bWantsProjected);
			}
		}
	}
	else if (ProjectionData.TraceMode == EEnvQueryTrace::Geometry)
	{
		TArray<FNavLocation> Workload;
		TArray<uint8> TraceHits;

		Workload.Reserve(QueryInstance.Items.Num());
		for (int32 Idx = 0; Idx < QueryInstance.Items.Num(); Idx++)
		{
			if (QueryInstance.Items[Idx].IsValid())
			{
				const FVector& ItemLocation = GetItemLocation(QueryInstance, Idx);
				Workload.Add(FNavLocation(ItemLocation));
			}
		}

		FEQSHelpers::RunPhysProjection(QueryInstance.World, ProjectionData, Workload, TraceHits);

		int32 Idx = 0;
		for (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It, Idx++)
		{
			const bool bProjected = TraceHits.IsValidIndex(Idx) && TraceHits[Idx];
			if (bProjected)
			{
				ItemTypeCDO->SetItemNavLocation(It.GetItemData(), Workload[Idx]);
			}

			It.SetScore(TestPurpose, FilterType, bProjected, bWantsProjected);
		}
	}
}
Example #18
0
FName FSourceControlModule::GetSourceControlProviderName(int32 ProviderIndex)
{
	TArray<ISourceControlProvider*> Providers = IModularFeatures::Get().GetModularFeatureImplementations<ISourceControlProvider>(SourceControlFeatureName);
	check(Providers.IsValidIndex(ProviderIndex));
	return Providers[ProviderIndex]->GetName();
}
Example #19
0
void FSourceControlModule::SetCurrentSourceControlProvider(int32 ProviderIndex)
{
	TArray<ISourceControlProvider*> Providers = IModularFeatures::Get().GetModularFeatureImplementations<ISourceControlProvider>(SourceControlFeatureName);
	check(Providers.IsValidIndex(ProviderIndex));
	SetCurrentSourceControlProvider(*Providers[ProviderIndex]);
}
void FHttpNetworkReplayStreamer::HttpEnumerateSessionsFinished( FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded )
{
	check( HttpState == EHttptate::EnumeratingSessions );

	HttpState = EHttptate::Idle;

	if ( bSucceeded && HttpResponse->GetResponseCode() == EHttpResponseCodes::Ok )
	{		
		UE_LOG( LogHttpReplay, Verbose, TEXT( "FHttpNetworkReplayStreamer::HttpEnumerateSessionsFinished." ) );

		TArray<FNetworkReplayStreamInfo> Streams;
		FString StreamsString = HttpResponse->GetContentAsString();

		int32 Index = INDEX_NONE;

		TArray< FString > Tokens;

		// Parse the string as { token 1, token ..., token n }
		// This isn't perfect, we should convert to JSON when the dust settles
		if ( StreamsString.FindChar( '{', Index ) )
		{
			StreamsString = StreamsString.RightChop( Index + 1 );

			while ( StreamsString.FindChar( ',', Index ) )
			{
				Tokens.Add( StreamsString.Left( Index ) );
				StreamsString = StreamsString.RightChop( Index + 1 );
			}

			if ( StreamsString.FindChar( '}', Index ) )
			{
				Tokens.Add( StreamsString.Left( Index ) );
			}
			else
			{
				UE_LOG( LogHttpReplay, Warning, TEXT( "FHttpNetworkReplayStreamer::HttpEnumerateSessionsFinished. '}' not found." ) );
				EnumerateStreamsDelegate.ExecuteIfBound( TArray<FNetworkReplayStreamInfo>() );		// FIXME: Notify failure here
				EnumerateStreamsDelegate = FOnEnumerateStreamsComplete();
				return;
			}

			if ( Tokens.Num() > 0 )
			{
				Tokens[ Tokens.Num() - 1 ].RemoveFromStart( TEXT( " " ) );
				Tokens[ Tokens.Num() - 1 ].RemoveFromEnd( TEXT( " " ) );
			}
		}
		else
		{
			UE_LOG( LogHttpReplay, Warning, TEXT( "FHttpNetworkReplayStreamer::HttpEnumerateSessionsFinished. '{' not found." ) );
			EnumerateStreamsDelegate.ExecuteIfBound( TArray<FNetworkReplayStreamInfo>() );		// FIXME: Notify failure here
			EnumerateStreamsDelegate = FOnEnumerateStreamsComplete();
			return;
		}

		const int NUM_TOKENS_PER_INFO = 6;

		if ( Tokens.Num() == 0 || ( Tokens.Num() % NUM_TOKENS_PER_INFO ) != 0 )
		{
			UE_LOG( LogHttpReplay, Warning, TEXT( "FHttpNetworkReplayStreamer::HttpEnumerateSessionsFinished. Invalid number of tokens: %i" ), Tokens.Num() );
			EnumerateStreamsDelegate.ExecuteIfBound( TArray<FNetworkReplayStreamInfo>() );		// FIXME: Notify failure here
			EnumerateStreamsDelegate = FOnEnumerateStreamsComplete();
			return;
		}

		// Convert tokens to individual FNetworkReplayStreamInfo's
		for ( int i = 0; i < Tokens.Num(); i += NUM_TOKENS_PER_INFO )
		{
			FNetworkReplayStreamInfo NewStream;

			NewStream.Name			= Tokens[i];
			NewStream.bIsLive		= false;
			NewStream.SizeInBytes	= 0;
			NewStream.Timestamp		= 0;

			if ( Tokens.IsValidIndex( i + 1 ) )
			{
				// Server returns milliseconds from January 1, 1970, 00:00:00 GMT
				// We need to compensate for the fact that FDateTime starts at January 1, 0001 A.D. and is in 100 nanosecond resolution
				NewStream.Timestamp = FDateTime( FCString::Atoi64( *Tokens[ i + 1 ] ) * 1000 * 10 + FDateTime( 1970, 1, 1 ).GetTicks() );
			}

			if ( Tokens.IsValidIndex( i + 2 ) )
			{
				NewStream.SizeInBytes = FCString::Atoi( *Tokens[ i + 2 ] );
			}

			if ( Tokens.IsValidIndex( i + 3 ) )
			{
				NewStream.LengthInMS = FCString::Atoi( *Tokens[ i + 3 ] );
			}

			if ( Tokens.IsValidIndex( i + 4 ) )
			{
				NewStream.NumViewers = FCString::Atoi( *Tokens[ i + 4 ] );
			}

			if ( Tokens.IsValidIndex( i + 5 ) )
			{
				NewStream.bIsLive = Tokens[ i + 5 ].Contains( TEXT( "true" ) );
			}

			Streams.Add( NewStream );
		}

		EnumerateStreamsDelegate.ExecuteIfBound( Streams );
	}
	else
	{
		UE_LOG( LogHttpReplay, Warning, TEXT( "FHttpNetworkReplayStreamer::HttpEnumerateSessionsFinished. FAILED" ) );
		EnumerateStreamsDelegate.ExecuteIfBound( TArray<FNetworkReplayStreamInfo>() );		// FIXME: Notify failure here
	}

	EnumerateStreamsDelegate = FOnEnumerateStreamsComplete();
}
void UBehaviorTreeGraphNode_CompositeDecorator::BuildDescription()
{
	FString BaseDesc("Composite Decorator");
	if (!bShowOperations)
	{
		CachedDescription = BaseDesc;
		return;
	}

	TArray<UBTDecorator*> NodeInstances;
	TArray<FBTDecoratorLogic> Operations;
	CollectDecoratorData(NodeInstances, Operations);

	TArray<FLogicDesc> OpStack;
	FString Description = BaseDesc + TEXT(":");
	FString Indent("\n");
	bool bPendingNotOp = false;

	for (int32 i = 0; i < Operations.Num(); i++)
	{
		const FBTDecoratorLogic& TestOp = Operations[i];
		if (TestOp.Operation == EBTDecoratorLogic::And ||
			TestOp.Operation == EBTDecoratorLogic::Or)
		{
			Indent += TEXT("- ");

			FLogicDesc NewOpDesc;
			NewOpDesc.NumLeft = TestOp.Number;
			NewOpDesc.OperationDesc = (TestOp.Operation == EBTDecoratorLogic::And) ? TEXT("AND") : TEXT("OR");
			
			OpStack.Add(NewOpDesc);
		}
		else if (TestOp.Operation == EBTDecoratorLogic::Not)
		{
			// special case: NOT before TEST
			if (Operations.IsValidIndex(i + 1) && Operations[i + 1].Operation == EBTDecoratorLogic::Test)
			{
				bPendingNotOp = true;
			}
			else
			{
				Indent += TEXT("- ");
				Description += Indent;
				Description += TEXT("NOT:");

				FLogicDesc NewOpDesc;
				NewOpDesc.NumLeft = 0;

				OpStack.Add(NewOpDesc);
			}
		}
		else if (TestOp.Operation == EBTDecoratorLogic::Test)
		{
			Description += Indent;
			if (bPendingNotOp)
			{
				Description += TEXT("NOT: ");
				bPendingNotOp = false;
			}

			Description += NodeInstances[TestOp.Number]->GetStaticDescription();
			UpdateLogicOpStack(OpStack, Description, Indent);
		}
	}

	CachedDescription = Description;
}
Example #22
0
	const FAIResourceID& GetResource(int32 ResourceIndex)
	{
		return ResourceIDs.IsValidIndex(ResourceIndex) ? ResourceIDs[ResourceIndex] : InvalidResource;
	}
Example #23
0
void FBehaviorTreeDebugger::SetNodeRuntimeDescription(const TArray<FString>& RuntimeDescriptions, class UBehaviorTreeGraphNode* Node, class UBTNode* NodeInstance)
{
	Node->DebuggerRuntimeDescription = RuntimeDescriptions.IsValidIndex(NodeInstance->GetExecutionIndex()) ?
		RuntimeDescriptions[NodeInstance->GetExecutionIndex()] : FString();
}
Example #24
0
void UStaticMesh::FixupZeroTriangleSections()
{
	if (RenderData->MaterialIndexToImportIndex.Num() > 0 && RenderData->LODResources.Num())
	{
		TArray<int32> MaterialMap;
		FMeshSectionInfoMap NewSectionInfoMap;

		// Iterate over all sections of all LODs and identify all material indices that need to be remapped.
		for (int32 LODIndex = 0; LODIndex < RenderData->LODResources.Num(); ++ LODIndex)
		{
			FStaticMeshLODResources& LOD = RenderData->LODResources[LODIndex];
			int32 NumSections = LOD.Sections.Num();

			for (int32 SectionIndex = 0; SectionIndex < NumSections; ++SectionIndex)
			{
				FMeshSectionInfo DefaultSectionInfo(SectionIndex);
				if (RenderData->MaterialIndexToImportIndex.IsValidIndex(SectionIndex))
				{
					int32 ImportIndex = RenderData->MaterialIndexToImportIndex[SectionIndex];
					FMeshSectionInfo SectionInfo = SectionInfoMap.Get(LODIndex, ImportIndex);
					int32 OriginalMaterialIndex = SectionInfo.MaterialIndex;

					// If import index == material index, remap it.
					if (SectionInfo.MaterialIndex == ImportIndex)
					{
						SectionInfo.MaterialIndex = SectionIndex;
					}

					// Update the material mapping table.
					while (SectionInfo.MaterialIndex >= MaterialMap.Num())
					{
						MaterialMap.Add(INDEX_NONE);
					}
					if (SectionInfo.MaterialIndex >= 0)
					{
						MaterialMap[SectionInfo.MaterialIndex] = OriginalMaterialIndex;
					}

					// Update the new section info map if needed.
					if (SectionInfo != DefaultSectionInfo)
					{
						NewSectionInfoMap.Set(LODIndex, SectionIndex, SectionInfo);
					}
				}
			}
		}

		// Compact the materials array.
		for (int32 i = RenderData->LODResources[0].Sections.Num(); i < MaterialMap.Num(); ++i)
		{
			if (MaterialMap[i] == INDEX_NONE)
			{
				int32 NextValidIndex = i+1;
				for (; NextValidIndex < MaterialMap.Num(); ++NextValidIndex)
				{
					if (MaterialMap[NextValidIndex] != INDEX_NONE)
					{
						break;
					}
				}
				if (MaterialMap.IsValidIndex(NextValidIndex))
				{
					MaterialMap[i] = MaterialMap[NextValidIndex];
					for (TMap<uint32,FMeshSectionInfo>::TIterator It(NewSectionInfoMap.Map); It; ++It)
					{
						FMeshSectionInfo& SectionInfo = It.Value();
						if (SectionInfo.MaterialIndex == NextValidIndex)
						{
							SectionInfo.MaterialIndex = i;
						}
					}
				}
				MaterialMap.RemoveAt(i, NextValidIndex - i);
			}
		}

		SectionInfoMap.Clear();
		SectionInfoMap.CopyFrom(NewSectionInfoMap);

		// Check if we need to remap materials.
		bool bRemapMaterials = false;
		for (int32 MaterialIndex = 0; MaterialIndex < MaterialMap.Num(); ++MaterialIndex)
		{
			if (MaterialMap[MaterialIndex] != MaterialIndex)
			{
				bRemapMaterials = true;
				break;
			}
		}

		// Remap the materials array if needed.
		if (bRemapMaterials)
		{
			TArray<UMaterialInterface*> OldMaterials;
			Exchange(Materials,OldMaterials);
			Materials.Empty(MaterialMap.Num());
			for (int32 MaterialIndex = 0; MaterialIndex < MaterialMap.Num(); ++MaterialIndex)
			{
				UMaterialInterface* Material = NULL;
				int32 OldMaterialIndex = MaterialMap[MaterialIndex];
				if (OldMaterials.IsValidIndex(OldMaterialIndex))
				{
					Material = OldMaterials[OldMaterialIndex];
				}
				Materials.Add(Material);
			}
		}
	}
	else
	{
		int32 FoundMaxMaterialIndex = -1;
		TSet<int32> DiscoveredMaterialIndices;
		
		// Find the maximum material index that is used by the mesh
		// Also keep track of which materials are actually used in the array
		for(int32 LODIndex = 0; LODIndex < RenderData->LODResources.Num(); ++LODIndex)
		{
			if (RenderData->LODResources.IsValidIndex(LODIndex))
			{
				FStaticMeshLODResources& LOD = RenderData->LODResources[LODIndex];
				int32 NumSections = LOD.Sections.Num();
				for (int32 SectionIndex = 0; SectionIndex < NumSections; ++SectionIndex)
				{
					FMeshSectionInfo Info = SectionInfoMap.Get(LODIndex, SectionIndex);
					if(Info.MaterialIndex > FoundMaxMaterialIndex)
					{
						FoundMaxMaterialIndex = Info.MaterialIndex;
					}

					DiscoveredMaterialIndices.Add(Info.MaterialIndex);
				}
			}
		}

		// NULL references to materials in indices that are not used by any LOD.
		// This is to fix up an import bug which caused more materials to be added to this array than needed.
		for ( int32 MaterialIdx = 0; MaterialIdx < Materials.Num(); ++MaterialIdx )
		{
			if ( !DiscoveredMaterialIndices.Contains(MaterialIdx) )
			{
				// Materials that are not used by any LOD resource should not be in this array.
				Materials[MaterialIdx] = NULL;
			}
		}

		// Remove entries at the end of the materials array.
		if (Materials.Num() > (FoundMaxMaterialIndex + 1))
		{
			Materials.RemoveAt(FoundMaxMaterialIndex+1, Materials.Num() - FoundMaxMaterialIndex - 1);
		}
	}
}
	void StoreSelection(HWND hWnd)
	{
		int32 Idx = SendDlgItemMessage(hWnd, IDC_BUILDLIST, CB_GETCURSEL, 0, 0);
		Identifier = SortedIdentifiers.IsValidIndex(Idx) ? SortedIdentifiers[Idx] : TEXT("");
	}
Example #26
0
bool DiffTreeView::HasPrevDifference(TSharedRef< STreeView<TSharedPtr< FBlueprintDifferenceTreeEntry > > > TreeView, const TArray< TSharedPtr<class FBlueprintDifferenceTreeEntry> >& Differences)
{
	int32 CurrentIndex = CurrentDifference(TreeView, Differences);
	return Differences.IsValidIndex(CurrentIndex - 1);
}
void FTextFormatData::Compile_NoLock()
{
	LexedExpression.Reset();
	if (SourceType == ESourceType::Text)
	{
		SourceExpression = SourceText.ToString();
		CompiledTextSnapshot = FTextSnapshot(SourceText);
	}
	CompiledExpressionType = FTextFormat::EExpressionType::Simple;
	BaseFormatStringLength = 0;
	FormatArgumentEstimateMultiplier = 1;

	TValueOrError<TArray<FExpressionToken>, FExpressionError> Result = ExpressionParser::Lex(*SourceExpression, FTextFormatter::Get().GetTextFormatDefinitions());
	bool bValidExpression = Result.IsValid();
	if (bValidExpression)
	{
		LexedExpression = Result.StealValue();

		// Quickly make sure the tokens are valid (argument modifiers may only follow an argument token)
		for (int32 TokenIndex = 0; TokenIndex < LexedExpression.Num(); ++TokenIndex)
		{
			const FExpressionToken& Token = LexedExpression[TokenIndex];

			if (const auto* Literal = Token.Node.Cast<TextFormatTokens::FStringLiteral>())
			{
				BaseFormatStringLength += Literal->StringLen;
			}
			else if (auto* Escaped = Token.Node.Cast<TextFormatTokens::FEscapedCharacter>())
			{
				BaseFormatStringLength += 1;
			}
			else if (const auto* ArgumentToken = Token.Node.Cast<TextFormatTokens::FArgumentTokenSpecifier>())
			{
				CompiledExpressionType = FTextFormat::EExpressionType::Complex;

				if (LexedExpression.IsValidIndex(TokenIndex + 1))
				{
					const FExpressionToken& NextToken = LexedExpression[TokenIndex + 1];

					// Peek to see if the next token is an argument modifier
					if (const auto* ArgumentModifierToken = NextToken.Node.Cast<TextFormatTokens::FArgumentModifierTokenSpecifier>())
					{
						int32 ArgModLength = 0;
						bool ArgModUsesFormatArgs = false;
						ArgumentModifierToken->TextFormatArgumentModifier->EstimateLength(ArgModLength, ArgModUsesFormatArgs);

						BaseFormatStringLength += ArgModLength;
						FormatArgumentEstimateMultiplier += (ArgModUsesFormatArgs) ? 1 : 0;

						++TokenIndex; // walk over the argument token so that the next iteration will skip over the argument modifier
						continue;
					}
				}
			}
			else if (Token.Node.Cast<TextFormatTokens::FArgumentModifierTokenSpecifier>())
			{
				// Unexpected argument modifier token!
				const FText ErrorSourceText = FText::FromString(Token.Context.GetString());
				Result = MakeError(FExpressionError(FText::Format(LOCTEXT("UnexpectedArgumentModifierToken", "Unexpected 'argument modifier' token: {0} (token started at index {1})"), ErrorSourceText, Token.Context.GetCharacterIndex())));
				bValidExpression = false;
				break;
			}
		}
	}
	
	if (!bValidExpression)
	{
		LexedExpression.Reset();
		CompiledExpressionType = FTextFormat::EExpressionType::Invalid;
		UE_LOG(LogTextFormatter, Warning, TEXT("Failed to compile text format string '%s': %s"), *SourceExpression, *Result.GetError().Text.ToString());
	}
}
bool FDesktopPlatformWindows::FileDialogShared(bool bSave, const void* ParentWindowHandle, const FString& DialogTitle, const FString& DefaultPath, const FString& DefaultFile, const FString& FileTypes, uint32 Flags, TArray<FString>& OutFilenames, int32& OutFilterIndex)
{
	FScopedSystemModalMode SystemModalScope;

	WCHAR Filename[MAX_FILENAME_STR];
	FCString::Strcpy(Filename, MAX_FILENAME_STR, *(DefaultFile.Replace(TEXT("/"), TEXT("\\"))));

	// Convert the forward slashes in the path name to backslashes, otherwise it'll be ignored as invalid and use whatever is cached in the registry
	WCHAR Pathname[MAX_FILENAME_STR];
	FCString::Strcpy(Pathname, MAX_FILENAME_STR, *(FPaths::ConvertRelativePathToFull(DefaultPath).Replace(TEXT("/"), TEXT("\\"))));

	// Convert the "|" delimited list of filetypes to NULL delimited then add a second NULL character to indicate the end of the list
	WCHAR FileTypeStr[MAX_FILETYPES_STR];
	WCHAR* FileTypesPtr = NULL;
	const int32 FileTypesLen = FileTypes.Len();

	// Nicely formatted file types for lookup later and suitable to append to filenames without extensions
	TArray<FString> CleanExtensionList;

	// The strings must be in pairs for windows.
	// It is formatted as follows: Pair1String1|Pair1String2|Pair2String1|Pair2String2
	// where the second string in the pair is the extension.  To get the clean extensions we only care about the second string in the pair
	TArray<FString> UnformattedExtensions;
	FileTypes.ParseIntoArray( &UnformattedExtensions, TEXT("|"), true );
	for( int32 ExtensionIndex = 1; ExtensionIndex < UnformattedExtensions.Num(); ExtensionIndex += 2)
	{
		const FString& Extension = UnformattedExtensions[ExtensionIndex];
		// Assume the user typed in an extension or doesnt want one when using the *.* extension. We can't determine what extension they wan't in that case
		if( Extension != TEXT("*.*") )
		{
			// Add to the clean extension list, first removing the * wildcard from the extension
			int32 WildCardIndex = Extension.Find( TEXT("*") );
			CleanExtensionList.Add( WildCardIndex != INDEX_NONE ? Extension.RightChop( WildCardIndex+1 ) : Extension );
		}
	}

	if (FileTypesLen > 0 && FileTypesLen - 1 < MAX_FILETYPES_STR)
	{
		FileTypesPtr = FileTypeStr;
		FCString::Strcpy(FileTypeStr, MAX_FILETYPES_STR, *FileTypes);

		TCHAR* Pos = FileTypeStr;
		while( Pos[0] != 0 )
		{
			if ( Pos[0] == '|' )
			{
				Pos[0] = 0;
			}

			Pos++;
		}

		// Add two trailing NULL characters to indicate the end of the list
		FileTypeStr[FileTypesLen] = 0;
		FileTypeStr[FileTypesLen + 1] = 0;
	}

	OPENFILENAME ofn;
	FMemory::Memzero(&ofn, sizeof(OPENFILENAME));

	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = (HWND)ParentWindowHandle;
	ofn.lpstrFilter = FileTypesPtr;
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = Filename;
	ofn.nMaxFile = MAX_FILENAME_STR;
	ofn.lpstrInitialDir = Pathname;
	ofn.lpstrTitle = *DialogTitle;
	if(FileTypesLen > 0)
	{
		ofn.lpstrDefExt = &FileTypeStr[0];
	}

	ofn.Flags = OFN_HIDEREADONLY | OFN_ENABLESIZING | OFN_EXPLORER;

	if ( bSave )
	{
		ofn.Flags |= OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT | OFN_NOVALIDATE;
	}
	else
	{
		ofn.Flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
	}

	if ( Flags & EFileDialogFlags::Multiple )
	{
		ofn.Flags |= OFN_ALLOWMULTISELECT;
	}

	bool bSuccess;
	if ( bSave )
	{
		bSuccess = !!::GetSaveFileName(&ofn);
	}
	else
	{
		bSuccess = !!::GetOpenFileName(&ofn);
	}

	if ( bSuccess )
	{
		// GetOpenFileName/GetSaveFileName changes the CWD on success. Change it back immediately.
		FPlatformProcess::SetCurrentWorkingDirectoryToBaseDir();

		if ( Flags & EFileDialogFlags::Multiple )
		{
			// When selecting multiple files, the returned string is a NULL delimited list
			// where the first element is the directory and all remaining elements are filenames.
			// There is an extra NULL character to indicate the end of the list.
			FString DirectoryOrSingleFileName = FString(Filename);
			TCHAR* Pos = Filename + DirectoryOrSingleFileName.Len() + 1;

			if ( Pos[0] == 0 )
			{
				// One item selected. There was an extra trailing NULL character.
				OutFilenames.Add(DirectoryOrSingleFileName);
			}
			else
			{
				// Multiple items selected. Keep adding filenames until two NULL characters.
				FString SelectedFile;
				do
				{
					SelectedFile = FString(Pos);
					new(OutFilenames) FString(DirectoryOrSingleFileName / SelectedFile);
					Pos += SelectedFile.Len() + 1;
				}
				while (Pos[0] != 0);
			}
		}
		else
		{
			new(OutFilenames) FString(Filename);
		}

		// The index of the filter in OPENFILENAME starts at 1.
		OutFilterIndex = ofn.nFilterIndex - 1;

		// Get the extension to add to the filename (if one doesnt already exist)
		FString Extension = CleanExtensionList.IsValidIndex( OutFilterIndex ) ? CleanExtensionList[OutFilterIndex] : TEXT("");

		// Make sure all filenames gathered have their paths normalized and proper extensions added
		for ( auto FilenameIt = OutFilenames.CreateIterator(); FilenameIt; ++FilenameIt )
		{
			FString& Filename = *FilenameIt;
			
			Filename = IFileManager::Get().ConvertToRelativePath(*Filename);

			if( FPaths::GetExtension(Filename).IsEmpty() && !Extension.IsEmpty() )
			{
				// filename does not have an extension. Add an extension based on the filter that the user chose in the dialog
				Filename += Extension;
			}

			FPaths::NormalizeFilename(Filename);
		}
	}
	else
	{
		uint32 Error = ::CommDlgExtendedError();
		if ( Error != ERROR_SUCCESS )
		{
			UE_LOG(LogDesktopPlatform, Warning, TEXT("Error reading results of file dialog. Error: 0x%04X"), Error);
		}
	}

	return bSuccess;
}
	void CollectDecorators(UBehaviorTree* BTAsset,
		UBehaviorTreeGraphNode* GraphNode, TArray<UBTDecorator*>& DecoratorInstances, TArray<FBTDecoratorLogic>& DecoratorOperations,
		bool bInitializeNodes, UBTCompositeNode* RootNode, uint16* ExecutionIndex, uint8 TreeDepth, int32 ChildIdx)
	{
		TMap<UBehaviorTreeGraphNode_CompositeDecorator*, FIntIntPair> CompositeMap;
		int32 NumNodes = 0;

		for (int32 i = 0; i < GraphNode->Decorators.Num(); i++)
		{
			UBehaviorTreeGraphNode* MyNode = GraphNode->Decorators[i];
			if (MyNode == NULL || MyNode->bInjectedNode)
			{
				continue;
			}

			UBehaviorTreeGraphNode_Decorator* MyDecoratorNode = Cast<UBehaviorTreeGraphNode_Decorator>(MyNode);
			UBehaviorTreeGraphNode_CompositeDecorator* MyCompositeNode = Cast<UBehaviorTreeGraphNode_CompositeDecorator>(MyNode);

			if (MyDecoratorNode)
			{
				MyDecoratorNode->CollectDecoratorData(DecoratorInstances, DecoratorOperations);
				NumNodes++;
			}
			else if (MyCompositeNode)
			{
				MyCompositeNode->SetDecoratorData(RootNode, ChildIdx);

				FIntIntPair RangeData;
				RangeData.FirstIdx = DecoratorInstances.Num();

				MyCompositeNode->CollectDecoratorData(DecoratorInstances, DecoratorOperations);
				NumNodes++;

				RangeData.LastIdx = DecoratorInstances.Num() - 1;
				CompositeMap.Add(MyCompositeNode, RangeData);
			}
		}

		for (int32 i = 0; i < DecoratorInstances.Num(); i++)
		{
			if (DecoratorInstances[i] && BTAsset && Cast<UBehaviorTree>(DecoratorInstances[i]->GetOuter()) == NULL)
			{
				DecoratorInstances[i]->Rename(NULL, BTAsset);
			}

			DecoratorInstances[i]->InitializeNode(RootNode, *ExecutionIndex, 0, TreeDepth);
			if (bInitializeNodes)
			{
				DecoratorInstances[i]->InitializeDecorator(ChildIdx);
				*ExecutionIndex += 1;

				// make sure that flow abort mode matches - skip for root level nodes
				DecoratorInstances[i]->UpdateFlowAbortMode();
			}
		}

		if (bInitializeNodes)
		{
			// initialize composite decorators
			for (TMap<UBehaviorTreeGraphNode_CompositeDecorator*, FIntIntPair>::TIterator It(CompositeMap); It; ++It)
			{
				UBehaviorTreeGraphNode_CompositeDecorator* Node = It.Key();
				const FIntIntPair& PairInfo = It.Value();

				if (DecoratorInstances.IsValidIndex(PairInfo.FirstIdx) &&
					DecoratorInstances.IsValidIndex(PairInfo.LastIdx))
				{
					Node->FirstExecutionIndex = DecoratorInstances[PairInfo.FirstIdx]->GetExecutionIndex();
					Node->LastExecutionIndex = DecoratorInstances[PairInfo.LastIdx]->GetExecutionIndex();
				}
			}
		}

		// setup logic operations only when composite decorator is linked
		if (CompositeMap.Num())
		{
			if (NumNodes > 1)
			{
				FBTDecoratorLogic LogicOp(EBTDecoratorLogic::And, NumNodes);
				DecoratorOperations.Insert(LogicOp, 0);
			}
		}
		else
		{
			DecoratorOperations.Reset();
		}
	}
Example #30
0
void SMergeTreeView::Construct(const FArguments InArgs, const FBlueprintMergeData& InData)
{
	Data = InData;
	CurrentDifference = -1;

	TArray< FSCSDiffEntry > RemoteDifferingProperties;
	TArray< int > RemoteDiffsSortKeys;
	TArray< FSCSDiffEntry > LocalDifferingProperties;
	TArray< int > LocalDiffsSortKeys;

	DiffUtils::CompareUnrelatedSCS(InData.BlueprintBase, InData.BlueprintRemote, RemoteDifferingProperties, &RemoteDiffsSortKeys);
	DiffUtils::CompareUnrelatedSCS(InData.BlueprintBase, InData.BlueprintLocal, LocalDifferingProperties, &LocalDiffsSortKeys);

	check(RemoteDiffsSortKeys.Num() == RemoteDifferingProperties.Num() && LocalDifferingProperties.Num() == LocalDiffsSortKeys.Num());

	// Order the differing properties, and eliminate dupes. Eventually dupes should be treated as collisions when
	// attempting to complete a merge automatically:
	int RemoteIter = 0;
	int LocalIter = 0;
	while (RemoteDifferingProperties.IsValidIndex(RemoteIter) || LocalDifferingProperties.IsValidIndex(LocalIter))
	{
		const bool bStillHaveLocalDiffs = LocalDifferingProperties.IsValidIndex(LocalIter);
		const bool bStillHaveRemoteDiffs = RemoteDifferingProperties.IsValidIndex(RemoteIter);
		FSCSDiffEntry Entry;

		if (bStillHaveLocalDiffs && bStillHaveRemoteDiffs)
		{
			if (LocalDiffsSortKeys[LocalIter] <= RemoteDiffsSortKeys[RemoteIter])
			{
				Entry = LocalDifferingProperties[LocalIter++];
			}
			else
			{
				Entry = RemoteDifferingProperties[RemoteIter++];
			}
		}
		else if (bStillHaveLocalDiffs)
		{
			Entry = LocalDifferingProperties[LocalIter++];
		}
		else
		{
			check(bStillHaveRemoteDiffs);
			Entry = RemoteDifferingProperties[RemoteIter++];
		}

		if (!DifferingProperties.Contains(Entry))
		{
			DifferingProperties.Push(Entry);
		}
	}

	// generate controls:
	// EMergeParticipant::MERGE_PARTICIPANT_REMOTE
	{
		SCSViews.Push(
			FSCSDiff(InData.BlueprintRemote)
			);
	}
	// EMergeParticipant::MERGE_PARTICIPANT_BASE
	{
		SCSViews.Push(
			FSCSDiff(InData.BlueprintBase)
			);
	}
	// EMergeParticipant::MERGE_PARTICIPANT_LOCAL
	{
		SCSViews.Push(
			FSCSDiff(InData.BlueprintLocal)
			);
	}

	ChildSlot[
		SNew(SSplitter)
			+ SSplitter::Slot()
			[
				GetRemoteView().TreeWidget()
			]
		+ SSplitter::Slot()
			[
				GetBaseView().TreeWidget()
			]
		+ SSplitter::Slot()
			[
				GetLocalView().TreeWidget()
			]
	];
}