HyCodeYourTale

ECS Events

ECS Events

ECS eventy vyžadují speciální způsob registrace pomocí EntityEventSystem. Nelze je registrovat běžným způsobem přes register().

---

Důležité: Způsob registrace

ECS eventy NEFUNGUJÍ s běžnou registrací:

// ŠPATNĚ - Toto nebude fungovat!
getEventRegistry().register(BreakBlockEvent.class, event -> {
// Nikdy se nezavolá
});

// SPRÁVNĚ - Použij EntityEventSystem
public class MyBlockSystem extends EntityEventSystem {
// ...
}
getEntityStoreRegistry().registerSystem(new MyBlockSystem());

---

BreakBlockEvent

Vyvolán když hráč rozbije blok.

Typ: ECS Event
Registrace: EntityEventSystem
Cancellable: Ano

public class BlockBreakSystem extends EntityEventSystem {

public BlockBreakSystem() {
super(BreakBlockEvent.class);
}

@Override
public void handle(
int i,
@Nonnull ArchetypeChunk chunk,
@Nonnull Store store,
@Nonnull CommandBuffer commandBuffer,
@Nonnull BreakBlockEvent event
) {
// DŮLEŽITÉ: Přeskoč prázdné bloky!
// BreakBlockEvent se vyvolá i pro vzduch
if (event.getBlockType() == BlockType.EMPTY) return;

// Získej referenci na entitu
Ref ref = chunk.getReferenceTo(i);

// Bezpečný přístup ke komponentům - EntityEventSystem zajišťuje správný thread
Player player = store.getComponent(ref, Player.getComponentType());

if (player == null) return;

// Informace o rozbitém bloku
BlockType blockType = event.getBlockType();
String blockId = blockType.getId();

player.sendMessage(Message.raw("Rozbil jsi: " + blockId));

// Zrušení rozbití bloku
// event.cancel();
}

@Nullable
@Override
public Query getQuery() {
// Filtruj pouze entity s PlayerRef komponentou
return PlayerRef.getComponentType();
}
}

// Registrace v setup()
@Override
protected void setup() {
getEntityStoreRegistry().registerSystem(new BlockBreakSystem());
}

Dostupné metody:
| Metoda | Návratový typ | Popis |
|--------|---------------|-------|
| getBlockType() | BlockType | Typ rozbitého bloku |
| getTargetBlock() | BlockPos | Pozice bloku |
| getItemInHand() | ItemStack | Nástroj v ruce |
| cancel() | void | Zruší rozbití |

Důležité: Event se vyvolá i pro prázdné bloky (vzduch). Vždy kontroluj:

if (event.getBlockType() == BlockType.EMPTY) return;

---

PlaceBlockEvent

Vyvolán když hráč položí blok.

Typ: ECS Event
Registrace: EntityEventSystem
Cancellable: Ano

public class BlockPlaceSystem extends EntityEventSystem {

public BlockPlaceSystem() {
super(PlaceBlockEvent.class);
}

@Override
public void handle(
int i,
@Nonnull ArchetypeChunk chunk,
@Nonnull Store store,
@Nonnull CommandBuffer commandBuffer,
@Nonnull PlaceBlockEvent event
) {
Ref ref = chunk.getReferenceTo(i);
Player player = store.getComponent(ref, Player.getComponentType());

if (player != null) {
player.sendMessage(Message.raw("Položil jsi blok"));
}
}

@Nullable
@Override
public Query getQuery() {
return PlayerRef.getComponentType();
}
}

---

UseBlockEvent

Vyvolán když hráč použije blok (pravé tlačítko).

Typ: ECS Event
Registrace: EntityEventSystem
Cancellable: Ano

public class BlockUseSystem extends EntityEventSystem {

public BlockUseSystem() {
super(UseBlockEvent.class);
}

@Override
public void handle(
int i,
@Nonnull ArchetypeChunk chunk,
@Nonnull Store store,
@Nonnull CommandBuffer commandBuffer,
@Nonnull UseBlockEvent event
) {
Ref ref = chunk.getReferenceTo(i);
Player player = store.getComponent(ref, Player.getComponentType());

if (player != null) {
// Zpracování použití bloku (truhla, dveře, atd.)
}
}

@Nullable
@Override
public Query getQuery() {
return PlayerRef.getComponentType();
}
}

---

DamageBlockEvent

Vyvolán když hráč poškodí blok (během rozbíjení).

Typ: ECS Event
Registrace: EntityEventSystem
Cancellable: Ano

public class BlockDamageSystem extends EntityEventSystem {

public BlockDamageSystem() {
super(DamageBlockEvent.class);
}

@Override
public void handle(
int i,
@Nonnull ArchetypeChunk chunk,
@Nonnull Store store,
@Nonnull CommandBuffer commandBuffer,
@Nonnull DamageBlockEvent event
) {
// Zpracování poškození bloku
}

@Nullable
@Override
public Query getQuery() {
return PlayerRef.getComponentType();
}
}

---

DamageEvent

Vyvolán když entita obdrží poškození.

