NPCSpawningConfig class

Пакет: com.hypixel.hytale.server.spawning

Файл: com/hypixel/hytale/server/spawning/SpawningPlugin.java

Поля (5)

МодификаторыТипИмя
public static final BuilderCodec<SpawningPlugin.NPCSpawningConfig> CODEC
private String defaultMarkerModel
private double localSpawnControllerJoinDelay
private int maxActiveJobs
private double spawnBudgetFactor

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.spawning;

class="kw">import com.hypixel.hytale.assetstore.AssetRegistry;
class="kw">import com.hypixel.hytale.assetstore.event.LoadedAssetsEvent;
class="kw">import com.hypixel.hytale.assetstore.event.RemovedAssetsEvent;
class="kw">import com.hypixel.hytale.assetstore.map.DefaultAssetMap;
class="kw">import com.hypixel.hytale.assetstore.map.IndexedAssetMap;
class="kw">import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
class="kw">import com.hypixel.hytale.builtin.tagset.config.NPCGroup;
class="kw">import com.hypixel.hytale.builtin.weather.components.WeatherTracker;
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.common.map.IWeightedMap;
class="kw">import com.hypixel.hytale.common.util.FormatUtil;
class="kw">import com.hypixel.hytale.component.AddReason;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.RemoveReason;
class="kw">import com.hypixel.hytale.component.ResourceType;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.spatial.KDTree;
class="kw">import com.hypixel.hytale.component.spatial.SpatialResource;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.server.core.Options;
class="kw">import com.hypixel.hytale.server.core.asset.HytaleAssetStore;
class="kw">import com.hypixel.hytale.server.core.asset.LoadAssetEvent;
class="kw">import com.hypixel.hytale.server.core.asset.type.blockset.config.BlockSet;
class="kw">import com.hypixel.hytale.server.core.asset.type.environment.config.Environment;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.Model;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
class="kw">import com.hypixel.hytale.server.core.asset.type.responsecurve.config.ResponseCurve;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.modules.entity.EntityModule;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction;
class="kw">import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
class="kw">import com.hypixel.hytale.server.core.plugin.JavaPlugin;
class="kw">import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
class="kw">import com.hypixel.hytale.server.core.universe.Universe;
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 com.hypixel.hytale.server.core.util.Config;
class="kw">import com.hypixel.hytale.server.flock.config.FlockAsset;
class="kw">import com.hypixel.hytale.server.npc.AllNPCsLoadedEvent;
class="kw">import com.hypixel.hytale.server.npc.NPCPlugin;
class="kw">import com.hypixel.hytale.server.npc.asset.builder.BuilderInfo;
class="kw">import com.hypixel.hytale.server.npc.components.SpawnBeaconReference;
class="kw">import com.hypixel.hytale.server.npc.components.SpawnMarkerReference;
class="kw">import com.hypixel.hytale.server.npc.entities.NPCEntity;
class="kw">import com.hypixel.hytale.server.npc.systems.SpawnReferenceSystems;
class="kw">import com.hypixel.hytale.server.spawning.assets.spawnmarker.config.SpawnMarker;
class="kw">import com.hypixel.hytale.server.spawning.assets.spawns.config.BeaconNPCSpawn;
class="kw">import com.hypixel.hytale.server.spawning.assets.spawns.config.NPCSpawn;
class="kw">import com.hypixel.hytale.server.spawning.assets.spawns.config.RoleSpawnParameters;
class="kw">import com.hypixel.hytale.server.spawning.assets.spawns.config.WorldNPCSpawn;
class="kw">import com.hypixel.hytale.server.spawning.assets.spawnsuppression.SpawnSuppression;
class="kw">import com.hypixel.hytale.server.spawning.beacons.InitialBeaconDelay;
class="kw">import com.hypixel.hytale.server.spawning.beacons.LegacySpawnBeaconEntity;
class="kw">import com.hypixel.hytale.server.spawning.beacons.SpawnBeacon;
class="kw">import com.hypixel.hytale.server.spawning.beacons.SpawnBeaconSystems;
class="kw">import com.hypixel.hytale.server.spawning.blockstates.SpawnMarkerBlock;
class="kw">import com.hypixel.hytale.server.spawning.blockstates.SpawnMarkerBlockReference;
class="kw">import com.hypixel.hytale.server.spawning.blockstates.SpawnMarkerBlockStateSystems;
class="kw">import com.hypixel.hytale.server.spawning.commands.SpawnCommand;
class="kw">import com.hypixel.hytale.server.spawning.corecomponents.builders.BuilderActionTriggerSpawnBeacon;
class="kw">import com.hypixel.hytale.server.spawning.interactions.TriggerSpawnMarkersInteraction;
class="kw">import com.hypixel.hytale.server.spawning.local.LocalSpawnBeacon;
class="kw">import com.hypixel.hytale.server.spawning.local.LocalSpawnBeaconSystem;
class="kw">import com.hypixel.hytale.server.spawning.local.LocalSpawnController;
class="kw">import com.hypixel.hytale.server.spawning.local.LocalSpawnControllerSystem;
class="kw">import com.hypixel.hytale.server.spawning.local.LocalSpawnForceTriggerSystem;
class="kw">import com.hypixel.hytale.server.spawning.local.LocalSpawnSetupSystem;
class="kw">import com.hypixel.hytale.server.spawning.local.LocalSpawnState;
class="kw">import com.hypixel.hytale.server.spawning.managers.BeaconSpawnManager;
class="kw">import com.hypixel.hytale.server.spawning.managers.SpawnManager;
class="kw">import com.hypixel.hytale.server.spawning.spawnmarkers.SpawnMarkerEntity;
class="kw">import com.hypixel.hytale.server.spawning.spawnmarkers.SpawnMarkerSystems;
class="kw">import com.hypixel.hytale.server.spawning.suppression.component.ChunkSuppressionEntry;
class="kw">import com.hypixel.hytale.server.spawning.suppression.component.ChunkSuppressionQueue;
class="kw">import com.hypixel.hytale.server.spawning.suppression.component.SpawnSuppressionComponent;
class="kw">import com.hypixel.hytale.server.spawning.suppression.component.SpawnSuppressionController;
class="kw">import com.hypixel.hytale.server.spawning.suppression.system.ChunkSuppressionSystems;
class="kw">import com.hypixel.hytale.server.spawning.suppression.system.SpawnMarkerSuppressionSystem;
class="kw">import com.hypixel.hytale.server.spawning.suppression.system.SpawnSuppressionSystems;
class="kw">import com.hypixel.hytale.server.spawning.systems.BeaconSpatialSystem;
class="kw">import com.hypixel.hytale.server.spawning.systems.LegacyBeaconSpatialSystem;
class="kw">import com.hypixel.hytale.server.spawning.systems.SpawnMarkerSpatialSystem;
class="kw">import com.hypixel.hytale.server.spawning.util.FloodFillEntryPoolProviderSimple;
class="kw">import com.hypixel.hytale.server.spawning.util.FloodFillPositionSelector;
class="kw">import com.hypixel.hytale.server.spawning.world.WorldEnvironmentSpawnData;
class="kw">import com.hypixel.hytale.server.spawning.world.WorldNPCSpawnStat;
class="kw">import com.hypixel.hytale.server.spawning.world.component.ChunkSpawnData;
class="kw">import com.hypixel.hytale.server.spawning.world.component.ChunkSpawnedNPCData;
class="kw">import com.hypixel.hytale.server.spawning.world.component.SpawnJobData;
class="kw">import com.hypixel.hytale.server.spawning.world.component.WorldSpawnData;
class="kw">import com.hypixel.hytale.server.spawning.world.manager.EnvironmentSpawnParameters;
class="kw">import com.hypixel.hytale.server.spawning.world.manager.WorldSpawnManager;
class="kw">import com.hypixel.hytale.server.spawning.world.manager.WorldSpawnWrapper;
class="kw">import com.hypixel.hytale.server.spawning.world.system.ChunkSpawningSystems;
class="kw">import com.hypixel.hytale.server.spawning.world.system.MoonPhaseChangeEventSystem;
class="kw">import com.hypixel.hytale.server.spawning.world.system.WorldSpawnJobSystems;
class="kw">import com.hypixel.hytale.server.spawning.world.system.WorldSpawnTrackingSystem;
class="kw">import com.hypixel.hytale.server.spawning.world.system.WorldSpawningSystem;
class="kw">import com.hypixel.hytale.server.spawning.wrappers.BeaconSpawnWrapper;
class="kw">import com.hypixel.hytale.server.spawning.wrappers.SpawnWrapper;
class="kw">import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.ints.IntIterator;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.ints.IntSet;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectListIterator;
class="kw">import java.util.List;
class="kw">import java.util.Map;
class="kw">import java.util.Set;
class="kw">import java.util.Map.Entry;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class SpawningPlugin class="kw">extends JavaPlugin {
   class="kw">private class="kw">static class="kw">final String DEFAULT_SPAWN_MARKER_MODEL = "NPC_Spawn_Marker";
   class="kw">private class="kw">static class="kw">final int TICK_COLUMN_BUDGET = 20480;
   class="kw">private class="kw">static class="kw">final float OVERPOPULATION_RATIO = 0.25F;
   class="kw">private class="kw">static class="kw">final int OVERPOPULATION_GROUP_BUFFER = 4;
   class="kw">private class="kw">static SpawningPlugin instance;
   class="kw">private ComponentType<ChunkStore, SpawnMarkerBlock> spawnMarkerBlockComponentType;
   class="kw">private Model spawnMarkerModel;
   class="kw">private double localSpawnControllerJoinDelay;
   class="kw">private int tickColumnBudget;
   class="kw">private class="kw">final WorldSpawnManager worldSpawnManager = new WorldSpawnManager();
   class="kw">private class="kw">final BeaconSpawnManager beaconSpawnManager = new BeaconSpawnManager();
   class="kw">private class="kw">final Config<SpawningPlugin.NPCSpawningConfig> config = this.withConfig("SpawningModule", SpawningPlugin.NPCSpawningConfig.CODEC);
   class="kw">private ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> legacyBeaconSpatialResource;
   class="kw">private ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> spawnMarkerSpatialResource;
   class="kw">private ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> manualSpawnBeaconSpatialResource;
   class="kw">private ComponentType<EntityStore, SpawnMarkerEntity> spawnMarkerComponentType;
   class="kw">private ComponentType<EntityStore, LocalSpawnController> localSpawnControllerComponentType;
   class="kw">private ResourceType<EntityStore, WorldSpawnData> worldSpawnDataResourceType;
   class="kw">private ComponentType<EntityStore, SpawnSuppressionComponent> spawnSuppressorComponentType;
   class="kw">private ResourceType<EntityStore, SpawnSuppressionController> spawnSuppressionControllerResourceType;
   class="kw">private ComponentType<EntityStore, LocalSpawnBeacon> localSpawnBeaconComponentType;
   class="kw">private ResourceType<EntityStore, LocalSpawnState> localSpawnStateResourceType;
   class="kw">private ComponentType<ChunkStore, SpawnJobData> spawnJobDataComponentType;
   class="kw">private ComponentType<ChunkStore, ChunkSpawnData> chunkSpawnDataComponentType;
   class="kw">private ComponentType<ChunkStore, ChunkSpawnedNPCData> chunkSpawnedNPCDataComponentType;
   class="kw">private ResourceType<ChunkStore, ChunkSuppressionQueue> chunkSuppressionQueueResourceType;
   class="kw">private ComponentType<ChunkStore, ChunkSuppressionEntry> chunkSuppressionEntryComponentType;
   class="kw">private ComponentType<EntityStore, InitialBeaconDelay> initialBeaconDelayComponentType;
   class="kw">private ComponentType<EntityStore, SpawnMarkerReference> spawnMarkerReferenceComponentType;
   class="kw">private ComponentType<EntityStore, SpawnBeaconReference> spawnBeaconReferenceComponentType;
   class="kw">private ComponentType<EntityStore, FloodFillPositionSelector> floodFillPositionSelectorComponentType;
   class="kw">private ResourceType<EntityStore, FloodFillEntryPoolProviderSimple> floodFillEntryPoolProviderSimpleResourceType;
   class="kw">private ComponentType<EntityStore, SpawnMarkerBlockReference> spawnMarkerBlockReferenceComponentType;

