// Fill out your copyright notice in the Description page of Project Settings.


#include "SurvivalPlayerState.h"

#include "CharacterAppearanceComponent.h"
#include "FpsPlayer.h"
#include "Net/UnrealNetwork.h"

void ASurvivalPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	// Aucune condition : COND_OwnerOnly serait exactement le contraire de ce
	// qu'on veut. L'interet d'une apparence, c'est que les trois autres la
	// voient ; celle du proprietaire est la seule dont il pourrait se passer,
	// puisqu'il ne voit pas son propre corps en vue premiere personne.
	DOREPLIFETIME(ASurvivalPlayerState, CharacterAppearance);
}

void ASurvivalPlayerState::SetCharacterAppearance(const FCharacterAppearance& InAppearance)
{
	if (!HasAuthority())
	{
		UE_LOG(LogTemp, Warning, TEXT("ASurvivalPlayerState : SetCharacterAppearance appelee sans autorite, ignoree."));
		return;
	}

	// L'apparence n'est PAS validee ici, et c'est deliberé : borner un index
	// demande le catalogue, que seul UCharacterAppearanceComponent connait. Or
	// celui-ci passe deja tout ce qu'il monte par Catalog->Sanitize(), donc un
	// index aberrant venu du reseau est corrige au montage, sur chaque machine.
	// Dupliquer la validation ici demanderait de donner le catalogue au
	// PlayerState pour un resultat identique -- et cette coop entre amis n'a de
	// toute facon aucune anti-triche a faire respecter.
	CharacterAppearance = InAppearance;

	// Un OnRep ne se declenche jamais sur la machine qui ecrit la propriete.
	// Chez l'hote, qui est serveur ET client local, sans cette ligne son propre
	// personnage resterait au visage par defaut pendant que les autres le
	// verraient correctement.
	ApplyAppearanceToPawn();
}

void ASurvivalPlayerState::OnRep_CharacterAppearance()
{
	ApplyAppearanceToPawn();
}

void ASurvivalPlayerState::ApplyAppearanceToPawn()
{
	// Le pawn peut manquer, et ce n'est pas une erreur : chez un client, le
	// PlayerState et le pawn arrivent par deux chemins de replication
	// independants, dans un ordre qu'on ne controle pas. Quand c'est le
	// PlayerState qui gagne, on ne fait rien -- c'est le BeginPlay du pawn qui
	// viendra chercher l'apparence a son tour.
	if (AFpsPlayer* Player = Cast<AFpsPlayer>(GetPawn()))
	{
		if (UCharacterAppearanceComponent* Appearance = Player->GetAppearanceComponent())
		{
			Appearance->ApplyAppearance(CharacterAppearance);
		}
	}
}

void ASurvivalPlayerState::CopyProperties(APlayerState* PlayerState)
{
	Super::CopyProperties(PlayerState);

	if (ASurvivalPlayerState* SurvivalState = Cast<ASurvivalPlayerState>(PlayerState))
	{
		SurvivalState->CharacterAppearance = CharacterAppearance;
	}
}
