package joshie.harvest.mining;
import joshie.harvest.api.calendar.Season;
import joshie.harvest.api.mining.IMiningRegistry;
import joshie.harvest.api.mining.MiningContext;
import joshie.harvest.core.util.annotations.HFApiImplementation;
import net.minecraft.block.state.IBlockState;
import net.minecraft.world.World;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nullable;
import java.util.*;
import static joshie.harvest.api.calendar.Season.*;
@HFApiImplementation
public class MiningRegistry implements IMiningRegistry {
public static final MiningRegistry INSTANCE = new MiningRegistry();
private final EnumMap<Season, WeightedState> gatherings = new EnumMap<>(Season.class);
public final Set<IBlockState> all = new HashSet<>();
private MiningRegistry() {}
@Override
public void registerOre(MiningContext context, IBlockState state, double weight, Season... seasons) {
if (seasons == null || seasons.length == 0) seasons = new Season[] { SPRING, SUMMER, AUTUMN, WINTER };
for (Season season: seasons) {
WeightedState weightedState = gatherings.get(season);
if (weightedState == null) {
weightedState = new WeightedState();
gatherings.put(season, weightedState);
}
weightedState.add(context, state, weight);
}
all.add(state);
}
@Nullable
public IBlockState getRandomStateForSeason(World world, int floor, @Nullable Season season) {
if (season == null) season = Season.SPRING;
return gatherings.get(season).get(world, floor);
}
private class WeightedState {
private final NavigableMap<Double, Pair<IBlockState, MiningContext>> map = new TreeMap<>();
private double total = 0;
public void add(MiningContext context, IBlockState state, double weight) {
if (weight <= 0) return;
total += weight;
map.put(total, Pair.of(state, context));
}
@Nullable
public IBlockState get(World world, int floor) {
Pair<IBlockState, MiningContext> pair = map.ceilingEntry((world.rand.nextDouble() * total)).getValue();
if (pair.getValue().isValidFloor(floor)) {
return pair.getKey();
} else return null;
}
}
}