Effects & Buffs
Dokumentace k efektům a buffům v Hytale.
Obsah
| Soubor | Popis |
|--------|-------|
| EFFECT_TYPES.md | EntityEffect, ActiveEntityEffect, OverlapBehavior, RemovalBehavior |
| APPLYING_EFFECTS.md | EffectControllerComponent, aplikace a odebrání efektů |
---
Přehled
Efekty jsou spravovány přes EffectControllerComponent - ECS komponentu která drží aktivní efekty na entitě.
---
EffectControllerComponent
Z dekompilovaného kódu - komponenta pro správu efektů:
// Získání effect controlleru
EffectControllerComponent effects = store.getComponent(
ref,
EffectControllerComponent.getComponentType()
);if (effects != null) {
// Práce s efekty
}
---
Typy Efektů (Koncept)
| Kategorie | Příklady |
|-----------|----------|
| Buff | Speed, Strength, Resistance |
| Debuff | Slowness, Weakness, Poison |
| Neutral | Invisibility, Night Vision |
| Special | Fire, Freezing |
---
Aplikace Efektu
public void applyEffect(Player player, String effectId, int duration, int level) {
World world = player.getWorld(); world.execute(() -> {
Ref ref = player.getRef();
Store store = ref.getStore();
EffectControllerComponent effects = store.getComponent(
ref,
EffectControllerComponent.getComponentType()
);
if (effects != null) {
// Aplikuj efekt
// effects.addEffect(effectId, duration, level);
}
});
}
---
Odebrání Efektu
public void removeEffect(Player player, String effectId) {
World world = player.getWorld(); world.execute(() -> {
Ref ref = player.getRef();
Store store = ref.getStore();
EffectControllerComponent effects = store.getComponent(
ref,
EffectControllerComponent.getComponentType()
);
if (effects != null) {
// Odeber efekt
// effects.removeEffect(effectId);
}
});
}
---
Kontrola Aktivního Efektu
public boolean hasEffect(Player player, String effectId) {
Ref ref = player.getRef();
Store store = ref.getStore(); EffectControllerComponent effects = store.getComponent(
ref,
EffectControllerComponent.getComponentType()
);
if (effects != null) {
// return effects.hasEffect(effectId);
}
return false;
}
---
Effect Definice (Assets)
Efekty mohou být definovány v assets:
{
"Id": "speed",
"Name": "Speed",
"Type": "Buff",
"Icon": "effect_speed.png",
"Color": "#7CAFC2",
"Modifiers": [
{
"Attribute": "MovementSpeed",
"Operation": "Multiply",
"ValuePerLevel": 0.2
}
],
"Particles": "speed_particles",
"Sound": "effect_applied"
}
---
Vizuální Efekty
ComponentUpdateType
Z dekompilovaného kódu:
| Typ | Popis |
|-----|-------|
| EntityEffects | Aktivní efekty na entitě |
| DynamicLight | Dynamické osvětlení |
| ActiveAnimations | Aktivní animace |
---
Příkaz pro Efekty
public class EffectCommand extends AbstractPlayerCommand { private final RequiredArg effectArg =
withRequiredArg("effect", "desc", ArgTypes.STRING);
private final DefaultArg durationArg =
withDefaultArg("duration", "desc", ArgTypes.INTEGER, 30, "30");
private final DefaultArg levelArg =
withDefaultArg("level", "desc", ArgTypes.INTEGER, 1, "1");
public EffectCommand() {
super("effect", "myplugin.commands.effect.desc");
requirePermission(HytalePermissions.of("myplugin.effect"));
}
@Override
protected void execute(CommandContext context, Store store,
Ref ref, PlayerRef playerRef, World world) {
String effectId = effectArg.get(context);
int duration = durationArg.get(context);
int level = levelArg.get(context);
// Aplikuj efekt
applyEffect(ref, store, effectId, duration, level);
context.sendMessage(
Message.raw("Aplikován efekt: " + effectId +
" (level " + level + ", " + duration + "s)")
);
}
private void applyEffect(Ref ref, Store store,
String effectId, int duration, int level) {
EffectControllerComponent effects = store.getComponent(
ref,
EffectControllerComponent.getComponentType()
);
if (effects != null) {
// effects.addEffect(effectId, duration * 20, level); // ticks
}
}
}
---
Knockback
KnockbackComponent
// Knockback je komponenta pro fyziku odhození
KnockbackComponent knockback = store.getComponent(
ref,
KnockbackComponent.getComponentType()
);
---
Movement States
MovementStatesComponent
// Stav pohybu entity (běh, chůze, plavání, létání...)
MovementStatesComponent movement = store.getComponent(
ref,
MovementStatesComponent.getComponentType()
);
---
Vlastní Effect Systém
Pokud potřebuješ vlastní effect systém:
public class CustomEffect implements Component {
private final String effectId;
private final long startTime;
private final int duration; // v tickech
private final int level; public CustomEffect(String effectId, int duration, int level) {
this.effectId = effectId;
this.startTime = System.currentTimeMillis();
this.duration = duration;
this.level = level;
}
public boolean isExpired() {
long elapsed = System.currentTimeMillis() - startTime;
return elapsed >= (duration * 50); // 50ms per tick
}
public String getEffectId() { return effectId; }
public int getLevel() { return level; }
@Override
public Component clone() {
return new CustomEffect(effectId, duration, level);
}
}
Effect Manager
public class EffectManager { private final Map> playerEffects = new ConcurrentHashMap<>();
public void addEffect(UUID playerId, String effectId, int duration, int level) {
playerEffects.computeIfAbsent(playerId, k -> new CopyOnWriteArrayList<>())
.add(new CustomEffect(effectId, duration, level));
}
public void removeExpiredEffects() {
for (List effects : playerEffects.values()) {
effects.removeIf(CustomEffect::isExpired);
}
}
public boolean hasEffect(UUID playerId, String effectId) {
List effects = playerEffects.get(playerId);
if (effects == null) return false;
return effects.stream()
.anyMatch(e -> e.getEffectId().equals(effectId) && !e.isExpired());
}
}
---
Shrnutí
| Komponenta | Popis |
|------------|-------|
| EffectControllerComponent | Správa efektů |
| KnockbackComponent | Knockback fyzika |
| MovementStatesComponent | Stav pohybu |
| Operace | Poznámka |
|---------|----------|
| Přidání efektu | Přes EffectControllerComponent |
| Odebrání efektu | Přes EffectControllerComponent |
| Kontrola efektu | Přes EffectControllerComponent |
| Vlastní systém | Implementuj vlastní Component |