A bit of general cleanup

This commit is contained in:
Sollace 2022-10-06 23:04:32 +02:00
parent 8f45fcf811
commit 7a8ba44f0d
5 changed files with 78 additions and 96 deletions

View file

@ -8,7 +8,6 @@ import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -20,9 +19,9 @@ public interface TreeType {
TreeType NONE = new TreeTypeImpl( TreeType NONE = new TreeTypeImpl(
Unicopia.id("none"), Unicopia.id("none"),
false, false,
new Weighted<Supplier<ItemStack>>(),
Set.of(), Set.of(),
Set.of() Set.of(),
Weighted.of()
); );
Direction[] WIDE_DIRS = new Direction[] { Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST }; Direction[] WIDE_DIRS = new Direction[] { Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST };

View file

@ -1,7 +1,6 @@
package com.minelittlepony.unicopia.ability.data.tree; package com.minelittlepony.unicopia.ability.data.tree;
import com.minelittlepony.unicopia.util.Weighted; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -11,21 +10,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
public final class TreeTypeImpl implements TreeType { public record TreeTypeImpl (
private final Identifier name; Identifier name,
private final boolean wideTrunk; boolean wideTrunk,
private final Set<Identifier> logs; Set<Identifier> logs,
private final Set<Identifier> leaves; Set<Identifier> leaves,
private final Weighted<Supplier<ItemStack>> pool; Supplier<Optional<Supplier<ItemStack>>> pool
) implements TreeType {
TreeTypeImpl(Identifier name, boolean wideTrunk, Weighted<Supplier<ItemStack>> pool, Set<Identifier> logs, Set<Identifier> leaves) {
this.name = name;
this.wideTrunk = wideTrunk;
this.pool = pool;
this.logs = logs;
this.leaves = leaves;
}
@Override @Override
public boolean isLeaves(BlockState state) { public boolean isLeaves(BlockState state) {
return findMatch(leaves, state) && isNonPersistent(state); return findMatch(leaves, state) && isNonPersistent(state);
@ -46,20 +37,10 @@ public final class TreeTypeImpl implements TreeType {
return pool.get().map(Supplier::get).orElse(ItemStack.EMPTY); return pool.get().map(Supplier::get).orElse(ItemStack.EMPTY);
} }
@Override
public boolean equals(Object o) {
return o instanceof TreeTypeImpl && name.compareTo(((TreeTypeImpl)o).name) == 0;
}
private static boolean findMatch(Set<Identifier> ids, BlockState state) { private static boolean findMatch(Set<Identifier> ids, BlockState state) {
return ids.contains(Registry.BLOCK.getId(state.getBlock())); return ids.contains(Registry.BLOCK.getId(state.getBlock()));
} }
@Override
public int hashCode() {
return name.hashCode();
}
static boolean isNonPersistent(BlockState state) { static boolean isNonPersistent(BlockState state) {
return !state.contains(LeavesBlock.PERSISTENT) || !state.get(LeavesBlock.PERSISTENT); return !state.contains(LeavesBlock.PERSISTENT) || !state.get(LeavesBlock.PERSISTENT);
} }

View file

@ -65,18 +65,13 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
wideTrunk = buffer.readBoolean(); wideTrunk = buffer.readBoolean();
} }
private Weighted<Supplier<ItemStack>> getWeighted(Weighted<Supplier<ItemStack>> weighted) {
drops.forEach(drop -> drop.appendDrop(weighted));
return weighted;
}
public TreeType toTreeType(Identifier id) { public TreeType toTreeType(Identifier id) {
return new TreeTypeImpl( return new TreeTypeImpl(
id, id,
wideTrunk, wideTrunk,
getWeighted(new Weighted<Supplier<ItemStack>>()),
Objects.requireNonNull(logs, "TreeType must have logs"), Objects.requireNonNull(logs, "TreeType must have logs"),
Objects.requireNonNull(leaves, "TreeType must have leaves") Objects.requireNonNull(leaves, "TreeType must have leaves"),
Weighted.of(weighted -> drops.forEach(drop -> drop.appendDrop(weighted)))
); );
} }
@ -96,7 +91,7 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
item = buffer.readIdentifier(); item = buffer.readIdentifier();
} }
void appendDrop(Weighted<Supplier<ItemStack>> weighted) { void appendDrop(Weighted.Builder<Supplier<ItemStack>> weighted) {
Registry.ITEM.getOrEmpty(item).ifPresent(item -> { Registry.ITEM.getOrEmpty(item).ifPresent(item -> {
weighted.put(weight, item::getDefaultStack); weighted.put(weight, item::getDefaultStack);
}); });

View file

@ -1,7 +1,7 @@
package com.minelittlepony.unicopia.ability.magic.spell.effect; package com.minelittlepony.unicopia.ability.magic.spell.effect;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.function.Supplier;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell; import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell;
@ -32,12 +32,13 @@ import net.minecraft.world.WorldEvents;
* An area-effect spell that summons the undead. * An area-effect spell that summons the undead.
*/ */
public class NecromancySpell extends AbstractAreaEffectSpell { public class NecromancySpell extends AbstractAreaEffectSpell {
private final Weighted<EntityType<? extends LivingEntity>> spawnPool = new Weighted<EntityType<? extends LivingEntity>>() private final Supplier<Optional<EntityType<? extends LivingEntity>>> spawnPool = new Weighted.Builder<EntityType<? extends LivingEntity>>()
.put(7, EntityType.ZOMBIE) .put(7, EntityType.ZOMBIE)
.put(4, EntityType.HUSK) .put(4, EntityType.HUSK)
.put(3, EntityType.DROWNED) .put(3, EntityType.DROWNED)
.put(2, EntityType.ZOMBIFIED_PIGLIN) .put(2, EntityType.ZOMBIFIED_PIGLIN)
.put(1, EntityType.ZOMBIE_VILLAGER); .put(1, EntityType.ZOMBIE_VILLAGER)
.build();
private final List<EntityReference<LivingEntity>> summonedEntities = new ArrayList<>(); private final List<EntityReference<LivingEntity>> summonedEntities = new ArrayList<>();

View file

@ -1,80 +1,86 @@
package com.minelittlepony.unicopia.util; package com.minelittlepony.unicopia.util;
import java.util.List; import java.util.*;
import java.util.Optional;
import java.util.Random;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import com.google.common.collect.Lists; import net.minecraft.util.Pair;
public class Weighted<T> { public final class Weighted {
private static final Supplier<Optional<?>> EMPTY = Optional::empty;
private static final Random rand = new Random(); @SuppressWarnings("unchecked")
public static <T> Supplier<Optional<T>> of() {
return (Supplier<Optional<T>>)(Object)EMPTY;
}
public static <T> Supplier<Optional<T>> of(Consumer<Weighted.Builder<T>> constructor) {
Weighted.Builder<T> result = new Weighted.Builder<>();
constructor.accept(result);
return result.build();
}
public final static class Builder<T> {
private static final Random RANDOM = new Random();
private float totalWeight = 0; private float totalWeight = 0;
private final List<Entry> entries = Lists.newArrayList(); private final List<Pair<WeightedValue<T>, Range>> entries = new ArrayList<>();
public static <T> Weighted<T> of(Consumer<Weighted<T>> constructor) { public Builder<T> putAll(Map<Integer, T> map) {
Weighted<T> result = new Weighted<>(); map.forEach(this::put);
return this;
constructor.accept(result);
return result;
} }
public Weighted<T> put(int weight, @NotNull T value) { public Builder<T> put(int weight, @NotNull T value) {
entries.add(new Entry(weight, value)); entries.add(new Pair<>(new WeightedValue<>(weight, value), new Range()));
totalWeight += weight; totalWeight += weight;
recalculate(); float rangeStart = 0;
for (var i : entries) {
rangeStart = i.getRight().set(rangeStart, (i.getLeft().weight() / totalWeight));
}
return this; return this;
} }
private void recalculate() { public Supplier<Optional<T>> build() {
float rangeStart = 0;
for (Entry i : entries) {
i.min = rangeStart;
i.max = rangeStart + (i.weight/totalWeight);
rangeStart = i.max;
}
}
public Optional<T> get() {
if (entries.isEmpty()) { if (entries.isEmpty()) {
return Optional.empty(); return of();
} }
if (entries.size() == 1) {
float random = rand.nextFloat(); final var val = Optional.ofNullable(entries.get(0).getLeft().result());
return () -> val;
}
final var entries = new ArrayList<>(this.entries);
return () -> {
final float pointer = RANDOM.nextFloat();
return entries.stream() return entries.stream()
.filter(i -> random >= i.min && random <= i.max) .filter(i -> i.getRight().isIn(pointer))
.map(Entry::getResult) .map(i -> i.getLeft().result())
.findFirst(); .findFirst();
};
} }
class Entry { private record WeightedValue<T> (float weight, T result) {}
final float weight;
final T result;
private final class Range {
float min; float min;
float max; float max;
Entry(int weight, T result) { public boolean isIn(float pointer) {
this.weight = weight; return pointer >= min && pointer <= max;
this.result = result;
} }
T getResult() { public float set(float start, float size) {
return result; min = start;
max = start + size;
return max;
}
} }
} }
} }