260 lines
9.0 KiB
Markdown
260 lines
9.0 KiB
Markdown
---
|
|
title: Hiérarchie des Entités
|
|
type: docs
|
|
weight: 1
|
|
---
|
|
|
|
Hytale utilise une architecture **Entity Component System (ECS)**. Contrairement à la POO traditionnelle où les entités ont des méthodes directement sur elles, les entités Hytale sont composées de composants stockés dans un `EntityStore`.
|
|
|
|
{{< callout type="warning" >}}
|
|
**Architecture ECS:** Les classes d'entités comme `Player` et `LivingEntity` sont elles-mêmes des instances de `Component<EntityStore>`. Les données sont accessibles via la recherche de composants, pas via des appels de méthodes directs sur les entités.
|
|
{{< /callout >}}
|
|
|
|
## Aperçu de la Hiérarchie de Classes
|
|
|
|
{{< filetree/container >}}
|
|
{{< filetree/folder name="Entity (Component)" state="open" >}}
|
|
{{< filetree/folder name="LivingEntity" state="open" >}}
|
|
{{< filetree/file name="Player" >}}
|
|
{{< /filetree/folder >}}
|
|
{{< /filetree/folder >}}
|
|
{{< /filetree/container >}}
|
|
|
|
---
|
|
|
|
## Entity (Classe de Base)
|
|
|
|
**Package:** `com.hypixel.hytale.server.core.entity`
|
|
|
|
La classe de base pour toutes les entités. `Entity` implémente `Component<EntityStore>` - elle est stockée comme composant dans le système ECS.
|
|
|
|
### Méthodes Disponibles
|
|
|
|
| Méthode | Type de Retour | Description | Notes |
|
|
|---------|----------------|-------------|-------|
|
|
| `getWorld()` | `World` | Le monde où se trouve l'entité | |
|
|
| `getUuid()` | `UUID` | Identifiant unique | Dépréciée |
|
|
| `wasRemoved()` | `boolean` | Si l'entité a été supprimée | |
|
|
| `remove()` | `boolean` | Supprimer l'entité du monde | |
|
|
| `getNetworkId()` | `int` | ID réseau de l'entité | Dépréciée |
|
|
| `getTransformComponent()` | `TransformComponent` | Données de position/rotation | Dépréciée |
|
|
| `getReference()` | `Ref<EntityStore>` | Référence ECS | |
|
|
|
|
```java
|
|
// Exemple: Accéder aux données d'entité
|
|
Entity entity = ...; // obtenue depuis un événement ou une recherche
|
|
|
|
if (!entity.wasRemoved()) {
|
|
World world = entity.getWorld();
|
|
|
|
// Accès à la position (dépréciée mais fonctionne)
|
|
TransformComponent transform = entity.getTransformComponent();
|
|
Vector3d position = transform.getPosition();
|
|
|
|
// Référence ECS pour l'accès aux composants
|
|
Ref<EntityStore> ref = entity.getReference();
|
|
if (ref != null && ref.isValid()) {
|
|
Store<EntityStore> store = ref.getStore();
|
|
// Accéder à d'autres composants via le store
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## LivingEntity
|
|
|
|
**Package:** `com.hypixel.hytale.server.core.entity`
|
|
|
|
Étend Entity avec des capacités d'inventaire. Classe de base pour les entités qui peuvent porter des objets.
|
|
|
|
### Méthodes Disponibles
|
|
|
|
| Méthode | Type de Retour | Description |
|
|
|---------|----------------|-------------|
|
|
| `getInventory()` | `Inventory` | Inventaire de l'entité |
|
|
| `setInventory(Inventory)` | `Inventory` | Définir l'inventaire |
|
|
| `getCurrentFallDistance()` | `double` | Distance de chute actuelle |
|
|
| `getStatModifiersManager()` | `StatModifiersManager` | Modificateurs de stats |
|
|
|
|
```java
|
|
LivingEntity living = (LivingEntity) entity;
|
|
|
|
// Accès à l'inventaire
|
|
Inventory inventory = living.getInventory();
|
|
|
|
// Suivi de la distance de chute
|
|
double fallDistance = living.getCurrentFallDistance();
|
|
|
|
// Modificateurs de stats
|
|
StatModifiersManager stats = living.getStatModifiersManager();
|
|
```
|
|
|
|
{{< callout type="info" >}}
|
|
La santé, les dégâts et les effets sont gérés via le système ECS, pas directement sur LivingEntity. Voir [Composants d'Entité]({{< relref "entity-components" >}}) pour l'accès aux données basé sur les composants.
|
|
{{< /callout >}}
|
|
|
|
---
|
|
|
|
## Player
|
|
|
|
**Package:** `com.hypixel.hytale.server.core.entity.entities`
|
|
|
|
Étend LivingEntity avec des fonctionnalités spécifiques aux joueurs.
|
|
|
|
### Méthodes Disponibles
|
|
|
|
| Méthode | Type de Retour | Description |
|
|
|---------|----------------|-------------|
|
|
| `sendMessage(Message)` | `void` | Envoyer un message au joueur |
|
|
| `hasPermission(String)` | `boolean` | Vérifier une permission |
|
|
| `hasPermission(String, boolean)` | `boolean` | Vérifier avec valeur par défaut |
|
|
| `getDisplayName()` | `String` | Nom d'affichage du joueur |
|
|
| `getGameMode()` | `GameMode` | Mode de jeu actuel |
|
|
| `getInventory()` | `Inventory` | Inventaire du joueur |
|
|
| `getPlayerRef()` | `PlayerRef` | Référence thread-safe (dépréciée) |
|
|
| `getWindowManager()` | `WindowManager` | Gestion des fenêtres |
|
|
| `getPageManager()` | `PageManager` | Gestion des pages |
|
|
| `getHudManager()` | `HudManager` | Gestion du HUD |
|
|
| `getHotbarManager()` | `HotbarManager` | Gestion de la barre d'action |
|
|
|
|
```java
|
|
Player player = event.getPlayer();
|
|
|
|
if (player != null) {
|
|
// Envoyer des messages (nécessite un objet Message)
|
|
player.sendMessage(Message.raw("Bienvenue !"));
|
|
player.sendMessage(Message.translation("greeting.key")
|
|
.param("name", player.getDisplayName()));
|
|
|
|
// Vérifier les permissions
|
|
if (player.hasPermission("admin.teleport")) {
|
|
// A la permission
|
|
}
|
|
|
|
// Obtenir le nom d'affichage
|
|
String name = player.getDisplayName();
|
|
|
|
// Obtenir l'inventaire
|
|
Inventory inventory = player.getInventory();
|
|
|
|
// Obtenir la position via TransformComponent (dépréciée)
|
|
TransformComponent transform = player.getTransformComponent();
|
|
Vector3d position = transform.getPosition();
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## PlayerRef (Référence Thread-Safe)
|
|
|
|
**Package:** `com.hypixel.hytale.server.core.universe`
|
|
|
|
`PlayerRef` fournit un accès thread-safe aux données du joueur. Utilisez-le pour les opérations async ou pour stocker des références.
|
|
|
|
### Méthodes Disponibles
|
|
|
|
| Méthode | Type de Retour | Description |
|
|
|---------|----------------|-------------|
|
|
| `getUsername()` | `String` | Nom d'utilisateur du joueur |
|
|
| `getUuid()` | `UUID` | UUID du joueur |
|
|
| `getWorldUuid()` | `UUID` | UUID du monde actuel |
|
|
| `sendMessage(Message)` | `void` | Envoyer un message |
|
|
| `getReference()` | `Ref<EntityStore>` | Référence ECS (peut être null) |
|
|
| `getPacketHandler()` | `PacketHandler` | Gestionnaire réseau |
|
|
|
|
```java
|
|
// Obtenir PlayerRef depuis l'événement
|
|
PlayerRef playerRef = event.getPlayerRef();
|
|
|
|
// Accès thread-safe aux données du joueur
|
|
String username = playerRef.getUsername();
|
|
UUID uuid = playerRef.getUuid();
|
|
|
|
// Envoyer un message (thread-safe)
|
|
playerRef.sendMessage(Message.raw("Bonjour, " + username + " !"));
|
|
|
|
// Obtenir la référence ECS pour l'accès aux composants
|
|
Ref<EntityStore> ref = playerRef.getReference();
|
|
if (ref != null && ref.isValid()) {
|
|
Store<EntityStore> store = ref.getStore();
|
|
|
|
// Accéder au composant Player
|
|
Player player = store.getComponent(ref, Player.getComponentType());
|
|
|
|
// Accéder au TransformComponent pour la position
|
|
TransformComponent transform = store.getComponent(ref, TransformComponent.getComponentType());
|
|
if (transform != null) {
|
|
Vector3d position = transform.getPosition();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Pattern d'Accès aux Composants ECS
|
|
|
|
La bonne façon d'accéder aux données d'entité dans l'ECS de Hytale:
|
|
|
|
```java
|
|
getEventRegistry().register(PlayerConnectEvent.class, event -> {
|
|
PlayerRef playerRef = event.getPlayerRef();
|
|
|
|
// Obtenir la référence ECS
|
|
Ref<EntityStore> ref = playerRef.getReference();
|
|
if (ref == null || !ref.isValid()) {
|
|
return;
|
|
}
|
|
|
|
// Obtenir le store pour l'accès aux composants
|
|
Store<EntityStore> store = ref.getStore();
|
|
|
|
// Accéder à divers composants
|
|
Player player = store.getComponent(ref, Player.getComponentType());
|
|
TransformComponent transform = store.getComponent(ref, TransformComponent.getComponentType());
|
|
|
|
if (player != null && transform != null) {
|
|
Vector3d position = transform.getPosition();
|
|
player.sendMessage(Message.raw("Vous êtes à : " + position.toString()));
|
|
}
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Vérification de Type & Cast
|
|
|
|
Utilisez le pattern matching pour une vérification de type sûre:
|
|
|
|
```java
|
|
public void handleEntity(Entity entity) {
|
|
if (entity instanceof Player player) {
|
|
player.sendMessage(Message.raw("Vous êtes un joueur !"));
|
|
|
|
} else if (entity instanceof LivingEntity living) {
|
|
Inventory inv = living.getInventory();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Bonnes Pratiques
|
|
|
|
{{< callout type="info" >}}
|
|
**Directives de Gestion des Entités:**
|
|
- Toujours vérifier `wasRemoved()` avant d'utiliser des références d'entités stockées
|
|
- Utiliser `PlayerRef` pour stocker des références de joueurs entre les ticks
|
|
- Accéder à la position via `TransformComponent` (les méthodes dépréciées fonctionnent mais l'ECS est préféré)
|
|
- Vérifier `ref.isValid()` avant d'accéder aux composants ECS
|
|
{{< /callout >}}
|
|
|
|
{{< callout type="warning" >}}
|
|
**Sécurité des Threads:** Les objets Entity ne sont pas thread-safe. Utilisez `PlayerRef` pour les opérations async. Ne stockez jamais de références directes d'entités dans des structures de données à longue durée de vie sans nettoyage approprié.
|
|
{{< /callout >}}
|
|
|
|
{{< callout type="error" >}}
|
|
**Critique:** Ne stockez jamais de références `Entity` ou `Player` dans des champs statiques ou des maps sans nettoyage approprié. Utilisez les UUID et recherchez les entités quand nécessaire.
|
|
{{< /callout >}}
|
|
|