Init
This commit is contained in:
147
content/world/portals/_index.en.md
Normal file
147
content/world/portals/_index.en.md
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: Portals
|
||||
type: docs
|
||||
weight: 6
|
||||
---
|
||||
|
||||
The portals system provides mechanics for inter-dimensional travel between worlds, including portal devices, void events, and fragment instances.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals`
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Portals System
|
||||
├── Components
|
||||
│ ├── PortalDevice - Portal block component
|
||||
│ ├── VoidEvent - Void invasion event
|
||||
│ └── VoidSpawner - Void spawner entity
|
||||
├── Resources
|
||||
│ └── PortalWorld - Portal world data
|
||||
├── Interactions
|
||||
│ ├── EnterPortalInteraction - Enter portal
|
||||
│ └── ReturnPortalInteraction - Return from portal
|
||||
├── Systems
|
||||
│ ├── PortalTrackerSystems - UI tracking
|
||||
│ ├── PortalInvalidDestinationSystem - Destination validation
|
||||
│ ├── VoidEventStagesSystem - Void event progression
|
||||
│ └── VoidSpawnerSystems - Spawner management
|
||||
└── Commands
|
||||
├── FragmentCommands - Fragment management
|
||||
├── LeaveCommand - Leave portal world
|
||||
└── VoidEventCommands - Void event control
|
||||
```
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### Portal Device
|
||||
|
||||
A portal device is a block-based entity that can transport players to fragment worlds:
|
||||
|
||||
```java
|
||||
// PortalDevice is a ChunkStore component
|
||||
PortalDevice portal = BlockModule.get().getComponent(
|
||||
PortalDevice.getComponentType(),
|
||||
world, x, y, z
|
||||
);
|
||||
|
||||
// Get destination world
|
||||
World targetWorld = portal.getDestinationWorld();
|
||||
```
|
||||
|
||||
### Portal World
|
||||
|
||||
A portal world is a temporary instance created when players activate a portal:
|
||||
|
||||
```java
|
||||
// PortalWorld is an EntityStore resource
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
|
||||
// Check if this is a portal world
|
||||
if (portalWorld.exists()) {
|
||||
Transform spawn = portalWorld.getSpawnPoint();
|
||||
double remaining = portalWorld.getRemainingSeconds(world);
|
||||
}
|
||||
```
|
||||
|
||||
### Fragment Instances
|
||||
|
||||
Fragments are temporary worlds with:
|
||||
- Time limit before auto-closure
|
||||
- Spawn point for returning players
|
||||
- Death tracking (players who died cannot re-enter)
|
||||
- Optional void invasion events
|
||||
|
||||
## Key Features
|
||||
|
||||
### Portal States
|
||||
|
||||
Portals have three visual states:
|
||||
- **Off** - Portal is inactive
|
||||
- **Spawning** - Instance is being created
|
||||
- **On/Active** - Portal is ready for travel
|
||||
|
||||
### Time Limits
|
||||
|
||||
Portal worlds have configurable time limits:
|
||||
```java
|
||||
int totalTime = portalWorld.getTimeLimitSeconds();
|
||||
double elapsed = portalWorld.getElapsedSeconds(world);
|
||||
double remaining = portalWorld.getRemainingSeconds(world);
|
||||
```
|
||||
|
||||
### Death Tracking
|
||||
|
||||
Players who die in a portal world cannot re-enter:
|
||||
```java
|
||||
Set<UUID> deaths = portalWorld.getDiedInWorld();
|
||||
if (deaths.contains(playerUuid)) {
|
||||
// Player died here - show "DIED_IN_WORLD" state
|
||||
}
|
||||
```
|
||||
|
||||
### Cursed Items
|
||||
|
||||
Items can become "cursed" in portal worlds and are removed on death:
|
||||
```java
|
||||
// Uncurse items when returning
|
||||
CursedItems.uncurseAll(inventory.getCombinedEverything());
|
||||
```
|
||||
|
||||
## Plugin Access
|
||||
|
||||
```java
|
||||
PortalsPlugin portals = PortalsPlugin.getInstance();
|
||||
|
||||
// Component types
|
||||
ComponentType<ChunkStore, PortalDevice> portalDeviceType =
|
||||
portals.getPortalDeviceComponentType();
|
||||
ComponentType<EntityStore, VoidEvent> voidEventType =
|
||||
portals.getVoidEventComponentType();
|
||||
ComponentType<EntityStore, VoidSpawner> voidSpawnerType =
|
||||
portals.getVoidPortalComponentType();
|
||||
|
||||
// Resource type
|
||||
ResourceType<EntityStore, PortalWorld> portalWorldType =
|
||||
portals.getPortalResourceType();
|
||||
```
|
||||
|
||||
## Concurrent Fragments Limit
|
||||
|
||||
The system limits concurrent portal fragments:
|
||||
```java
|
||||
public static final int MAX_CONCURRENT_FRAGMENTS = 4;
|
||||
|
||||
int active = portals.countActiveFragments();
|
||||
if (active >= MAX_CONCURRENT_FRAGMENTS) {
|
||||
// Cannot create new fragments
|
||||
}
|
||||
```
|
||||
|
||||
## Related Topics
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="portal-components" title="Portal Components" subtitle="PortalDevice, VoidEvent components" >}}
|
||||
{{< card link="portal-systems" title="Portal Systems" subtitle="ECS systems for portal logic" >}}
|
||||
{{< card link="portal-commands" title="Portal Commands" subtitle="Admin and player commands" >}}
|
||||
{{< /cards >}}
|
||||
147
content/world/portals/_index.fr.md
Normal file
147
content/world/portals/_index.fr.md
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: Portails
|
||||
type: docs
|
||||
weight: 6
|
||||
---
|
||||
|
||||
Le systeme de portails fournit des mecaniques de voyage inter-dimensionnel entre les mondes, incluant les dispositifs de portail, les evenements du vide et les instances de fragment.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals`
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Systeme Portails
|
||||
├── Composants
|
||||
│ ├── PortalDevice - Composant bloc portail
|
||||
│ ├── VoidEvent - Evenement invasion du vide
|
||||
│ └── VoidSpawner - Entite spawner du vide
|
||||
├── Ressources
|
||||
│ └── PortalWorld - Donnees monde portail
|
||||
├── Interactions
|
||||
│ ├── EnterPortalInteraction - Entrer portail
|
||||
│ └── ReturnPortalInteraction - Retour du portail
|
||||
├── Systemes
|
||||
│ ├── PortalTrackerSystems - Suivi UI
|
||||
│ ├── PortalInvalidDestinationSystem - Validation destination
|
||||
│ ├── VoidEventStagesSystem - Progression evenement vide
|
||||
│ └── VoidSpawnerSystems - Gestion spawners
|
||||
└── Commandes
|
||||
├── FragmentCommands - Gestion fragments
|
||||
├── LeaveCommand - Quitter monde portail
|
||||
└── VoidEventCommands - Controle evenement vide
|
||||
```
|
||||
|
||||
## Concepts Cles
|
||||
|
||||
### Dispositif Portail
|
||||
|
||||
Un dispositif de portail est une entite basee sur un bloc qui peut transporter les joueurs vers des mondes fragments:
|
||||
|
||||
```java
|
||||
// PortalDevice est un composant ChunkStore
|
||||
PortalDevice portal = BlockModule.get().getComponent(
|
||||
PortalDevice.getComponentType(),
|
||||
world, x, y, z
|
||||
);
|
||||
|
||||
// Obtenir monde de destination
|
||||
World targetWorld = portal.getDestinationWorld();
|
||||
```
|
||||
|
||||
### Monde Portail
|
||||
|
||||
Un monde portail est une instance temporaire creee quand les joueurs activent un portail:
|
||||
|
||||
```java
|
||||
// PortalWorld est une ressource EntityStore
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
|
||||
// Verifier si c'est un monde portail
|
||||
if (portalWorld.exists()) {
|
||||
Transform spawn = portalWorld.getSpawnPoint();
|
||||
double remaining = portalWorld.getRemainingSeconds(world);
|
||||
}
|
||||
```
|
||||
|
||||
### Instances Fragment
|
||||
|
||||
Les fragments sont des mondes temporaires avec:
|
||||
- Limite de temps avant fermeture automatique
|
||||
- Point de spawn pour les joueurs revenant
|
||||
- Suivi des morts (les joueurs morts ne peuvent pas re-entrer)
|
||||
- Evenements d'invasion du vide optionnels
|
||||
|
||||
## Fonctionnalites Cles
|
||||
|
||||
### Etats du Portail
|
||||
|
||||
Les portails ont trois etats visuels:
|
||||
- **Eteint** - Portail inactif
|
||||
- **Invocation** - Instance en creation
|
||||
- **Actif** - Portail pret pour le voyage
|
||||
|
||||
### Limites de Temps
|
||||
|
||||
Les mondes portails ont des limites de temps configurables:
|
||||
```java
|
||||
int totalTime = portalWorld.getTimeLimitSeconds();
|
||||
double elapsed = portalWorld.getElapsedSeconds(world);
|
||||
double remaining = portalWorld.getRemainingSeconds(world);
|
||||
```
|
||||
|
||||
### Suivi des Morts
|
||||
|
||||
Les joueurs morts dans un monde portail ne peuvent pas re-entrer:
|
||||
```java
|
||||
Set<UUID> deaths = portalWorld.getDiedInWorld();
|
||||
if (deaths.contains(playerUuid)) {
|
||||
// Joueur mort ici - afficher etat "DIED_IN_WORLD"
|
||||
}
|
||||
```
|
||||
|
||||
### Items Maudits
|
||||
|
||||
Les items peuvent devenir "maudits" dans les mondes portails et sont retires a la mort:
|
||||
```java
|
||||
// Retirer malediction des items au retour
|
||||
CursedItems.uncurseAll(inventory.getCombinedEverything());
|
||||
```
|
||||
|
||||
## Acces au Plugin
|
||||
|
||||
```java
|
||||
PortalsPlugin portals = PortalsPlugin.getInstance();
|
||||
|
||||
// Types de composants
|
||||
ComponentType<ChunkStore, PortalDevice> portalDeviceType =
|
||||
portals.getPortalDeviceComponentType();
|
||||
ComponentType<EntityStore, VoidEvent> voidEventType =
|
||||
portals.getVoidEventComponentType();
|
||||
ComponentType<EntityStore, VoidSpawner> voidSpawnerType =
|
||||
portals.getVoidPortalComponentType();
|
||||
|
||||
// Type de ressource
|
||||
ResourceType<EntityStore, PortalWorld> portalWorldType =
|
||||
portals.getPortalResourceType();
|
||||
```
|
||||
|
||||
## Limite Fragments Concurrents
|
||||
|
||||
Le systeme limite les fragments portails concurrents:
|
||||
```java
|
||||
public static final int MAX_CONCURRENT_FRAGMENTS = 4;
|
||||
|
||||
int active = portals.countActiveFragments();
|
||||
if (active >= MAX_CONCURRENT_FRAGMENTS) {
|
||||
// Impossible de creer nouveaux fragments
|
||||
}
|
||||
```
|
||||
|
||||
## Sujets Connexes
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="portal-components" title="Composants Portail" subtitle="Composants PortalDevice, VoidEvent" >}}
|
||||
{{< card link="portal-systems" title="Systemes Portail" subtitle="Systemes ECS pour logique portail" >}}
|
||||
{{< card link="portal-commands" title="Commandes Portail" subtitle="Commandes admin et joueur" >}}
|
||||
{{< /cards >}}
|
||||
224
content/world/portals/portal-commands.en.md
Normal file
224
content/world/portals/portal-commands.en.md
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
title: Portal Commands
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Commands for managing portals, fragments, and void events.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals.commands`
|
||||
|
||||
## Player Commands
|
||||
|
||||
### /leave
|
||||
|
||||
Leave the current portal world and return to the origin world.
|
||||
|
||||
```
|
||||
/leave
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
- Only works when inside a portal world
|
||||
- Uncurses all items in inventory before leaving
|
||||
- Teleports player back to the portal device location
|
||||
|
||||
**Implementation:**
|
||||
```java
|
||||
public class LeaveCommand extends AbstractPlayerCommand {
|
||||
@Override
|
||||
protected void execute(CommandContext context, Store<EntityStore> store,
|
||||
Ref<EntityStore> ref, PlayerRef playerRef, World world) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) {
|
||||
playerRef.sendMessage(MESSAGE_NOT_IN_PORTAL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove curse from all items
|
||||
CursedItems.uncurseAll(player.getInventory().getCombinedEverything());
|
||||
|
||||
// Exit the instance
|
||||
InstancesPlugin.exitInstance(ref, store);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Fragment Commands
|
||||
|
||||
### /fragment
|
||||
|
||||
Parent command for fragment management.
|
||||
|
||||
```
|
||||
/fragment <subcommand>
|
||||
```
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `timer` | Modify fragment time remaining |
|
||||
|
||||
### /fragment timer
|
||||
|
||||
Set the remaining time for the current portal fragment.
|
||||
|
||||
```
|
||||
/fragment timer <seconds>
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `seconds` | INTEGER | New remaining time in seconds |
|
||||
|
||||
**Example:**
|
||||
```
|
||||
/fragment timer 300 # Set 5 minutes remaining
|
||||
/fragment timer 60 # Set 1 minute remaining
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
```java
|
||||
public class TimerFragmentCommand extends PortalWorldCommandBase {
|
||||
private final RequiredArg<Integer> remainingSecondsArg;
|
||||
|
||||
@Override
|
||||
protected void execute(CommandContext context, World world,
|
||||
PortalWorld portalWorld, Store<EntityStore> store) {
|
||||
int before = (int) portalWorld.getRemainingSeconds(world);
|
||||
int desired = remainingSecondsArg.get(context);
|
||||
portalWorld.setRemainingSeconds(world, desired);
|
||||
// Reports: "Changed from {before} to {after}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Void Event Commands
|
||||
|
||||
### /voidevent
|
||||
|
||||
Parent command for void event management.
|
||||
|
||||
```
|
||||
/voidevent <subcommand>
|
||||
```
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|-------------|
|
||||
| `start` | Start a void event |
|
||||
|
||||
### /voidevent start
|
||||
|
||||
Start a void invasion event in the current world.
|
||||
|
||||
```
|
||||
/voidevent start [--override]
|
||||
```
|
||||
|
||||
**Flags:**
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--override` | Force start even if not in a portal world |
|
||||
|
||||
**Behavior:**
|
||||
- If already in a portal world with void event active: fails
|
||||
- If not in portal world without `--override`: fails
|
||||
- With `--override`: creates temporary portal world configuration
|
||||
- Sets remaining time to 1 second to trigger void event
|
||||
|
||||
**Implementation:**
|
||||
```java
|
||||
public class StartVoidEventCommand extends AbstractWorldCommand {
|
||||
private final FlagArg overrideWorld;
|
||||
|
||||
@Override
|
||||
protected void execute(CommandContext context, World world,
|
||||
Store<EntityStore> store) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
|
||||
// Check if already running
|
||||
if (portalWorld.exists() && portalWorld.isVoidEventActive()) {
|
||||
context.sendMessage("Void event already running");
|
||||
return;
|
||||
}
|
||||
|
||||
// If not in portal world, require --override
|
||||
if (!portalWorld.exists()) {
|
||||
if (!overrideWorld.get(context)) {
|
||||
context.sendMessage("Not in portal world");
|
||||
return;
|
||||
}
|
||||
// Set up temporary portal world config
|
||||
portalWorld.init(portalType, timeLimit, removalCondition, config);
|
||||
}
|
||||
|
||||
// Trigger void event by setting timer to 1 second
|
||||
portalWorld.setRemainingSeconds(world, 1.0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Utility Commands
|
||||
|
||||
### /cursehelditem
|
||||
|
||||
Mark the currently held item as cursed (debug/testing command).
|
||||
|
||||
```
|
||||
/cursehelditem
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
- Adds curse marker to item in main hand
|
||||
- Cursed items are lost when player dies in portal world
|
||||
|
||||
## Command Base Classes
|
||||
|
||||
### PortalWorldCommandBase
|
||||
|
||||
Base class for commands that require a portal world:
|
||||
|
||||
```java
|
||||
public abstract class PortalWorldCommandBase extends AbstractWorldCommand {
|
||||
@Override
|
||||
protected final void execute(CommandContext context, World world,
|
||||
Store<EntityStore> store) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) {
|
||||
context.sendMessage(MESSAGE_NOT_IN_PORTAL);
|
||||
return;
|
||||
}
|
||||
execute(context, world, portalWorld, store);
|
||||
}
|
||||
|
||||
protected abstract void execute(CommandContext context, World world,
|
||||
PortalWorld portalWorld,
|
||||
Store<EntityStore> store);
|
||||
}
|
||||
```
|
||||
|
||||
## Command Registration
|
||||
|
||||
Commands are registered in PortalsPlugin setup:
|
||||
|
||||
```java
|
||||
this.getCommandRegistry().registerCommand(new LeaveCommand());
|
||||
this.getCommandRegistry().registerCommand(new CursedHeldItemCommand());
|
||||
this.getCommandRegistry().registerCommand(new VoidEventCommands());
|
||||
this.getCommandRegistry().registerCommand(new FragmentCommands());
|
||||
```
|
||||
|
||||
## Messages
|
||||
|
||||
Portal commands use translation keys for messages:
|
||||
|
||||
| Key | Description |
|
||||
|-----|-------------|
|
||||
| `server.commands.leave.notInPortal` | Not in a portal world |
|
||||
| `server.commands.leave.uncursedTemp` | Items were uncursed |
|
||||
| `server.commands.portals.notInPortal` | Not in portal world |
|
||||
| `server.commands.voidevent.start.alreadyRunning` | Void event active |
|
||||
| `server.commands.voidevent.start.success` | Void event started |
|
||||
| `server.commands.fragment.timer.success` | Timer changed |
|
||||
224
content/world/portals/portal-commands.fr.md
Normal file
224
content/world/portals/portal-commands.fr.md
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
title: Commandes Portail
|
||||
type: docs
|
||||
weight: 3
|
||||
---
|
||||
|
||||
Commandes pour gerer les portails, fragments et evenements du vide.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals.commands`
|
||||
|
||||
## Commandes Joueur
|
||||
|
||||
### /leave
|
||||
|
||||
Quitter le monde portail actuel et retourner au monde d'origine.
|
||||
|
||||
```
|
||||
/leave
|
||||
```
|
||||
|
||||
**Comportement:**
|
||||
- Fonctionne uniquement dans un monde portail
|
||||
- Retire la malediction de tous les items avant de partir
|
||||
- Teleporte le joueur vers l'emplacement du dispositif portail
|
||||
|
||||
**Implementation:**
|
||||
```java
|
||||
public class LeaveCommand extends AbstractPlayerCommand {
|
||||
@Override
|
||||
protected void execute(CommandContext context, Store<EntityStore> store,
|
||||
Ref<EntityStore> ref, PlayerRef playerRef, World world) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) {
|
||||
playerRef.sendMessage(MESSAGE_NOT_IN_PORTAL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Retirer malediction de tous items
|
||||
CursedItems.uncurseAll(player.getInventory().getCombinedEverything());
|
||||
|
||||
// Sortir de l'instance
|
||||
InstancesPlugin.exitInstance(ref, store);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Commandes Fragment
|
||||
|
||||
### /fragment
|
||||
|
||||
Commande parente pour gestion fragments.
|
||||
|
||||
```
|
||||
/fragment <sous-commande>
|
||||
```
|
||||
|
||||
| Sous-commande | Description |
|
||||
|---------------|-------------|
|
||||
| `timer` | Modifier temps restant fragment |
|
||||
|
||||
### /fragment timer
|
||||
|
||||
Definir le temps restant pour le fragment portail actuel.
|
||||
|
||||
```
|
||||
/fragment timer <secondes>
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
| Argument | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `secondes` | INTEGER | Nouveau temps restant en secondes |
|
||||
|
||||
**Exemple:**
|
||||
```
|
||||
/fragment timer 300 # Definir 5 minutes restantes
|
||||
/fragment timer 60 # Definir 1 minute restante
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
```java
|
||||
public class TimerFragmentCommand extends PortalWorldCommandBase {
|
||||
private final RequiredArg<Integer> remainingSecondsArg;
|
||||
|
||||
@Override
|
||||
protected void execute(CommandContext context, World world,
|
||||
PortalWorld portalWorld, Store<EntityStore> store) {
|
||||
int before = (int) portalWorld.getRemainingSeconds(world);
|
||||
int desired = remainingSecondsArg.get(context);
|
||||
portalWorld.setRemainingSeconds(world, desired);
|
||||
// Rapporte: "Change de {before} a {after}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Commandes Evenement Vide
|
||||
|
||||
### /voidevent
|
||||
|
||||
Commande parente pour gestion evenement vide.
|
||||
|
||||
```
|
||||
/voidevent <sous-commande>
|
||||
```
|
||||
|
||||
| Sous-commande | Description |
|
||||
|---------------|-------------|
|
||||
| `start` | Demarrer un evenement vide |
|
||||
|
||||
### /voidevent start
|
||||
|
||||
Demarrer un evenement invasion du vide dans le monde actuel.
|
||||
|
||||
```
|
||||
/voidevent start [--override]
|
||||
```
|
||||
|
||||
**Flags:**
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--override` | Forcer demarrage meme si pas dans monde portail |
|
||||
|
||||
**Comportement:**
|
||||
- Si deja dans monde portail avec evenement vide actif: echoue
|
||||
- Si pas dans monde portail sans `--override`: echoue
|
||||
- Avec `--override`: cree configuration monde portail temporaire
|
||||
- Met temps restant a 1 seconde pour declencher evenement vide
|
||||
|
||||
**Implementation:**
|
||||
```java
|
||||
public class StartVoidEventCommand extends AbstractWorldCommand {
|
||||
private final FlagArg overrideWorld;
|
||||
|
||||
@Override
|
||||
protected void execute(CommandContext context, World world,
|
||||
Store<EntityStore> store) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
|
||||
// Verifier si deja en cours
|
||||
if (portalWorld.exists() && portalWorld.isVoidEventActive()) {
|
||||
context.sendMessage("Evenement vide deja en cours");
|
||||
return;
|
||||
}
|
||||
|
||||
// Si pas dans monde portail, requiert --override
|
||||
if (!portalWorld.exists()) {
|
||||
if (!overrideWorld.get(context)) {
|
||||
context.sendMessage("Pas dans monde portail");
|
||||
return;
|
||||
}
|
||||
// Configurer monde portail temporaire
|
||||
portalWorld.init(portalType, timeLimit, removalCondition, config);
|
||||
}
|
||||
|
||||
// Declencher evenement vide en mettant timer a 1 seconde
|
||||
portalWorld.setRemainingSeconds(world, 1.0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Commandes Utilitaires
|
||||
|
||||
### /cursehelditem
|
||||
|
||||
Marquer l'item tenu comme maudit (commande debug/test).
|
||||
|
||||
```
|
||||
/cursehelditem
|
||||
```
|
||||
|
||||
**Comportement:**
|
||||
- Ajoute marqueur malediction a l'item en main principale
|
||||
- Items maudits sont perdus quand joueur meurt dans monde portail
|
||||
|
||||
## Classes de Base Commandes
|
||||
|
||||
### PortalWorldCommandBase
|
||||
|
||||
Classe de base pour commandes necessitant un monde portail:
|
||||
|
||||
```java
|
||||
public abstract class PortalWorldCommandBase extends AbstractWorldCommand {
|
||||
@Override
|
||||
protected final void execute(CommandContext context, World world,
|
||||
Store<EntityStore> store) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) {
|
||||
context.sendMessage(MESSAGE_NOT_IN_PORTAL);
|
||||
return;
|
||||
}
|
||||
execute(context, world, portalWorld, store);
|
||||
}
|
||||
|
||||
protected abstract void execute(CommandContext context, World world,
|
||||
PortalWorld portalWorld,
|
||||
Store<EntityStore> store);
|
||||
}
|
||||
```
|
||||
|
||||
## Enregistrement Commandes
|
||||
|
||||
Les commandes sont enregistrees dans setup PortalsPlugin:
|
||||
|
||||
```java
|
||||
this.getCommandRegistry().registerCommand(new LeaveCommand());
|
||||
this.getCommandRegistry().registerCommand(new CursedHeldItemCommand());
|
||||
this.getCommandRegistry().registerCommand(new VoidEventCommands());
|
||||
this.getCommandRegistry().registerCommand(new FragmentCommands());
|
||||
```
|
||||
|
||||
## Messages
|
||||
|
||||
Les commandes portail utilisent des cles de traduction pour les messages:
|
||||
|
||||
| Cle | Description |
|
||||
|-----|-------------|
|
||||
| `server.commands.leave.notInPortal` | Pas dans monde portail |
|
||||
| `server.commands.leave.uncursedTemp` | Items ont ete decursifies |
|
||||
| `server.commands.portals.notInPortal` | Pas dans monde portail |
|
||||
| `server.commands.voidevent.start.alreadyRunning` | Evenement vide actif |
|
||||
| `server.commands.voidevent.start.success` | Evenement vide demarre |
|
||||
| `server.commands.fragment.timer.success` | Timer modifie |
|
||||
270
content/world/portals/portal-components.en.md
Normal file
270
content/world/portals/portal-components.en.md
Normal file
@@ -0,0 +1,270 @@
|
||||
---
|
||||
title: Portal Components
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||
Portal components define the data structures for portal devices, portal worlds, and void events.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals.components`
|
||||
|
||||
## PortalDevice
|
||||
|
||||
A chunk-level component representing a portal block device.
|
||||
|
||||
```java
|
||||
public class PortalDevice implements Component<ChunkStore> {
|
||||
// Configuration for portal states
|
||||
private PortalDeviceConfig config;
|
||||
|
||||
// Block type key for the portal device
|
||||
private String baseBlockTypeKey;
|
||||
|
||||
// UUID of the destination world (if active)
|
||||
private UUID destinationWorldUuid;
|
||||
}
|
||||
```
|
||||
|
||||
### Accessing Portal Devices
|
||||
|
||||
```java
|
||||
// Get portal device at block position
|
||||
PortalDevice portal = BlockModule.get().getComponent(
|
||||
PortalDevice.getComponentType(),
|
||||
world, x, y, z
|
||||
);
|
||||
|
||||
if (portal != null) {
|
||||
// Portal exists at this location
|
||||
BlockType blockType = portal.getBaseBlockType();
|
||||
World destination = portal.getDestinationWorld();
|
||||
}
|
||||
```
|
||||
|
||||
### Destination World
|
||||
|
||||
```java
|
||||
// Set destination when activating portal
|
||||
portal.setDestinationWorld(targetWorld);
|
||||
|
||||
// Get destination (null if inactive or world closed)
|
||||
World destination = portal.getDestinationWorld();
|
||||
if (destination == null || !destination.isAlive()) {
|
||||
// Portal destination invalid
|
||||
}
|
||||
```
|
||||
|
||||
## PortalDeviceConfig
|
||||
|
||||
Configuration for portal device visual states.
|
||||
|
||||
```java
|
||||
public class PortalDeviceConfig {
|
||||
// State when instance is being created
|
||||
private String spawningState = "Spawning";
|
||||
|
||||
// State when portal is active
|
||||
private String onState = "Active";
|
||||
|
||||
// State when portal is inactive
|
||||
private String offState = "default";
|
||||
|
||||
// Block placed at spawn point in portal world
|
||||
private String returnBlock;
|
||||
}
|
||||
```
|
||||
|
||||
### State Validation
|
||||
|
||||
```java
|
||||
// Verify all states exist on block type
|
||||
PortalDeviceConfig config = portal.getConfig();
|
||||
if (config.areBlockStatesValid(baseBlockType)) {
|
||||
// All states (on, off, spawning) are valid
|
||||
}
|
||||
```
|
||||
|
||||
### State Names
|
||||
|
||||
| State | Description | Default |
|
||||
|-------|-------------|---------|
|
||||
| `spawningState` | Transition from off to on | "Spawning" |
|
||||
| `onState` | Portal is active | "Active" |
|
||||
| `offState` | Portal is inactive | "default" |
|
||||
|
||||
## PortalWorld
|
||||
|
||||
A resource attached to worlds created by portals.
|
||||
|
||||
```java
|
||||
public class PortalWorld implements Resource<EntityStore> {
|
||||
// Portal type configuration ID
|
||||
private String portalTypeId;
|
||||
|
||||
// Time limit in seconds
|
||||
private int timeLimitSeconds;
|
||||
|
||||
// Removal condition handler
|
||||
private PortalRemovalCondition worldRemovalCondition;
|
||||
|
||||
// Players who died in this world
|
||||
private Set<UUID> diedInWorld;
|
||||
|
||||
// Players currently seeing the UI
|
||||
private Set<UUID> seesUi;
|
||||
|
||||
// Spawn point transform
|
||||
private Transform spawnPoint;
|
||||
|
||||
// Reference to active void event
|
||||
private Ref<EntityStore> voidEventRef;
|
||||
}
|
||||
```
|
||||
|
||||
### Checking Portal World
|
||||
|
||||
```java
|
||||
// Get portal world resource
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
|
||||
// Check if this is a valid portal world
|
||||
if (portalWorld.exists()) {
|
||||
PortalType type = portalWorld.getPortalType();
|
||||
int timeLimit = portalWorld.getTimeLimitSeconds();
|
||||
}
|
||||
```
|
||||
|
||||
### Time Management
|
||||
|
||||
```java
|
||||
// Get elapsed and remaining time
|
||||
double elapsed = portalWorld.getElapsedSeconds(world);
|
||||
double remaining = portalWorld.getRemainingSeconds(world);
|
||||
|
||||
// Modify remaining time (e.g., extend timer)
|
||||
portalWorld.setRemainingSeconds(world, 300.0); // 5 minutes
|
||||
```
|
||||
|
||||
### Death Tracking
|
||||
|
||||
```java
|
||||
// Check if player died in this world
|
||||
if (portalWorld.getDiedInWorld().contains(playerUuid)) {
|
||||
// Cannot re-enter - died here
|
||||
}
|
||||
|
||||
// Track a death
|
||||
portalWorld.getDiedInWorld().add(playerUuid);
|
||||
```
|
||||
|
||||
### UI State
|
||||
|
||||
```java
|
||||
// Track players seeing the portal UI
|
||||
portalWorld.getSeesUi().add(playerUuid);
|
||||
portalWorld.getSeesUi().remove(playerUuid);
|
||||
```
|
||||
|
||||
## VoidEvent
|
||||
|
||||
Component for void invasion events in portal worlds.
|
||||
|
||||
```java
|
||||
public class VoidEvent implements Component<EntityStore> {
|
||||
// Minimum distance between spawners
|
||||
public static final double MIN_BLOCKS_BETWEEN_SPAWNERS = 62.0;
|
||||
|
||||
// Spatial grid of void spawners
|
||||
private SpatialHashGrid<Ref<EntityStore>> voidSpawners;
|
||||
|
||||
// Current active stage
|
||||
private VoidEventStage activeStage;
|
||||
}
|
||||
```
|
||||
|
||||
### Void Event Access
|
||||
|
||||
```java
|
||||
// Check if void event is active
|
||||
Ref<EntityStore> voidRef = portalWorld.getVoidEventRef();
|
||||
if (portalWorld.isVoidEventActive()) {
|
||||
VoidEvent voidEvent = store.getComponent(voidRef, VoidEvent.getComponentType());
|
||||
VoidEventStage stage = voidEvent.getActiveStage();
|
||||
}
|
||||
```
|
||||
|
||||
### Void Spawner Grid
|
||||
|
||||
```java
|
||||
// Get spawner grid
|
||||
SpatialHashGrid<Ref<EntityStore>> spawners = voidEvent.getVoidSpawners();
|
||||
|
||||
// Spawners maintain minimum distance of 62 blocks
|
||||
```
|
||||
|
||||
## VoidEventConfig
|
||||
|
||||
Configuration for void events.
|
||||
|
||||
```java
|
||||
public class VoidEventConfig {
|
||||
// Duration of void event in seconds
|
||||
private int durationSeconds;
|
||||
|
||||
// Stages of the void event
|
||||
private List<VoidEventStage> stages;
|
||||
}
|
||||
```
|
||||
|
||||
## VoidEventStage
|
||||
|
||||
Single stage in a void event progression.
|
||||
|
||||
```java
|
||||
public class VoidEventStage {
|
||||
// When this stage starts (seconds from event start)
|
||||
private int startTime;
|
||||
|
||||
// Spawners to activate
|
||||
private List<VoidSpawnerConfig> spawners;
|
||||
}
|
||||
```
|
||||
|
||||
## VoidSpawner
|
||||
|
||||
Entity component for void invasion spawners.
|
||||
|
||||
```java
|
||||
public class VoidSpawner implements Component<EntityStore> {
|
||||
// Spawner configuration
|
||||
// Tracks active spawning state
|
||||
}
|
||||
```
|
||||
|
||||
## Component Registration
|
||||
|
||||
Components are registered in PortalsPlugin setup:
|
||||
|
||||
```java
|
||||
// In PortalsPlugin.setup()
|
||||
this.portalDeviceComponentType = this.getChunkStoreRegistry()
|
||||
.registerComponent(PortalDevice.class, "Portal", PortalDevice.CODEC);
|
||||
|
||||
this.voidEventComponentType = this.getEntityStoreRegistry()
|
||||
.registerComponent(VoidEvent.class, VoidEvent::new);
|
||||
|
||||
this.voidPortalComponentType = this.getEntityStoreRegistry()
|
||||
.registerComponent(VoidSpawner.class, VoidSpawner::new);
|
||||
```
|
||||
|
||||
## Serialization
|
||||
|
||||
PortalDevice uses BuilderCodec for persistence:
|
||||
|
||||
```java
|
||||
public static final BuilderCodec<PortalDevice> CODEC = BuilderCodec.builder(...)
|
||||
.append(new KeyedCodec<>("Config", PortalDeviceConfig.CODEC), ...)
|
||||
.append(new KeyedCodec<>("BaseBlockType", Codec.STRING), ...)
|
||||
.append(new KeyedCodec<>("DestinationWorld", Codec.UUID_BINARY), ...)
|
||||
.build();
|
||||
```
|
||||
270
content/world/portals/portal-components.fr.md
Normal file
270
content/world/portals/portal-components.fr.md
Normal file
@@ -0,0 +1,270 @@
|
||||
---
|
||||
title: Composants Portail
|
||||
type: docs
|
||||
weight: 1
|
||||
---
|
||||
|
||||
Les composants portail definissent les structures de donnees pour les dispositifs portail, les mondes portail et les evenements du vide.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals.components`
|
||||
|
||||
## PortalDevice
|
||||
|
||||
Un composant au niveau chunk representant un bloc dispositif portail.
|
||||
|
||||
```java
|
||||
public class PortalDevice implements Component<ChunkStore> {
|
||||
// Configuration pour etats du portail
|
||||
private PortalDeviceConfig config;
|
||||
|
||||
// Cle type de bloc pour le dispositif portail
|
||||
private String baseBlockTypeKey;
|
||||
|
||||
// UUID du monde de destination (si actif)
|
||||
private UUID destinationWorldUuid;
|
||||
}
|
||||
```
|
||||
|
||||
### Acceder aux Dispositifs Portail
|
||||
|
||||
```java
|
||||
// Obtenir dispositif portail a position bloc
|
||||
PortalDevice portal = BlockModule.get().getComponent(
|
||||
PortalDevice.getComponentType(),
|
||||
world, x, y, z
|
||||
);
|
||||
|
||||
if (portal != null) {
|
||||
// Portail existe a cet emplacement
|
||||
BlockType blockType = portal.getBaseBlockType();
|
||||
World destination = portal.getDestinationWorld();
|
||||
}
|
||||
```
|
||||
|
||||
### Monde de Destination
|
||||
|
||||
```java
|
||||
// Definir destination lors activation portail
|
||||
portal.setDestinationWorld(targetWorld);
|
||||
|
||||
// Obtenir destination (null si inactif ou monde ferme)
|
||||
World destination = portal.getDestinationWorld();
|
||||
if (destination == null || !destination.isAlive()) {
|
||||
// Destination portail invalide
|
||||
}
|
||||
```
|
||||
|
||||
## PortalDeviceConfig
|
||||
|
||||
Configuration pour les etats visuels du dispositif portail.
|
||||
|
||||
```java
|
||||
public class PortalDeviceConfig {
|
||||
// Etat quand instance en creation
|
||||
private String spawningState = "Spawning";
|
||||
|
||||
// Etat quand portail actif
|
||||
private String onState = "Active";
|
||||
|
||||
// Etat quand portail inactif
|
||||
private String offState = "default";
|
||||
|
||||
// Bloc place au point de spawn dans monde portail
|
||||
private String returnBlock;
|
||||
}
|
||||
```
|
||||
|
||||
### Validation des Etats
|
||||
|
||||
```java
|
||||
// Verifier que tous les etats existent sur type de bloc
|
||||
PortalDeviceConfig config = portal.getConfig();
|
||||
if (config.areBlockStatesValid(baseBlockType)) {
|
||||
// Tous les etats (on, off, spawning) sont valides
|
||||
}
|
||||
```
|
||||
|
||||
### Noms des Etats
|
||||
|
||||
| Etat | Description | Defaut |
|
||||
|------|-------------|--------|
|
||||
| `spawningState` | Transition de eteint a actif | "Spawning" |
|
||||
| `onState` | Portail actif | "Active" |
|
||||
| `offState` | Portail inactif | "default" |
|
||||
|
||||
## PortalWorld
|
||||
|
||||
Une ressource attachee aux mondes crees par les portails.
|
||||
|
||||
```java
|
||||
public class PortalWorld implements Resource<EntityStore> {
|
||||
// ID configuration type portail
|
||||
private String portalTypeId;
|
||||
|
||||
// Limite temps en secondes
|
||||
private int timeLimitSeconds;
|
||||
|
||||
// Handler condition de suppression
|
||||
private PortalRemovalCondition worldRemovalCondition;
|
||||
|
||||
// Joueurs morts dans ce monde
|
||||
private Set<UUID> diedInWorld;
|
||||
|
||||
// Joueurs voyant actuellement l'UI
|
||||
private Set<UUID> seesUi;
|
||||
|
||||
// Transform point de spawn
|
||||
private Transform spawnPoint;
|
||||
|
||||
// Reference vers evenement vide actif
|
||||
private Ref<EntityStore> voidEventRef;
|
||||
}
|
||||
```
|
||||
|
||||
### Verifier Monde Portail
|
||||
|
||||
```java
|
||||
// Obtenir ressource monde portail
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
|
||||
// Verifier si c'est un monde portail valide
|
||||
if (portalWorld.exists()) {
|
||||
PortalType type = portalWorld.getPortalType();
|
||||
int timeLimit = portalWorld.getTimeLimitSeconds();
|
||||
}
|
||||
```
|
||||
|
||||
### Gestion du Temps
|
||||
|
||||
```java
|
||||
// Obtenir temps ecoule et restant
|
||||
double elapsed = portalWorld.getElapsedSeconds(world);
|
||||
double remaining = portalWorld.getRemainingSeconds(world);
|
||||
|
||||
// Modifier temps restant (ex: etendre timer)
|
||||
portalWorld.setRemainingSeconds(world, 300.0); // 5 minutes
|
||||
```
|
||||
|
||||
### Suivi des Morts
|
||||
|
||||
```java
|
||||
// Verifier si joueur mort dans ce monde
|
||||
if (portalWorld.getDiedInWorld().contains(playerUuid)) {
|
||||
// Ne peut pas re-entrer - mort ici
|
||||
}
|
||||
|
||||
// Enregistrer une mort
|
||||
portalWorld.getDiedInWorld().add(playerUuid);
|
||||
```
|
||||
|
||||
### Etat UI
|
||||
|
||||
```java
|
||||
// Suivre joueurs voyant l'UI portail
|
||||
portalWorld.getSeesUi().add(playerUuid);
|
||||
portalWorld.getSeesUi().remove(playerUuid);
|
||||
```
|
||||
|
||||
## VoidEvent
|
||||
|
||||
Composant pour evenements invasion du vide dans mondes portail.
|
||||
|
||||
```java
|
||||
public class VoidEvent implements Component<EntityStore> {
|
||||
// Distance minimum entre spawners
|
||||
public static final double MIN_BLOCKS_BETWEEN_SPAWNERS = 62.0;
|
||||
|
||||
// Grille spatiale des spawners du vide
|
||||
private SpatialHashGrid<Ref<EntityStore>> voidSpawners;
|
||||
|
||||
// Etape active actuelle
|
||||
private VoidEventStage activeStage;
|
||||
}
|
||||
```
|
||||
|
||||
### Acces Evenement Vide
|
||||
|
||||
```java
|
||||
// Verifier si evenement vide actif
|
||||
Ref<EntityStore> voidRef = portalWorld.getVoidEventRef();
|
||||
if (portalWorld.isVoidEventActive()) {
|
||||
VoidEvent voidEvent = store.getComponent(voidRef, VoidEvent.getComponentType());
|
||||
VoidEventStage stage = voidEvent.getActiveStage();
|
||||
}
|
||||
```
|
||||
|
||||
### Grille Spawners Vide
|
||||
|
||||
```java
|
||||
// Obtenir grille spawners
|
||||
SpatialHashGrid<Ref<EntityStore>> spawners = voidEvent.getVoidSpawners();
|
||||
|
||||
// Spawners maintiennent distance minimum de 62 blocs
|
||||
```
|
||||
|
||||
## VoidEventConfig
|
||||
|
||||
Configuration pour evenements du vide.
|
||||
|
||||
```java
|
||||
public class VoidEventConfig {
|
||||
// Duree evenement vide en secondes
|
||||
private int durationSeconds;
|
||||
|
||||
// Etapes de l'evenement vide
|
||||
private List<VoidEventStage> stages;
|
||||
}
|
||||
```
|
||||
|
||||
## VoidEventStage
|
||||
|
||||
Etape unique dans progression evenement vide.
|
||||
|
||||
```java
|
||||
public class VoidEventStage {
|
||||
// Quand cette etape demarre (secondes depuis debut evenement)
|
||||
private int startTime;
|
||||
|
||||
// Spawners a activer
|
||||
private List<VoidSpawnerConfig> spawners;
|
||||
}
|
||||
```
|
||||
|
||||
## VoidSpawner
|
||||
|
||||
Composant entite pour spawners invasion du vide.
|
||||
|
||||
```java
|
||||
public class VoidSpawner implements Component<EntityStore> {
|
||||
// Configuration spawner
|
||||
// Suit etat de spawn actif
|
||||
}
|
||||
```
|
||||
|
||||
## Enregistrement Composants
|
||||
|
||||
Les composants sont enregistres dans setup PortalsPlugin:
|
||||
|
||||
```java
|
||||
// Dans PortalsPlugin.setup()
|
||||
this.portalDeviceComponentType = this.getChunkStoreRegistry()
|
||||
.registerComponent(PortalDevice.class, "Portal", PortalDevice.CODEC);
|
||||
|
||||
this.voidEventComponentType = this.getEntityStoreRegistry()
|
||||
.registerComponent(VoidEvent.class, VoidEvent::new);
|
||||
|
||||
this.voidPortalComponentType = this.getEntityStoreRegistry()
|
||||
.registerComponent(VoidSpawner.class, VoidSpawner::new);
|
||||
```
|
||||
|
||||
## Serialisation
|
||||
|
||||
PortalDevice utilise BuilderCodec pour persistance:
|
||||
|
||||
```java
|
||||
public static final BuilderCodec<PortalDevice> CODEC = BuilderCodec.builder(...)
|
||||
.append(new KeyedCodec<>("Config", PortalDeviceConfig.CODEC), ...)
|
||||
.append(new KeyedCodec<>("BaseBlockType", Codec.STRING), ...)
|
||||
.append(new KeyedCodec<>("DestinationWorld", Codec.UUID_BINARY), ...)
|
||||
.build();
|
||||
```
|
||||
280
content/world/portals/portal-systems.en.md
Normal file
280
content/world/portals/portal-systems.en.md
Normal file
@@ -0,0 +1,280 @@
|
||||
---
|
||||
title: Portal Systems
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Portal systems handle the runtime logic for portal tracking, void events, and instance management.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals.systems`
|
||||
|
||||
## Portal Tracker Systems
|
||||
|
||||
### TrackerSystem
|
||||
|
||||
Tracks players entering and leaving portal worlds:
|
||||
|
||||
```java
|
||||
public class TrackerSystem extends RefSystem<EntityStore> {
|
||||
// Called when player enters portal world
|
||||
@Override
|
||||
public void onEntityAdded(Ref<EntityStore> ref, AddReason reason,
|
||||
Store<EntityStore> store,
|
||||
CommandBuffer<EntityStore> commandBuffer) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) return;
|
||||
|
||||
// Send portal UI to player
|
||||
PlayerRef playerRef = commandBuffer.getComponent(ref, PlayerRef.getComponentType());
|
||||
UpdatePortal packet = portalWorld.createFullPacket(world);
|
||||
playerRef.getPacketHandler().write(packet);
|
||||
}
|
||||
|
||||
// Called when player leaves portal world
|
||||
@Override
|
||||
public void onEntityRemove(Ref<EntityStore> ref, RemoveReason reason,
|
||||
Store<EntityStore> store,
|
||||
CommandBuffer<EntityStore> commandBuffer) {
|
||||
// Clear UI state
|
||||
playerRef.getPacketHandler().write(new UpdatePortal(null, null));
|
||||
portalWorld.getSeesUi().remove(playerRef.getUuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<EntityStore> getQuery() {
|
||||
return Query.and(Player.getComponentType(), PlayerRef.getComponentType());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### UiTickingSystem
|
||||
|
||||
Updates portal UI every second:
|
||||
|
||||
```java
|
||||
public class UiTickingSystem extends DelayedEntitySystem<EntityStore> {
|
||||
public UiTickingSystem() {
|
||||
super(1.0f); // Tick every 1 second
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(float dt, int index, ArchetypeChunk<EntityStore> archetypeChunk,
|
||||
Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) return;
|
||||
|
||||
// Send updated time to player
|
||||
UpdatePortal packet = portalWorld.createUpdatePacket(world);
|
||||
playerRef.getPacketHandler().write(packet);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Portal Destination Systems
|
||||
|
||||
### PortalInvalidDestinationSystem
|
||||
|
||||
Handles portals with invalid destinations:
|
||||
|
||||
```java
|
||||
public class PortalInvalidDestinationSystem {
|
||||
// Turns off portals when destination world closes
|
||||
public static void turnOffPortalsInWorld(World world, World closedWorld) {
|
||||
// Find all portals pointing to closedWorld
|
||||
// Set their destination to null
|
||||
// Update block state to "off"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CloseWorldWhenBreakingDeviceSystems
|
||||
|
||||
Handles portal device destruction:
|
||||
|
||||
```java
|
||||
// When portal device component is removed
|
||||
public class ComponentRemoved extends System<ChunkStore> {
|
||||
// Close the destination world
|
||||
}
|
||||
|
||||
// When portal block entity is removed
|
||||
public class EntityRemoved extends System<ChunkStore> {
|
||||
// Close the destination world
|
||||
}
|
||||
```
|
||||
|
||||
## Void Event Systems
|
||||
|
||||
### VoidEventRefSystem
|
||||
|
||||
Manages void event entity references:
|
||||
|
||||
```java
|
||||
public class VoidEventRefSystem extends System<EntityStore> {
|
||||
// Tracks void event entity lifecycle
|
||||
// Updates PortalWorld.voidEventRef
|
||||
}
|
||||
```
|
||||
|
||||
### VoidEventStagesSystem
|
||||
|
||||
Progresses through void event stages:
|
||||
|
||||
```java
|
||||
public class VoidEventStagesSystem extends System<EntityStore> {
|
||||
// Checks elapsed time
|
||||
// Activates next stage when time threshold reached
|
||||
// Updates VoidEvent.activeStage
|
||||
}
|
||||
```
|
||||
|
||||
### VoidInvasionPortalsSpawnSystem
|
||||
|
||||
Spawns invasion portals during void events:
|
||||
|
||||
```java
|
||||
public class VoidInvasionPortalsSpawnSystem extends System<EntityStore> {
|
||||
// Creates void spawner entities
|
||||
// Uses spatial hash grid to maintain minimum distance
|
||||
}
|
||||
```
|
||||
|
||||
### VoidSpawnerSystems.Instantiate
|
||||
|
||||
Instantiates void spawner entities:
|
||||
|
||||
```java
|
||||
public class Instantiate extends System<EntityStore> {
|
||||
// Creates spawner entity from config
|
||||
// Adds to VoidEvent's spatial grid
|
||||
}
|
||||
```
|
||||
|
||||
### StartVoidEventInFragmentSystem
|
||||
|
||||
Initiates void events in portal fragments:
|
||||
|
||||
```java
|
||||
public class StartVoidEventInFragmentSystem extends System<EntityStore> {
|
||||
// Checks if void invasion should start
|
||||
// Creates VoidEvent entity
|
||||
// Sets up first stage
|
||||
}
|
||||
```
|
||||
|
||||
## Curse Systems
|
||||
|
||||
### DiedInPortalSystem
|
||||
|
||||
Tracks player deaths in portal worlds:
|
||||
|
||||
```java
|
||||
public class DiedInPortalSystem extends System<EntityStore> {
|
||||
// On player death in portal world:
|
||||
// - Add player UUID to diedInWorld set
|
||||
// - Prevents re-entry
|
||||
}
|
||||
```
|
||||
|
||||
### CurseItemDropsSystem
|
||||
|
||||
Marks dropped items as cursed:
|
||||
|
||||
```java
|
||||
public class CurseItemDropsSystem extends System<EntityStore> {
|
||||
// Items dropped in portal world become cursed
|
||||
// Cursed items are lost on death
|
||||
}
|
||||
```
|
||||
|
||||
### DeleteCursedItemsOnSpawnSystem
|
||||
|
||||
Removes cursed items when player spawns:
|
||||
|
||||
```java
|
||||
public class DeleteCursedItemsOnSpawnSystem extends System<EntityStore> {
|
||||
// When player respawns after dying in portal
|
||||
// Remove all cursed items from inventory
|
||||
}
|
||||
```
|
||||
|
||||
## Portal Interactions
|
||||
|
||||
### EnterPortalInteraction
|
||||
|
||||
Handles entering a portal:
|
||||
|
||||
```java
|
||||
public class EnterPortalInteraction extends SimpleBlockInteraction {
|
||||
// Minimum time before allowing portal use
|
||||
public static final Duration MINIMUM_TIME_IN_WORLD = Duration.ofMillis(3000L);
|
||||
|
||||
@Override
|
||||
protected void interactWithBlock(...) {
|
||||
// Check portal device exists
|
||||
// Verify destination world is alive
|
||||
// Check player hasn't died in target world
|
||||
// Teleport player to instance
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Target world states:
|
||||
- `OKAY` - Can enter
|
||||
- `WORLD_DEAD` - Destination closed
|
||||
- `DIED_IN_WORLD` - Player died there
|
||||
- `NO_SPAWN_AVAILABLE` - No spawn point
|
||||
|
||||
### ReturnPortalInteraction
|
||||
|
||||
Handles returning from a portal world:
|
||||
|
||||
```java
|
||||
public class ReturnPortalInteraction extends SimpleBlockInteraction {
|
||||
// Minimum time before allowing return
|
||||
public static final Duration MINIMUM_TIME_IN_WORLD = Duration.ofSeconds(15L);
|
||||
|
||||
// Warning shown before timer expires
|
||||
public static final Duration WARNING_TIME = Duration.ofSeconds(4L);
|
||||
|
||||
@Override
|
||||
protected void interactWithBlock(...) {
|
||||
// Check minimum time elapsed
|
||||
// Uncurse all items
|
||||
// Exit instance
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## System Registration
|
||||
|
||||
All systems are registered in PortalsPlugin setup:
|
||||
|
||||
```java
|
||||
// ChunkStore systems
|
||||
this.getChunkStoreRegistry().registerSystem(new PortalInvalidDestinationSystem());
|
||||
this.getChunkStoreRegistry().registerSystem(new CloseWorldWhenBreakingDeviceSystems.ComponentRemoved());
|
||||
this.getChunkStoreRegistry().registerSystem(new CloseWorldWhenBreakingDeviceSystems.EntityRemoved());
|
||||
|
||||
// EntityStore systems
|
||||
this.getEntityStoreRegistry().registerSystem(new PortalTrackerSystems.TrackerSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new PortalTrackerSystems.UiTickingSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new DiedInPortalSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new CurseItemDropsSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new DeleteCursedItemsOnSpawnSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidEventRefSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidInvasionPortalsSpawnSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidSpawnerSystems.Instantiate());
|
||||
this.getEntityStoreRegistry().registerSystem(new StartVoidEventInFragmentSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidEventStagesSystem());
|
||||
```
|
||||
|
||||
## Interaction Registration
|
||||
|
||||
Portal interactions are registered as codec types:
|
||||
|
||||
```java
|
||||
this.getCodecRegistry(Interaction.CODEC)
|
||||
.register("Portal", EnterPortalInteraction.class, EnterPortalInteraction.CODEC)
|
||||
.register("PortalReturn", ReturnPortalInteraction.class, ReturnPortalInteraction.CODEC);
|
||||
```
|
||||
280
content/world/portals/portal-systems.fr.md
Normal file
280
content/world/portals/portal-systems.fr.md
Normal file
@@ -0,0 +1,280 @@
|
||||
---
|
||||
title: Systemes Portail
|
||||
type: docs
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Les systemes portail gerent la logique d'execution pour le suivi des portails, les evenements du vide et la gestion des instances.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.portals.systems`
|
||||
|
||||
## Systemes de Suivi Portail
|
||||
|
||||
### TrackerSystem
|
||||
|
||||
Suit les joueurs entrant et sortant des mondes portail:
|
||||
|
||||
```java
|
||||
public class TrackerSystem extends RefSystem<EntityStore> {
|
||||
// Appele quand joueur entre dans monde portail
|
||||
@Override
|
||||
public void onEntityAdded(Ref<EntityStore> ref, AddReason reason,
|
||||
Store<EntityStore> store,
|
||||
CommandBuffer<EntityStore> commandBuffer) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) return;
|
||||
|
||||
// Envoyer UI portail au joueur
|
||||
PlayerRef playerRef = commandBuffer.getComponent(ref, PlayerRef.getComponentType());
|
||||
UpdatePortal packet = portalWorld.createFullPacket(world);
|
||||
playerRef.getPacketHandler().write(packet);
|
||||
}
|
||||
|
||||
// Appele quand joueur quitte monde portail
|
||||
@Override
|
||||
public void onEntityRemove(Ref<EntityStore> ref, RemoveReason reason,
|
||||
Store<EntityStore> store,
|
||||
CommandBuffer<EntityStore> commandBuffer) {
|
||||
// Effacer etat UI
|
||||
playerRef.getPacketHandler().write(new UpdatePortal(null, null));
|
||||
portalWorld.getSeesUi().remove(playerRef.getUuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<EntityStore> getQuery() {
|
||||
return Query.and(Player.getComponentType(), PlayerRef.getComponentType());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### UiTickingSystem
|
||||
|
||||
Met a jour l'UI portail chaque seconde:
|
||||
|
||||
```java
|
||||
public class UiTickingSystem extends DelayedEntitySystem<EntityStore> {
|
||||
public UiTickingSystem() {
|
||||
super(1.0f); // Tick chaque 1 seconde
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(float dt, int index, ArchetypeChunk<EntityStore> archetypeChunk,
|
||||
Store<EntityStore> store, CommandBuffer<EntityStore> commandBuffer) {
|
||||
PortalWorld portalWorld = store.getResource(PortalWorld.getResourceType());
|
||||
if (!portalWorld.exists()) return;
|
||||
|
||||
// Envoyer temps mis a jour au joueur
|
||||
UpdatePortal packet = portalWorld.createUpdatePacket(world);
|
||||
playerRef.getPacketHandler().write(packet);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Systemes Destination Portail
|
||||
|
||||
### PortalInvalidDestinationSystem
|
||||
|
||||
Gere les portails avec destinations invalides:
|
||||
|
||||
```java
|
||||
public class PortalInvalidDestinationSystem {
|
||||
// Eteint portails quand monde destination ferme
|
||||
public static void turnOffPortalsInWorld(World world, World closedWorld) {
|
||||
// Trouver tous portails pointant vers closedWorld
|
||||
// Mettre leur destination a null
|
||||
// Mettre a jour etat bloc a "off"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CloseWorldWhenBreakingDeviceSystems
|
||||
|
||||
Gere la destruction du dispositif portail:
|
||||
|
||||
```java
|
||||
// Quand composant dispositif portail supprime
|
||||
public class ComponentRemoved extends System<ChunkStore> {
|
||||
// Fermer le monde de destination
|
||||
}
|
||||
|
||||
// Quand entite bloc portail supprimee
|
||||
public class EntityRemoved extends System<ChunkStore> {
|
||||
// Fermer le monde de destination
|
||||
}
|
||||
```
|
||||
|
||||
## Systemes Evenement Vide
|
||||
|
||||
### VoidEventRefSystem
|
||||
|
||||
Gere les references entites evenement vide:
|
||||
|
||||
```java
|
||||
public class VoidEventRefSystem extends System<EntityStore> {
|
||||
// Suit cycle de vie entite evenement vide
|
||||
// Met a jour PortalWorld.voidEventRef
|
||||
}
|
||||
```
|
||||
|
||||
### VoidEventStagesSystem
|
||||
|
||||
Progresse a travers les etapes evenement vide:
|
||||
|
||||
```java
|
||||
public class VoidEventStagesSystem extends System<EntityStore> {
|
||||
// Verifie temps ecoule
|
||||
// Active etape suivante quand seuil temps atteint
|
||||
// Met a jour VoidEvent.activeStage
|
||||
}
|
||||
```
|
||||
|
||||
### VoidInvasionPortalsSpawnSystem
|
||||
|
||||
Fait apparaitre portails invasion pendant evenements vide:
|
||||
|
||||
```java
|
||||
public class VoidInvasionPortalsSpawnSystem extends System<EntityStore> {
|
||||
// Cree entites spawner vide
|
||||
// Utilise grille hash spatiale pour maintenir distance minimum
|
||||
}
|
||||
```
|
||||
|
||||
### VoidSpawnerSystems.Instantiate
|
||||
|
||||
Instancie entites spawner vide:
|
||||
|
||||
```java
|
||||
public class Instantiate extends System<EntityStore> {
|
||||
// Cree entite spawner depuis config
|
||||
// Ajoute a grille spatiale VoidEvent
|
||||
}
|
||||
```
|
||||
|
||||
### StartVoidEventInFragmentSystem
|
||||
|
||||
Initie evenements vide dans fragments portail:
|
||||
|
||||
```java
|
||||
public class StartVoidEventInFragmentSystem extends System<EntityStore> {
|
||||
// Verifie si invasion vide devrait demarrer
|
||||
// Cree entite VoidEvent
|
||||
// Configure premiere etape
|
||||
}
|
||||
```
|
||||
|
||||
## Systemes Malediction
|
||||
|
||||
### DiedInPortalSystem
|
||||
|
||||
Suit les morts joueurs dans mondes portail:
|
||||
|
||||
```java
|
||||
public class DiedInPortalSystem extends System<EntityStore> {
|
||||
// A la mort joueur dans monde portail:
|
||||
// - Ajouter UUID joueur a set diedInWorld
|
||||
// - Empeche re-entree
|
||||
}
|
||||
```
|
||||
|
||||
### CurseItemDropsSystem
|
||||
|
||||
Marque items laches comme maudits:
|
||||
|
||||
```java
|
||||
public class CurseItemDropsSystem extends System<EntityStore> {
|
||||
// Items laches dans monde portail deviennent maudits
|
||||
// Items maudits sont perdus a la mort
|
||||
}
|
||||
```
|
||||
|
||||
### DeleteCursedItemsOnSpawnSystem
|
||||
|
||||
Supprime items maudits quand joueur spawn:
|
||||
|
||||
```java
|
||||
public class DeleteCursedItemsOnSpawnSystem extends System<EntityStore> {
|
||||
// Quand joueur reapparait apres mort dans portail
|
||||
// Supprimer tous items maudits de l'inventaire
|
||||
}
|
||||
```
|
||||
|
||||
## Interactions Portail
|
||||
|
||||
### EnterPortalInteraction
|
||||
|
||||
Gere l'entree dans un portail:
|
||||
|
||||
```java
|
||||
public class EnterPortalInteraction extends SimpleBlockInteraction {
|
||||
// Temps minimum avant autoriser utilisation portail
|
||||
public static final Duration MINIMUM_TIME_IN_WORLD = Duration.ofMillis(3000L);
|
||||
|
||||
@Override
|
||||
protected void interactWithBlock(...) {
|
||||
// Verifier dispositif portail existe
|
||||
// Verifier monde destination vivant
|
||||
// Verifier joueur pas mort dans monde cible
|
||||
// Teleporter joueur vers instance
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Etats monde cible:
|
||||
- `OKAY` - Peut entrer
|
||||
- `WORLD_DEAD` - Destination fermee
|
||||
- `DIED_IN_WORLD` - Joueur mort la-bas
|
||||
- `NO_SPAWN_AVAILABLE` - Pas de point de spawn
|
||||
|
||||
### ReturnPortalInteraction
|
||||
|
||||
Gere le retour d'un monde portail:
|
||||
|
||||
```java
|
||||
public class ReturnPortalInteraction extends SimpleBlockInteraction {
|
||||
// Temps minimum avant autoriser retour
|
||||
public static final Duration MINIMUM_TIME_IN_WORLD = Duration.ofSeconds(15L);
|
||||
|
||||
// Avertissement affiche avant expiration timer
|
||||
public static final Duration WARNING_TIME = Duration.ofSeconds(4L);
|
||||
|
||||
@Override
|
||||
protected void interactWithBlock(...) {
|
||||
// Verifier temps minimum ecoule
|
||||
// Retirer malediction tous items
|
||||
// Sortir instance
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Enregistrement Systemes
|
||||
|
||||
Tous les systemes sont enregistres dans setup PortalsPlugin:
|
||||
|
||||
```java
|
||||
// Systemes ChunkStore
|
||||
this.getChunkStoreRegistry().registerSystem(new PortalInvalidDestinationSystem());
|
||||
this.getChunkStoreRegistry().registerSystem(new CloseWorldWhenBreakingDeviceSystems.ComponentRemoved());
|
||||
this.getChunkStoreRegistry().registerSystem(new CloseWorldWhenBreakingDeviceSystems.EntityRemoved());
|
||||
|
||||
// Systemes EntityStore
|
||||
this.getEntityStoreRegistry().registerSystem(new PortalTrackerSystems.TrackerSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new PortalTrackerSystems.UiTickingSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new DiedInPortalSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new CurseItemDropsSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new DeleteCursedItemsOnSpawnSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidEventRefSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidInvasionPortalsSpawnSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidSpawnerSystems.Instantiate());
|
||||
this.getEntityStoreRegistry().registerSystem(new StartVoidEventInFragmentSystem());
|
||||
this.getEntityStoreRegistry().registerSystem(new VoidEventStagesSystem());
|
||||
```
|
||||
|
||||
## Enregistrement Interactions
|
||||
|
||||
Les interactions portail sont enregistrees comme types codec:
|
||||
|
||||
```java
|
||||
this.getCodecRegistry(Interaction.CODEC)
|
||||
.register("Portal", EnterPortalInteraction.class, EnterPortalInteraction.CODEC)
|
||||
.register("PortalReturn", ReturnPortalInteraction.class, ReturnPortalInteraction.CODEC);
|
||||
```
|
||||
Reference in New Issue
Block a user