   class="kw">public class="kw">static SpawningPlugin get() {
      class="kw">return instance;
   }

   class="kw">public SpawningPlugin(@Nonnull JavaPluginInit var1) {
      super(var1);
   }

   @Override
   class="kw">public void setup() {
      instance = this;
      this.getCommandRegistry().registerCommand(new SpawnCommand());
      this.getEventRegistry().register(LoadedAssetsEvent.class, Environment.class, this::onEnvironmentChange);
      this.getEventRegistry().register(AllNPCsLoadedEvent.class, this::onLoadedNPCEvent);
      this.getEventRegistry().register(LoadedAssetsEvent.class, SpawnMarker.class, this::onSpawnMarkersChange);
      this.getEventRegistry().register(RemovedAssetsEvent.class, SpawnMarker.class, SpawningPlugin::onSpawnMarkersRemove);
      this.getEventRegistry().register(LoadedAssetsEvent.class, WorldNPCSpawn.class, this::onWorldNPCSpawnsLoaded);
      this.getEventRegistry().register(LoadedAssetsEvent.class, BeaconNPCSpawn.class, this::onBeaconNPCSpawnsLoaded);
      this.getEventRegistry().register(RemovedAssetsEvent.class, WorldNPCSpawn.class, this::onWorldNPCSpawnsRemoved);
      this.getEventRegistry().register(RemovedAssetsEvent.class, BeaconNPCSpawn.class, this::onBeaconNPCSpawnsRemoved);
      this.getEventRegistry().register(LoadedAssetsEvent.class, ModelAsset.class, this::onModelAssetChange);
      this.getEventRegistry().register((short)-7, LoadAssetEvent.class, this::onLoadAsset);
      this.getEntityRegistry().registerEntity("LegacySpawnBeacon", LegacySpawnBeaconEntity.class, LegacySpawnBeaconEntity::new, LegacySpawnBeaconEntity.CODEC);
      this.getEntityRegistry().registerEntity("SpawnBeacon", SpawnBeacon.class, SpawnBeacon::new, SpawnBeacon.CODEC);
      AssetRegistry.register(
         ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(
                              SpawnMarker.class, new DefaultAssetMap()
                           )
                           .setPath("NPC/Spawn/Markers"))
                        .setCodec(SpawnMarker.CODEC))
                     .setKeyFunction(SpawnMarker::getId))
                  .loadsAfter(FlockAsset.class, ModelAsset.class))
               .loadsBefore(Interaction.class))
            .build()
      );
      AssetRegistry.register(
         ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(
                              WorldNPCSpawn.class, new IndexedLookupTableAssetMap<>(WorldNPCSpawn[]::new)
                           )
                           .setPath("NPC/Spawn/World"))
                        .setCodec(WorldNPCSpawn.CODEC))
                     .setKeyFunction(WorldNPCSpawn::getId))
                  .setReplaceOnRemove(WorldNPCSpawn::new))
               .loadsAfter(Environment.class, BlockSet.class, FlockAsset.class))
            .build()
      );
      AssetRegistry.register(
         ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(
                              BeaconNPCSpawn.class, new IndexedLookupTableAssetMap<>(BeaconNPCSpawn[]::new)
                           )
                           .setPath("NPC/Spawn/Beacons"))
                        .setCodec(BeaconNPCSpawn.CODEC))
                     .setKeyFunction(BeaconNPCSpawn::getId))
                  .setReplaceOnRemove(BeaconNPCSpawn::new))
               .loadsAfter(Environment.class, BlockSet.class, SpawnSuppression.class, FlockAsset.class, ModelAsset.class, ResponseCurve.class))
            .build()
      );
      AssetRegistry.register(
         ((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)((HytaleAssetStore.Builder)HytaleAssetStore.builder(
                              SpawnSuppression.class, new IndexedAssetMap()
                           )
                           .setPath("NPC/Spawn/Suppression"))
                        .setCodec(SpawnSuppression.CODEC))
                     .setKeyFunction(SpawnSuppression::getId))
                  .setReplaceOnRemove(SpawnSuppression::new))
               .loadsAfter(NPCGroup.class))
            .build()
      );
      NPCPlugin.get().registerCoreComponentType("TriggerSpawnBeacon", BuilderActionTriggerSpawnBeacon::new);
      this.spawnMarkerBlockComponentType = this.getChunkStoreRegistry().registerComponent(SpawnMarkerBlock.class, "SpawnMarkerBlock", SpawnMarkerBlock.CODEC);
      this.spawnMarkerComponentType = this.getEntityStoreRegistry().registerComponent(SpawnMarkerEntity.class, "SpawnMarkerComponent", SpawnMarkerEntity.CODEC);
      this.localSpawnControllerComponentType = this.getEntityStoreRegistry().registerComponent(LocalSpawnController.class, LocalSpawnController::new);
      this.worldSpawnDataResourceType = this.getEntityStoreRegistry().registerResource(WorldSpawnData.class, WorldSpawnData::new);
      this.localSpawnBeaconComponentType = this.getEntityStoreRegistry().registerComponent(LocalSpawnBeacon.class, "LocalSpawnBeacon", LocalSpawnBeacon.CODEC);
      this.localSpawnStateResourceType = this.getEntityStoreRegistry().registerResource(LocalSpawnState.class, LocalSpawnState::new);
      this.legacyBeaconSpatialResource = this.getEntityStoreRegistry().registerSpatialResource(() -> new KDTree<>(Ref::isValid));
      this.spawnMarkerSpatialResource = this.getEntityStoreRegistry().registerSpatialResource(() -> new KDTree<>(Ref::isValid));
      this.manualSpawnBeaconSpatialResource = this.getEntityStoreRegistry().registerSpatialResource(() -> new KDTree<>(Ref::isValid));
      this.spawnSuppressorComponentType = this.getEntityStoreRegistry()
         .registerComponent(SpawnSuppressionComponent.class, "SpawnSuppression", SpawnSuppressionComponent.CODEC);
      this.spawnSuppressionControllerResourceType = this.getEntityStoreRegistry()
         .registerResource(SpawnSuppressionController.class, "SpawnSuppressionController", SpawnSuppressionController.CODEC);
      this.initialBeaconDelayComponentType = this.getEntityStoreRegistry().registerComponent(InitialBeaconDelay.class, InitialBeaconDelay::new);
      this.spawnMarkerReferenceComponentType = this.getEntityStoreRegistry()
         .registerComponent(SpawnMarkerReference.class, "SpawnMarkerReference", SpawnMarkerReference.CODEC);
      this.spawnBeaconReferenceComponentType = this.getEntityStoreRegistry()
         .registerComponent(SpawnBeaconReference.class, "SpawnBeaconReference", SpawnBeaconReference.CODEC);
      this.floodFillPositionSelectorComponentType = this.getEntityStoreRegistry().registerComponent(FloodFillPositionSelector.class, () -> {
         throw new UnsupportedOperationException("Not implemented");
      });
      this.floodFillEntryPoolProviderSimpleResourceType = this.getEntityStoreRegistry()
         .registerResource(FloodFillEntryPoolProviderSimple.class, FloodFillEntryPoolProviderSimple::new);
      this.spawnMarkerBlockReferenceComponentType = this.getEntityStoreRegistry()
         .registerComponent(SpawnMarkerBlockReference.class, "SpawnMarkerBlockReference", SpawnMarkerBlockReference.CODEC);
      this.spawnJobDataComponentType = this.getChunkStoreRegistry().registerComponent(SpawnJobData.class, SpawnJobData::new);
      this.chunkSpawnDataComponentType = this.getChunkStoreRegistry().registerComponent(ChunkSpawnData.class, ChunkSpawnData::new);
      this.chunkSpawnedNPCDataComponentType = this.getChunkStoreRegistry()
         .registerComponent(ChunkSpawnedNPCData.class, "ChunkSpawnedNPCData", ChunkSpawnedNPCData.CODEC);
      this.chunkSuppressionQueueResourceType = this.getChunkStoreRegistry().registerResource(ChunkSuppressionQueue.class, ChunkSuppressionQueue::new);
      this.chunkSuppressionEntryComponentType = this.getChunkStoreRegistry().registerComponent(ChunkSuppressionEntry.class, () -> {
         throw new UnsupportedOperationException("Not implemented");
      });
      EntityModule var1 = EntityModule.get();
      ComponentType var2 = var1.getPlayerComponentType();
      ComponentType var3 = var1.getTransformComponentType();
      ComponentType var4 = var1.getComponentType(LegacySpawnBeaconEntity.class);
      ComponentType var5 = var1.getComponentType(SpawnBeacon.class);
      ResourceType var6 = var1.getPlayerSpatialResourceType();
      this.getEntityStoreRegistry().registerSystem(new SpawnSuppressionSystems.EnsureNetworkSendable());
      this.getEntityStoreRegistry()
         .registerSystem(
            new SpawnSuppressionSystems.Load(
               this.spawnSuppressionControllerResourceType,
               this.spawnMarkerComponentType,
               this.chunkSuppressionQueueResourceType,
               this.chunkSuppressionEntryComponentType
            )
         );
      this.getEntityStoreRegistry()
         .registerSystem(
            new SpawnSuppressionSystems.Suppressor(
               this.spawnSuppressorComponentType,
               this.spawnSuppressionControllerResourceType,
               this.spawnMarkerComponentType,
               this.chunkSuppressionQueueResourceType,
               this.spawnMarkerSpatialResource
            )
         );
      this.getEntityStoreRegistry().registerSystem(new LegacyBeaconSpatialSystem(this.legacyBeaconSpatialResource));
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerSpatialSystem(this.spawnMarkerSpatialResource));
      this.getEntityStoreRegistry().registerSystem(new BeaconSpatialSystem(this.manualSpawnBeaconSpatialResource));
      this.getEntityStoreRegistry()
         .registerSystem(new SpawnMarkerSuppressionSystem(this.spawnMarkerComponentType, this.spawnSuppressionControllerResourceType));
      this.getChunkStoreRegistry()
         .registerSystem(new ChunkSuppressionSystems.ChunkAdded(this.chunkSuppressionEntryComponentType, this.spawnSuppressionControllerResourceType));
      this.getChunkStoreRegistry()
         .registerSystem(new ChunkSuppressionSystems.Ticking(this.chunkSuppressionEntryComponentType, this.chunkSuppressionQueueResourceType));
      this.getEntityStoreRegistry().registerSystem(new LocalSpawnSetupSystem(var2));
      this.getEntityStoreRegistry()
         .registerSystem(
            new LocalSpawnControllerSystem(
               this.localSpawnControllerComponentType,
               var3,
               WeatherTracker.getComponentType(),
               this.localSpawnBeaconComponentType,
               var4,
               this.localSpawnStateResourceType,
               this.legacyBeaconSpatialResource
            )
         );
      this.getEntityStoreRegistry().registerSystem(new LocalSpawnBeaconSystem(this.localSpawnBeaconComponentType, this.localSpawnStateResourceType));
      this.getEntityStoreRegistry().registerSystem(new LocalSpawnForceTriggerSystem(this.localSpawnControllerComponentType, this.localSpawnStateResourceType));
      this.getEntityStoreRegistry().registerSystem(new SpawnBeaconSystems.LegacyEntityAdded(var4));
      this.getEntityStoreRegistry().registerSystem(new SpawnBeaconSystems.EntityAdded(var5));
      this.getEntityStoreRegistry().registerSystem(new SpawnBeaconSystems.CheckDespawn(var4, this.initialBeaconDelayComponentType));
      this.getEntityStoreRegistry()
         .registerSystem(
            new SpawnBeaconSystems.PositionSelectorUpdate(this.floodFillPositionSelectorComponentType, this.floodFillEntryPoolProviderSimpleResourceType)
         );
      this.getEntityStoreRegistry()
         .registerSystem(new SpawnBeaconSystems.ControllerTick(var4, this.floodFillPositionSelectorComponentType, this.initialBeaconDelayComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnBeaconSystems.SpawnJobTick(var4, this.initialBeaconDelayComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnBeaconSystems.LoadTimeDelay(this.initialBeaconDelayComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerSystems.EnsureNetworkSendable());
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerSystems.CacheMarker(this.spawnMarkerComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerSystems.EntityAdded(this.spawnMarkerComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerSystems.EntityAddedFromExternal(this.spawnMarkerComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerSystems.AddedFromWorldGen());
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerSystems.Ticking(this.spawnMarkerComponentType, var6));
      this.getEntityStoreRegistry()
         .registerSystem(new SpawnReferenceSystems.MarkerAddRemoveSystem(SpawnMarkerReference.getComponentType(), this.spawnMarkerComponentType));
      this.getEntityStoreRegistry()
         .registerSystem(new SpawnReferenceSystems.MarkerDeathSystem(SpawnMarkerReference.getComponentType(), this.spawnMarkerComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnReferenceSystems.BeaconAddRemoveSystem(SpawnBeaconReference.getComponentType(), var4));
      this.getEntityStoreRegistry()
         .registerSystem(new WorldSpawnTrackingSystem(this.worldSpawnDataResourceType, this.chunkSpawnDataComponentType, this.chunkSpawnedNPCDataComponentType));
      this.getEntityStoreRegistry().registerSystem(new MoonPhaseChangeEventSystem());
      this.getEntityStoreRegistry()
         .registerSystem(new SpawnReferenceSystems.TickingSpawnMarkerSystem(this.spawnMarkerReferenceComponentType, this.spawnMarkerComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnReferenceSystems.TickingSpawnBeaconSystem(this.spawnBeaconReferenceComponentType));
      this.getChunkStoreRegistry()
         .registerSystem(
            new WorldSpawningSystem(
               this.worldSpawnDataResourceType, this.chunkSpawnDataComponentType, this.chunkSpawnedNPCDataComponentType, this.spawnJobDataComponentType
            )
         );
      this.getChunkStoreRegistry().registerSystem(new WorldSpawnJobSystems.EntityRemoved(this.worldSpawnDataResourceType, this.spawnJobDataComponentType));
      this.getChunkStoreRegistry()
         .registerSystem(
            new WorldSpawnJobSystems.Ticking(
               this.worldSpawnDataResourceType,
               this.spawnSuppressionControllerResourceType,
               this.spawnJobDataComponentType,
               this.chunkSpawnDataComponentType,
               this.chunkSpawnedNPCDataComponentType
            )
         );
      this.getChunkStoreRegistry().registerSystem(new WorldSpawnJobSystems.TickingState(this.worldSpawnDataResourceType, this.spawnJobDataComponentType));
      this.getChunkStoreRegistry()
         .registerSystem(
            new ChunkSpawningSystems.ChunkRefAdded(this.worldSpawnDataResourceType, this.chunkSpawnDataComponentType, this.chunkSpawnedNPCDataComponentType)
         );
      this.getChunkStoreRegistry()
         .registerSystem(
            new ChunkSpawningSystems.TickingState(this.worldSpawnDataResourceType, this.chunkSpawnDataComponentType, this.chunkSpawnedNPCDataComponentType)
         );
      this.getChunkStoreRegistry().registerSystem(new SpawnMarkerBlockStateSystems.AddOrRemove(this.spawnMarkerBlockComponentType));
      this.getChunkStoreRegistry().registerSystem(new SpawnMarkerBlockStateSystems.TickHeartbeat(this.spawnMarkerBlockComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerBlockStateSystems.SpawnMarkerAddedFromExternal(this.spawnMarkerBlockReferenceComponentType));
      this.getEntityStoreRegistry().registerSystem(new SpawnMarkerBlockStateSystems.SpawnMarkerTickHeartbeat(this.spawnMarkerBlockReferenceComponentType));
      Interaction.CODEC.register("TriggerSpawnMarkers", TriggerSpawnMarkersInteraction.class, TriggerSpawnMarkersInteraction.CODEC);
   }

   @Override
   class="kw">public void start() {
      SpawningPlugin.NPCSpawningConfig var1 = this.config.get();
      String var2 = var1.defaultMarkerModel;
      this.localSpawnControllerJoinDelay = var1.localSpawnControllerJoinDelay;
      this.tickColumnBudget = MathUtil.floor(var1.spawnBudgetFactor * 20480.0);
      DefaultAssetMap var3 = ModelAsset.getAssetMap();
      ModelAsset var4 = var3.getAsset(var2);
      if (var4 == null) {
         this.getLogger().at(Level.SEVERE).log("Spawn marker model %s does not exist", var2);
         var4 = var3.getAsset("NPC_Spawn_Marker");
         if (var4 == null) {
            throw new IllegalStateException(String.format("Default spawn marker '%s' not found", "NPC_Spawn_Marker"));
         }
      }

      this.spawnMarkerModel = Model.createUnitScaleModel(var4);
      this.setUpWithAllRoles();
   }

   @Override
   class="kw">public void shutdown() {
   }

   class="kw">public ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> getSpawnMarkerSpatialResource() {
      class="kw">return this.spawnMarkerSpatialResource;
   }

   class="kw">public ResourceType<EntityStore, SpatialResource<Ref<EntityStore>, EntityStore>> getManualSpawnBeaconSpatialResource() {
      class="kw">return this.manualSpawnBeaconSpatialResource;
   }

   class="kw">public ComponentType<EntityStore, SpawnMarkerEntity> getSpawnMarkerComponentType() {
      class="kw">return this.spawnMarkerComponentType;
   }

   class="kw">public ComponentType<EntityStore, LocalSpawnController> getLocalSpawnControllerComponentType() {
      class="kw">return this.localSpawnControllerComponentType;
   }

   class="kw">public ResourceType<EntityStore, WorldSpawnData> getWorldSpawnDataResourceType() {
      class="kw">return this.worldSpawnDataResourceType;
   }

   class="kw">public ComponentType<EntityStore, SpawnSuppressionComponent> getSpawnSuppressorComponentType() {
      class="kw">return this.spawnSuppressorComponentType;
   }

   class="kw">public ResourceType<EntityStore, SpawnSuppressionController> getSpawnSuppressionControllerResourceType() {
      class="kw">return this.spawnSuppressionControllerResourceType;
   }

   class="kw">public ComponentType<EntityStore, LocalSpawnBeacon> getLocalSpawnBeaconComponentType() {
      class="kw">return this.localSpawnBeaconComponentType;
   }

   class="kw">public ResourceType<EntityStore, LocalSpawnState> getLocalSpawnStateResourceType() {
      class="kw">return this.localSpawnStateResourceType;
   }

   class="kw">public ComponentType<EntityStore, InitialBeaconDelay> getInitialBeaconDelayComponentType() {
      class="kw">return this.initialBeaconDelayComponentType;
   }

   class="kw">public ComponentType<ChunkStore, SpawnJobData> getSpawnJobDataComponentType() {
      class="kw">return this.spawnJobDataComponentType;
   }

   class="kw">public ComponentType<ChunkStore, ChunkSpawnData> getChunkSpawnDataComponentType() {
      class="kw">return this.chunkSpawnDataComponentType;
   }

   class="kw">public ComponentType<ChunkStore, ChunkSpawnedNPCData> getChunkSpawnedNPCDataComponentType() {
      class="kw">return this.chunkSpawnedNPCDataComponentType;
   }

   class="kw">public ResourceType<ChunkStore, ChunkSuppressionQueue> getChunkSuppressionQueueResourceType() {
      class="kw">return this.chunkSuppressionQueueResourceType;
   }

   class="kw">public ResourceType<EntityStore, FloodFillEntryPoolProviderSimple> getFloodFillEntryPoolProviderSimpleResourceType() {
      class="kw">return this.floodFillEntryPoolProviderSimpleResourceType;
   }

   class="kw">public ComponentType<ChunkStore, ChunkSuppressionEntry> getChunkSuppressionEntryComponentType() {
      class="kw">return this.chunkSuppressionEntryComponentType;
   }

   class="kw">public BeaconSpawnWrapper getBeaconSpawnWrapper(int var1) {
      class="kw">return this.beaconSpawnManager.getSpawnWrapper(var1);
   }

   class="kw">public ComponentType<EntityStore, SpawnMarkerReference> getSpawnMarkerReferenceComponentType() {
      class="kw">return this.spawnMarkerReferenceComponentType;
   }

   class="kw">public ComponentType<EntityStore, SpawnBeaconReference> getSpawnBeaconReferenceComponentType() {
      class="kw">return this.spawnBeaconReferenceComponentType;
   }

   class="kw">public ComponentType<EntityStore, FloodFillPositionSelector> getFloodFillPositionSelectorComponentType() {
      class="kw">return this.floodFillPositionSelectorComponentType;
   }

   class="kw">public ComponentType<EntityStore, SpawnMarkerBlockReference> getSpawnMarkerBlockReferenceComponentType() {
      class="kw">return this.spawnMarkerBlockReferenceComponentType;
   }

   class="kw">public ComponentType<ChunkStore, SpawnMarkerBlock> getSpawnMarkerBlockComponentType() {
      class="kw">return this.spawnMarkerBlockComponentType;
   }

   class="kw">public boolean shouldNPCDespawn(@Nonnull Store<EntityStore> var1, @Nonnull NPCEntity var2, @Nonnull WorldTimeResource var3, int var4, boolean var5) {
      if (var4 == Integer.MIN_VALUE) {
         class="kw">return false;
      }

      SpawnManager var6 = var5 ? this.beaconSpawnManager : this.worldSpawnManager;
      SpawnWrapper var7 = var6.getSpawnWrapper(var4);
      if (var7 == null) {
         class="kw">return false;
      }

      if (!var5) {
         int var8 = var2.getEnvironment();
         if (var8 != Integer.MIN_VALUE) {
            WorldSpawnData var9 = var1.getResource(WorldSpawnData.getResourceType());
            WorldEnvironmentSpawnData var10 = var9.getWorldEnvironmentSpawnData(var8);
            if (var10 != null) {
               WorldNPCSpawnStat var11 = (WorldNPCSpawnStat)var10.getNpcStatMap().get(var2.getRoleIndex());
               if (var11 != null && !(var11 class="kw">instanceof WorldNPCSpawnStat.CountOnly) && var11.getActual() > var11.getExpected() * 1.25 + 4.0) {
                  get()
                     .getLogger()
                     .at(Level.WARNING)
                     .log(
                        "Removing NPC of type %s due to overpopulation (expected: %f, actual: %d)", var2.getRoleName(), var11.getExpected(), var11.getActual()
                     );
                  class="kw">return true;
               }
            }
         }
      }

      World var12 = var1.getExternalData().getWorld();
      class="kw">return var7.shouldDespawn(var12, var3);
   }

   class="kw">public Model getSpawnMarkerModel() {
      class="kw">return this.spawnMarkerModel;
   }

   class="kw">public EnvironmentSpawnParameters getWorldEnvironmentSpawnParameters(int var1) {
      class="kw">return this.worldSpawnManager.getEnvironmentSpawnParameters(var1);
   }

   class="kw">public List<BeaconSpawnWrapper> getBeaconSpawnsForEnvironment(int var1) {
      class="kw">return this.beaconSpawnManager.getBeaconSpawns(var1);
   }

   class="kw">public IntSet getRolesForEnvironment(int var1) {
      class="kw">return this.worldSpawnManager.getRolesForEnvironment(var1);
   }

   class="kw">public int getTickColumnBudget() {
      class="kw">return this.tickColumnBudget;
   }

   class="kw">public int getMaxActiveJobs() {
      class="kw">return this.config.get().maxActiveJobs;
   }

   class="kw">public double getLocalSpawnControllerJoinDelay() {
      class="kw">return this.localSpawnControllerJoinDelay;
   }

   class="kw">public class="kw">static <T class="kw">extends NPCSpawn> void validateSpawnsConfigurations(@Nonnull String var0, @Nonnull Map<String, T> var1, @Nonnull List<String> var2) {
      for (Entry var4 : var1.entrySet()) {
         RoleSpawnParameters[] var5 = var4.getValue().getNPCs();

         for (RoleSpawnParameters var9 : var5) {
            try {
               NPCPlugin.get().validateSpawnableRole(var9.getId());
            } catch (IllegalArgumentException var11) {
               var2.add(var0 + " " + var4.getKey() + ": " + var11.getMessage());
            }
         }
      }
   }

   class="kw">public class="kw">static void validateSpawnMarkers(@Nonnull Map<String, SpawnMarker> var0, @Nonnull List<String> var1) {
      for (Entry var3 : var0.entrySet()) {
         IWeightedMap var4 = var3.getValue().getWeightedConfigurations();
         if (var4 == null) {
            var1.add("Spawn marker " + var3.getKey() + ": No configurations defined");
         } else {
            var4.forEach(var2 -> {
               try {
                  String var3 = var2.getNpc();
                  if (var3 != null) {
                     NPCPlugin.get().validateSpawnableRole(var3);
                  }
               } catch (IllegalArgumentException var4) {
                  var1.add("Spawn marker " + var3.getKey() + ": " + var4.getMessage());
               }
            });
         }
      }
   }

   class="kw">public double getEnvironmentDensity(int var1) {
      EnvironmentSpawnParameters var2 = this.getWorldEnvironmentSpawnParameters(var1);
      class="kw">return var2 != null ? var2.getSpawnDensity() : 0.0;
   }

   class="kw">protected void onSpawnMarkersChange(@Nonnull LoadedAssetsEvent<String, SpawnMarker, DefaultAssetMap<String, SpawnMarker>> var1) {
      Map var2 = var1.getLoadedAssets();
      Universe.get()
         .getWorlds()
         .forEach(
            (var1x, var2x) -> var2x.execute(() -> var2x.getEntityStore().getStore().forEachChunk(SpawnMarkerEntity.getComponentType(), (var1xx, var2xx) -> {
               for (int var3 = 0; var3 < var1xx.size(); var3++) {
                  SpawnMarkerEntity var4 = var1xx.getComponent(var3, SpawnMarkerEntity.getComponentType());
                  if (var2.containsKey(var4.getSpawnMarkerId())) {
                     Holder var5 = var2xx.removeEntity(var1xx.getReferenceTo(var3), EntityStore.REGISTRY.newHolder(), RemoveReason.UNLOAD);
                     var2xx.addEntity(var5, AddReason.LOAD);
                  }
               }
            }))
         );
      if (!NPCPlugin.get().getBuilderManager().isEmpty()) {
         ObjectArrayList var3 = new ObjectArrayList();
         validateSpawnMarkers(var1.getLoadedAssets(), var3);
         ObjectListIterator var4 = var3.iterator();

         while (var4.hasNext()) {
            String var5 = (String)var4.next();
            this.getLogger().at(Level.SEVERE).log("%s", var5);
         }
      }
   }

   class="kw">protected class="kw">static void onSpawnMarkersRemove(@Nonnull RemovedAssetsEvent<String, SpawnMarker, DefaultAssetMap<String, SpawnMarker>> var0) {
      Set var1 = var0.getRemovedAssets();
      Universe.get()
         .getWorlds()
         .forEach((var1x, var2) -> var2.execute(() -> var2.getEntityStore().getStore().forEachChunk(SpawnMarkerEntity.getComponentType(), (var1xx, var2x) -> {
            for (int var3 = 0; var3 < var1xx.size(); var3++) {
               SpawnMarkerEntity var4 = var1xx.getComponent(var3, SpawnMarkerEntity.getComponentType());
               if (var4 != null && var1.contains(var4.getSpawnMarkerId())) {
                  var2x.removeEntity(var1xx.getReferenceTo(var3), RemoveReason.REMOVE);
               }
            }
         })));
   }

   class="kw">private void onEnvironmentChange(@Nonnull LoadedAssetsEvent<String, Environment, IndexedLookupTableAssetMap<String, Environment>> var1) {
      IndexedLookupTableAssetMap var2 = Environment.getAssetMap();

      for (Entry var4 : var1.getLoadedAssets().entrySet()) {
         String var5 = var4.getKey();
         int var6 = var2.getIndex(var5);
         if (var6 == Integer.MIN_VALUE) {
            throw new IllegalArgumentException("Unknown key! " + var5);
         }

         this.worldSpawnManager.updateSpawnParameters(var6, var4.getValue());
      }

      WorldSpawnManager.onEnvironmentChanged();
   }

   class="kw">private void onWorldNPCSpawnsLoaded(@Nonnull LoadedAssetsEvent<String, WorldNPCSpawn, IndexedLookupTableAssetMap<String, WorldNPCSpawn>> var1) {
      if (!NPCPlugin.get().getBuilderManager().isEmpty()) {
         IntOpenHashSet var2 = new IntOpenHashSet();

         for (String var4 : var1.getLoadedAssets().keySet()) {
            int var5 = ((IndexedLookupTableAssetMap)var1.getAssetMap()).getIndex(var4);
            if (var5 == Integer.MIN_VALUE) {
               throw new IllegalArgumentException("Unknown key! " + var4);
            }

            var2.add(var5);
         }

         this.worldSpawnManager.rebuildConfigurations(var2);
         ObjectArrayList var6 = new ObjectArrayList();
         validateSpawnsConfigurations("World spawn", var1.getLoadedAssets(), var6);
         ObjectListIterator var7 = var6.iterator();

         while (var7.hasNext()) {
            String var8 = (String)var7.next();
            this.getLogger().at(Level.SEVERE).log("%s", var8);
         }
      }
   }

   class="kw">private void onBeaconNPCSpawnsLoaded(@Nonnull LoadedAssetsEvent<String, BeaconNPCSpawn, IndexedLookupTableAssetMap<String, BeaconNPCSpawn>> var1) {
      if (!NPCPlugin.get().getBuilderManager().isEmpty()) {
         IntOpenHashSet var2 = new IntOpenHashSet();

         for (String var4 : var1.getLoadedAssets().keySet()) {
            int var5 = ((IndexedLookupTableAssetMap)var1.getAssetMap()).getIndex(var4);
            if (var5 == Integer.MIN_VALUE) {
               throw new IllegalArgumentException("Unknown key! " + var4);
            }

            var2.add(var5);
         }

         this.rebuildBeaconSpawnConfigurations(var2);
         Map var7 = var1.getLoadedAssets();
         Universe.get().getWorlds().forEach((var1x, var2x) -> var2x.execute(() -> {
            Store var2 = var2x.getEntityStore().getStore();
            var2.forEachChunk(LegacySpawnBeaconEntity.getComponentType(), (var1xx, var2xx) -> {
               for (int var3 = 0; var3 < var1xx.size(); var3++) {
                  LegacySpawnBeaconEntity var4 = var1xx.getComponent(var3, LegacySpawnBeaconEntity.getComponentType());
                  assert var4 != null;
                  if (var7.containsKey(var4.getSpawnConfigId())) {
                     Ref var5 = var1xx.getReferenceTo(var3);
                     Holder var6 = var2xx.removeEntity(var5, EntityStore.REGISTRY.newHolder(), RemoveReason.UNLOAD);
                     var2xx.addEntity(var6, AddReason.LOAD);
                  }
               }
            });
            var2.forEachChunk(SpawnBeacon.getComponentType(), (var1xx, var2xx) -> {
               for (int var3 = 0; var3 < var1xx.size(); var3++) {
                  SpawnBeacon var4 = var1xx.getComponent(var3, SpawnBeacon.getComponentType());
                  assert var4 != null;
                  if (var7.containsKey(var4.getSpawnConfigId())) {
                     Ref var5 = var1xx.getReferenceTo(var3);
                     Holder var6 = var2xx.removeEntity(var5, EntityStore.REGISTRY.newHolder(), RemoveReason.UNLOAD);
                     var2xx.addEntity(var6, AddReason.LOAD);
                  }
               }
            });
         }));
         ObjectArrayList var8 = new ObjectArrayList();
         validateSpawnsConfigurations("Beacon spawn", var1.getLoadedAssets(), var8);
         ObjectListIterator var9 = var8.iterator();

         while (var9.hasNext()) {
            String var6 = (String)var9.next();
            this.getLogger().at(Level.SEVERE).log("%s", var6);
         }
      }
   }

   class="kw">private void onWorldNPCSpawnsRemoved(@Nonnull RemovedAssetsEvent<String, WorldNPCSpawn, IndexedLookupTableAssetMap<String, WorldNPCSpawn>> var1) {
      for (String var3 : var1.getRemovedAssets()) {
         this.worldSpawnManager.onNPCSpawnRemoved(var3);
      }

      WorldSpawnManager.onEnvironmentChanged();
   }

   class="kw">private void onBeaconNPCSpawnsRemoved(@Nonnull RemovedAssetsEvent<String, BeaconNPCSpawn, IndexedLookupTableAssetMap<String, BeaconNPCSpawn>> var1) {
      for (String var3 : var1.getRemovedAssets()) {
         this.beaconSpawnManager.onNPCSpawnRemoved(var3);
      }

      Set var4 = var1.getRemovedAssets();
      Universe.get().getWorlds().forEach((var1x, var2) -> var2.execute(() -> {
         World var2 = var2.getEntityStore().getStore();
         var2.forEachChunk(LegacySpawnBeaconEntity.getComponentType(), (var1xx, var2x) -> {
            for (int var3 = 0; var3 < var1xx.size(); var3++) {
               LegacySpawnBeaconEntity var4 = var1xx.getComponent(var3, LegacySpawnBeaconEntity.getComponentType());
               assert var4 != null;
               if (var4.contains(var4.getSpawnConfigId())) {
                  Ref var5 = var1xx.getReferenceTo(var3);
                  var2x.removeEntity(var5, RemoveReason.REMOVE);
               }
            }
         });
         var2.forEachChunk(SpawnBeacon.getComponentType(), (var1xx, var2x) -> {
            for (int var3 = 0; var3 < var1xx.size(); var3++) {
               SpawnBeacon var4 = var1xx.getComponent(var3, SpawnBeacon.getComponentType());
               assert var4 != null;
               if (var4.contains(var4.getSpawnConfigId())) {
                  Ref var5 = var1xx.getReferenceTo(var3);
                  var2x.removeEntity(var5, RemoveReason.REMOVE);
               }
            }
         });
      }));
   }

   class="kw">private void onLoadedNPCEvent(@Nonnull AllNPCsLoadedEvent var1) {
      IntOpenHashSet var2 = new IntOpenHashSet();
      Int2ObjectMap var3 = var1.getLoadedNPCs();
      ObjectIterator var4 = var3.values().iterator();

      while (var4.hasNext()) {
         BuilderInfo var5 = (BuilderInfo)var4.next();
         String var6 = var5.getKeyName();
         this.worldSpawnManager.onNPCLoaded(var6, var2);
         this.beaconSpawnManager.onNPCLoaded(var6, var2);
      }

      this.worldSpawnManager.rebuildConfigurations(var2);
      this.rebuildBeaconSpawnConfigurations(var2);
   }

   class="kw">private void setUpWithAllRoles() {
      IntOpenHashSet var1 = new IntOpenHashSet();
      IndexedLookupTableAssetMap var2 = WorldNPCSpawn.getAssetMap();
      Map var3 = var2.getAssetMap();
      int var4 = 0;

      for (Entry var6 : var3.entrySet()) {
         WorldNPCSpawn var7 = var6.getValue();
         if (this.worldSpawnManager.addSpawnWrapper(new WorldSpawnWrapper(var7))) {
            var4++;
         }

         String var8 = var6.getKey();
         int var9 = var2.getIndex(var8);
         if (var9 == Integer.MIN_VALUE) {
            throw new IllegalArgumentException("Unknown key! " + var8);
         }

         var1.add(var9);
      }

      IndexedLookupTableAssetMap var13 = BeaconNPCSpawn.getAssetMap();
      Map var14 = var13.getAssetMap();
      int var15 = 0;

      for (Entry var17 : var14.entrySet()) {
         BeaconNPCSpawn var10 = var17.getValue();
         if (this.beaconSpawnManager.addSpawnWrapper(new BeaconSpawnWrapper(var10))) {
            var15++;
         }

         String var11 = var17.getKey();
         int var12 = var13.getIndex(var11);
         if (var12 == Integer.MIN_VALUE) {
            throw new IllegalArgumentException("Unknown key! " + var11);
         }

         var1.add(var12);
      }

      WorldSpawnManager.trackNPCs(var1);
      this.getLogger().at(Level.INFO).log("Successfully set up %s world spawn configurations", var4);
      this.getLogger().at(Level.INFO).log("Successfully set up %s beacon spawn configurations", var15);
   }

   class="kw">private void rebuildBeaconSpawnConfigurations(@Nullable IntSet var1) {
      if (var1 != null && !var1.isEmpty()) {
         int var2 = 0;
         IntIterator var3 = var1.iterator();

         while (var3.hasNext()) {
            int var4 = (Integer)var3.next();
            this.beaconSpawnManager.removeSpawnWrapper(var4);
            BeaconNPCSpawn var5 = BeaconNPCSpawn.getAssetMap().getAssetOrDefault(var4, null);
            if (var5 != null && this.beaconSpawnManager.addSpawnWrapper(new BeaconSpawnWrapper(var5))) {
               var2++;
            }
         }

         this.getLogger().at(Level.INFO).log("Successfully rebuilt %s beacon spawn configurations", var2);
      }
   }

   class="kw">private void onModelAssetChange(@Nonnull LoadedAssetsEvent<String, ModelAsset, DefaultAssetMap<String, ModelAsset>> var1) {
      if (this.spawnMarkerModel != null) {
         Map var2 = var1.getLoadedAssets();
         ModelAsset var3 = var2.get(this.spawnMarkerModel.getModelAssetId());
         if (var3 != null) {
            this.spawnMarkerModel = Model.createUnitScaleModel(var3);
         }
      }
   }

   class="kw">private void onLoadAsset(@Nonnull LoadAssetEvent var1) {
      HytaleLogger.getLogger().at(Level.INFO).log("Validating Spawn assets phase...");
      long var2 = System.nanoTime();
      ObjectArrayList var4 = new ObjectArrayList();
      validateSpawnsConfigurations("World spawn", WorldNPCSpawn.getAssetMap().getAssetMap(), var4);
      validateSpawnsConfigurations("Beacon spawn", BeaconNPCSpawn.getAssetMap().getAssetMap(), var4);
      validateSpawnMarkers(SpawnMarker.getAssetMap().getAssetMap(), var4);
      ObjectListIterator var5 = var4.iterator();

      while (var5.hasNext()) {
         String var6 = (String)var5.next();
         this.getLogger().at(Level.SEVERE).log("%s", var6);
      }

      if (!var4.isEmpty()) {
         var1.failed(Options.getOptionSet().has(Options.VALIDATE_ASSETS), "failed to validate spawning assets");
      }

      HytaleLogger.getLogger()
         .at(Level.INFO)
         .log(
            "Spawn assets validation phase completed! Boot time %s, Took %s",
            FormatUtil.nanosToString(System.nanoTime() - var1.getBootStart()),
            FormatUtil.nanosToString(System.nanoTime() - var2)
         );
   }

   class="kw">public class="kw">static class NPCSpawningConfig {
      @Nonnull
      class="kw">public class="kw">static class="kw">final BuilderCodec<SpawningPlugin.NPCSpawningConfig> CODEC = BuilderCodec.builder(
            SpawningPlugin.NPCSpawningConfig.class, SpawningPlugin.NPCSpawningConfig::new
         )
         .append(new KeyedCodec<>("SpawnBudgetFactor", Codec.DOUBLE), (var0, var1) -> var0.spawnBudgetFactor = var1, var0 -> var0.spawnBudgetFactor)
         .add()
         .append(new KeyedCodec<>("MaxActiveJobs", Codec.INTEGER), (var0, var1) -> var0.maxActiveJobs = var1, var0 -> var0.maxActiveJobs)
         .add()
         .append(new KeyedCodec<>("DefaultSpawnMarkerModel", Codec.STRING), (var0, var1) -> var0.defaultMarkerModel = var1, var0 -> var0.defaultMarkerModel)
         .add()
         .append(
            new KeyedCodec<>("LocalSpawnControllerJoinDelay", Codec.DOUBLE),
            (var0, var1) -> var0.localSpawnControllerJoinDelay = var1,
            var0 -> var0.localSpawnControllerJoinDelay
         )
         .add()
         .build();
      class="kw">private double spawnBudgetFactor = 1.0;
      class="kw">private int maxActiveJobs = 20;
      class="kw">private String defaultMarkerModel = "NPC_Spawn_Marker";
      class="kw">private double localSpawnControllerJoinDelay = 15.0;

      class="kw">public NPCSpawningConfig() {
      }
   }
}