init
This commit is contained in:
@@ -0,0 +1,450 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#include "NakedDesireCharacter.h"
|
||||
#include "NakedDesire/Locations/LocationTrigger.h"
|
||||
#include "NakedDesire/Clothing/ClothingManager.h"
|
||||
#include "Components/CapsuleComponent.h"
|
||||
#include "GameFramework/CharacterMovementComponent.h"
|
||||
#include "NakedDesire/InteractionSystem/InteractionManager.h"
|
||||
#include "NakedDesire/InteractionSystem/InteractionTarget.h"
|
||||
#include "NakedDesire/MissionBuilder/MissionsManager.h"
|
||||
#include "NakedDesire/Stats/StatsManager.h"
|
||||
#include "EnhancedInputComponent.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "Internationalization/Text.h"
|
||||
#include "NakedDesire/Clothing/ClothingItemData.h"
|
||||
#include "NakedDesire/Global/Constants.h"
|
||||
#include "NakedDesire/Global/NakedDesireUserSettings.h"
|
||||
#include "NakedDesire/SaveGame/GlobalSaveGameData.h"
|
||||
#include "Perception/AIPerceptionStimuliSourceComponent.h"
|
||||
#include "Perception/AISense_Sight.h"
|
||||
|
||||
ANakedDesireCharacter::ANakedDesireCharacter()
|
||||
{
|
||||
GetCharacterMovement()->MaxWalkSpeed = WalkSpeed;
|
||||
|
||||
GetCapsuleComponent()->OnComponentBeginOverlap.AddUniqueDynamic(this, &ANakedDesireCharacter::OnBeginOverlap);
|
||||
GetCapsuleComponent()->OnComponentEndOverlap.AddUniqueDynamic(this, &ANakedDesireCharacter::OnEndOverlap);
|
||||
|
||||
bUseControllerRotationYaw = false;
|
||||
|
||||
GetCharacterMovement()->bOrientRotationToMovement = true;
|
||||
GetCharacterMovement()->GetNavAgentPropertiesRef().bCanCrouch = true;
|
||||
|
||||
ClothingManager = CreateDefaultSubobject<UClothingManager>("Clothing Manager");
|
||||
StatsManager = CreateDefaultSubobject<UStatsManager>("Stats Manager");
|
||||
MissionsManager = CreateDefaultSubobject<UMissionsManager>("Missions Manager");
|
||||
InteractionManager = CreateDefaultSubobject<UInteractionManager>("Interaction Manager");
|
||||
|
||||
NipplesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Nipples");
|
||||
NipplesMeshComponent->SetupAttachment(GetMesh());
|
||||
AnalMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Anal");
|
||||
AnalMeshComponent->SetupAttachment(GetMesh());
|
||||
VaginaMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Vagina");
|
||||
VaginaMeshComponent->SetupAttachment(GetMesh());
|
||||
HeadMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Head");
|
||||
HeadMeshComponent->SetupAttachment(GetMesh());
|
||||
NeckMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Neck");
|
||||
NeckMeshComponent->SetupAttachment(GetMesh());
|
||||
FaceMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Face");
|
||||
FaceMeshComponent->SetupAttachment(GetMesh());
|
||||
EyesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Eyes");
|
||||
EyesMeshComponent->SetupAttachment(GetMesh());
|
||||
BodyMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Body");
|
||||
BodyMeshComponent->SetupAttachment(GetMesh());
|
||||
TopMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Top");
|
||||
TopMeshComponent->SetupAttachment(GetMesh());
|
||||
BottomMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Bottom");
|
||||
BottomMeshComponent->SetupAttachment(GetMesh());
|
||||
BraMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Bra");
|
||||
BraMeshComponent->SetupAttachment(GetMesh());
|
||||
PantiesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Panties");
|
||||
PantiesMeshComponent->SetupAttachment(GetMesh());
|
||||
SocksMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Socks");
|
||||
SocksMeshComponent->SetupAttachment(GetMesh());
|
||||
ShoesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("Shoes");
|
||||
ShoesMeshComponent->SetupAttachment(GetMesh());
|
||||
|
||||
BoobLCensorship = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Boob L Censorship"));
|
||||
BoobLCensorship->SetupAttachment(GetMesh(), FName(TEXT("boob_l")));
|
||||
BoobRCensorship = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Boob R Censorship"));
|
||||
BoobRCensorship->SetupAttachment(GetMesh(), FName(TEXT("boob_r")));
|
||||
FrontBottomCensorship = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Front Bottom Censorship"));
|
||||
FrontBottomCensorship->SetupAttachment(GetMesh(), FName(TEXT("pelvis")));
|
||||
BackBottomCensorship = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Back Bottom Censorship"));
|
||||
BackBottomCensorship->SetupAttachment(GetMesh(), FName(TEXT("pelvis")));
|
||||
|
||||
StimuliSourceComponent = CreateDefaultSubobject<UAIPerceptionStimuliSourceComponent>(TEXT("Stimuli Source Component"));
|
||||
}
|
||||
|
||||
EGait ANakedDesireCharacter::GetGait() const
|
||||
{
|
||||
return Gait;
|
||||
}
|
||||
|
||||
EStance ANakedDesireCharacter::GetStance() const
|
||||
{
|
||||
return Stance;
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
|
||||
if (StatsManager->Stamina == 0 && Gait == EGait::Run)
|
||||
{
|
||||
SetIsRunning(false);
|
||||
}
|
||||
|
||||
if (Gait == EGait::Run && GetCharacterMovement()->Velocity.SizeSquared2D() > 100 && StatsManager->Stamina > 0)
|
||||
{
|
||||
GetCharacterMovement()->MaxWalkSpeed = RunSpeed;
|
||||
StatsManager->DecreaseStamina(7 * DeltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCharacterMovement()->MaxWalkSpeed = WalkSpeed;
|
||||
if (StatsManager->Stamina < StatsManager->MaxStamina)
|
||||
{
|
||||
StatsManager->IncreaseStamina(15 * DeltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
||||
{
|
||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||
|
||||
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
|
||||
{
|
||||
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &ANakedDesireCharacter::OnLook);
|
||||
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ANakedDesireCharacter::OnMove);
|
||||
EnhancedInputComponent->BindAction(RunAction, ETriggerEvent::Started, this, &ANakedDesireCharacter::OnRunPress);
|
||||
EnhancedInputComponent->BindAction(RunAction, ETriggerEvent::Completed, this, &ANakedDesireCharacter::OnRunRelease);
|
||||
EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Completed, this, &ANakedDesireCharacter::OnCrouchToggle);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::NotifyControllerChanged()
|
||||
{
|
||||
Super::NotifyControllerChanged();
|
||||
|
||||
if (const APlayerController* PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
|
||||
{
|
||||
if (const ULocalPlayer* LocalPlayer = PC->GetLocalPlayer())
|
||||
{
|
||||
if (UEnhancedInputLocalPlayerSubsystem* InputSystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
|
||||
{
|
||||
if (MappingContext)
|
||||
{
|
||||
InputSystem->AddMappingContext(MappingContext, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
StimuliSourceComponent->RegisterForSense(TSubclassOf<UAISense_Sight>());
|
||||
StimuliSourceComponent->RegisterWithPerceptionSystem();
|
||||
|
||||
UGlobalSaveGameData* SaveGameData = UGlobalSaveGameData::LoadOrCreateSaveGame(DefaultPlayerClothing, DefaultWardrobeClothing);
|
||||
|
||||
SetupClothingSlots();
|
||||
|
||||
ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &ANakedDesireCharacter::OnClothingEquip);
|
||||
ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &ANakedDesireCharacter::OnClothingUnequip);
|
||||
|
||||
UNakedDesireUserSettings::GetNakedDesireUserSettings()->OnSettingsChanged.AddUniqueDynamic(this, &ANakedDesireCharacter::OnSettingsChanged);
|
||||
|
||||
ClothingManager->HydrateClothing(SaveGameData);
|
||||
}
|
||||
|
||||
UAISense_Sight::EVisibilityResult ANakedDesireCharacter::CanBeSeenFrom(const FCanBeSeenFromContext& Context,
|
||||
FVector& OutSeenLocation, int32& OutNumberOfLoSChecksPerformed, int32& OutNumberOfAsyncLosCheckRequested,
|
||||
float& OutSightStrength, int32* UserData, const FOnPendingVisibilityQueryProcessedDelegate* Delegate)
|
||||
{
|
||||
const FVector StartLocation = Context.ObserverLocation;
|
||||
const FVector BoobsBoneLocation = GetMesh()->GetBoneLocation(FName(TEXT("boobs_root")));
|
||||
const FVector PelvisBoneLocation = GetMesh()->GetBoneLocation(FName(TEXT("pelvis")));
|
||||
|
||||
OutNumberOfLoSChecksPerformed++;
|
||||
|
||||
FHitResult BoobsHitResult;
|
||||
const bool BoobsHit = CheckSight(StartLocation, BoobsBoneLocation, BoobsHitResult, Context.IgnoreActor);
|
||||
|
||||
FHitResult PelvisHitResult;
|
||||
const bool PelvisHit = CheckSight(StartLocation, PelvisBoneLocation, PelvisHitResult, Context.IgnoreActor);
|
||||
|
||||
if ((!BoobsHit || BoobsHitResult.GetActor() == this) && ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::FrontTop))
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("Boobs hit"));
|
||||
OutSeenLocation = BoobsBoneLocation;
|
||||
OutSightStrength = 1.0f;
|
||||
return UAISense_Sight::EVisibilityResult::Visible;
|
||||
}
|
||||
|
||||
if ((!PelvisHit || PelvisHitResult.GetActor() == this) &&
|
||||
(ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::BackBottom) || ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::FrontBottom)))
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("Pelvis hit"));
|
||||
OutSeenLocation = PelvisBoneLocation;
|
||||
OutSightStrength = 1.0f;
|
||||
return UAISense_Sight::EVisibilityResult::Visible;
|
||||
}
|
||||
|
||||
UE_LOG(LogTemp, Warning, TEXT("Not visoble"));
|
||||
|
||||
return UAISense_Sight::EVisibilityResult::NotVisible;
|
||||
}
|
||||
|
||||
bool ANakedDesireCharacter::CheckSight(const FVector& StartLocation, const FVector& EndLocation, FHitResult& HitResult,
|
||||
const AActor* IgnoreActor)
|
||||
{
|
||||
FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(AILineOfSight), true);
|
||||
QueryParams.AddIgnoredActor(IgnoreActor);
|
||||
QueryParams.AddIgnoredActor(this); // ignore self
|
||||
|
||||
const bool bHit = GetWorld()->LineTraceSingleByChannel(
|
||||
HitResult,
|
||||
StartLocation,
|
||||
EndLocation,
|
||||
ECC_Visibility,
|
||||
QueryParams
|
||||
);
|
||||
|
||||
// DrawDebugLine(GetWorld(), StartLocation, EndLocation, bHit ? FColor::Red : FColor::Green, false, 1.0f);
|
||||
|
||||
return bHit;
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
|
||||
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
|
||||
{
|
||||
if (OtherActor->Implements<UInteractionTarget>())
|
||||
{
|
||||
InteractionManager->OnTargetEnter(OtherActor);
|
||||
}
|
||||
|
||||
if (const ALocationTrigger* AreaTrigger = Cast<ALocationTrigger>(OtherActor))
|
||||
{
|
||||
CurrentArea = AreaTrigger->GetLocationData();
|
||||
OnAreaEnter.Broadcast(CurrentArea);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
|
||||
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
|
||||
{
|
||||
if (OtherActor->Implements<UInteractionTarget>())
|
||||
{
|
||||
InteractionManager->OnTargetExit(OtherActor);
|
||||
}
|
||||
|
||||
if (const ALocationTrigger* AreaTrigger = Cast<ALocationTrigger>(OtherActor))
|
||||
{
|
||||
CurrentArea = nullptr;
|
||||
OnAreaExit.Broadcast(AreaTrigger->GetLocationData());
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnClothingEquip(const UClothingItemData* ClothingItemData)
|
||||
{
|
||||
if (ClothingItemData->Info->CoveredBodyParts.Contains(EPrivateBodyPartType::BackBottom))
|
||||
{
|
||||
BackBottomCensorship->SetVisibility(false);
|
||||
}
|
||||
if (ClothingItemData->Info->CoveredBodyParts.Contains(EPrivateBodyPartType::FrontBottom))
|
||||
{
|
||||
FrontBottomCensorship->SetVisibility(false);
|
||||
}
|
||||
if (ClothingItemData->Info->CoveredBodyParts.Contains(EPrivateBodyPartType::FrontTop))
|
||||
{
|
||||
BoobLCensorship->SetVisibility(false);
|
||||
BoobRCensorship->SetVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnClothingUnequip(const UClothingItemData* ClothingItemData)
|
||||
{
|
||||
if (!UNakedDesireUserSettings::GetNakedDesireUserSettings()->GetIsCensorshipEnabled() && !IS_DEMO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::BackBottom))
|
||||
{
|
||||
BackBottomCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::FrontBottom))
|
||||
{
|
||||
FrontBottomCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::FrontTop))
|
||||
{
|
||||
BoobLCensorship->SetVisibility(true);
|
||||
BoobRCensorship->SetVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnSettingsChanged(UNakedDesireUserSettings* Settings)
|
||||
{
|
||||
if (Settings->GetIsCensorshipEnabled())
|
||||
{
|
||||
if (ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::BackBottom))
|
||||
{
|
||||
BackBottomCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::FrontBottom))
|
||||
{
|
||||
FrontBottomCensorship->SetVisibility(true);
|
||||
}
|
||||
if (ClothingManager->IsBodyTypeExposed(EPrivateBodyPartType::FrontTop))
|
||||
{
|
||||
BoobLCensorship->SetVisibility(true);
|
||||
BoobRCensorship->SetVisibility(true);
|
||||
}
|
||||
}
|
||||
else if (!IS_DEMO)
|
||||
{
|
||||
BackBottomCensorship->SetVisibility(false);
|
||||
FrontBottomCensorship->SetVisibility(false);
|
||||
BoobLCensorship->SetVisibility(false);
|
||||
BoobRCensorship->SetVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnLook(const FInputActionValue& Value)
|
||||
{
|
||||
const FVector2D MouseValue = Value.Get<FVector2D>();
|
||||
|
||||
AddControllerYawInput(MouseValue.X);
|
||||
AddControllerPitchInput(MouseValue.Y);
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnMove(const FInputActionValue& Value)
|
||||
{
|
||||
const FVector2D MoveInput = Value.Get<FVector2D>();
|
||||
const FRotator Rotator = Controller->GetControlRotation();
|
||||
const FRotationMatrix Direction = FRotationMatrix(FRotator(0, Rotator.Yaw, 0));
|
||||
const FVector ForwardDirection = Direction.GetUnitAxis(EAxis::X);
|
||||
const FVector RightDirection = Direction.GetUnitAxis(EAxis::Y);
|
||||
|
||||
AddMovementInput(ForwardDirection, MoveInput.Y);
|
||||
AddMovementInput(RightDirection, MoveInput.X);
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnRunPress(const FInputActionValue& Value)
|
||||
{
|
||||
SetIsRunning(true);
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnRunRelease(const FInputActionValue& Value)
|
||||
{
|
||||
SetIsRunning(false);
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::OnCrouchToggle(const FInputActionValue& Value)
|
||||
{
|
||||
if (GetCharacterMovement()->IsCrouching())
|
||||
{
|
||||
UnCrouch();
|
||||
}
|
||||
else
|
||||
{
|
||||
Crouch();
|
||||
}
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::SetupClothingSlots()
|
||||
{
|
||||
#define LOCTEXT_NAMESPACE "ClothingSlots"
|
||||
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
NipplesMeshComponent, EClothingSlotType::Nipples,
|
||||
nullptr,
|
||||
LOCTEXT("Nipples", "Nipples")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
AnalMeshComponent, EClothingSlotType::Anal,
|
||||
nullptr,
|
||||
LOCTEXT("Anal", "Anal")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
VaginaMeshComponent, EClothingSlotType::Vagina,
|
||||
nullptr,
|
||||
LOCTEXT("Vagina", "Vagina")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
HeadMeshComponent, EClothingSlotType::Head,
|
||||
nullptr,
|
||||
LOCTEXT("Head", "Head")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
NeckMeshComponent, EClothingSlotType::Neck,
|
||||
nullptr,
|
||||
LOCTEXT("Neck", "Neck")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
FaceMeshComponent, EClothingSlotType::Face,
|
||||
nullptr,
|
||||
LOCTEXT("Face", "Face")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
EyesMeshComponent, EClothingSlotType::Eyes,
|
||||
nullptr,
|
||||
LOCTEXT("Eyes", "Eyes")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
BodyMeshComponent, EClothingSlotType::Body,
|
||||
nullptr,
|
||||
LOCTEXT("Body", "Body")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
TopMeshComponent, EClothingSlotType::Top,
|
||||
nullptr,
|
||||
LOCTEXT("Top", "Top")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
BottomMeshComponent, EClothingSlotType::Bottom,
|
||||
nullptr,
|
||||
LOCTEXT("Bottom", "Bottom")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
BraMeshComponent, EClothingSlotType::Bra,
|
||||
nullptr,
|
||||
LOCTEXT("Bra", "Bra")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
PantiesMeshComponent, EClothingSlotType::Panties,
|
||||
nullptr,
|
||||
LOCTEXT("Panties", "Panties")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
SocksMeshComponent, EClothingSlotType::Socks,
|
||||
nullptr,
|
||||
LOCTEXT("Socks", "Socks")));
|
||||
ClothingManager->ClothingSlots.Add(
|
||||
FClothingSlotData(
|
||||
ShoesMeshComponent, EClothingSlotType::Shoes,
|
||||
nullptr,
|
||||
LOCTEXT("Shoes", "Shoes")));
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::NotifyNoticed(ANPCAIController* NPCController)
|
||||
{
|
||||
OnNoticed.Broadcast(NPCController);
|
||||
}
|
||||
|
||||
void ANakedDesireCharacter::SetIsRunning(const bool Value)
|
||||
{
|
||||
Gait = Value ? EGait::Run : EGait::Walk;
|
||||
GetCharacterMovement()->MaxWalkSpeed = Gait == EGait::Run ? RunSpeed : WalkSpeed;
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "InputAction.h"
|
||||
#include "InputMappingContext.h"
|
||||
#include "NakedDesire/Global/Gait.h"
|
||||
#include "NakedDesire/Global/NakedDesireUserSettings.h"
|
||||
#include "NakedDesire/Global/Stance.h"
|
||||
#include "Perception/AISightTargetInterface.h"
|
||||
#include "NakedDesireCharacter.generated.h"
|
||||
|
||||
class UAIPerceptionStimuliSourceComponent;
|
||||
class UClothingItemData;
|
||||
class UClothingList;
|
||||
struct FClothingSlotData;
|
||||
class UInteractionManager;
|
||||
class UClothingPickerWidget;
|
||||
class UClothingManager;
|
||||
class UStatsManager;
|
||||
class UMissionsManager;
|
||||
class ANPCAIController;
|
||||
class ULocationData;
|
||||
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FOnNoticedSignature, ANPCAIController*);
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FOnAreaChangeSignature, ULocationData*);
|
||||
|
||||
UCLASS(config=Game)
|
||||
class ANakedDesireCharacter : public ACharacter, public IAISightTargetInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
ANakedDesireCharacter();
|
||||
|
||||
// Input
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
UInputMappingContext* MappingContext;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
UInputAction* LookAction;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
UInputAction* MoveAction;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
UInputAction* RunAction;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Input")
|
||||
UInputAction* CrouchAction;
|
||||
|
||||
// Clothing
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Clothing Manager|Clothing")
|
||||
UClothingList* DefaultPlayerClothing = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Clothing Manager|Clothing")
|
||||
UClothingList* DefaultWardrobeClothing = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* NipplesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* AnalMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* VaginaMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* HeadMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* NeckMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* FaceMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* EyesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* BodyMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* TopMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* BottomMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* BraMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* PantiesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* SocksMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
USkeletalMeshComponent* ShoesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Censorship")
|
||||
UStaticMeshComponent* BoobLCensorship;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Censorship")
|
||||
UStaticMeshComponent* BoobRCensorship;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Censorship")
|
||||
UStaticMeshComponent* FrontBottomCensorship;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Censorship")
|
||||
UStaticMeshComponent* BackBottomCensorship;
|
||||
|
||||
// Components
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Clothing")
|
||||
UClothingManager* ClothingManager;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
UStatsManager* StatsManager;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
UMissionsManager* MissionsManager;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
UInteractionManager* InteractionManager;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
UAIPerceptionStimuliSourceComponent* StimuliSourceComponent;
|
||||
|
||||
// Variables
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
float WalkSpeed = 250.0f;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||
float RunSpeed = 500.0f;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int Money = 300000;
|
||||
|
||||
int XP = 0;
|
||||
|
||||
UPROPERTY()
|
||||
ULocationData* CurrentArea = nullptr;
|
||||
|
||||
FOnNoticedSignature OnNoticed;
|
||||
|
||||
FOnAreaChangeSignature OnAreaEnter;
|
||||
FOnAreaChangeSignature OnAreaExit;
|
||||
|
||||
void NotifyNoticed(ANPCAIController* NPCController);
|
||||
void SetIsRunning(bool Value);
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
EGait GetGait() const;
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
EStance GetStance() const;
|
||||
|
||||
protected:
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;
|
||||
virtual void NotifyControllerChanged() override;
|
||||
virtual void BeginPlay() override;
|
||||
virtual UAISense_Sight::EVisibilityResult CanBeSeenFrom(const FCanBeSeenFromContext& Context, FVector& OutSeenLocation, int32& OutNumberOfLoSChecksPerformed, int32& OutNumberOfAsyncLosCheckRequested, float& OutSightStrength, int32* UserData = nullptr, const FOnPendingVisibilityQueryProcessedDelegate* Delegate = nullptr) override;
|
||||
|
||||
private:
|
||||
EGait Gait = EGait::Walk;
|
||||
EStance Stance = EStance::Stand;
|
||||
|
||||
UFUNCTION()
|
||||
void OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp,
|
||||
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
|
||||
|
||||
UFUNCTION()
|
||||
void OnEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp,
|
||||
int32 OtherBodyIndex);
|
||||
|
||||
UFUNCTION()
|
||||
void OnClothingEquip(const UClothingItemData* ClothingItemData);
|
||||
|
||||
UFUNCTION()
|
||||
void OnClothingUnequip(const UClothingItemData* ClothingItemData);
|
||||
|
||||
UFUNCTION()
|
||||
void OnSettingsChanged(UNakedDesireUserSettings* Settings);
|
||||
|
||||
void OnLook(const FInputActionValue& Value);
|
||||
void OnMove(const FInputActionValue& Value);
|
||||
void OnRunPress(const FInputActionValue& Value);
|
||||
void OnRunRelease(const FInputActionValue& Value);
|
||||
void OnCrouchToggle(const FInputActionValue& Value);
|
||||
|
||||
void SetupClothingSlots();
|
||||
|
||||
bool CheckSight(const FVector& StartLocation, const FVector& EndLocation, FHitResult& HitResult, const AActor* IgnoreActor);
|
||||
};
|
||||
@@ -0,0 +1,136 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "PlayerCinematic.h"
|
||||
|
||||
#include "NakedDesireCharacter.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "NakedDesire/Clothing/ClothingItemData.h"
|
||||
#include "NakedDesire/Clothing/ClothingManager.h"
|
||||
|
||||
|
||||
// Sets default values
|
||||
APlayerCinematic::APlayerCinematic()
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
|
||||
NipplesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Nipples"));
|
||||
NipplesMeshComponent->SetupAttachment(GetMesh());
|
||||
AnalMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Anal"));
|
||||
AnalMeshComponent->SetupAttachment(GetMesh());
|
||||
VaginaMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Vagina"));
|
||||
VaginaMeshComponent->SetupAttachment(GetMesh());
|
||||
HeadMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Head"));
|
||||
HeadMeshComponent->SetupAttachment(GetMesh());
|
||||
NeckMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Neck"));
|
||||
NeckMeshComponent->SetupAttachment(GetMesh());
|
||||
FaceMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Face"));
|
||||
FaceMeshComponent->SetupAttachment(GetMesh());
|
||||
EyesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Eyes"));
|
||||
EyesMeshComponent->SetupAttachment(GetMesh());
|
||||
BodyMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Body"));
|
||||
BodyMeshComponent->SetupAttachment(GetMesh());
|
||||
TopMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Top"));
|
||||
TopMeshComponent->SetupAttachment(GetMesh());
|
||||
BottomMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Bottom"));
|
||||
BottomMeshComponent->SetupAttachment(GetMesh());
|
||||
BraMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Bra"));
|
||||
BraMeshComponent->SetupAttachment(GetMesh());
|
||||
PantiesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Panties"));
|
||||
PantiesMeshComponent->SetupAttachment(GetMesh());
|
||||
SocksMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Socks"));
|
||||
SocksMeshComponent->SetupAttachment(GetMesh());
|
||||
ShoesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Shoes"));
|
||||
ShoesMeshComponent->SetupAttachment(GetMesh());
|
||||
}
|
||||
|
||||
void APlayerCinematic::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
Player = Cast<ANakedDesireCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
|
||||
if (!Player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Player->ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &APlayerCinematic::OnClothingEquip);
|
||||
Player->ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &APlayerCinematic::OnClothingUnequip);
|
||||
|
||||
for (const UClothingItemData* ClothingItemData : Player->ClothingManager->GetEquippedClothing())
|
||||
{
|
||||
EquipClothing(ClothingItemData);
|
||||
}
|
||||
}
|
||||
|
||||
void APlayerCinematic::OnClothingEquip(const UClothingItemData* ClothingData)
|
||||
{
|
||||
EquipClothing(ClothingData);
|
||||
}
|
||||
|
||||
void APlayerCinematic::OnClothingUnequip(const UClothingItemData* ClothingData)
|
||||
{
|
||||
UnequipClothing(ClothingData);
|
||||
}
|
||||
|
||||
USkeletalMeshComponent* APlayerCinematic::GetMeshByType(const EClothingSlotType SlotType) const
|
||||
{
|
||||
switch (SlotType)
|
||||
{
|
||||
case EClothingSlotType::Nipples:
|
||||
return NipplesMeshComponent;
|
||||
case EClothingSlotType::Anal:
|
||||
return AnalMeshComponent;
|
||||
case EClothingSlotType::Vagina:
|
||||
return VaginaMeshComponent;
|
||||
case EClothingSlotType::Head:
|
||||
return HeadMeshComponent;
|
||||
case EClothingSlotType::Neck:
|
||||
return NeckMeshComponent;
|
||||
case EClothingSlotType::Face:
|
||||
return FaceMeshComponent;
|
||||
case EClothingSlotType::Eyes:
|
||||
return EyesMeshComponent;
|
||||
case EClothingSlotType::Body:
|
||||
return BodyMeshComponent;
|
||||
case EClothingSlotType::Top:
|
||||
return TopMeshComponent;
|
||||
case EClothingSlotType::Bottom:
|
||||
return BottomMeshComponent;
|
||||
case EClothingSlotType::Bra:
|
||||
return BraMeshComponent;
|
||||
case EClothingSlotType::Panties:
|
||||
return PantiesMeshComponent;
|
||||
case EClothingSlotType::Socks:
|
||||
return SocksMeshComponent;
|
||||
case EClothingSlotType::Shoes:
|
||||
return ShoesMeshComponent;
|
||||
default:
|
||||
return NipplesMeshComponent;
|
||||
}
|
||||
}
|
||||
|
||||
void APlayerCinematic::EquipClothing(const UClothingItemData* ClothingData)
|
||||
{
|
||||
USkeletalMeshComponent* MeshComponent = GetMeshByType(ClothingData->Info->SlotType);
|
||||
MeshComponent->SetSkeletalMesh(ClothingData->Info->SkeletalMesh);
|
||||
if (ClothingData->Info->UseLeaderPose)
|
||||
{
|
||||
MeshComponent->SetLeaderPoseComponent(GetMesh());
|
||||
}
|
||||
|
||||
if (!ClothingData->Info->Materials.IsEmpty())
|
||||
{
|
||||
for (const TPair<FName, UMaterialInstance*>& Material : ClothingData->Info->Materials)
|
||||
{
|
||||
MeshComponent->SetMaterialByName(Material.Key, Material.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APlayerCinematic::UnequipClothing(const UClothingItemData* ClothingData)
|
||||
{
|
||||
USkeletalMeshComponent* MeshComponent = GetMeshByType(ClothingData->Info->SlotType);
|
||||
MeshComponent->SetSkeletalMesh(nullptr);
|
||||
MeshComponent->SetLeaderPoseComponent(nullptr);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "NakedDesire/Clothing/ClothingSlotType.h"
|
||||
#include "PlayerCinematic.generated.h"
|
||||
|
||||
class UClothingItemData;
|
||||
class ANakedDesireCharacter;
|
||||
|
||||
UCLASS()
|
||||
class NAKEDDESIRE_API APlayerCinematic : public ACharacter
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* NipplesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* AnalMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* VaginaMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* HeadMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* NeckMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* FaceMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* EyesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* BodyMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* TopMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* BottomMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* BraMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* PantiesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* SocksMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* ShoesMeshComponent;
|
||||
|
||||
UPROPERTY()
|
||||
ANakedDesireCharacter* Player;
|
||||
|
||||
public:
|
||||
APlayerCinematic();
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
UFUNCTION()
|
||||
void OnClothingEquip(const UClothingItemData* ClothingData);
|
||||
|
||||
UFUNCTION()
|
||||
void OnClothingUnequip(const UClothingItemData* ClothingData);
|
||||
|
||||
USkeletalMeshComponent* GetMeshByType(const EClothingSlotType SlotType) const;
|
||||
void EquipClothing(const UClothingItemData* ClothingData);
|
||||
void UnequipClothing(const UClothingItemData* ClothingData);
|
||||
};
|
||||
@@ -0,0 +1,140 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "PlayerImpostor.h"
|
||||
|
||||
#include "NakedDesireCharacter.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "NakedDesire/Clothing/ClothingManager.h"
|
||||
|
||||
|
||||
APlayerImpostor::APlayerImpostor()
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
|
||||
RootSceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
|
||||
SetRootComponent(RootSceneComponent);
|
||||
|
||||
Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("RootMesh"));
|
||||
Mesh->SetupAttachment(RootComponent);
|
||||
|
||||
NipplesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Nipples"));
|
||||
NipplesMeshComponent->SetupAttachment(GetMesh());
|
||||
AnalMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Anal"));
|
||||
AnalMeshComponent->SetupAttachment(GetMesh());
|
||||
VaginaMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Vagina"));
|
||||
VaginaMeshComponent->SetupAttachment(GetMesh());
|
||||
HeadMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Head"));
|
||||
HeadMeshComponent->SetupAttachment(GetMesh());
|
||||
NeckMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Neck"));
|
||||
NeckMeshComponent->SetupAttachment(GetMesh());
|
||||
FaceMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Face"));
|
||||
FaceMeshComponent->SetupAttachment(GetMesh());
|
||||
EyesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Eyes"));
|
||||
EyesMeshComponent->SetupAttachment(GetMesh());
|
||||
BodyMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Body"));
|
||||
BodyMeshComponent->SetupAttachment(GetMesh());
|
||||
TopMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Top"));
|
||||
TopMeshComponent->SetupAttachment(GetMesh());
|
||||
BottomMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Bottom"));
|
||||
BottomMeshComponent->SetupAttachment(GetMesh());
|
||||
BraMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Bra"));
|
||||
BraMeshComponent->SetupAttachment(GetMesh());
|
||||
PantiesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Panties"));
|
||||
PantiesMeshComponent->SetupAttachment(GetMesh());
|
||||
SocksMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Socks"));
|
||||
SocksMeshComponent->SetupAttachment(GetMesh());
|
||||
ShoesMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Shoes"));
|
||||
ShoesMeshComponent->SetupAttachment(GetMesh());
|
||||
}
|
||||
|
||||
void APlayerImpostor::OnClothingEquip(const UClothingItemData* ClothingData)
|
||||
{
|
||||
EquipClothing(ClothingData);
|
||||
}
|
||||
|
||||
void APlayerImpostor::OnClothingUnequip(const UClothingItemData* ClothingData)
|
||||
{
|
||||
UnequipClothing(ClothingData);
|
||||
}
|
||||
|
||||
void APlayerImpostor::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
Player = Cast<ANakedDesireCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
|
||||
if (!Player)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Player->ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &APlayerImpostor::OnClothingEquip);
|
||||
Player->ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &APlayerImpostor::OnClothingUnequip);
|
||||
|
||||
for (const UClothingItemData* ClothingItemData : Player->ClothingManager->GetEquippedClothing())
|
||||
{
|
||||
EquipClothing(ClothingItemData);
|
||||
}
|
||||
}
|
||||
|
||||
USkeletalMeshComponent* APlayerImpostor::GetMeshByType(const EClothingSlotType SlotType) const
|
||||
{
|
||||
switch (SlotType)
|
||||
{
|
||||
case EClothingSlotType::Nipples:
|
||||
return NipplesMeshComponent;
|
||||
case EClothingSlotType::Anal:
|
||||
return AnalMeshComponent;
|
||||
case EClothingSlotType::Vagina:
|
||||
return VaginaMeshComponent;
|
||||
case EClothingSlotType::Head:
|
||||
return HeadMeshComponent;
|
||||
case EClothingSlotType::Neck:
|
||||
return NeckMeshComponent;
|
||||
case EClothingSlotType::Face:
|
||||
return FaceMeshComponent;
|
||||
case EClothingSlotType::Eyes:
|
||||
return EyesMeshComponent;
|
||||
case EClothingSlotType::Body:
|
||||
return BodyMeshComponent;
|
||||
case EClothingSlotType::Top:
|
||||
return TopMeshComponent;
|
||||
case EClothingSlotType::Bottom:
|
||||
return BottomMeshComponent;
|
||||
case EClothingSlotType::Bra:
|
||||
return BraMeshComponent;
|
||||
case EClothingSlotType::Panties:
|
||||
return PantiesMeshComponent;
|
||||
case EClothingSlotType::Socks:
|
||||
return SocksMeshComponent;
|
||||
case EClothingSlotType::Shoes:
|
||||
return ShoesMeshComponent;
|
||||
default:
|
||||
return NipplesMeshComponent;
|
||||
}
|
||||
}
|
||||
|
||||
void APlayerImpostor::EquipClothing(const UClothingItemData* ClothingData)
|
||||
{
|
||||
USkeletalMeshComponent* MeshComponent = GetMeshByType(ClothingData->Info->SlotType);
|
||||
MeshComponent->SetSkeletalMesh(ClothingData->Info->SkeletalMesh);
|
||||
if (ClothingData->Info->UseLeaderPose)
|
||||
{
|
||||
MeshComponent->SetLeaderPoseComponent(GetMesh());
|
||||
}
|
||||
|
||||
if (!ClothingData->Info->Materials.IsEmpty())
|
||||
{
|
||||
for (const TPair<FName, UMaterialInstance*>& Material : ClothingData->Info->Materials)
|
||||
{
|
||||
MeshComponent->SetMaterialByName(Material.Key, Material.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APlayerImpostor::UnequipClothing(const UClothingItemData* ClothingData)
|
||||
{
|
||||
USkeletalMeshComponent* MeshComponent = GetMeshByType(ClothingData->Info->SlotType);
|
||||
MeshComponent->SetSkeletalMesh(nullptr);
|
||||
MeshComponent->SetLeaderPoseComponent(nullptr);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "NakedDesire/Clothing/ClothingItemData.h"
|
||||
#include "NakedDesire/Clothing/ClothingSlotType.h"
|
||||
#include "PlayerImpostor.generated.h"
|
||||
|
||||
class ANakedDesireCharacter;
|
||||
|
||||
UCLASS()
|
||||
class NAKEDDESIRE_API APlayerImpostor : public APawn
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true))
|
||||
USceneComponent* RootSceneComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true))
|
||||
USkeletalMeshComponent* Mesh;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* NipplesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* AnalMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* VaginaMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* HeadMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* NeckMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* FaceMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* EyesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* BodyMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* TopMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* BottomMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* BraMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* PantiesMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* SocksMeshComponent;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = true), Category = "Clothing")
|
||||
USkeletalMeshComponent* ShoesMeshComponent;
|
||||
|
||||
UPROPERTY()
|
||||
ANakedDesireCharacter* Player;
|
||||
|
||||
public:
|
||||
APlayerImpostor();
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
UFUNCTION()
|
||||
void OnClothingEquip(const UClothingItemData* ClothingData);
|
||||
|
||||
UFUNCTION()
|
||||
void OnClothingUnequip(const UClothingItemData* ClothingData);
|
||||
|
||||
USkeletalMeshComponent* GetMesh() const { return Mesh; };
|
||||
USkeletalMeshComponent* GetMeshByType(const EClothingSlotType SlotType) const;
|
||||
void EquipClothing(const UClothingItemData* ClothingData);
|
||||
void UnequipClothing(const UClothingItemData* ClothingData);
|
||||
};
|
||||
@@ -0,0 +1,42 @@
|
||||
// © 2025 Naked People Team. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "PrivateBodyPartType.generated.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Missions.BodyType"
|
||||
const FText BackBottom = LOCTEXT("BackBottom", "back bottom");
|
||||
const FText FrontBottom = LOCTEXT("FrontBottom", "front bottom");
|
||||
const FText FrontTop = LOCTEXT("FrontTop", "front top");
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EPrivateBodyPartType : uint8
|
||||
{
|
||||
FrontBottom = 0,
|
||||
BackBottom = 1,
|
||||
FrontTop = 2
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class UPrivateBodyPartType : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
static FText GetString(const EPrivateBodyPartType BodyType)
|
||||
{
|
||||
switch (BodyType)
|
||||
{
|
||||
case EPrivateBodyPartType::BackBottom:
|
||||
return BackBottom;
|
||||
case EPrivateBodyPartType::FrontBottom:
|
||||
return FrontBottom;
|
||||
case EPrivateBodyPartType::FrontTop:
|
||||
return FrontTop;
|
||||
default:
|
||||
return FText::GetEmpty();
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user