(Feat) Add Harvetable

This commit is contained in:
2026-08-16 19:35:27 +02:00
parent d6f46f32af
commit 2c272c11b9
41 changed files with 1759 additions and 71 deletions
+68 -2
View File
@@ -3,6 +3,12 @@
#pragma once
#include "CoreMinimal.h"
// FVector_NetQuantize / FVector_NetQuantizeNormal, dans la signature de
// Server_UseItem : un point d'impact au demi-centimetre pres et une direction
// deja normalisee tiennent en quelques octets la ou deux FVector pleins en
// coutent vingt-quatre, pour une precision dont personne ne verrait la difference
// sur un jet de copeaux.
#include "Engine/NetSerialization.h"
#include "GameFramework/Character.h"
#include "FpsPlayer.generated.h"
@@ -12,6 +18,7 @@ class UCameraComponent;
class UCharacterAppearanceComponent;
class UCraftingComponent;
class UFootstepComponent;
class UHarvestingComponent;
class UHeadBobComponent;
class UHeldItemComponent;
class UInputAction;
@@ -167,6 +174,9 @@ public:
UFUNCTION(BlueprintPure, Category = "Audio")
UFootstepComponent* GetFootstepComponent() const { return FootstepComponent; }
UFUNCTION(BlueprintPure, Category = "Harvesting")
UHarvestingComponent* GetHarvestingComponent() const { return HarvestingComponent; }
// ------------------------------------------------------------------
// Commandes console d'apparence
//
@@ -245,6 +255,23 @@ public:
UFUNCTION(BlueprintCallable, Category = "Inventaire")
void DropAllItems();
/**
* Donne un objet au joueur, et pose au sol ce qui ne rentre pas.
*
* Le chemin normal de tout ce que le monde produit : récolte, surplus de
* fabrication, futur butin. Refuser parce que l'inventaire est plein ferait
* disparaître ce que le joueur vient d'obtenir sous ses yeux — c'est le
* genre de perte silencieuse qui coûte une session de jeu.
*
* Passe par `AddItem`, donc exactement comme un ramassage : piles entamées
* d'abord, puis barre rapide, puis grille.
*
* @return le nombre d'exemplaires réellement entrés dans l'inventaire ; le
* reste est au sol.
*/
UFUNCTION(BlueprintCallable, Category = "Inventaire")
int32 GiveItemOrDrop(UItemDataAsset* Item, int32 Quantity, int32 RemainingUses = -1);
UFUNCTION(BlueprintPure, Category = "Survie")
bool IsDead() const { return bIsDead; }
@@ -472,6 +499,16 @@ protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Audio")
TObjectPtr<UFootstepComponent> FootstepComponent;
/**
* Le coup d'outil : trace du geste et recolte.
*
* Sur le pawn parce qu'il frappe avec CE corps, depuis CETTE camera, et qu'un
* cadavre ne recolte plus. Pendant exact d'UInteractionComponent, dont il
* partage le schema reseau -- voir son commentaire de classe.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Harvesting")
TObjectPtr<UHarvestingComponent> HarvestingComponent;
// ------------------------------------------------------------------
// Enhanced Input : assets à assigner dans le Blueprint
// ------------------------------------------------------------------
@@ -786,12 +823,34 @@ private:
* Le slot est passé explicitement : SelectedHotbarIndex n'est PAS répliqué,
* c'est une intention purement locale. Le serveur ne peut donc pas deviner
* ce que le joueur avait en main.
*
* La CIBLE aussi voyage, pour la même raison de fond : elle a été tracée
* depuis le point de vue réel du joueur à l'instant du geste. La retracer
* côté serveur la retracerait depuis une position qui a un demi-aller-retour
* de retard — un joueur en mouvement raterait des arbres qu'il vise pourtant
* en plein. Le serveur revalide la distance, il ne refait pas la visée.
*/
UFUNCTION(Server, Reliable)
void Server_UseItem(int32 SlotIndex);
void Server_UseItem(int32 SlotIndex, AActor* SwingTarget, FVector_NetQuantize ImpactPoint,
FVector_NetQuantizeNormal HitDirection);
/** L'utilisation réelle, côté autorité. */
void PerformUseItem(int32 SlotIndex);
void PerformUseItem(int32 SlotIndex, AActor* SwingTarget, const FVector& ImpactPoint,
const FVector& HitDirection);
/**
* Le coup d'outil côté autorité, une fois la cible validée.
*
* Séparée de `PerformUseItem` parce qu'elle porte une décision qui lui est
* propre : l'usure. Un coup qui ne porte pas — mauvais outil, souche, vide —
* ne consomme aucune charge, sinon taper un rocher à la hache l'abîmerait
* sans rien rendre.
*
* @param SlotIndex la case de l'outil, pour y prélever la charge. INDEX_NONE
* à mains nues.
*/
void PerformToolSwing(const UItemDataAsset* Tool, int32 SlotIndex, AActor* SwingTarget,
const FVector& ImpactPoint, const FVector& HitDirection);
/**
* Point d'entrée unique du sprint : applique en local ET prévient le serveur.
@@ -839,6 +898,13 @@ private:
UFUNCTION()
void HandleCraftOverflow(UItemDataAsset* Item, int32 Quantity, int32 RemainingUses);
/**
* Pose une pile aux pieds du joueur. Le fond commun de `HandleCraftOverflow`
* et de `GiveItemOrDrop` : deux copies finiraient par diverger, et l'une des
* deux oublierait le trace vers le sol.
*/
void DropAtFeet(UItemDataAsset* Item, int32 Quantity, int32 RemainingUses);
/** Fait apparaitre un pickup deja configure a un endroit donne. */
APickupItem* SpawnPickup(const struct FInventorySlot& Slot, const FVector& Location);