Typ: ECS Event
Registrace: EntityEventSystem
Cancellable: Ano
Závislost: Vyžaduje Hytale:DamageModule

public class DamageSystem extends EntityEventSystem {

public DamageSystem() {
super(DamageEvent.class);
}

@Override
public void handle(
int i,
@Nonnull ArchetypeChunk chunk,
@Nonnull Store store,
@Nonnull CommandBuffer commandBuffer,
@Nonnull DamageEvent event
) {
Ref ref = chunk.getReferenceTo(i);
Player player = store.getComponent(ref, Player.getComponentType());

if (player != null) {
// Hráč obdržel poškození
player.sendMessage(Message.raw("Obdržel jsi poškození!"));
}
}

@Nullable
@Override
public Query getQuery() {
return PlayerRef.getComponentType();
}
}

manifest.json - Závislost:

{
"Dependencies": {
"Hytale:DamageModule": "*"
}
}

---

DeathEvent

Vyvolán když hráč nebo entita zemře.

Typ: ECS Event
Registrace: EntityEventSystem
Cancellable: Ne
Závislost: Vyžaduje Hytale:DamageModule

public class DeathSystem extends EntityEventSystem {

public DeathSystem() {
super(DeathEvent.class);
}

@Override
public void handle(
int i,
@Nonnull ArchetypeChunk chunk,
@Nonnull Store store,
@Nonnull CommandBuffer commandBuffer,
@Nonnull DeathEvent event
) {
Ref ref = chunk.getReferenceTo(i);
Player player = store.getComponent(ref, Player.getComponentType());

if (player != null) {
player.sendMessage(Message.raw("Zemřel jsi!"));

// Logování smrti
getLogger().atInfo().log("Hráč " + player.getName() + " zemřel");
}
}

@Nullable
@Override
public Query getQuery() {
return PlayerRef.getComponentType();
}
}

manifest.json - Závislost:

{
"Dependencies": {
"Hytale:DamageModule": "*"
}
}

---

EntityRemoveEvent

Vyvolán když je entita odstraněna ze světa.

Typ: ECS Event
Registrace: EntityEventSystem
Cancellable: Ne

public class EntityRemoveSystem extends EntityEventSystem {

public EntityRemoveSystem() {
super(EntityRemoveEvent.class);
}

@Override
public void handle(
int i,
@Nonnull ArchetypeChunk chunk,
@Nonnull Store store,
@Nonnull CommandBuffer commandBuffer,
@Nonnull EntityRemoveEvent event
) {
// Entita byla odstraněna
}

@Nullable
@Override
public Query getQuery() {
return null; // Všechny entity
}
}

---

Anatomie EntityEventSystem

public class MySystem extends EntityEventSystem {

// Konstruktor - předej třídu eventu
public MySystem() {
super(MyEvent.class);
}

// Hlavní handler
@Override
public void handle(
int i, // Index entity v chunku
@Nonnull ArchetypeChunk chunk, // Chunk s entitami
@Nonnull Store store, // ECS store
@Nonnull CommandBuffer buffer, // Pro modifikace
@Nonnull MyEvent event // Event data
) {
// Získej referenci na entitu
Ref ref = chunk.getReferenceTo(i);

// Přístup ke komponentům (bezpečné - jsme na správném threadu)
Player player = store.getComponent(ref, Player.getComponentType());
CustomComponent custom = store.getComponent(ref, CustomComponent.getComponentType());

// Modifikace přes CommandBuffer
// buffer.addComponent(ref, newComponent);
// buffer.removeComponent(ref, componentType);
}

// Query filtruje které entity dostanou event
@Nullable
@Override
public Query getQuery() {
// Pouze entity s PlayerRef komponentou
return PlayerRef.getComponentType();

// Pro všechny entity:
// return null;

// Složitější query:
// return Query.and(PlayerRef.getComponentType(), CustomComponent.getComponentType());
}
}

---

Shrnutí ECS Eventů

| Event | Cancellable | Závislost |
|-------|-------------|-----------|
| BreakBlockEvent | Ano | - |
| PlaceBlockEvent | Ano | - |
| UseBlockEvent | Ano | - |
| DamageBlockEvent | Ano | - |
| DamageEvent | Ano | DamageModule |
| DeathEvent | Ne | DamageModule |
| EntityRemoveEvent | Ne | - |

---

Registrace více systémů

@Override
protected void setup() {
// Registruj všechny ECS systémy
getEntityStoreRegistry().registerSystem(new BlockBreakSystem());
getEntityStoreRegistry().registerSystem(new BlockPlaceSystem());
getEntityStoreRegistry().registerSystem(new DeathSystem());
getEntityStoreRegistry().registerSystem(new DamageSystem());
}

---

Thread Safety

ECS eventy jsou automaticky zpracovány na správném world threadu. Uvnitř handle() metody:

  • Přístup ke komponentům je bezpečný

  • Není potřeba world.execute()

  • Modifikace provádíš přes CommandBuffer

Last updated: 20. ledna 2026