10 KiB
10 KiB
title, type, weight
| title | type | weight |
|---|---|---|
| Effets d'Entité | docs | 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
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
// 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é :
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
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
// 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
// Ajouter un effet qui n'expire jamais
controller.addInfiniteEffect(
entityRef,
EntityEffect.getAssetMap().getIndex(effect.getId()),
effect,
componentAccessor
);
Supprimer des Effets
// Supprimer un effet spécifique
controller.removeEffect(
entityRef,
EntityEffect.getAssetMap().getIndex(effect.getId()),
componentAccessor
);
Comportements de Superposition
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
// É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
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
public enum ValueType {
Absolute, // Ajouter/soustraire une valeur fixe
Percent // Multiplier par un pourcentage
}
Exemples Pratiques
Buff par Commande
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, pasaddArgument() - Utilisez
arg.get(ctx)pour récupérer les valeurs, pasctx.getArg() - Utilisez
ctx.sender()pasctx.getSender() - Utilisez
target.getUsername()pastarget.getName() - Utilisez
target.getReference()pour obtenir la référence d'entité (PlayerRef n'a pasgetPlayer()) {{< /callout >}}
Effet de Dégâts dans le Temps
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
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
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 :
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
EXTENDpour les buffs cumulables afin de récompenser l'application répétée - Utilisez
OVERWRITEpour les effets qui doivent réinitialiser leur durée - Utilisez
IGNOREpour 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 >}}