WorldSpawningSystem class
Пакет: com.hypixel.hytale.server.spawning.world.system
Файл: com/hypixel/hytale/server/spawning/world/system/WorldSpawningSystem.java
extends: TickingSystem<ChunkStore>
Поля (76)
| Модификаторы | Тип | Имя |
|---|---|---|
final |
HytaleLogger |
LOGGER |
|
|
break |
|
boolean |
var1 |
|
|
var1 |
|
Ref |
var10 |
|
Environment |
var10 |
|
int |
var10 |
|
int |
var11 |
|
HytaleLogger.Api |
var11 |
|
boolean |
var11 |
|
|
var11 |
|
|
var11 |
|
ChunkSpawnData |
var12 |
|
WorldChunk |
var12 |
|
boolean |
var12 |
|
|
var12 |
|
|
var12 |
|
ChunkEnvironmentSpawnData |
var13 |
|
String |
var13 |
|
int |
var14 |
|
int |
var14 |
|
|
var14 |
|
WorldEnvironmentSpawnData |
var15 |
|
int |
var15 |
|
ChunkSpawnData |
var15 |
|
double |
var16 |
|
ChunkSpawnData |
var16 |
|
ChunkSpawnedNPCData |
var16 |
|
World |
var17 |
|
ChunkEnvironmentSpawnData |
var17 |
|
HytaleLogger.Api |
var18 |
|
WorldSpawnData |
var18 |
|
double |
var18 |
|
Environment |
var19 |
|
HytaleLogger.Api |
var19 |
|
double |
var2 |
|
String |
var20 |
|
WorldChunk |
var20 |
|
int |
var21 |
|
|
var21 |
|
SpawnJobData |
var21 |
|
boolean |
var21 |
|
|
var21 |
|
int |
var22 |
|
FlockAsset |
var22 |
|
ObjectIterator |
var23 |
|
ChunkSpawnData |
var24 |
|
WorldNPCSpawnStat |
var25 |
|
ChunkSpawnedNPCData |
var26 |
|
ChunkEnvironmentSpawnData |
var27 |
|
World |
var4 |
|
int[] |
var4 |
|
ChunkSpawnData |
var4 |
|
GameplayConfig |
var5 |
|
WorldNPCSpawnStat |
var5 |
|
|
var5 |
|
int |
var5 |
|
ChunkSpawnData |
var5 |
|
ChunkSpawnData |
var5 |
|
Store |
var6 |
|
WorldEnvironmentSpawnData |
var6 |
|
|
var6 |
|
boolean |
var6 |
|
ChunkEnvironmentSpawnData |
var6 |
|
ChunkSpawnedNPCData |
var6 |
|
WorldSpawnData |
var7 |
|
int |
var7 |
|
|
var7 |
|
List |
var7 |
|
ChunkEnvironmentSpawnData |
var7 |
|
WorldTimeResource |
var8 |
|
int |
var8 |
|
int |
var8 |
|
WorldSpawnData.UnspawnableEntry |
var9 |
|
Ref |
var9 |
|
double |
var9 |
Методы (28)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
private |
boolean |
createRandomSpawnJobboolean createRandomSpawnJob(@Nonnull WorldSpawnData var1, @Nonnull Store<ChunkStore> var2, @Nonnull ComponentAccessor<EntityStore> var3) |
|
|
for for(int var7 : var1) |
|
|
for for(int var9 = 0; var9 < var1.length; var9++) |
|
|
for for(Ref var14 : var7) |
|
|
for for(Ref var22 : var7) |
static |
int |
getAndConsumeNextEnvironmentIndexint getAndConsumeNextEnvironmentIndex(@Nonnull WorldSpawnData var0, @Nonnull int[] var1) |
static |
boolean |
getAndUpdateSpawnCooldownboolean getAndUpdateSpawnCooldown(@Nonnull ChunkSpawnData var0) |
|
|
if if(var10 != null) |
|
|
if if(var12 != null) |
|
|
if if(var19 != null) |
|
|
if if(var7 == Integer.MIN_VALUE) |
|
|
if if(var8 == 0) |
|
|
if if(var9 == null) |
|
|
if if(var14 > var8) |
|
|
if if(var7 != Integer.MIN_VALUE) |
|
|
if if(var2 == 0.0) |
|
|
if if(var10 != Integer.MIN_VALUE) |
|
|
if if(var2 <= 0.0) |
|
|
if if(var6) |
|
|
if if(var15 != null) |
|
|
if if(var16 != null) |
|
|
if if(var24 != null) |
|
|
if if(var26 != null) |
|
|
if if(var11) |
|
|
if if(var5 == null) |
|
|
if if(var4 == null) |
|
|
if if(var5 == null) |
|
|
if if(var6 == null) |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.server.spawning.world.system;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.ResourceType;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.system.tick.TickingSystem;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.random.RandomExtra;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.server.core.asset.type.environment.config.Environment;
class="kw">import com.hypixel.hytale.server.core.asset.type.gameplay.GameplayConfig;
class="kw">import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
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.flock.config.FlockAsset;
class="kw">import com.hypixel.hytale.server.npc.NPCPlugin;
class="kw">import com.hypixel.hytale.server.spawning.SpawningPlugin;
class="kw">import com.hypixel.hytale.server.spawning.world.ChunkEnvironmentSpawnData;
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 it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import java.time.Duration;
class="kw">import java.util.List;
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">public class WorldSpawningSystem class="kw">extends TickingSystem<ChunkStore> {
class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
class="kw">private class="kw">static class="kw">final long SPAWN_COOLDOWN_NANOS = Duration.ofSeconds(1L).toNanos();
class="kw">private class="kw">final ResourceType<EntityStore, WorldSpawnData> worldSpawnDataResourceType;
class="kw">private class="kw">final ComponentType<ChunkStore, ChunkSpawnData> chunkSpawnDataComponentType;
class="kw">private class="kw">final ComponentType<ChunkStore, ChunkSpawnedNPCData> chunkSpawnedNPCDataComponentType;
class="kw">private class="kw">final ComponentType<ChunkStore, SpawnJobData> spawnJobDataComponentType;
class="kw">private class="kw">final ComponentType<ChunkStore, WorldChunk> worldChunkComponentType;
class="kw">public WorldSpawningSystem(
@Nonnull ResourceType<EntityStore, WorldSpawnData> var1,
@Nonnull ComponentType<ChunkStore, ChunkSpawnData> var2,
@Nonnull ComponentType<ChunkStore, ChunkSpawnedNPCData> var3,
@Nonnull ComponentType<ChunkStore, SpawnJobData> var4
) {
this.worldSpawnDataResourceType = var1;
this.chunkSpawnDataComponentType = var2;
this.chunkSpawnedNPCDataComponentType = var3;
this.spawnJobDataComponentType = var4;
this.worldChunkComponentType = WorldChunk.getComponentType();
}
@Override
class="kw">public void tick(float var1, int var2, @Nonnull Store<ChunkStore> var3) {
World var4 = var3.getExternalData().getWorld();
if (var4.getWorldConfig().isSpawningNPC() && var4.getPlayerCount() != 0) {
GameplayConfig var5 = var4.getGameplayConfig();
Store var6 = var4.getEntityStore().getStore();
WorldSpawnData var7 = var6.getResource(this.worldSpawnDataResourceType);
if (!var7.isUnspawnable()
&& var4.getChunkStore().getStore().getEntityCount() != 0
&& (var5.getMaxEnvironmentalNPCSpawns() <= 0 || var7.getActualNPCs() < var5.getMaxEnvironmentalNPCSpawns())
&& !(var7.getActualNPCs() > var7.getExpectedNPCs())) {
WorldTimeResource var8 = var6.getResource(WorldTimeResource.getResourceType());
if (var7.hasUnprocessedUnspawnableChunks()) {
while (var7.hasUnprocessedUnspawnableChunks()) {
WorldSpawnData.UnspawnableEntry var9 = var7.nextUnspawnableChunk();
Ref var10 = var4.getChunkStore().getChunkReference(var9.getChunkIndex());
if (var10 != null) {
int var11 = var9.getEnvironmentIndex();
ChunkSpawnData var12 = var3.getComponent(var10, this.chunkSpawnDataComponentType);
if (var12 != null) {
ChunkEnvironmentSpawnData var13 = var12.getEnvironmentSpawnData(var11);
int var14 = -var13.getSegmentCount();
var7.adjustSegmentCount(var14);
WorldEnvironmentSpawnData var15 = var7.getWorldEnvironmentSpawnData(var11);
double var16 = var15.getExpectedNPCs();
var15.adjustSegmentCount(var14);
var15.updateExpectedNPCs(var8.getMoonPhase());
var13.markProcessedAsUnspawnable();
HytaleLogger.Api var18 = LOGGER.at(Level.FINEST);
if (var18.isEnabled()) {
Environment var19 = Environment.getAssetMap().getAsset(var11);
if (var19 != null) {
String var20 = var19.getId();
var18.log("Reducing expected NPC count for %s due to un-spawnable chunk. Was %s, now %s", var20, var16, var15.getExpectedNPCs());
}
}
}
}
}
var7.recalculateWorldCount();
}
int var21 = var7.getActiveSpawnJobs();
int var22 = SpawningPlugin.get().getMaxActiveJobs();
while (var21 < var22 && var7.getActualNPCs() < MathUtil.floor(var7.getExpectedNPCs()) && this.createRandomSpawnJob(var7, var3, var6)) {
var21 = var7.getActiveSpawnJobs();
}
}
}
}
class="kw">private boolean createRandomSpawnJob(@Nonnull WorldSpawnData var1, @Nonnull Store<ChunkStore> var2, @Nonnull ComponentAccessor<EntityStore> var3) {
int[] var4 = var1.getWorldEnvironmentSpawnDataIndexes();
WorldNPCSpawnStat var5;
WorldEnvironmentSpawnData var6;
int var7;
do {
var7 = getAndConsumeNextEnvironmentIndex(var1, var4);
if (var7 == Integer.MIN_VALUE) {
class="kw">return false;
}
var6 = var1.getWorldEnvironmentSpawnData(var7);
var5 = var6.pickRandomSpawnNPCStat(var3);
} while (var5 == null);
int var8 = var5.getAvailableSlots();
if (var8 == 0) {
class="kw">return false;
}
Ref var9 = this.pickRandomChunk(var6, var5, var1, var2);
if (var9 == null) {
class="kw">return false;
}
Environment var10 = Environment.getAssetMap().getAsset(var7);
HytaleLogger.Api var11 = LOGGER.at(Level.FINER);
if (var11.isEnabled()) {
WorldChunk var12 = var2.getComponent(var9, this.worldChunkComponentType);
assert var12 != null;
String var13 = NPCPlugin.get().getName(var5.getRoleIndex());
var11.log(
"Trying SpawnJob env=%s role=%s chunk=[%s/%s] env(exp/act)=%s/%s npc(exp/act)=%s/%s",
var10.getId(),
var13,
var12.getX(),
var12.getZ(),
(int)var6.getExpectedNPCs(),
var6.getActualNPCs(),
(int)var5.getExpected(),
var5.getActual()
);
}
SpawnJobData var21 = var2.addComponent(var9, this.spawnJobDataComponentType);
FlockAsset var22 = var5.getSpawnParams().getFlockDefinition();
int var14 = var22 != null ? var22.pickFlockSize() : 1;
int var15 = var5.getRoleIndex();
if (var14 > var8) {
var14 = var8;
}
var21.init(var15, var10, var7, var5.getSpawnWrapper(), var22, var14);
if (var6.isFullyPopulated()) {
var21.setIgnoreFullyPopulated(true);
}
ChunkSpawnData var16 = var2.getComponent(var9, this.chunkSpawnDataComponentType);
assert var16 != null;
var16.getEnvironmentSpawnData(var7).getRandomChunkColumnIterator().saveIteratorPosition();
World var17 = var2.getExternalData().getWorld();
WorldSpawnData var18 = var17.getEntityStore().getStore().getResource(WorldSpawnData.getResourceType());
var18.trackNPC(var7, var15, var14, var17, var3);
HytaleLogger.Api var19 = LOGGER.at(Level.FINEST);
if (var19.isEnabled()) {
WorldChunk var20 = var2.getComponent(var9, this.worldChunkComponentType);
assert var20 != null;
var19.log(
"Start Spawnjob id=%s env=%s role=%s chunk=[%s/%s]", var21.getJobId(), var10.getId(), NPCPlugin.get().getName(var15), var20.getX(), var20.getZ()
);
}
var1.adjustActiveSpawnJobs(1, var14);
class="kw">return true;
}
class="kw">private class="kw">static int getAndConsumeNextEnvironmentIndex(@Nonnull WorldSpawnData var0, @Nonnull int[] var1) {
double var2 = 0.0;
for (int var7 : var1) {
if (var7 != Integer.MIN_VALUE) {
var2 += var0.getWorldEnvironmentSpawnData(var7).spawnWeight();
}
}
if (var2 == 0.0) {
class="kw">return Integer.MIN_VALUE;
}
var2 *= ThreadLocalRandom.current().nextDouble();
for (int var9 = 0; var9 < var1.length; var9++) {
int var10 = var1[var9];
if (var10 != Integer.MIN_VALUE) {
var2 -= var0.getWorldEnvironmentSpawnData(var10).spawnWeight();
if (var2 <= 0.0) {
var1[var9] = Integer.MIN_VALUE;
class="kw">return var10;
}
}
}
class="kw">return Integer.MIN_VALUE;
}
@Nullable
class="kw">private Ref<ChunkStore> pickRandomChunk(
@Nonnull WorldEnvironmentSpawnData var1, @Nonnull WorldNPCSpawnStat var2, @Nonnull WorldSpawnData var3, @Nonnull Store<ChunkStore> var4
) {
int var5 = var2.getRoleIndex();
boolean var6 = var1.isFullyPopulated();
List var7 = var1.getChunkRefList();
int var8 = var1.getEnvironmentIndex();
double var9 = 0.0;
boolean var11 = false;
boolean var12 = true;
if (var6) {
for (Ref var14 : var7) {
if (var14.isValid()) {
ChunkSpawnData var15 = var4.getComponent(var14, this.chunkSpawnDataComponentType);
if (var15 != null) {
ChunkSpawnedNPCData var16 = var4.getComponent(var14, this.chunkSpawnedNPCDataComponentType);
if (var16 != null) {
ChunkEnvironmentSpawnData var17 = var15.getEnvironmentSpawnData(var8);
var12 = var12 && var17.isFullyPopulated(var16.getEnvironmentSpawnCount(var8));
if (var17.isRoleSpawnable(var5)) {
var11 = true;
var9 += var4.getComponent(var14, this.spawnJobDataComponentType) == null && !getAndUpdateSpawnCooldown(var15) ? 1.0 : 0.0;
}
}
}
}
}
} else {
for (Ref var22 : var7) {
if (var22.isValid()) {
ChunkSpawnData var24 = var4.getComponent(var22, this.chunkSpawnDataComponentType);
if (var24 != null) {
ChunkSpawnedNPCData var26 = var4.getComponent(var22, this.chunkSpawnedNPCDataComponentType);
if (var26 != null) {
ChunkEnvironmentSpawnData var27 = var24.getEnvironmentSpawnData(var8);
double var18 = var26.getEnvironmentSpawnCount(var8);
var12 = var12 && var27.isFullyPopulated(var18);
if (var27.isRoleSpawnable(var5)) {
var11 = true;
var9 += var4.getComponent(var22, this.spawnJobDataComponentType) == null && !getAndUpdateSpawnCooldown(var24)
? var27.getWeight(var18)
: 0.0;
}
}
}
}
}
}
var1.setFullyPopulated(var12);
if (var11) {
class="kw">return RandomExtra.randomWeightedElement(
var7,
(var3x, var4x) -> {
ChunkSpawnData var5 = var4.getComponent(var3x, this.chunkSpawnDataComponentType);
if (var5 == null) {
class="kw">return false;
}
ChunkEnvironmentSpawnData var6 = var5.getEnvironmentSpawnData(var8);
class="kw">return var6.isRoleSpawnable(var4x);
},
var6
? (var2x, var3x) -> {
ChunkSpawnData var4 = var4.getComponent(var2x, this.chunkSpawnDataComponentType);
if (var4 == null) {
class="kw">return 0.0;
} else {
class="kw">return var4.getComponent(var2x, this.spawnJobDataComponentType) == null && !var4.isOnSpawnCooldown() ? 1.0 : 0.0;
}
}
: (var3x, var4x) -> {
ChunkSpawnData var5 = var4.getComponent(var3x, this.chunkSpawnDataComponentType);
if (var5 == null) {
class="kw">return 0.0;
}
ChunkSpawnedNPCData var6 = var4.getComponent(var3x, this.chunkSpawnedNPCDataComponentType);
if (var6 == null) {
class="kw">return 0.0;
}
ChunkEnvironmentSpawnData var7 = var5.getEnvironmentSpawnData(var8);
class="kw">return var4.getComponent(var3x, this.spawnJobDataComponentType) == null && !var5.isOnSpawnCooldown()
? var7.getWeight(var6.getEnvironmentSpawnCount(var8))
: 0.0;
},
var9,
var5
);
}
var2.setUnspawnable(true);
boolean var21 = true;
ObjectIterator var23 = var1.getNpcStatMap().values().iterator();
while (var23.hasNext()) {
WorldNPCSpawnStat var25 = (WorldNPCSpawnStat)var23.next();
if (!var25.isUnspawnable()) {
var21 = false;
break;
}
}
var1.setUnspawnable(var21);
var3.updateSpawnability();
class="kw">return null;
}
class="kw">private class="kw">static boolean getAndUpdateSpawnCooldown(@Nonnull ChunkSpawnData var0) {
boolean var1 = var0.isOnSpawnCooldown();
if (var1 && System.nanoTime() - var0.getLastSpawn() > SPAWN_COOLDOWN_NANOS) {
var0.setLastSpawn(0L);
var1 = false;
}
class="kw">return var1;
}
}