Files

98 lines
3.3 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "CharacterPartsDataAsset.h"
namespace
{
/**
* Rendue par GetParts quand la categorie n'existe pas, pour que l'appelant
* n'ait jamais a tester un pointeur.
*
* Le nom porte le prefixe du fichier : le build unity concatene les .cpp du
* module et un namespace anonyme n'isole plus rien. Une constante nommee
* "EmptyParts" tout court finirait par entrer en collision -- invisible en
* build incremental, elle ne sortirait qu'au premier -Rebuild.
*/
const TArray<FCharacterPartEntry> CharacterPartsEmptyList;
/** Borne un index de piece OBLIGATOIRE : hors bornes, on retombe sur 0. */
void ClampRequiredIndex(uint8& Index, int32 Count)
{
if (Count <= 0 || Index >= Count)
{
Index = 0;
}
}
/** Borne un index de piece FACULTATIVE : hors bornes, on retire la piece. */
void ClampOptionalIndex(uint8& Index, int32 Count)
{
if (Index == FCharacterAppearance::NoPart)
{
return;
}
if (Count <= 0 || Index >= Count)
{
Index = FCharacterAppearance::NoPart;
}
}
}
const FCharacterBodySet* UCharacterPartsDataAsset::GetBodySet(ECharacterBodyType BodyType) const
{
const int32 Index = static_cast<int32>(BodyType);
return BodySets.IsValidIndex(Index) ? &BodySets[Index] : nullptr;
}
const TArray<FCharacterPartEntry>& UCharacterPartsDataAsset::GetParts(ECharacterBodyType BodyType, ECharacterPartCategory Category) const
{
const FCharacterBodySet* Set = GetBodySet(BodyType);
if (!Set)
{
return CharacterPartsEmptyList;
}
switch (Category)
{
case ECharacterPartCategory::Head: return Set->Heads;
case ECharacterPartCategory::Hair: return Set->Hairstyles;
case ECharacterPartCategory::Eyebrows: return Set->Eyebrows;
case ECharacterPartCategory::Beard: return Set->Beards;
case ECharacterPartCategory::Mustache: return Set->Mustaches;
default: return CharacterPartsEmptyList;
}
}
int32 UCharacterPartsDataAsset::GetPartCount(ECharacterBodyType BodyType, ECharacterPartCategory Category) const
{
return GetParts(BodyType, Category).Num();
}
void UCharacterPartsDataAsset::Sanitize(FCharacterAppearance& InOut) const
{
// La silhouette d'abord : tout le reste est indexe DANS son jeu de pieces,
// donc la borner apres ne servirait a rien.
if (static_cast<uint8>(InOut.BodyType) >= BodySets.Num())
{
InOut.BodyType = ECharacterBodyType::BodyA;
}
ClampRequiredIndex(InOut.HeadIndex, GetPartCount(InOut.BodyType, ECharacterPartCategory::Head));
ClampRequiredIndex(InOut.EyebrowsIndex, GetPartCount(InOut.BodyType, ECharacterPartCategory::Eyebrows));
// Cheveux, barbe et moustache sont facultatifs : un crane rase est un choix,
// pas une erreur.
ClampOptionalIndex(InOut.HairIndex, GetPartCount(InOut.BodyType, ECharacterPartCategory::Hair));
ClampOptionalIndex(InOut.BeardIndex, GetPartCount(InOut.BodyType, ECharacterPartCategory::Beard));
ClampOptionalIndex(InOut.MustacheIndex, GetPartCount(InOut.BodyType, ECharacterPartCategory::Mustache));
ClampRequiredIndex(InOut.EyesIndex, EyeMaterials.Num());
ClampRequiredIndex(InOut.SkinColorIndex, SkinColors.Num());
ClampRequiredIndex(InOut.HairColorIndex, HairColors.Num());
ClampRequiredIndex(InOut.EyeColorIndex, EyeColors.Num());
ClampRequiredIndex(InOut.UnderwearColorIndex, UnderwearColors.Num());
}