80 lines
3.4 KiB
Java
80 lines
3.4 KiB
Java
package net.minecraft.world.level;
|
|
|
|
import com.mojang.serialization.Codec;
|
|
import com.mojang.serialization.DataResult;
|
|
import com.mojang.serialization.MapCodec;
|
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|
import java.util.Optional;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.util.InclusiveRange;
|
|
import net.minecraft.util.random.WeightedList;
|
|
import net.minecraft.world.entity.EquipmentTable;
|
|
|
|
public record SpawnData(CompoundTag entityToSpawn, Optional<SpawnData.CustomSpawnRules> customSpawnRules, Optional<EquipmentTable> equipment) {
|
|
public static final String ENTITY_TAG = "entity";
|
|
public static final Codec<SpawnData> CODEC = RecordCodecBuilder.create(
|
|
instance -> instance.group(
|
|
CompoundTag.CODEC.fieldOf("entity").forGetter(spawnData -> spawnData.entityToSpawn),
|
|
SpawnData.CustomSpawnRules.CODEC.optionalFieldOf("custom_spawn_rules").forGetter(spawnData -> spawnData.customSpawnRules),
|
|
EquipmentTable.CODEC.optionalFieldOf("equipment").forGetter(spawnData -> spawnData.equipment)
|
|
)
|
|
.apply(instance, SpawnData::new)
|
|
);
|
|
public static final Codec<WeightedList<SpawnData>> LIST_CODEC = WeightedList.codec(CODEC);
|
|
|
|
public SpawnData() {
|
|
this(new CompoundTag(), Optional.empty(), Optional.empty());
|
|
}
|
|
|
|
public SpawnData(CompoundTag entityToSpawn, Optional<SpawnData.CustomSpawnRules> customSpawnRules, Optional<EquipmentTable> equipment) {
|
|
Optional<ResourceLocation> optional = entityToSpawn.read("id", ResourceLocation.CODEC);
|
|
if (optional.isPresent()) {
|
|
entityToSpawn.store("id", ResourceLocation.CODEC, (ResourceLocation)optional.get());
|
|
} else {
|
|
entityToSpawn.remove("id");
|
|
}
|
|
|
|
this.entityToSpawn = entityToSpawn;
|
|
this.customSpawnRules = customSpawnRules;
|
|
this.equipment = equipment;
|
|
}
|
|
|
|
public CompoundTag getEntityToSpawn() {
|
|
return this.entityToSpawn;
|
|
}
|
|
|
|
public Optional<SpawnData.CustomSpawnRules> getCustomSpawnRules() {
|
|
return this.customSpawnRules;
|
|
}
|
|
|
|
public Optional<EquipmentTable> getEquipment() {
|
|
return this.equipment;
|
|
}
|
|
|
|
public record CustomSpawnRules(InclusiveRange<Integer> blockLightLimit, InclusiveRange<Integer> skyLightLimit) {
|
|
private static final InclusiveRange<Integer> LIGHT_RANGE = new InclusiveRange(0, 15);
|
|
public static final Codec<SpawnData.CustomSpawnRules> CODEC = RecordCodecBuilder.create(
|
|
instance -> instance.group(
|
|
lightLimit("block_light_limit").forGetter(customSpawnRules -> customSpawnRules.blockLightLimit),
|
|
lightLimit("sky_light_limit").forGetter(customSpawnRules -> customSpawnRules.skyLightLimit)
|
|
)
|
|
.apply(instance, SpawnData.CustomSpawnRules::new)
|
|
);
|
|
|
|
private static DataResult<InclusiveRange<Integer>> checkLightBoundaries(InclusiveRange<Integer> lightValues) {
|
|
return !LIGHT_RANGE.contains(lightValues) ? DataResult.error(() -> "Light values must be withing range " + LIGHT_RANGE) : DataResult.success(lightValues);
|
|
}
|
|
|
|
private static MapCodec<InclusiveRange<Integer>> lightLimit(String fieldName) {
|
|
return InclusiveRange.INT.lenientOptionalFieldOf(fieldName, LIGHT_RANGE).validate(SpawnData.CustomSpawnRules::checkLightBoundaries);
|
|
}
|
|
|
|
public boolean isValidPosition(BlockPos pos, ServerLevel level) {
|
|
return this.blockLightLimit.isValueInRange(level.getBrightness(LightLayer.BLOCK, pos))
|
|
&& this.skyLightLimit.isValueInRange(level.getBrightness(LightLayer.SKY, pos));
|
|
}
|
|
}
|
|
}
|