mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-24 05:47: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.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 };
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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<>();
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
private float totalWeight = 0;
|
return (Supplier<Optional<T>>)(Object)EMPTY;
|
||||||
|
}
|
||||||
private final List<Entry> entries = Lists.newArrayList();
|
|
||||||
|
|
||||||
public static <T> Weighted<T> of(Consumer<Weighted<T>> constructor) {
|
|
||||||
Weighted<T> result = new Weighted<>();
|
|
||||||
|
|
||||||
|
public static <T> Supplier<Optional<T>> of(Consumer<Weighted.Builder<T>> constructor) {
|
||||||
|
Weighted.Builder<T> result = new Weighted.Builder<>();
|
||||||
constructor.accept(result);
|
constructor.accept(result);
|
||||||
|
return result.build();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Weighted<T> put(int weight, @NotNull T value) {
|
public final static class Builder<T> {
|
||||||
entries.add(new Entry(weight, value));
|
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;
|
public Builder<T> putAll(Map<Integer, T> map) {
|
||||||
}
|
map.forEach(this::put);
|
||||||
|
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
totalWeight += weight;
|
||||||
.filter(i -> random >= i.min && random <= i.max)
|
|
||||||
.map(Entry::getResult)
|
|
||||||
.findFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Entry {
|
float rangeStart = 0;
|
||||||
|
|
||||||
final float weight;
|
for (var i : entries) {
|
||||||
|
rangeStart = i.getRight().set(rangeStart, (i.getLeft().weight() / totalWeight));
|
||||||
|
}
|
||||||
|
|
||||||
final T result;
|
return this;
|
||||||
|
|
||||||
float min;
|
|
||||||
float max;
|
|
||||||
|
|
||||||
Entry(int weight, T result) {
|
|
||||||
this.weight = weight;
|
|
||||||
this.result = result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T getResult() {
|
public Supplier<Optional<T>> build() {
|
||||||
return result;
|
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