Init
This commit is contained in:
369
content/advanced/effects/entity-effects.fr.md
Normal file
369
content/advanced/effects/entity-effects.fr.md
Normal file
@@ -0,0 +1,369 @@
|
||||
---
|
||||
title: Effets d'Entité
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Les effets d'entité sont des effets de statut qui peuvent inclure des composants visuels, des modificateurs de stats et des comportements basés sur la durée.
|
||||
|
||||
## Configuration EntityEffect
|
||||
|
||||
```java
|
||||
public class EntityEffect {
|
||||
protected String id;
|
||||
protected String name; // Clé de localisation
|
||||
|
||||
protected ApplicationEffects applicationEffects; // Effets visuels/audio
|
||||
|
||||
protected String modelChange; // Changer le modèle de l'entité
|
||||
protected float duration; // Durée par défaut (secondes)
|
||||
|
||||
protected boolean infinite; // N'expire jamais ?
|
||||
protected boolean debuff; // Est un effet négatif ?
|
||||
protected String statusEffectIcon; // Icône UI
|
||||
|
||||
// Dégâts et stats
|
||||
protected Int2FloatMap entityStats; // Modificateurs de stats
|
||||
protected ValueType valueType; // Absolute ou Percent
|
||||
|
||||
// Comportement
|
||||
protected OverlapBehavior overlapBehavior; // EXTEND, OVERWRITE, IGNORE
|
||||
protected RemovalBehavior removalBehavior; // COMPLETE, DURATION, INFINITE
|
||||
|
||||
protected boolean invulnerable; // Accorder l'invulnérabilité
|
||||
}
|
||||
```
|
||||
|
||||
## Accéder aux Assets d'Effets
|
||||
|
||||
```java
|
||||
// Obtenir un effet par ID
|
||||
EntityEffect effect = EntityEffect.getAssetMap().getAsset("fire_resistance");
|
||||
|
||||
// Obtenir l'index de l'effet pour les opérations
|
||||
int effectIndex = EntityEffect.getAssetMap().getIndex(effect.getId());
|
||||
```
|
||||
|
||||
## EffectControllerComponent
|
||||
|
||||
Le `EffectControllerComponent` gère les effets actifs sur une entité :
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.entity.effect.EffectControllerComponent;
|
||||
|
||||
// Obtenir le contrôleur d'effets de l'entité
|
||||
EffectControllerComponent controller = store.getComponent(
|
||||
entityRef,
|
||||
EffectControllerComponent.getComponentType()
|
||||
);
|
||||
```
|
||||
|
||||
## Ajouter des Effets
|
||||
|
||||
### Ajout Basique
|
||||
|
||||
```java
|
||||
EntityEffect effect = EntityEffect.getAssetMap().getAsset("speed_boost");
|
||||
|
||||
// Ajouter avec les paramètres par défaut
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
effect,
|
||||
componentAccessor
|
||||
);
|
||||
```
|
||||
|
||||
### Avec Durée Personnalisée
|
||||
|
||||
```java
|
||||
// Ajouter avec durée personnalisée et comportement de superposition
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
effect,
|
||||
100.0f, // Durée en secondes
|
||||
OverlapBehavior.EXTEND, // Comment gérer la superposition
|
||||
componentAccessor
|
||||
);
|
||||
```
|
||||
|
||||
### Effets Infinis
|
||||
|
||||
```java
|
||||
// Ajouter un effet qui n'expire jamais
|
||||
controller.addInfiniteEffect(
|
||||
entityRef,
|
||||
EntityEffect.getAssetMap().getIndex(effect.getId()),
|
||||
effect,
|
||||
componentAccessor
|
||||
);
|
||||
```
|
||||
|
||||
## Supprimer des Effets
|
||||
|
||||
```java
|
||||
// Supprimer un effet spécifique
|
||||
controller.removeEffect(
|
||||
entityRef,
|
||||
EntityEffect.getAssetMap().getIndex(effect.getId()),
|
||||
componentAccessor
|
||||
);
|
||||
```
|
||||
|
||||
## Comportements de Superposition
|
||||
|
||||
```java
|
||||
public enum OverlapBehavior {
|
||||
EXTEND, // Ajouter la durée à l'effet existant
|
||||
OVERWRITE, // Remplacer l'effet existant
|
||||
IGNORE // Ne pas appliquer si déjà actif
|
||||
}
|
||||
```
|
||||
|
||||
### Exemples d'Utilisation
|
||||
|
||||
```java
|
||||
// Étendre la durée si déjà appliqué
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
effect,
|
||||
30.0f,
|
||||
OverlapBehavior.EXTEND,
|
||||
componentAccessor
|
||||
);
|
||||
|
||||
// Remplacer avec une durée fraîche
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
effect,
|
||||
30.0f,
|
||||
OverlapBehavior.OVERWRITE,
|
||||
componentAccessor
|
||||
);
|
||||
|
||||
// Appliquer seulement si pas déjà actif
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
effect,
|
||||
30.0f,
|
||||
OverlapBehavior.IGNORE,
|
||||
componentAccessor
|
||||
);
|
||||
```
|
||||
|
||||
## Comportements de Suppression
|
||||
|
||||
```java
|
||||
public enum RemovalBehavior {
|
||||
COMPLETE, // Supprimer quand terminé
|
||||
DURATION, // Supprimer après la durée
|
||||
INFINITE // Ne jamais supprimer automatiquement
|
||||
}
|
||||
```
|
||||
|
||||
## Types de Valeurs pour les Stats
|
||||
|
||||
```java
|
||||
public enum ValueType {
|
||||
Absolute, // Ajouter/soustraire une valeur fixe
|
||||
Percent // Multiplier par un pourcentage
|
||||
}
|
||||
```
|
||||
|
||||
## Exemples Pratiques
|
||||
|
||||
### Buff par Commande
|
||||
|
||||
```java
|
||||
public class BuffCommand extends AbstractCommand {
|
||||
private final RequiredArg<PlayerRef> playerArg;
|
||||
private final RequiredArg<String> effectArg;
|
||||
private final RequiredArg<Integer> durationArg;
|
||||
|
||||
// Serait défini lors de l'initialisation du plugin
|
||||
private Store<EntityStore> store;
|
||||
private ComponentAccessor<EntityStore> componentAccessor;
|
||||
|
||||
public BuffCommand() {
|
||||
super("buff", "effects.command.buff.description");
|
||||
this.playerArg = withRequiredArg("player", "Joueur cible", ArgTypes.PLAYER_REF);
|
||||
this.effectArg = withRequiredArg("effect", "ID de l'effet", ArgTypes.STRING);
|
||||
this.durationArg = withRequiredArg("duration", "Durée en secondes", ArgTypes.INTEGER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Void> execute(CommandContext ctx) {
|
||||
PlayerRef target = playerArg.get(ctx);
|
||||
String effectId = effectArg.get(ctx);
|
||||
int duration = durationArg.get(ctx);
|
||||
|
||||
Ref<EntityStore> entityRef = target.getReference();
|
||||
if (entityRef == null || !entityRef.isValid()) {
|
||||
ctx.sender().sendMessage(Message.raw("Joueur non trouvé"));
|
||||
return null;
|
||||
}
|
||||
|
||||
EntityEffect effect = EntityEffect.getAssetMap().getAsset(effectId);
|
||||
if (effect == null) {
|
||||
ctx.sender().sendMessage(Message.raw("Effet inconnu : " + effectId));
|
||||
return null;
|
||||
}
|
||||
|
||||
EffectControllerComponent controller = store.getComponent(
|
||||
entityRef,
|
||||
EffectControllerComponent.getComponentType()
|
||||
);
|
||||
|
||||
if (controller != null) {
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
effect,
|
||||
(float) duration,
|
||||
OverlapBehavior.EXTEND,
|
||||
componentAccessor
|
||||
);
|
||||
}
|
||||
|
||||
ctx.sender().sendMessage(Message.raw("Appliqué " + effectId + " à " + target.getUsername()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Notes API :**
|
||||
- Utilisez `withRequiredArg()` pour définir les arguments, pas `addArgument()`
|
||||
- Utilisez `arg.get(ctx)` pour récupérer les valeurs, pas `ctx.getArg()`
|
||||
- Utilisez `ctx.sender()` pas `ctx.getSender()`
|
||||
- Utilisez `target.getUsername()` pas `target.getName()`
|
||||
- Utilisez `target.getReference()` pour obtenir la référence d'entité (PlayerRef n'a pas `getPlayer()`)
|
||||
{{< /callout >}}
|
||||
|
||||
### Effet de Dégâts dans le Temps
|
||||
|
||||
```java
|
||||
public void applyPoison(Player player, float duration, Store<EntityStore> store,
|
||||
ComponentAccessor<EntityStore> componentAccessor) {
|
||||
EntityEffect poison = EntityEffect.getAssetMap().getAsset("poison");
|
||||
|
||||
Ref<EntityStore> entityRef = player.getReference();
|
||||
EffectControllerComponent controller = store.getComponent(
|
||||
entityRef,
|
||||
EffectControllerComponent.getComponentType()
|
||||
);
|
||||
|
||||
if (controller != null && poison != null) {
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
poison,
|
||||
duration,
|
||||
OverlapBehavior.EXTEND,
|
||||
componentAccessor
|
||||
);
|
||||
}
|
||||
|
||||
player.sendMessage(Message.raw("Vous avez été empoisonné !"));
|
||||
}
|
||||
```
|
||||
|
||||
### Invulnérabilité Temporaire
|
||||
|
||||
```java
|
||||
public void grantInvulnerability(Player player, float seconds, Store<EntityStore> store,
|
||||
ComponentAccessor<EntityStore> componentAccessor) {
|
||||
EntityEffect invuln = EntityEffect.getAssetMap().getAsset("invulnerability");
|
||||
|
||||
Ref<EntityStore> entityRef = player.getReference();
|
||||
EffectControllerComponent controller = store.getComponent(
|
||||
entityRef,
|
||||
EffectControllerComponent.getComponentType()
|
||||
);
|
||||
|
||||
if (controller != null && invuln != null) {
|
||||
controller.addEffect(
|
||||
entityRef,
|
||||
invuln,
|
||||
seconds,
|
||||
OverlapBehavior.OVERWRITE, // Durée fraîche
|
||||
componentAccessor
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Effacer Tous les Effets
|
||||
|
||||
```java
|
||||
public void clearAllEffects(Player player, Store<EntityStore> store,
|
||||
ComponentAccessor<EntityStore> componentAccessor) {
|
||||
Ref<EntityStore> entityRef = player.getReference();
|
||||
EffectControllerComponent controller = store.getComponent(
|
||||
entityRef,
|
||||
EffectControllerComponent.getComponentType()
|
||||
);
|
||||
|
||||
if (controller != null) {
|
||||
// Utiliser la méthode clearEffects intégrée
|
||||
controller.clearEffects(
|
||||
entityRef,
|
||||
componentAccessor
|
||||
);
|
||||
}
|
||||
|
||||
player.sendMessage(Message.raw("Tous les effets effacés !"));
|
||||
}
|
||||
```
|
||||
|
||||
## Combiner avec d'Autres Effets
|
||||
|
||||
Les effets d'entité fonctionnent bien avec les particules et les lumières dynamiques :
|
||||
|
||||
```java
|
||||
public void applyMagicBuff(Player player, Store<EntityStore> store,
|
||||
ComponentAccessor<EntityStore> componentAccessor) {
|
||||
Ref<EntityStore> entityRef = player.getReference();
|
||||
|
||||
// Appliquer l'effet de statut
|
||||
EntityEffect buff = EntityEffect.getAssetMap().getAsset("magic_power");
|
||||
EffectControllerComponent controller = store.getComponent(
|
||||
entityRef,
|
||||
EffectControllerComponent.getComponentType()
|
||||
);
|
||||
if (controller != null && buff != null) {
|
||||
controller.addEffect(entityRef, buff, componentAccessor);
|
||||
}
|
||||
|
||||
// Ajouter une lueur visuelle
|
||||
ColorLight glow = new ColorLight((byte) 10, (byte) 200, (byte) 50, (byte) 255);
|
||||
DynamicLight light = new DynamicLight(glow);
|
||||
componentAccessor.putComponent(
|
||||
entityRef,
|
||||
DynamicLight.getComponentType(),
|
||||
light
|
||||
);
|
||||
|
||||
// Obtenir la position via TransformComponent pour les particules
|
||||
TransformComponent transform = store.getComponent(entityRef, TransformComponent.getComponentType());
|
||||
if (transform != null) {
|
||||
ParticleUtil.spawnParticleEffect(
|
||||
"magic_aura",
|
||||
transform.getPosition(),
|
||||
componentAccessor
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Note :** Utilisez `player.getReference()` pour obtenir la référence d'entité. La position doit être obtenue via `TransformComponent`, pas directement depuis Player.
|
||||
{{< /callout >}}
|
||||
|
||||
## Bonnes Pratiques
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Directives pour les Effets :**
|
||||
- Utilisez `EXTEND` pour les buffs cumulables afin de récompenser l'application répétée
|
||||
- Utilisez `OVERWRITE` pour les effets qui doivent réinitialiser leur durée
|
||||
- Utilisez `IGNORE` pour empêcher l'empilement d'effets quand indésirable
|
||||
- Vérifiez toujours si l'effet existe avant de l'appliquer
|
||||
- Considérez les performances avec de nombreux effets simultanés
|
||||
{{< /callout >}}
|
||||
Reference in New Issue
Block a user