mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 23:27:59 +01:00
A bit of general cleanup
This commit is contained in:
parent
8f45fcf811
commit
7a8ba44f0d
5 changed files with 78 additions and 96 deletions
|
@ -8,7 +8,6 @@ import java.util.HashSet;
|
|||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -20,9 +19,9 @@ public interface TreeType {
|
|||
TreeType NONE = new TreeTypeImpl(
|
||||
Unicopia.id("none"),
|
||||
false,
|
||||
new Weighted<Supplier<ItemStack>>(),
|
||||
Set.of(),
|
||||
Set.of()
|
||||
Set.of(),
|
||||
Weighted.of()
|
||||
);
|
||||
Direction[] WIDE_DIRS = new Direction[] { Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST };
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.minelittlepony.unicopia.ability.data.tree;
|
||||
|
||||
import com.minelittlepony.unicopia.util.Weighted;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
@ -11,21 +10,13 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class TreeTypeImpl implements TreeType {
|
||||
private final Identifier name;
|
||||
private final boolean wideTrunk;
|
||||
private final Set<Identifier> logs;
|
||||
private final Set<Identifier> leaves;
|
||||
private final Weighted<Supplier<ItemStack>> pool;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public record TreeTypeImpl (
|
||||
Identifier name,
|
||||
boolean wideTrunk,
|
||||
Set<Identifier> logs,
|
||||
Set<Identifier> leaves,
|
||||
Supplier<Optional<Supplier<ItemStack>>> pool
|
||||
) implements TreeType {
|
||||
@Override
|
||||
public boolean isLeaves(BlockState 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);
|
||||
}
|
||||
|
||||
@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) {
|
||||
return ids.contains(Registry.BLOCK.getId(state.getBlock()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
static boolean isNonPersistent(BlockState state) {
|
||||
return !state.contains(LeavesBlock.PERSISTENT) || !state.get(LeavesBlock.PERSISTENT);
|
||||
}
|
||||
|
|
|
@ -65,18 +65,13 @@ public class TreeTypeLoader extends JsonDataLoader implements IdentifiableResour
|
|||
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) {
|
||||
return new TreeTypeImpl(
|
||||
id,
|
||||
wideTrunk,
|
||||
getWeighted(new Weighted<Supplier<ItemStack>>()),
|
||||
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();
|
||||
}
|
||||
|
||||
void appendDrop(Weighted<Supplier<ItemStack>> weighted) {
|
||||
void appendDrop(Weighted.Builder<Supplier<ItemStack>> weighted) {
|
||||
Registry.ITEM.getOrEmpty(item).ifPresent(item -> {
|
||||
weighted.put(weight, item::getDefaultStack);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
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.
|
||||
*/
|
||||
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(4, EntityType.HUSK)
|
||||
.put(3, EntityType.DROWNED)
|
||||
.put(2, EntityType.ZOMBIFIED_PIGLIN)
|
||||
.put(1, EntityType.ZOMBIE_VILLAGER);
|
||||
.put(1, EntityType.ZOMBIE_VILLAGER)
|
||||
.build();
|
||||
|
||||
private final List<EntityReference<LivingEntity>> summonedEntities = new ArrayList<>();
|
||||
|
||||
|
|
|
@ -1,80 +1,86 @@
|
|||
package com.minelittlepony.unicopia.util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
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();
|
||||
|
||||
private float totalWeight = 0;
|
||||
|
||||
private final List<Entry> entries = Lists.newArrayList();
|
||||
|
||||
public static <T> Weighted<T> of(Consumer<Weighted<T>> constructor) {
|
||||
Weighted<T> result = new Weighted<>();
|
||||
@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;
|
||||
return result.build();
|
||||
}
|
||||
|
||||
public Weighted<T> put(int weight, @NotNull T value) {
|
||||
entries.add(new Entry(weight, value));
|
||||
public final static class Builder<T> {
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
totalWeight += weight;
|
||||
private float totalWeight = 0;
|
||||
|
||||
recalculate();
|
||||
private final List<Pair<WeightedValue<T>, Range>> entries = new ArrayList<>();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void recalculate() {
|
||||
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()) {
|
||||
return Optional.empty();
|
||||
public Builder<T> putAll(Map<Integer, T> map) {
|
||||
map.forEach(this::put);
|
||||
return this;
|
||||
}
|
||||
|
||||
float random = rand.nextFloat();
|
||||
public Builder<T> put(int weight, @NotNull T value) {
|
||||
entries.add(new Pair<>(new WeightedValue<>(weight, value), new Range()));
|
||||
|
||||
return entries.stream()
|
||||
.filter(i -> random >= i.min && random <= i.max)
|
||||
.map(Entry::getResult)
|
||||
.findFirst();
|
||||
}
|
||||
totalWeight += weight;
|
||||
|
||||
class Entry {
|
||||
float rangeStart = 0;
|
||||
|
||||
final float weight;
|
||||
for (var i : entries) {
|
||||
rangeStart = i.getRight().set(rangeStart, (i.getLeft().weight() / totalWeight));
|
||||
}
|
||||
|
||||
final T result;
|
||||
|
||||
float min;
|
||||
float max;
|
||||
|
||||
Entry(int weight, T result) {
|
||||
this.weight = weight;
|
||||
this.result = result;
|
||||
return this;
|
||||
}
|
||||
|
||||
T getResult() {
|
||||
return result;
|
||||
public Supplier<Optional<T>> build() {
|
||||
if (entries.isEmpty()) {
|
||||
return of();
|
||||
}
|
||||
if (entries.size() == 1) {
|
||||
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()
|
||||
.filter(i -> i.getRight().isIn(pointer))
|
||||
.map(i -> i.getLeft().result())
|
||||
.findFirst();
|
||||
};
|
||||
}
|
||||
|
||||
private record WeightedValue<T> (float weight, T result) {}
|
||||
|
||||
private final class Range {
|
||||
float min;
|
||||
float max;
|
||||
|
||||
public boolean isIn(float pointer) {
|
||||
return pointer >= min && pointer <= max;
|
||||
}
|
||||
|
||||
public float set(float start, float size) {
|
||||
min = start;
|
||||
max = start + size;
|
||||
return max;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue