Config class
Пакет: com.hypixel.hytale.builtin.adventure.worldevents.condition
Файл: com/hypixel/hytale/builtin/adventure/worldevents/condition/LocationCondition.java
implements: EventCondition.Config
Поля (11)
| Модификаторы | Тип | Имя |
|---|---|---|
|
public static final BuilderCodec<LocationCondition.Config> |
CODEC |
|
protected static final int |
DEFAULT_CLEARANCE |
|
protected static final int |
DEFAULT_SEARCH_RADIUS |
|
protected static final LocationCondition.Config |
EMPTY |
|
protected int |
clearance |
|
protected EventLocation.Config |
location |
|
protected ContextKey |
locationKey |
|
protected int |
searchRadius |
|
protected Spawner.Config[] |
spawners |
|
LocationCondition |
var1 |
|
Spawner[] |
var1 |
Методы (5)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
|
public EventCondition |
createpublic EventCondition create() |
|
protected Spawner[] |
createSpawnersprotected Spawner[] createSpawners() |
|
|
for for(Spawner.Config var5 : this.spawners) |
|
|
for for(int var2 = 0; var2 < this.spawners.length; var2++) |
|
public void |
validatepublic void validate(@Nonnull Validator var1) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.adventure.worldevents.condition;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.WorldEventManager;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.WorldEventsConfig;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.condition.location.EventLocation;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.condition.location.NoLocation;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.condition.spawner.Spawner;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.context.ContextKey;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.context.LocationContext;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.event.Validator;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.event.WorldEvent;
class="kw">import com.hypixel.hytale.builtin.adventure.worldevents.util.Vector3iList;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import java.util.concurrent.CancellationException;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.CompletionException;
class="kw">import java.util.concurrent.ThreadLocalRandom;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3i;
class="kw">import org.joml.Vector3ic;
class="kw">public class LocationCondition class="kw">implements EventCondition.Ticking {
class="kw">public class="kw">static class="kw">final String ID = "LocationCondition";
class="kw">public class="kw">static class="kw">final EventCondition.Type TYPE = new EventCondition.Type("LocationCondition", 0.5F);
class="kw">public class="kw">static class="kw">final BuilderCodec<LocationCondition> CODEC = BuilderCodec.builder(LocationCondition.class, LocationCondition::new).build();
class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
class="kw">private class="kw">static class="kw">final int SPAWN_ATTEMPTS_PER_TICK = 2;
@Nonnull
class="kw">protected LocationCondition.Config config = LocationCondition.Config.EMPTY;
@Nonnull
class="kw">protected Spawner[] spawners = Spawner.EMPTY_ARRAY;
@Nonnull
class="kw">protected EventLocation location = NoLocation.INSTANCE;
class="kw">protected boolean valid = false;
class="kw">protected boolean spawnerError = false;
class="kw">protected class="kw">final Vector3i position = new Vector3i();
class="kw">protected class="kw">final Vector3iList eventLocations = new Vector3iList(8);
@Nullable
class="kw">protected CompletableFuture<Vector3iList> pending = null;
class="kw">public LocationCondition() {
}
@Override
class="kw">public boolean test() {
class="kw">return this.valid || this.spawnerError;
}
@Override
class="kw">public void reset() {
this.valid = false;
this.spawnerError = false;
this.cancelPending();
}
@Override
class="kw">public void onCancel(@Nonnull WorldEvent var1) {
this.cancelPending();
}
@Override
class="kw">public void tick(float var1, @Nonnull Store<EntityStore> var2) {
this.valid = false;
if (this.pending == null) {
this.pending = this.location.find(var2);
}
if (this.pending.isDone()) {
Vector3iList var3 = getResult(this.pending);
this.pending = null;
if (var3 != null && !var3.empty()) {
int var4 = getExclusionRadius(var2);
if (var4 > 0) {
try {
collectCurrentEventLocations(var2, this.eventLocations);
filterPositions(var3, this.eventLocations, var4);
} class="kw">finally {
this.eventLocations.clear();
}
}
if (!var3.empty()) {
World var5 = var2.getExternalData().getWorld();
ChunkStore var6 = var5.getChunkStore();
ThreadLocalRandom var7 = ThreadLocalRandom.current();
for (int var8 = 0; !this.valid && var8 < 2; var8++) {
Vector3ic var9 = var3.get(var7, this.position);
if (var9 != null) {
int var10 = var9.x();
int var11 = var9.z();
int var12 = Spawner.findSurface(var10, var9.y(), var11, this.config.clearance, this.config.searchRadius, var6);
if (var12 != Integer.MIN_VALUE) {
this.position.set(var10, var12, var11);
this.valid = true;
for (Spawner var16 : this.spawners) {
Spawner.Result var17 = var16.test(var5, this.position, var7);
if (var17 == Spawner.Result.ERROR) {
this.spawnerError = true;
this.valid = false;
class="kw">return;
}
if (var17 == Spawner.Result.FAIL) {
this.valid = false;
this.spawnerError = false;
break;
}
}
}
}
}
}
}
}
}
@Override
class="kw">public boolean onStart(@Nonnull WorldEvent var1) {
if (this.config.locationKey == null) {
((HytaleLogger.Api)LOGGER.atWarning()).log("Condition failed: locationKey is not set");
class="kw">return false;
} else {
var1.context.remove(this.config.locationKey, LocationContext.class);
class="kw">return true;
}
}
@Override
class="kw">public boolean onComplete(@Nonnull WorldEvent var1) {
if (this.spawnerError) {
((HytaleLogger.Api)LOGGER.atWarning()).log("Condition failed: one or more spawners had an error. See earlier logs");
class="kw">return false;
}
if (this.config.locationKey == null) {
((HytaleLogger.Api)LOGGER.atWarning()).log("Condition failed: locationKey is not set");
class="kw">return false;
}
var1.context.put(this.config.locationKey, new LocationContext(new Vector3i(this.position)));
boolean var2 = true;
for (Spawner var6 : this.spawners) {
var2 &= var6.onComplete(this.position, var1);
}
class="kw">return var2;
}
class="kw">protected void cancelPending() {
if (this.pending != null) {
this.pending.cancel(false);
this.pending = null;
}
}
@Nullable
class="kw">protected class="kw">static Vector3iList getResult(@Nonnull CompletableFuture<Vector3iList> var0) {
try {
class="kw">return var0.join();
} catch (CancellationException var2) {
class="kw">return null;
} catch (CompletionException var3) {
((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(var3)).log("Location search failed");
class="kw">return null;
}
}
class="kw">protected class="kw">static int getExclusionRadius(@Nonnull Store<EntityStore> var0) {
World var1 = var0.getExternalData().getWorld();
WorldEventsConfig var2 = var1.getGameplayConfig().getPluginConfig().get(WorldEventsConfig.class);
class="kw">return var2 != null ? var2.exclusionRadius() : 512;
}
class="kw">protected class="kw">static void collectCurrentEventLocations(@Nonnull Store<EntityStore> var0, @Nonnull Vector3iList var1) {
WorldEventManager var2 = var0.getResource(WorldEventManager.getResourceType());
var2.forEach(var1, (var0x, var1x) -> var0x.context.forEach(LocationContext.class, var1x, null, (var0xx, var1xx, var2x) -> var1xx.add(var0xx.location())));
}
class="kw">protected class="kw">static void filterPositions(@Nonnull Vector3iList var0, @Nonnull Vector3iList var1, int var2) {
Vector3i var3 = new Vector3i();
Vector3i var4 = new Vector3i();
long var5 = (long)var2 * var2;
for (int var7 = 0; var7 < var1.size(); var7++) {
Vector3i var8 = var1.get(var7, var3);
int var9 = 0;
while (var9 < var0.size()) {
Vector3i var10 = var0.get(var9, var4);
long var11 = var10.distanceSquared(var8);
if (var11 < var5) {
var0.remove(var9);
} else {
var9++;
}
}
}
}
class="kw">public class="kw">static class Config class="kw">implements EventCondition.Config {
class="kw">public class="kw">static class="kw">final BuilderCodec<LocationCondition.Config> CODEC = BuilderCodec.builder(LocationCondition.Config.class, LocationCondition.Config::new)
.documentation("A condition that completes once it has found a suitable location to spawn content at.")
.<ContextKey>append(new KeyedCodec<>("LocationKey", ContextKey.CODEC), (var0, var1) -> var0.locationKey = var1, var0 -> var0.locationKey)
.documentation("Define the location variable name that this condition has found and that can be referenced by other conditions and actions.")
.add()
.<EventLocation.Config>append(
new KeyedCodec<>("LocationType", EventLocation.Config.TYPE_CODEC), (var0, var1) -> var0.location = var1, var0 -> var0.location
)
.documentation("The location configuration used to determine where the content will be spawned.")
.add()
.<Spawner.Config[]>append(new KeyedCodec<>("Content", Spawner.Config.ARRAY_CODEC), (var0, var1) -> var0.spawners = var1, var0 -> var0.spawners)
.documentation("A list of different types of content to spawn at the given location.")
.add()
.<Integer>append(new KeyedCodec<>("Clearance", Codec.INTEGER), (var0, var1) -> var0.clearance = var1, var0 -> var0.clearance)
.documentation("The number of open blocks required above a candidate surface for it to be considered valid.")
.addValidator(Validators.greaterThanOrEqual(0))
.add()
.<Integer>append(new KeyedCodec<>("SearchRadius", Codec.INTEGER), (var0, var1) -> var0.searchRadius = var1, var0 -> var0.searchRadius)
.documentation("The maximum number of blocks to search in either direction from a candidate's own Y when looking for a nearby surface.")
.addValidator(Validators.greaterThanOrEqual(0))
.add()
.build();
class="kw">protected class="kw">static class="kw">final LocationCondition.Config EMPTY = new LocationCondition.Config();
class="kw">protected class="kw">static class="kw">final int DEFAULT_CLEARANCE = 2;
class="kw">protected class="kw">static class="kw">final int DEFAULT_SEARCH_RADIUS = 16;
@Nullable
class="kw">protected ContextKey locationKey = null;
@Nonnull
class="kw">protected EventLocation.Config location = NoLocation.Config.INSTANCE;
@Nonnull
class="kw">protected Spawner.Config[] spawners = Spawner.Config.EMPTY_ARRAY;
class="kw">protected int clearance = 2;
class="kw">protected int searchRadius = 16;
class="kw">public Config() {
}
@Nonnull
@Override
class="kw">public EventCondition create() {
LocationCondition var1 = new LocationCondition();
var1.config = this;
var1.spawners = this.createSpawners();
var1.location = this.location.create();
class="kw">return var1;
}
@Override
class="kw">public void validate(@Nonnull Validator var1) {
var1.addDefinedKey("LocationCondition", "LocationKey", this.locationKey);
for (Spawner.Config var5 : this.spawners) {
var5.validate(var1);
}
}
@Nonnull
class="kw">protected Spawner[] createSpawners() {
Spawner[] var1 = new Spawner[this.spawners.length];
for (int var2 = 0; var2 < this.spawners.length; var2++) {
var1[var2] = this.spawners[var2].create();
}
class="kw">return var1;
}
}
}