Aller au contenu

Zones

Une zone est une région à laquelle s’ajoutent les règles qui s’y appliquent. Les zones ouvertes par l’API se comportent exactement comme celles définies dans zones.yml, et les deux apparaissent dans /sh list.

public interface SomaHider {
ZoneBuilder hide();
ZoneBuilder hide(Region region);
Collection<HiderZone> zones();
void refresh();
}
MéthodeEffet
hide()Commence une zone qui couvre tout le serveur.
hide(Region)Commence une zone délimitée par une région.
zones()Renvoie les zones ouvertes, les vôtres comme celles issues de la configuration.
refresh()Recalcule la visibilité tout de suite, sans attendre la passe suivante.

hide() sans région donne une zone sans frontière : tous les joueurs connectés sont dedans. C’est ce qu’il faut pour un événement à l’échelle du serveur plutôt que localisé.

refresh() sert rarement. SomaHider recalcule déjà la visibilité plusieurs fois par seconde, et réagit seul aux connexions, aux déconnexions et aux téléportations. Appelez-le quand vous venez de modifier quelque chose que lit une règle personnalisée et que vous ne voulez pas attendre. Il est sûr depuis n’importe quel thread : en dehors du thread principal, il planifie le travail au lieu de l’exécuter sur place.

Region décide qui se trouve à l’intérieur :

@FunctionalInterface
public interface Region {
boolean contains(Location location);
}

Un cercle est fourni :

Region arena = Region.circle(center, 40.0);

Il compare x et z au centre et vérifie le monde : c’est donc un cylindre sans limite de hauteur, la même forme qu’une zone définie dans zones.yml.

Toute autre forme s’écrit en lambda :

Region cuboid = location -> box.getWorld().equals(location.getWorld())
&& box.contains(location.toVector());

contains s’exécute sur le thread principal, une fois par joueur connecté et par passe. Restez-en à du calcul. N’y mettez ni appel à une base de données, ni requête réseau, ni verrou.

public interface ZoneBuilder {
ZoneBuilder named(String name);
ZoneBuilder disguise(DisguiseProfile disguise);
ZoneBuilder disguise(ConfigurationSection section);
ZoneBuilder duration(Duration duration);
ZoneBuilder groupResolver(GroupResolver resolver);
ZoneBuilder reveal(VisibilityRule... rules);
HiderZone open();
}
MéthodeValeur par défaut si omise
named(String)Un nom généré, du type zone4.
disguise(...)La section disguise de config.yml.
duration(Duration)Aucune expiration. La zone tourne jusqu’à ce que vous la fermiez.
groupResolver(GroupResolver)Un resolver qui renvoie null pour tout le monde, les règles de groupe ne correspondent donc jamais.
reveal(VisibilityRule...)Aucune règle. Tout le monde est masqué pour tout le monde.

open() enregistre la zone et la renvoie. Elle commence à masquer les joueurs à la passe suivante, quelques ticks plus tard.

Donnez à vos zones un nom que vous reconnaîtrez dans /sh list, et assurez-vous qu’il n’entre pas en conflit avec un identifiant de zones.yml : /sh stop <nom> compare les noms sans tenir compte de la casse.

@FunctionalInterface
public interface GroupResolver {
String groupOf(Player player);
}

L’identifiant de groupe est ce que comparent Reveal.sameGroup() et ses voisines. Renvoyer null signifie que le joueur n’appartient à aucun groupe, et un groupe null n’est jamais révélé par une règle de groupe.

groupOf est appelé pendant les passes de visibilité : gardez-le économe. Lire un champ ou une map en cache convient, interroger une base de données non.

public interface HiderZone {
String name();
void close();
}

Une zone se ferme quand vous appelez close(), ou d’elle-même une fois sa duration écoulée. La fermeture libère tous les joueurs qu’elle masquait, et les déguisements qui leur avaient été attribués sont oubliés.

Rien ne ferme vos zones à la désactivation de votre plugin : fermez-les donc dans onDisable() si une zone orpheline poserait problème.

@Override
public void onDisable() {
if (zone != null) {
zone.close();
}
}