150 lines
6.0 KiB
Java
150 lines
6.0 KiB
Java
package com.hypixel.hytale.builtin.adventure.farming.config.modifiers;
|
|
|
|
import com.hypixel.hytale.codec.Codec;
|
|
import com.hypixel.hytale.codec.KeyedCodec;
|
|
import com.hypixel.hytale.codec.builder.BuilderCodec;
|
|
import com.hypixel.hytale.component.CommandBuffer;
|
|
import com.hypixel.hytale.component.Ref;
|
|
import com.hypixel.hytale.protocol.Range;
|
|
import com.hypixel.hytale.protocol.Rangef;
|
|
import com.hypixel.hytale.server.core.asset.type.blocktype.config.farming.GrowthModifierAsset;
|
|
import com.hypixel.hytale.server.core.codec.ProtocolCodecs;
|
|
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
|
|
import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
|
|
import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkLightData;
|
|
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
|
|
import javax.annotation.Nonnull;
|
|
|
|
public class LightLevelGrowthModifierAsset extends GrowthModifierAsset {
|
|
public static final BuilderCodec<LightLevelGrowthModifierAsset> CODEC = BuilderCodec.builder(
|
|
LightLevelGrowthModifierAsset.class, LightLevelGrowthModifierAsset::new, ABSTRACT_CODEC
|
|
)
|
|
.addField(
|
|
new KeyedCodec<>("ArtificialLight", LightLevelGrowthModifierAsset.ArtificialLight.CODEC),
|
|
(lightLevel, artificialLight) -> lightLevel.artificialLight = artificialLight,
|
|
lightLevel -> lightLevel.artificialLight
|
|
)
|
|
.addField(
|
|
new KeyedCodec<>("Sunlight", ProtocolCodecs.RANGEF), (lightLevel, sunLight) -> lightLevel.sunlight = sunLight, lightLevel -> lightLevel.sunlight
|
|
)
|
|
.addField(
|
|
new KeyedCodec<>("RequireBoth", Codec.BOOLEAN),
|
|
(lightLevel, requireBoth) -> lightLevel.requireBoth = requireBoth,
|
|
lightLevel -> lightLevel.requireBoth
|
|
)
|
|
.build();
|
|
protected LightLevelGrowthModifierAsset.ArtificialLight artificialLight;
|
|
protected Rangef sunlight;
|
|
protected boolean requireBoth;
|
|
|
|
public LightLevelGrowthModifierAsset.ArtificialLight getArtificialLight() {
|
|
return this.artificialLight;
|
|
}
|
|
|
|
public Rangef getSunlight() {
|
|
return this.sunlight;
|
|
}
|
|
|
|
public boolean isRequireBoth() {
|
|
return this.requireBoth;
|
|
}
|
|
|
|
protected boolean checkArtificialLight(byte red, byte green, byte blue) {
|
|
LightLevelGrowthModifierAsset.ArtificialLight artificialLight = this.artificialLight;
|
|
Range redRange = artificialLight.getRed();
|
|
Range greenRange = artificialLight.getGreen();
|
|
Range blueRange = artificialLight.getBlue();
|
|
return isInRange(redRange, red) && isInRange(greenRange, green) && isInRange(blueRange, blue);
|
|
}
|
|
|
|
protected boolean checkSunLight(WorldTimeResource worldTimeResource, byte sky) {
|
|
Rangef range = this.sunlight;
|
|
double sunlightFactor = worldTimeResource.getSunlightFactor();
|
|
double daylight = sunlightFactor * sky;
|
|
return range.min <= daylight && daylight <= range.max;
|
|
}
|
|
|
|
protected static boolean isInRange(@Nonnull Range range, int value) {
|
|
return range.min <= value && value <= range.max;
|
|
}
|
|
|
|
@Override
|
|
public double getCurrentGrowthMultiplier(
|
|
CommandBuffer<ChunkStore> commandBuffer, Ref<ChunkStore> sectionRef, Ref<ChunkStore> blockRef, int x, int y, int z, boolean initialTick
|
|
) {
|
|
BlockSection blockSection = commandBuffer.getComponent(sectionRef, BlockSection.getComponentType());
|
|
short lightRaw = blockSection.getGlobalLight().getLightRaw(x, y, z);
|
|
byte redLight = ChunkLightData.getLightValue(lightRaw, 0);
|
|
byte greenLight = ChunkLightData.getLightValue(lightRaw, 1);
|
|
byte blueLight = ChunkLightData.getLightValue(lightRaw, 2);
|
|
byte skyLight = ChunkLightData.getLightValue(lightRaw, 3);
|
|
WorldTimeResource worldTimeResource = commandBuffer.getExternalData()
|
|
.getWorld()
|
|
.getEntityStore()
|
|
.getStore()
|
|
.getResource(WorldTimeResource.getResourceType());
|
|
boolean active = false;
|
|
boolean onlySunlight = false;
|
|
if (this.requireBoth) {
|
|
active = this.checkArtificialLight(redLight, greenLight, blueLight) && this.checkSunLight(worldTimeResource, skyLight);
|
|
} else if (this.checkArtificialLight(redLight, greenLight, blueLight)) {
|
|
active = true;
|
|
} else if (this.checkSunLight(worldTimeResource, skyLight)) {
|
|
active = true;
|
|
onlySunlight = true;
|
|
}
|
|
|
|
if (active) {
|
|
return onlySunlight && initialTick
|
|
? super.getCurrentGrowthMultiplier(commandBuffer, sectionRef, blockRef, x, y, z, initialTick) * 0.6F
|
|
: super.getCurrentGrowthMultiplier(commandBuffer, sectionRef, blockRef, x, y, z, initialTick);
|
|
} else {
|
|
return 1.0;
|
|
}
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "LightLevelGrowthModifierAsset{artificialLight="
|
|
+ this.artificialLight
|
|
+ ", sunLight="
|
|
+ this.sunlight
|
|
+ ", requireBoth="
|
|
+ this.requireBoth
|
|
+ "} "
|
|
+ super.toString();
|
|
}
|
|
|
|
public static class ArtificialLight {
|
|
public static final BuilderCodec<LightLevelGrowthModifierAsset.ArtificialLight> CODEC = BuilderCodec.builder(
|
|
LightLevelGrowthModifierAsset.ArtificialLight.class, LightLevelGrowthModifierAsset.ArtificialLight::new
|
|
)
|
|
.addField(new KeyedCodec<>("Red", ProtocolCodecs.RANGE), (light, red) -> light.red = red, light -> light.red)
|
|
.addField(new KeyedCodec<>("Green", ProtocolCodecs.RANGE), (light, green) -> light.green = green, light -> light.green)
|
|
.addField(new KeyedCodec<>("Blue", ProtocolCodecs.RANGE), (light, blue) -> light.blue = blue, light -> light.blue)
|
|
.build();
|
|
protected Range red;
|
|
protected Range green;
|
|
protected Range blue;
|
|
|
|
public Range getRed() {
|
|
return this.red;
|
|
}
|
|
|
|
public Range getGreen() {
|
|
return this.green;
|
|
}
|
|
|
|
public Range getBlue() {
|
|
return this.blue;
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public String toString() {
|
|
return "ArtificialLightLevel{red=" + this.red + ", green=" + this.green + ", blue=" + this.blue + "}";
|
|
}
|
|
}
|
|
}
|