119 lines
4.3 KiB
C++
119 lines
4.3 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "GameFramework/Actor.h"
|
|
#include "Interactable.h"
|
|
#include "PickupItem.generated.h"
|
|
|
|
class UItemDataAsset;
|
|
class USphereComponent;
|
|
class UStaticMeshComponent;
|
|
|
|
/**
|
|
* Un objet pose dans le monde. Il ne DECRIT pas l'objet, il ne fait que
|
|
* pointer vers son UItemDataAsset et porter une quantite.
|
|
*
|
|
* Consequence pratique : pour creer un nouveau type de ramassable, tu n'as
|
|
* plus besoin d'un Blueprint par objet. Un seul BP_Pickup suffit, tu changes
|
|
* juste l'ItemData sur chaque instance posee dans le niveau.
|
|
*/
|
|
UCLASS()
|
|
class SURVIVAL_PROJET_API APickupItem : public AActor, public IInteractable
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
APickupItem();
|
|
|
|
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
|
|
|
/**
|
|
* Configure un pickup engendre a l'execution (objet jete au sol).
|
|
* A appeler entre SpawnActorDeferred() et FinishSpawning() pour que
|
|
* OnConstruction ait deja les bonnes donnees et pose le bon mesh.
|
|
*
|
|
* A n'appeler que sur le SERVEUR : c'est lui qui engendre les acteurs du
|
|
* monde, les clients recoivent l'acteur deja configure par replication.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Item")
|
|
void InitPickup(UItemDataAsset* InItemData, int32 InQuantity, int32 InRemainingUses = -1);
|
|
|
|
// --- IInteractable ---
|
|
virtual FText GetInteractionPrompt_Implementation(AActor* Interactor) const override;
|
|
virtual bool CanInteract_Implementation(AActor* Interactor) const override;
|
|
virtual void Interact_Implementation(AActor* Interactor) override;
|
|
virtual void OnBeginFocus_Implementation() override;
|
|
virtual void OnEndFocus_Implementation() override;
|
|
|
|
protected:
|
|
/**
|
|
* Sans garde WITH_EDITOR : on veut aussi que le mesh se pose correctement
|
|
* sur les pickups engendres a l'execution quand on jette un objet.
|
|
*/
|
|
virtual void OnConstruction(const FTransform& Transform) override;
|
|
|
|
/** Visuel uniquement, sans collision. */
|
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Item")
|
|
TObjectPtr<UStaticMeshComponent> Mesh;
|
|
|
|
/**
|
|
* Volume que le trace d'interaction vient toucher.
|
|
* Volontairement separe du mesh : beaucoup de meshes d'asset packs,
|
|
* en particulier la vegetation, n'ont aucune geometrie de collision.
|
|
* Avec une sphere dediee, le pickup fonctionne quel que soit le visuel.
|
|
*/
|
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Item")
|
|
TObjectPtr<USphereComponent> InteractionSphere;
|
|
|
|
/**
|
|
* Quel objet ce pickup represente. A assigner sur chaque instance.
|
|
*
|
|
* ReplicatedUsing et non simplement Replicated : chez un client, l'acteur
|
|
* est construit AVANT que ses proprietes arrivent. OnConstruction s'execute
|
|
* donc avec ItemData a nullptr et ne pose aucun mesh -- l'objet resterait
|
|
* invisible pour tout le monde sauf l'hote. C'est OnRep qui repose le visuel
|
|
* au moment ou la donnee arrive vraiment.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing = OnRep_ItemData, Category = "Item")
|
|
TObjectPtr<UItemDataAsset> ItemData;
|
|
|
|
/**
|
|
* Combien d'exemplaires ce tas contient.
|
|
* Replique parce que le prompt l'affiche ("Ramasser Branche x3") et qu'un
|
|
* ramassage partiel, inventaire plein, le fait diminuer sous les yeux de tous.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "Item")
|
|
int32 Quantity = 1;
|
|
|
|
/**
|
|
* Charges restantes pour un objet a usages multiples.
|
|
* -1 = plein, ce qui est le cas de tout objet pose a la main dans le niveau.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "Item")
|
|
int32 RemainingUses = -1;
|
|
|
|
/** Repose le mesh quand la donnee de l'objet arrive chez un client. */
|
|
UFUNCTION()
|
|
void OnRep_ItemData();
|
|
|
|
/**
|
|
* Applique le visuel decrit par l'ItemData. Partage par OnConstruction et
|
|
* OnRep_ItemData : deux copies finiraient par diverger, et le symptome
|
|
* serait un objet correct dans l'editeur mais nu en jeu.
|
|
*/
|
|
void ApplyItemVisuals();
|
|
|
|
/**
|
|
* Reprend automatiquement le WorldMesh de l'ItemData dans l'editeur.
|
|
* Decoche pour imposer un mesh different sur une instance precise.
|
|
*/
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
|
|
bool bUseMeshFromItemData = true;
|
|
|
|
/** Active le Custom Depth quand l'objet est vise. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item")
|
|
bool bHighlightOnFocus = true;
|
|
};
|