mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 19:46:42 +01:00
Various housekeeping
This commit is contained in:
parent
5708f9c80f
commit
58372537cc
19 changed files with 68 additions and 302 deletions
|
@ -1,7 +1,8 @@
|
||||||
package com.minelittlepony.unicopia.client.render.model;
|
package com.minelittlepony.unicopia.client.render.model;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.entity.SpellcastEntity;
|
import com.minelittlepony.unicopia.entity.SpellcastEntity;
|
||||||
import com.minelittlepony.unicopia.util.Color;
|
import com.minelittlepony.util.Color;
|
||||||
|
|
||||||
import net.minecraft.client.model.ModelPart;
|
import net.minecraft.client.model.ModelPart;
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
import net.minecraft.client.render.entity.model.EntityModel;
|
import net.minecraft.client.render.entity.model.EntityModel;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.entity.player;
|
package com.minelittlepony.unicopia.entity.player;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.util.MotionCompositor;
|
import com.minelittlepony.util.MotionCompositor;
|
||||||
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ import com.minelittlepony.unicopia.magic.spell.SpellRegistry;
|
||||||
import com.minelittlepony.unicopia.network.Channel;
|
import com.minelittlepony.unicopia.network.Channel;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
import com.minelittlepony.unicopia.network.MsgPlayerCapabilities;
|
||||||
import com.minelittlepony.unicopia.util.BasicEasingInterpolator;
|
import com.minelittlepony.util.BasicEasingInterpolator;
|
||||||
import com.minelittlepony.unicopia.util.IInterpolator;
|
import com.minelittlepony.util.IInterpolator;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
|
|
||||||
import net.minecraft.client.network.packet.EntityPassengersSetS2CPacket;
|
import net.minecraft.client.network.packet.EntityPassengersSetS2CPacket;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import com.minelittlepony.unicopia.entity.RaceContainer;
|
||||||
import com.minelittlepony.unicopia.magic.Caster;
|
import com.minelittlepony.unicopia.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.magic.HeldMagicEffect;
|
import com.minelittlepony.unicopia.magic.HeldMagicEffect;
|
||||||
import com.minelittlepony.unicopia.network.Transmittable;
|
import com.minelittlepony.unicopia.network.Transmittable;
|
||||||
import com.minelittlepony.unicopia.util.IInterpolator;
|
import com.minelittlepony.util.IInterpolator;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
|
|
||||||
|
|
|
@ -18,4 +18,8 @@ public enum CastResult {
|
||||||
* When right clicking a block the itemstack will be decremented.
|
* When right clicking a block the itemstack will be decremented.
|
||||||
*/
|
*/
|
||||||
DEFAULT;
|
DEFAULT;
|
||||||
|
|
||||||
|
public static CastResult cancelled(boolean cancelled) {
|
||||||
|
return cancelled ? NONE : DEFAULT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ public class DarknessSpell extends AbstractAttachableSpell {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyBlocks(Caster<?> source, int radius) {
|
private void applyBlocks(Caster<?> source, int radius) {
|
||||||
for (BlockPos pos : PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, radius))) {
|
PosHelper.getAllInRegionMutable(source.getOrigin(), new Sphere(false, radius)).filter(pos -> {
|
||||||
if (source.getWorld().random.nextInt(500) == 0) {
|
if (source.getWorld().random.nextInt(500) == 0) {
|
||||||
BlockState state = source.getWorld().getBlockState(pos);
|
BlockState state = source.getWorld().getBlockState(pos);
|
||||||
|
|
||||||
|
@ -112,11 +112,13 @@ public class DarknessSpell extends AbstractAttachableSpell {
|
||||||
if (source.getWorld() instanceof ServerWorld) {
|
if (source.getWorld() instanceof ServerWorld) {
|
||||||
growable.grow((ServerWorld)source.getWorld(), source.getWorld().random, pos, state);
|
growable.grow((ServerWorld)source.getWorld(), source.getWorld().random, pos, state);
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
|
}).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyEntities(Caster<?> source, int radius, Consumer<LivingEntity> consumer) {
|
private void applyEntities(Caster<?> source, int radius, Consumer<LivingEntity> consumer) {
|
||||||
|
|
|
@ -85,10 +85,9 @@ public class FireSpell extends AbstractSpell.RangedAreaSpell implements Useable,
|
||||||
if (player == null || player.isSneaking()) {
|
if (player == null || player.isSneaking()) {
|
||||||
result = applyBlocks(context.getWorld(), pos);
|
result = applyBlocks(context.getWorld(), pos);
|
||||||
} else {
|
} else {
|
||||||
|
result = PosHelper.getAllInRegionMutable(pos, effect_range).reduce(result,
|
||||||
for (BlockPos i : PosHelper.getAllInRegionMutable(pos, effect_range)) {
|
(r, i) -> applyBlocks(context.getWorld(), i),
|
||||||
result |= applyBlocks(context.getWorld(), i);
|
(a, b) -> a || b);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -111,17 +110,10 @@ public class FireSpell extends AbstractSpell.RangedAreaSpell implements Useable,
|
||||||
public CastResult onDispenced(BlockPos pos, Direction facing, BlockPointer source, Affinity affinity) {
|
public CastResult onDispenced(BlockPos pos, Direction facing, BlockPointer source, Affinity affinity) {
|
||||||
pos = pos.offset(facing, 4);
|
pos = pos.offset(facing, 4);
|
||||||
|
|
||||||
boolean result = false;
|
return CastResult.cancelled(PosHelper.getAllInRegionMutable(pos, effect_range).reduce(false,
|
||||||
|
(r, i) -> applyBlocks(source.getWorld(), i),
|
||||||
for (BlockPos i : PosHelper.getAllInRegionMutable(pos, effect_range)) {
|
(a, b) -> a || b)
|
||||||
result |= applyBlocks(source.getWorld(), i);
|
|| applyEntities(null, source.getWorld(), pos));
|
||||||
}
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
result = applyEntities(null, source.getWorld(), pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result ? CastResult.NONE : CastResult.DEFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean applyBlocks(World world, BlockPos pos) {
|
protected boolean applyBlocks(World world, BlockPos pos) {
|
||||||
|
|
|
@ -88,9 +88,7 @@ public class IceSpell extends AbstractSpell.RangedAreaSpell implements Useable,
|
||||||
|
|
||||||
private boolean applyBlocks(PlayerEntity owner, World world, BlockPos pos) {
|
private boolean applyBlocks(PlayerEntity owner, World world, BlockPos pos) {
|
||||||
|
|
||||||
for (BlockPos i : PosHelper.getAllInRegionMutable(pos, effect_range)) {
|
PosHelper.getAllInRegionMutable(pos, effect_range).forEach(i -> applyBlockSingle(owner, world, i));
|
||||||
applyBlockSingle(owner, world, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return applyEntities(owner, world, pos);
|
return applyEntities(owner, world, pos);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +134,7 @@ public class IceSpell extends AbstractSpell.RangedAreaSpell implements Useable,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSurroundedByIce(World w, BlockPos pos) {
|
public static boolean isSurroundedByIce(World w, BlockPos pos) {
|
||||||
return !PosHelper.adjacentNeighbours(pos).stream().anyMatch(i ->
|
return !PosHelper.adjacentNeighbours(pos).anyMatch(i ->
|
||||||
w.getBlockState(i).getMaterial() == Material.ICE
|
w.getBlockState(i).getMaterial() == Material.ICE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ public abstract class MixinLivingEntity extends Entity implements PonyContainer<
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- temporary
|
// ---------- temporary
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
||||||
public void onIsClimbing(CallbackInfoReturnable<Boolean> info) {
|
public void onIsClimbing(CallbackInfoReturnable<Boolean> info) {
|
||||||
LivingEntity self = (LivingEntity)(Object)this;
|
LivingEntity self = (LivingEntity)(Object)this;
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.particles;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.util.Color;
|
import com.minelittlepony.util.Color;
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ public interface ParticleSource {
|
||||||
default void spawnParticles(Shape area, int count, Consumer<Vec3d> particleSpawner) {
|
default void spawnParticles(Shape area, int count, Consumer<Vec3d> particleSpawner) {
|
||||||
Vec3d pos = getOriginVector();
|
Vec3d pos = getOriginVector();
|
||||||
|
|
||||||
area.randomPoints(count, getWorld().random).stream()
|
area.randomPoints(count, getWorld().random)
|
||||||
.map(point -> point.add(pos))
|
.map(point -> point.add(pos))
|
||||||
.forEach(particleSpawner);
|
.forEach(particleSpawner);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.google.common.cache.CacheLoader;
|
|
||||||
import com.google.common.cache.LoadingCache;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class BasicEasingInterpolator implements IInterpolator {
|
|
||||||
|
|
||||||
private static LoadingCache<UUID, BasicEasingInterpolator> instanceCache = CacheBuilder.newBuilder()
|
|
||||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
|
||||||
.build(CacheLoader.from(BasicEasingInterpolator::new));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets or creates a new basic, linear interpolator for the provided id.
|
|
||||||
*/
|
|
||||||
public static IInterpolator getInstance(UUID id) {
|
|
||||||
return instanceCache.getUnchecked(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Map<String, Float> properties = new HashMap<>();
|
|
||||||
|
|
||||||
private float getLast(String key, float to) {
|
|
||||||
if (properties.containsKey(key)) {
|
|
||||||
return properties.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return to;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float interpolate(String key, float to, float scalingFactor) {
|
|
||||||
float from = getLast(key, to);
|
|
||||||
|
|
||||||
from += (to - from) / scalingFactor;
|
|
||||||
|
|
||||||
if (Float.isNaN(from) || Float.isInfinite(from)) {
|
|
||||||
System.err.println("Error: Animation frame for " + key + " is NaN or Infinite.");
|
|
||||||
from = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
properties.put(key, from);
|
|
||||||
|
|
||||||
return from;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
|
||||||
|
|
||||||
public interface Color {
|
|
||||||
static float r(int hex) {
|
|
||||||
return (hex >> 16 & 255) / 255F;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float g(int hex) {
|
|
||||||
return (hex >> 8 & 255) / 255F;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float b(int hex) {
|
|
||||||
return (hex & 255) / 255F;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interpolator function for handling transitions between animation states.
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface IInterpolator {
|
|
||||||
/**
|
|
||||||
* Interpolates a value between the requested final destination and what it was last.
|
|
||||||
*
|
|
||||||
* @param key Identifier to track previous values
|
|
||||||
* @param to The new values
|
|
||||||
* @param scalingFactor Scaling factor to control how quickly values change
|
|
||||||
*/
|
|
||||||
float interpolate(String key, float to, float scalingFactor);
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
import com.google.common.collect.AbstractIterator;
|
|
||||||
|
|
||||||
public interface Iterators<T> extends Iterable<T> {
|
|
||||||
|
|
||||||
static <T> Iterators<T> iterate(Supplier<T> supplier) {
|
|
||||||
return () -> new AbstractIterator<T>() {
|
|
||||||
@Override
|
|
||||||
protected T computeNext() {
|
|
||||||
T next = supplier.get();
|
|
||||||
|
|
||||||
if (next == null) {
|
|
||||||
endOfData();
|
|
||||||
}
|
|
||||||
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a sequential {@code Stream} with this collection as its source.
|
|
||||||
*
|
|
||||||
* <p>This method should be overridden when the {@link #spliterator()}
|
|
||||||
* method cannot return a spliterator that is {@code IMMUTABLE},
|
|
||||||
* {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
|
|
||||||
* for details.)
|
|
||||||
*
|
|
||||||
* @implSpec
|
|
||||||
* The default implementation creates a sequential {@code Stream} from the
|
|
||||||
* collection's {@code Spliterator}.
|
|
||||||
*
|
|
||||||
* @return a sequential {@code Stream} over the elements in this collection
|
|
||||||
* @since 1.8
|
|
||||||
*/
|
|
||||||
default Stream<T> stream() {
|
|
||||||
return StreamSupport.stream(spliterator(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a possibly parallel {@code Stream} with this collection as its
|
|
||||||
* source. It is allowable for this method to return a sequential stream.
|
|
||||||
*
|
|
||||||
* <p>This method should be overridden when the {@link #spliterator()}
|
|
||||||
* method cannot return a spliterator that is {@code IMMUTABLE},
|
|
||||||
* {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
|
|
||||||
* for details.)
|
|
||||||
*
|
|
||||||
* @implSpec
|
|
||||||
* The default implementation creates a parallel {@code Stream} from the
|
|
||||||
* collection's {@code Spliterator}.
|
|
||||||
*
|
|
||||||
* @return a possibly parallel {@code Stream} over the elements in this
|
|
||||||
* collection
|
|
||||||
* @since 1.8
|
|
||||||
*/
|
|
||||||
default Stream<T> parallelStream() {
|
|
||||||
return StreamSupport.stream(spliterator(), true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates roll and incline for a player based on their motion vectors.
|
|
||||||
*
|
|
||||||
* @author Polyakovich - Big thank you to this dude and his meta-physics friend for working this all out.
|
|
||||||
*/
|
|
||||||
public abstract class MotionCompositor {
|
|
||||||
|
|
||||||
static double clampLimit(double num, double limit) {
|
|
||||||
return MathHelper.clamp(num, -limit, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static float sensibleAngle(float angle) {
|
|
||||||
angle %= 360;
|
|
||||||
|
|
||||||
if (angle > 180) angle -= 360;
|
|
||||||
if (angle < -180) angle += 360;
|
|
||||||
|
|
||||||
return angle;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Gets the angle of horizontal roll in degrees based on the player's vertical and horizontal motion.
|
|
||||||
*/
|
|
||||||
protected double calculateRoll(PlayerEntity player, double motionX, double motionY, double motionZ) {
|
|
||||||
|
|
||||||
// since model roll should probably be calculated from model rotation rather than entity rotation...
|
|
||||||
double roll = sensibleAngle(player.prevBodyYaw - player.bodyYaw);
|
|
||||||
double horMotion = Math.sqrt(motionX * motionX + motionZ * motionZ);
|
|
||||||
float modelYaw = sensibleAngle(player.bodyYaw);
|
|
||||||
|
|
||||||
// detecting that we're flying backwards and roll must be inverted
|
|
||||||
if (Math.abs(sensibleAngle((float) Math.toDegrees(Math.atan2(motionX, motionZ)) + modelYaw)) > 90) {
|
|
||||||
roll *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ayyy magic numbers (after 5 - an approximation of nice looking coefficients calculated by hand)
|
|
||||||
|
|
||||||
// roll might be zero, in which case Math.pow produces +Infinity. Anything x Infinity = NaN.
|
|
||||||
double pow = roll != 0 ? Math.pow(Math.abs(roll), -0.191) : 0;
|
|
||||||
|
|
||||||
roll *= horMotion * 5 * (3.6884f * pow);
|
|
||||||
|
|
||||||
assert !Float.isNaN((float)roll);
|
|
||||||
|
|
||||||
return MathHelper.clamp(roll, -54, 54);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the angle of inclination in degrees based on the player's vertical and horizontal motion.
|
|
||||||
*/
|
|
||||||
protected double calculateIncline(PlayerEntity player, double motionX, double motionY, double motionZ) {
|
|
||||||
double dist = Math.sqrt(motionX * motionX + motionZ * motionZ);
|
|
||||||
double angle = Math.atan2(motionY, dist);
|
|
||||||
|
|
||||||
if (!player.abilities.allowFlying) {
|
|
||||||
angle /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
angle = clampLimit(angle, Math.PI / 3);
|
|
||||||
|
|
||||||
return Math.toDegrees(angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +1,13 @@
|
||||||
package com.minelittlepony.unicopia.util;
|
package com.minelittlepony.unicopia.util;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Spliterator;
|
||||||
|
import java.util.Spliterators.AbstractSpliterator;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||||
|
@ -44,46 +48,29 @@ public interface PosHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Iterators<BlockPos> adjacentNeighbours(BlockPos origin) {
|
static Stream<BlockPos> adjacentNeighbours(BlockPos origin) {
|
||||||
BlockPos.Mutable pos = new BlockPos.Mutable(origin);
|
BlockPos.Mutable pos = new BlockPos.Mutable(origin);
|
||||||
Iterator<Direction> directions = Lists.newArrayList(Direction.values()).iterator();
|
List<Direction> directions = Lists.newArrayList(Direction.values());
|
||||||
|
Iterator<Direction> iter = directions.iterator();
|
||||||
|
return StreamSupport.stream(new AbstractSpliterator<BlockPos>(directions.size(), Spliterator.SIZED) {
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(Consumer<? super BlockPos> consumer) {
|
||||||
|
if (iter.hasNext()) {
|
||||||
|
Direction next = iter.next();
|
||||||
|
|
||||||
return Iterators.iterate(() -> {
|
pos.set(origin.getX() + next.getOffsetX(), origin.getY() + next.getOffsetY(), origin.getZ() + next.getOffsetZ());
|
||||||
if (directions.hasNext()) {
|
consumer.accept(pos);
|
||||||
Direction next = directions.next();
|
return true;
|
||||||
|
|
||||||
pos.set(origin.getX() + next.getOffsetX(), origin.getY() + next.getOffsetY(), origin.getZ() + next.getOffsetZ());
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static Iterators<BlockPos> getAllInRegionMutable(BlockPos origin, Shape shape) {
|
|
||||||
Iterator<BlockPos> iter = BlockPos.iterate(
|
|
||||||
origin.add(new BlockPos(shape.getLowerBound())),
|
|
||||||
origin.add(new BlockPos(shape.getUpperBound()))
|
|
||||||
).iterator();
|
|
||||||
|
|
||||||
return Iterators.iterate(() -> {
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
BlockPos pos = iter.next();
|
|
||||||
|
|
||||||
if (shape.isPointInside(new Vec3d(pos.subtract(origin)))) {
|
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}, false);
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static Stream<BlockPos> getAllInRegionMutable(BlockPos origin, Shape shape) {
|
||||||
* Creates a stream of mutable block positions ranging from the beginning position to end.
|
return BlockPos.stream(
|
||||||
*/
|
origin.add(new BlockPos(shape.getLowerBound())),
|
||||||
@Deprecated
|
origin.add(new BlockPos(shape.getUpperBound()))
|
||||||
static Stream<BlockPos> inRegion(BlockPos from, BlockPos to) {
|
).filter(pos -> shape.isPointInside(new Vec3d(pos.subtract(origin))));
|
||||||
return BlockPos.stream(from, to);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All of the Auxiliary effects used in minecraft for World.spawnEvent
|
* All of the Auxiliary effects used in minecraft for World.playGlobalEvent
|
||||||
*/
|
*/
|
||||||
public enum WorldEvent {
|
public enum WorldEvent {
|
||||||
DISPENSER_DISPENSE_BLOCK(1000),
|
DISPENSER_DISPENSE_BLOCK(1000),
|
||||||
|
@ -82,16 +82,7 @@ public enum WorldEvent {
|
||||||
play(world, pos, 0);
|
play(world, pos, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void play(World world, BlockPos pos, int data) {
|
private void play(World world, BlockPos pos, int data) {
|
||||||
world.playGlobalEvent(getId(), pos, data);
|
world.playGlobalEvent(getId(), pos, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WorldEvent fromId(int id) {
|
|
||||||
for (WorldEvent i : values()) {
|
|
||||||
if (i.id == id) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return UNKNOWN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package com.minelittlepony.unicopia.util.shape;
|
package com.minelittlepony.unicopia.util.shape;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.Spliterator;
|
||||||
|
import java.util.Spliterators.AbstractSpliterator;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import com.minelittlepony.unicopia.util.Iterators;
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
@ -75,16 +78,19 @@ public interface Shape {
|
||||||
/**
|
/**
|
||||||
* Returns a sequence of N random points.
|
* Returns a sequence of N random points.
|
||||||
*/
|
*/
|
||||||
default Iterators<Vec3d> randomPoints(int n, Random rand) {
|
default Stream<Vec3d> randomPoints(int n, Random rand) {
|
||||||
AtomicInteger atom = new AtomicInteger(n);
|
AtomicInteger atom = new AtomicInteger(n);
|
||||||
return Iterators.iterate(() -> {
|
return StreamSupport.stream(new AbstractSpliterator<Vec3d>(n, Spliterator.SIZED) {
|
||||||
if (atom.get() <= 0) {
|
@Override
|
||||||
return null;
|
public boolean tryAdvance(Consumer<? super Vec3d> consumer) {
|
||||||
|
|
||||||
|
if (atom.decrementAndGet() >= 0) {
|
||||||
|
consumer.accept(computePoint(rand));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}, false);
|
||||||
atom.decrementAndGet();
|
|
||||||
|
|
||||||
return computePoint(rand);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue