Init
This commit is contained in:
268
content/advanced/effects/dynamic-lights.en.md
Normal file
268
content/advanced/effects/dynamic-lights.en.md
Normal file
@@ -0,0 +1,268 @@
|
||||
---
|
||||
title: Dynamic Lights
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Dynamic lights add glow effects to entities using the `DynamicLight` component.
|
||||
|
||||
## ColorLight Structure
|
||||
|
||||
The `ColorLight` class defines light properties:
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.protocol.ColorLight;
|
||||
|
||||
public class ColorLight {
|
||||
public byte radius; // 0-255 (light radius/intensity)
|
||||
public byte red; // 0-255 (red channel)
|
||||
public byte green; // 0-255 (green channel)
|
||||
public byte blue; // 0-255 (blue channel)
|
||||
|
||||
public ColorLight(byte radius, byte red, byte green, byte blue) {
|
||||
this.radius = radius;
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## DynamicLight Component
|
||||
|
||||
Add temporary glow effects to entities:
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.modules.entity.component.DynamicLight;
|
||||
import com.hypixel.hytale.protocol.ColorLight;
|
||||
|
||||
// Create colored light (radius, R, G, B)
|
||||
ColorLight light = new ColorLight(
|
||||
(byte) 15, // Radius (0-255)
|
||||
(byte) 255, // Red (0-255)
|
||||
(byte) 100, // Green (0-255)
|
||||
(byte) 50 // Blue (0-255)
|
||||
);
|
||||
|
||||
// Add DynamicLight component
|
||||
DynamicLight dynamicLight = new DynamicLight(light);
|
||||
componentAccessor.putComponent(
|
||||
entityRef,
|
||||
DynamicLight.getComponentType(),
|
||||
dynamicLight
|
||||
);
|
||||
```
|
||||
|
||||
## PersistentDynamicLight Component
|
||||
|
||||
Use this component when light should be saved with entity data:
|
||||
|
||||
```java
|
||||
import com.hypixel.hytale.server.core.modules.entity.component.PersistentDynamicLight;
|
||||
|
||||
// Create persistent light
|
||||
PersistentDynamicLight persistentLight = new PersistentDynamicLight(light);
|
||||
componentAccessor.putComponent(
|
||||
entityRef,
|
||||
PersistentDynamicLight.getComponentType(),
|
||||
persistentLight
|
||||
);
|
||||
```
|
||||
|
||||
## Updating Light Properties
|
||||
|
||||
```java
|
||||
// Get existing light component
|
||||
DynamicLight dynamicLight = store.getComponent(
|
||||
entityRef,
|
||||
DynamicLight.getComponentType()
|
||||
);
|
||||
|
||||
if (dynamicLight != null) {
|
||||
// Create new light properties
|
||||
ColorLight newLight = new ColorLight(
|
||||
(byte) 20, // New radius
|
||||
(byte) 0, // No red
|
||||
(byte) 255, // Full green
|
||||
(byte) 100 // Some blue
|
||||
);
|
||||
|
||||
// Update and mark for network sync
|
||||
dynamicLight.setColorLight(newLight);
|
||||
// isNetworkOutdated is set automatically
|
||||
}
|
||||
```
|
||||
|
||||
## Removing Light
|
||||
|
||||
```java
|
||||
// Remove the component to disable light
|
||||
componentAccessor.removeComponent(
|
||||
entityRef,
|
||||
DynamicLight.getComponentType()
|
||||
);
|
||||
```
|
||||
|
||||
## Common Light Configurations
|
||||
|
||||
### Fire/Warm Glow
|
||||
|
||||
```java
|
||||
ColorLight fireLight = new ColorLight(
|
||||
(byte) 12,
|
||||
(byte) 255, // High red
|
||||
(byte) 150, // Medium orange
|
||||
(byte) 50 // Low blue
|
||||
);
|
||||
```
|
||||
|
||||
### Ice/Cold Glow
|
||||
|
||||
```java
|
||||
ColorLight iceLight = new ColorLight(
|
||||
(byte) 10,
|
||||
(byte) 100, // Low red
|
||||
(byte) 200, // Medium green
|
||||
(byte) 255 // High blue
|
||||
);
|
||||
```
|
||||
|
||||
### Magic/Purple Glow
|
||||
|
||||
```java
|
||||
ColorLight magicLight = new ColorLight(
|
||||
(byte) 15,
|
||||
(byte) 200, // High red
|
||||
(byte) 50, // Low green
|
||||
(byte) 255 // High blue
|
||||
);
|
||||
```
|
||||
|
||||
### Healing/Green Glow
|
||||
|
||||
```java
|
||||
ColorLight healLight = new ColorLight(
|
||||
(byte) 10,
|
||||
(byte) 50, // Low red
|
||||
(byte) 255, // High green
|
||||
(byte) 100 // Medium blue
|
||||
);
|
||||
```
|
||||
|
||||
## Practical Examples
|
||||
|
||||
### Adding a Glow Effect to a Player
|
||||
|
||||
```java
|
||||
// Add temporary glow effect to a player
|
||||
public void addGlowEffect(Player player, ComponentAccessor<EntityStore> componentAccessor,
|
||||
ScheduledExecutorService scheduler) {
|
||||
World world = player.getWorld();
|
||||
|
||||
// Add temporary glow
|
||||
ColorLight glow = new ColorLight(
|
||||
(byte) 8,
|
||||
(byte) 255,
|
||||
(byte) 215,
|
||||
(byte) 0 // Gold color
|
||||
);
|
||||
|
||||
DynamicLight light = new DynamicLight(glow);
|
||||
Ref<EntityStore> entityRef = player.getReference();
|
||||
componentAccessor.putComponent(
|
||||
entityRef,
|
||||
DynamicLight.getComponentType(),
|
||||
light
|
||||
);
|
||||
|
||||
// Remove after 3 seconds using standard Java scheduling
|
||||
scheduler.schedule(() -> {
|
||||
world.execute(() -> {
|
||||
if (entityRef.isValid()) {
|
||||
componentAccessor.removeComponent(
|
||||
entityRef,
|
||||
DynamicLight.getComponentType()
|
||||
);
|
||||
}
|
||||
});
|
||||
}, 3, TimeUnit.SECONDS);
|
||||
}
|
||||
```
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Note:** Use `player.getReference()` to get the entity reference, not `player.getEntityRef()`. Use standard Java `ScheduledExecutorService` for delayed tasks.
|
||||
{{< /callout >}}
|
||||
|
||||
### Pulsing Light Effect
|
||||
|
||||
Implement pulsing effects by updating the light in a tick handler:
|
||||
|
||||
```java
|
||||
// Track pulsing entities
|
||||
private final Map<Ref<EntityStore>, Integer> pulsingEntities = new ConcurrentHashMap<>();
|
||||
|
||||
// Call this method each tick
|
||||
public void onTick(float deltaTime) {
|
||||
for (Map.Entry<Ref<EntityStore>, Integer> entry : pulsingEntities.entrySet()) {
|
||||
Ref<EntityStore> entityRef = entry.getKey();
|
||||
int tick = entry.getValue() + 1;
|
||||
entry.setValue(tick);
|
||||
|
||||
// Calculate pulsing intensity
|
||||
double pulse = Math.sin(tick * 0.1) * 0.5 + 0.5;
|
||||
byte radius = (byte) (5 + pulse * 10);
|
||||
|
||||
ColorLight light = new ColorLight(
|
||||
radius,
|
||||
(byte) 255,
|
||||
(byte) (int)(100 + pulse * 100),
|
||||
(byte) 50
|
||||
);
|
||||
|
||||
DynamicLight dynamicLight = store.getComponent(
|
||||
entityRef,
|
||||
DynamicLight.getComponentType()
|
||||
);
|
||||
|
||||
if (dynamicLight != null) {
|
||||
dynamicLight.setColorLight(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startPulsingLight(Ref<EntityStore> entityRef) {
|
||||
pulsingEntities.put(entityRef, 0);
|
||||
}
|
||||
|
||||
public void stopPulsingLight(Ref<EntityStore> entityRef) {
|
||||
pulsingEntities.remove(entityRef);
|
||||
}
|
||||
```
|
||||
|
||||
## Network Synchronization
|
||||
|
||||
{{< callout type="info" >}}
|
||||
**Sync Details:**
|
||||
- `DynamicLight` changes are automatically marked for sync when using `setColorLight()`
|
||||
- The `isNetworkOutdated` flag triggers client updates
|
||||
- Use `consumeNetworkOutdated()` before manual sync operations
|
||||
{{< /callout >}}
|
||||
|
||||
## DynamicLight vs PersistentDynamicLight
|
||||
|
||||
| Feature | DynamicLight | PersistentDynamicLight |
|
||||
|---------|--------------|------------------------|
|
||||
| Saved to disk | No | Yes |
|
||||
| Survives restart | No | Yes |
|
||||
| Use case | Temporary effects | Permanent glows |
|
||||
| Performance | Lighter | Slightly heavier |
|
||||
|
||||
## Best Practices
|
||||
|
||||
{{< callout type="warning" >}}
|
||||
**Light Guidelines:**
|
||||
- Keep radius values reasonable (5-20 for most effects)
|
||||
- Don't add lights to too many entities simultaneously
|
||||
- Remove temporary lights when no longer needed
|
||||
- Use `PersistentDynamicLight` only when persistence is required
|
||||
{{< /callout >}}
|
||||
Reference in New Issue
Block a user