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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerState.h"
#include "CharacterAppearanceTypes.h"
#include "SurvivalPlayerState.generated.h"

/**
 * Ce que les AUTRES joueurs savent de toi : le pseudo, porte par APlayerState
 * lui-meme, et l'apparence du personnage.
 *
 * La regle de partage avec le pawn est simple : le PlayerState survit a la mort
 * du pawn, le pawn non. L'inventaire et les jauges restent donc sur le pawn,
 * puisque la regle du jeu veut qu'on perde tout au sol en mourant -- alors que
 * reapparaitre avec le visage de quelqu'un d'autre n'aurait aucun sens.
 *
 * C'est exactement pour cette raison que l'apparence est ici et non sur
 * AFpsPlayer : elle appartient au JOUEUR, pas au corps.
 */
UCLASS()
class EMBERWILD_API ASurvivalPlayerState : public APlayerState
{
	GENERATED_BODY()

public:
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

	UFUNCTION(BlueprintPure, Category = "Apparence")
	const FCharacterAppearance& GetCharacterAppearance() const { return CharacterAppearance; }

	/**
	 * A n'appeler que sur le SERVEUR : c'est lui qui fait autorite sur ce que
	 * les autres voient.
	 *
	 * Applique aussi en local dans la foulee, parce qu'un OnRep ne se declenche
	 * jamais sur la machine qui ecrit. Sans ce second appel, l'hote serait le
	 * seul a ne pas voir sa propre apparence -- le genre de bug qui ne se
	 * remarque qu'en testant a deux, et du mauvais cote.
	 */
	void SetCharacterAppearance(const FCharacterAppearance& InAppearance);

	/**
	 * Pousse l'apparence sur le pawn possede, s'il existe deja.
	 *
	 * Idempotente et appelee des DEUX cotes de la course : par l'OnRep quand
	 * l'apparence arrive avant le pawn, et par le pawn lui-meme a son BeginPlay
	 * quand c'est l'inverse. On ne sait pas lequel des deux gagne -- chez un
	 * client le pawn et le PlayerState arrivent par deux chemins de replication
	 * independants -- donc les deux doivent savoir se debrouiller seuls.
	 */
	void ApplyAppearanceToPawn();

protected:
	/**
	 * Repliquee a TOUT LE MONDE et pas au seul proprietaire : c'est justement
	 * ce que les autres doivent voir. Treize octets par joueur, envoyes une
	 * fois -- l'apparence ne change pas en cours de partie.
	 */
	UPROPERTY(ReplicatedUsing = OnRep_CharacterAppearance)
	FCharacterAppearance CharacterAppearance;

	UFUNCTION()
	void OnRep_CharacterAppearance();

	/**
	 * Le moteur engendre un NOUVEAU PlayerState a chaque voyage de map, et
	 * recopie l'ancien par ici. Sans cette surcharge, changer de carte remettrait
	 * tout le monde au visage par defaut.
	 */
	virtual void CopyProperties(APlayerState* PlayerState) override;
};
