More updating

This commit is contained in:
Sollace 2020-04-15 12:37:14 +02:00
parent 85b9ddb706
commit fdc7984ab6
93 changed files with 1544 additions and 1587 deletions

View file

@ -0,0 +1,23 @@
package com.minelittlepony.jumpingcastle.api;
import java.util.UUID;
import javax.annotation.Nullable;
import com.minelittlepony.jumpingcastle.api.payload.BinaryPayload;
/**
* Implementor for a Jumping Castle API bus.
*/
public interface Bus {
void sendToServer(String channel, long id, Message message, Target target);
void sendToClient(String channel, long id, Message message, UUID playerId);
void sendToClient(UUID playerId, BinaryPayload forwarded);
@Nullable
Object getMinecraftServer();
Server getServer();
}

View file

@ -0,0 +1,60 @@
package com.minelittlepony.jumpingcastle.api;
import java.util.UUID;
/**
* A channel for sending and recieving messages.
*/
public interface Channel {
/**
* Registers a handler for a specific message type transmitted over this channel.
*
* @param messageType The message type being recieved.
* @param handler A handler instance to handle the message.
*/
<T extends Message> Channel listenFor(Class<T> messageType, Message.Handler<T> handler);
/**
* Registers a handler for a specific message type transmitted over this channel.
*
* @param messageType The message type being recieved.
*/
<T extends Message & Message.Handler<T>> Channel listenFor(Class<T> messageType);
/**
* Gets the minecraft server
*/
<T> T getServer();
/**
* Sends a message over this channel. By default targets all other clients listening on this channel.
*
* @param message The message to send.
*/
default Channel send(Message message) {
return send(message, Target.CLIENTS);
}
/**
* Sends a message over this channel.
*
* @param message The message to send.
* @param target Recipients that must handle this message (clients, server, or both)
*/
Channel send(Message message, Target target);
/**
* Sends a message back. Use this if you're a server.
*
* @param message The message to send.
* @param recipient Recipient that must handle this message
*/
Channel respond(Message message, UUID recipient);
/**
* Sends a message back to all clients. Use this if you're a server.
*
* @param message The message to send.
*/
Channel broadcast(Message message);
}

View file

@ -0,0 +1,28 @@
package com.minelittlepony.jumpingcastle.api;
/**
* Jumping Castle main interface.
* <p>
*{@code
* JumpingCastle.listen("My Channel").consume(MyMessage.class, (msg, channel) -> {
* ...
* });
*
*/
public interface JumpingCastle {
/**
* Gets or creates a new channel indexed by the given identifier.
*
* @param channelName The channel name
*
* @return An instance of IChannel.
*/
static Channel subscribeTo(String channelName, Client clientHandler) {
return null;
}
@FunctionalInterface
public interface Client {
void connectionEstablished();
}
}

View file

@ -0,0 +1,45 @@
package com.minelittlepony.jumpingcastle.api;
import com.minelittlepony.jumpingcastle.api.payload.Serializable;
/**
* A message for communicating over a channel.
* Fields marked with @Expose are automatically serialized to the output packet stream
* and will be made available on the far end of the pipe.
*
* Override the read and write methods to customise this behaviour.
*
*/
public interface Message extends Serializable<Message> {
/**
* Gets a unique identifier to represent a packet over channel communications.
*/
static long identifier(Class<? extends Message> cls) {
return cls.getCanonicalName().hashCode();
}
/**
* Gets a unique identifier to represent this packet over channel communications.
*/
default long identifier() {
return identifier(getClass());
}
/**
* Handler interface for incoming messages.
*
* @param <T> The type of message to handle.
*/
@FunctionalInterface
public interface Handler<T extends Message> {
/**
* Called when a new message is received.
*
* @param message The message received.
*
* @param channel The channel used to deliver the message.
*/
void onPayload(T message, Channel channel);
}
}

View file

@ -0,0 +1,7 @@
package com.minelittlepony.jumpingcastle.api;
import java.util.UUID;
public interface Server {
void stopTrackingPlayer(UUID playerId);
}

View file

@ -0,0 +1,43 @@
package com.minelittlepony.jumpingcastle.api;
/**
* Targeting method to control who receives a message when sent.
* Senders choose whether a message is received on other clients, just the server, or both.
*/
public enum Target {
/**
* Message is ignored by the server and forwarded to connected clients.
*/
CLIENTS(true, false),
/**
* Only the server should process this message. Clients ignore it.
*/
SERVER(false, true),
/**
* The server should process this message and forward it to all available clients.
*/
SERVER_AND_CLIENTS(true, true);
private final boolean clients;
private final boolean servers;
Target(boolean clients, boolean servers) {
this.clients = clients;
this.servers = servers;
}
/**
* True if messages with this targeting must be processed by the client.
*/
public boolean isClients() {
return clients;
}
/**
* True if messages with this targeting must be processed by the server.
*/
public boolean isServers() {
return servers;
}
}

View file

@ -0,0 +1,63 @@
package com.minelittlepony.jumpingcastle.api.payload;
import javax.annotation.Nullable;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
public interface BinaryPayload {
@Nullable
static BinaryPayload of(Object buffer) {
if (buffer instanceof ByteBuf) {
return ByteBufBinaryPayload.of((ByteBuf)buffer);
}
return null;
}
static BinaryPayload create() {
return of(Unpooled.buffer());
}
<T> T buff();
byte[] bytes();
byte[] readToEnd();
long readLong();
BinaryPayload writeLong(long l);
int readInt();
BinaryPayload writeInt(int b);
byte readByte();
BinaryPayload writeByte(byte b);
String readString();
BinaryPayload writeString(String s);
byte[] readBytes(int len);
BinaryPayload writeBytes(byte[] bytes);
BinaryPayload reverse();
@SuppressWarnings("unchecked")
default <T extends Serializable<? super T>> T readBinary(Class<T> type) {
try {
return (T)type.newInstance().read(this);
} catch (InstantiationException | IllegalAccessException e) {
return null;
}
}
default <T extends Serializable<T>> BinaryPayload writeBinary(T message) {
message.write(this);
return this;
}
}

View file

@ -0,0 +1,89 @@
package com.minelittlepony.jumpingcastle.api.payload;
import java.nio.charset.StandardCharsets;
import io.netty.buffer.ByteBuf;
interface ByteBufBinaryPayload extends BinaryPayload {
static BinaryPayload of(ByteBuf buff) {
return (ByteBufBinaryPayload)(() -> buff);
}
@SuppressWarnings("unchecked")
ByteBuf buff();
@Override
default String readString() {
return buff().readCharSequence(readInt(), StandardCharsets.UTF_8).toString();
}
@Override
default int readInt() {
return buff().readInt();
}
@Override
default BinaryPayload writeInt(int b) {
buff().writeInt(b);
return this;
}
@Override
default byte readByte() {
return buff().readByte();
}
@Override
default BinaryPayload writeByte(byte b) {
buff().writeByte(b);
return this;
}
default byte[] bytes() {
return buff().array();
}
default byte[] readToEnd() {
byte[] bytes = new byte[buff().writerIndex() - buff().readerIndex()];
buff().readBytes(bytes);
return bytes;
}
@Override
default long readLong() {
return buff().readLong();
}
@Override
default BinaryPayload writeLong(long l) {
buff().writeLong(l);
return this;
}
@Override
default BinaryPayload reverse() {
buff().readerIndex(0);
return this;
}
@Override
default byte[] readBytes(int len) {
byte[] data = new byte[len];
buff().readBytes(data);
return data;
}
@Override
default BinaryPayload writeBytes(byte[] bytes) {
buff().writeBytes(bytes);
return this;
}
@Override
default BinaryPayload writeString(String s) {
buff().writeInt(s.getBytes(StandardCharsets.UTF_8).length);
buff().writeCharSequence(s, StandardCharsets.UTF_8);
return this;
}
}

View file

@ -0,0 +1,19 @@
package com.minelittlepony.jumpingcastle.api.payload;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonSerializer {
private static final Gson READER_GSON = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
public static <T> T read(BinaryPayload payload, Class<T> type) {
return (T)READER_GSON.fromJson(payload.readString(), type);
}
public static <T> void write(BinaryPayload payload, T object) {
payload.writeString(READER_GSON.toJson(object));
}
}

View file

@ -0,0 +1,19 @@
package com.minelittlepony.jumpingcastle.api.payload;
public interface Serializable<T extends Serializable<T>> {
/**
* Reads the contents of this message from a networking payload.
*/
@SuppressWarnings("unchecked")
default T read(BinaryPayload payload) {
return (T)JsonSerializer.read(payload, getClass());
}
/**
* Writes the contents of this message to a networking payload.
*/
default void write(BinaryPayload payload) {
JsonSerializer.write(payload, this);
}
}

View file

@ -9,9 +9,9 @@ import net.minecraft.entity.effect.StatusEffectType;
import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class UEffects { public interface UEffects {
public static final StatusEffect FOOD_POISONING = new CustomStatusEffect(new Identifier(UnicopiaCore.MODID, "food_poisoning"), StatusEffectType.BENEFICIAL, 3484199) StatusEffect FOOD_POISONING = new CustomStatusEffect(new Identifier(UnicopiaCore.MODID, "food_poisoning"), StatusEffectType.BENEFICIAL, 3484199)
.setSilent() .setSilent()
.direct((p, e, i) -> { .direct((p, e, i) -> {
StatusEffectInstance nausea = e.getStatusEffect(StatusEffects.NAUSEA); StatusEffectInstance nausea = e.getStatusEffect(StatusEffects.NAUSEA);

View file

@ -3,17 +3,17 @@ package com.minelittlepony.unicopia.core;
import net.minecraft.particle.DefaultParticleType; import net.minecraft.particle.DefaultParticleType;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class UParticles { public interface UParticles {
// TODO: // TODO:
interface ParticleTypeRegistry { interface ParticleTypeRegistry {
static ParticleTypeRegistry getTnstance() {return null;} static ParticleTypeRegistry getTnstance() {return null;}
DefaultParticleType register(Identifier id); DefaultParticleType register(Identifier id);
} }
public static final DefaultParticleType UNICORN_MAGIC = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "unicorn_magic")); DefaultParticleType UNICORN_MAGIC = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "unicorn_magic"));
public static final DefaultParticleType CHANGELING_MAGIC = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "changeling_magic")); DefaultParticleType CHANGELING_MAGIC = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "changeling_magic"));
public static final DefaultParticleType RAIN_DROPS = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "rain_drops")); DefaultParticleType RAIN_DROPS = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "rain_drops"));
public static final DefaultParticleType SPHERE = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "sphere")); DefaultParticleType SPHERE = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "sphere"));
public static final DefaultParticleType DISK = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "disk")); DefaultParticleType DISK = ParticleTypeRegistry.getTnstance().register(new Identifier("unicopia", "disk"));
} }

View file

@ -4,23 +4,23 @@ import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
public class USounds { public interface USounds {
public static final SoundEvent WING_FLAP = register("wing_flap"); SoundEvent WING_FLAP = register("wing_flap");
public static final SoundEvent WIND_RUSH = register("wind_rush"); SoundEvent WIND_RUSH = register("wind_rush");
public static final SoundEvent INSECT = register("insect"); SoundEvent INSECT = register("insect");
public static final SoundEvent CHANGELING_BUZZ = register("changeling_buzz"); SoundEvent CHANGELING_BUZZ = register("changeling_buzz");
public static final SoundEvent SLIME_ADVANCE = register("slime_advance"); SoundEvent SLIME_ADVANCE = register("slime_advance");
public static final SoundEvent SLIME_RETRACT = register("slime_retract"); SoundEvent SLIME_RETRACT = register("slime_retract");
public static final SoundEvent RECORD_CRUSADE = register("record.crusade"); SoundEvent RECORD_CRUSADE = register("record.crusade");
public static final SoundEvent RECORD_PET = register("record.pet"); SoundEvent RECORD_PET = register("record.pet");
public static final SoundEvent RECORD_POPULAR = register("record.popular"); SoundEvent RECORD_POPULAR = register("record.popular");
public static final SoundEvent RECORD_FUNK = register("record.funk"); SoundEvent RECORD_FUNK = register("record.funk");
private static SoundEvent register(String name) { static SoundEvent register(String name) {
Identifier id = new Identifier(UnicopiaCore.MODID, name); Identifier id = new Identifier(UnicopiaCore.MODID, name);
return Registry.register(Registry.SOUND_EVENT, id, new SoundEvent(id)); return Registry.register(Registry.SOUND_EVENT, id, new SoundEvent(id));
} }

View file

@ -5,9 +5,9 @@ import net.minecraft.item.Item;
import net.minecraft.tag.Tag; import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class UTags { public interface UTags {
// TODO: includes unicopia:alicorn_amulet // TODO: includes unicopia:alicorn_amulet
public static final Tag<Item> CURSED_ARTEFACTS = TagRegistry.item(new Identifier(UnicopiaCore.MODID, "cursed_artefacts")); Tag<Item> CURSED_ARTEFACTS = TagRegistry.item(new Identifier(UnicopiaCore.MODID, "cursed_artefacts"));
static void bootstrap() {} static void bootstrap() {}
} }

View file

@ -0,0 +1,48 @@
package com.minelittlepony.unicopia.core.client.particle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.particle.DustParticleEffect;
import net.minecraft.world.World;
public class ChangelingMagicParticle extends MagicParticle {
private final SpriteProvider provider;
public ChangelingMagicParticle(SpriteProvider provider, World world, double x, double y, double z, double dx, double dy, double dz) {
super(world, x, y, z, dx, dy, dz, 1, 1, 1);
this.provider = provider;
float intensity = random.nextFloat() * 0.6F + 0.4F;
colorRed = intensity * 0.5F;
colorGreen = intensity;
colorBlue = intensity * 0.4f;
}
@Override
public void tick() {
setSpriteForAge(provider);
super.tick();
}
@Environment(EnvType.CLIENT)
public static class Factory implements ParticleFactory<DustParticleEffect> {
private final SpriteProvider provider;
public Factory(SpriteProvider provider) {
this.provider = provider;
}
@Override
public Particle createParticle(DustParticleEffect effect, World world, double x, double y, double z, double dx, double dy, double dz) {
MagicParticle particle = new MagicParticle(world, x, y, z, dx, dy, dz);
particle.setSprite(provider);
return particle;
}
}
}

View file

@ -0,0 +1,115 @@
package com.minelittlepony.unicopia.core.client.particle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.ParticleTextureSheet;
import net.minecraft.client.particle.SpriteBillboardParticle;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.particle.DustParticleEffect;
import net.minecraft.world.World;
public class MagicParticle extends SpriteBillboardParticle {
private double startX;
private double startY;
private double startZ;
MagicParticle(World w, double x, double y, double z, double vX, double vY, double vZ, float r, float g, float b) {
super(w, x, y, z);
velocityX = vX;
velocityY = vY;
velocityZ = vZ;
startX = x;
startY = y;
startZ = z;
scale = random.nextFloat() * 0.2F + 0.5F;
maxAge = (int)(Math.random() * 10) + 40;
colorRed = r;
colorGreen = g;
colorBlue = b;
}
MagicParticle(World w, double x, double y, double z, double vX, double vY, double vZ) {
this(w, x, y, z, vX, vY, vZ, 1, 1, 1);
colorGreen *= 0.3F;
if (random.nextBoolean()) {
colorBlue *= 0.4F;
}
if (random.nextBoolean()) {
colorRed *= 0.9F;
}
if (random.nextBoolean()) {
colorGreen += 0.5F;
}
if (random.nextBoolean()) {
colorGreen *= 2F;
} else if (random.nextBoolean()) {
colorRed *= 3.9F;
}
}
@Override
public ParticleTextureSheet getType() {
return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE;
}
@Override
public float getSize(float tickDelta) {
float shrink = (age + tickDelta) / maxAge;
return this.scale * (1 - shrink * shrink);
}
@Override
public int getColorMultiplier(float p_70070_1_) {
int i = super.getColorMultiplier(p_70070_1_);
float f1 = (float)age / (float)maxAge;
f1 *= f1;
f1 *= f1;
int j = i & 255;
int k = i >> 16 & 255;
k += f1 * 15 * 16;
if (k > 240) k = 240;
return j | k << 16;
}
@Override
public void tick() {
prevPosX = x;
prevPosY = y;
prevPosZ = z;
if (this.age++ >= this.maxAge) {
this.markDead();
} else {
float var1 = (float)age / (float)maxAge;
var1 = 1 + var1 - var1 * var1 * 2;
x = startX + velocityX * var1;
y = startY + velocityY;
z = startZ + velocityZ * var1;
}
}
@Environment(EnvType.CLIENT)
public static class Factory implements ParticleFactory<DustParticleEffect> {
private final SpriteProvider provider;
public Factory(SpriteProvider provider) {
this.provider = provider;
}
@Override
public Particle createParticle(DustParticleEffect effect, World world, double x, double y, double z, double dx, double dy, double dz) {
MagicParticle particle = effect.getAlpha() > 0 ?
new MagicParticle(world, x, y, z, dx, dy, dz, effect.getRed(), effect.getGreen(), effect.getBlue())
: new MagicParticle(world, x, y, z, dx, dy, dz);
particle.setSprite(provider);
return particle;
}
}
}

View file

@ -1,35 +0,0 @@
package com.minelittlepony.unicopia.core.client.particle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.PortalParticle;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.particle.DefaultParticleType;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.world.World;
public class ParticleChangelingMagic extends PortalParticle {
private int baseTextureIndex = 128;
public ParticleChangelingMagic(World world, double x, double y, double z, double dx, double dy, double dz) {
super(world, x, y, z, dx, dy, dz);
float intensity = random.nextFloat() * 0.6F + 0.4F;
colorRed = intensity * 0.5F;
colorGreen = intensity;
colorBlue = intensity * 0.4f;
setParticleTextureIndex((int)(Math.random() * 8.0D));
}
@Override
public void tick() {
setParticleTextureIndex(baseTextureIndex + (7 - age * 8 / maxAge));
super.tick();
}
}

View file

@ -1,92 +0,0 @@
package com.minelittlepony.unicopia.core.client.particle;
import net.minecraft.client.particle.Particle;
import net.minecraft.entity.Entity;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleType;
import net.minecraft.world.World;
public class ParticleUnicornMagic extends Particle {
private float portalParticleScale;
private double portalPosX;
private double portalPosY;
private double portalPosZ;
public ParticleUnicornMagic(ParticleEffect type, World w, double x, double y, double z, double vX, double vY, double vZ/*, int tint*/) {
super(w, x, y, z, vX, vY, vZ);
motionX = vX;
motionY = vY;
motionZ = vZ;
portalPosX = posX = x;
portalPosY = posY = y;
portalPosZ = posZ = z;
portalParticleScale = particleScale = rand.nextFloat() * 0.2F + 0.5F;
particleMaxAge = (int)(Math.random() * 10) + 40;
setParticleTextureIndex((int)(Math.random() * 8));
if (tint >= 0) {
particleRed = Color.r(tint);
particleGreen = Color.g(tint);
particleBlue = Color.b(tint);
} else {
particleRed = 1;
particleGreen = 1;
particleBlue = 1;
particleGreen *= 0.3F;
if (rand.nextBoolean()) {
particleBlue *= 0.4F;
}
if (rand.nextBoolean()) {
particleRed *= 0.9F;
}
if (rand.nextBoolean()) {
particleGreen += 0.5F;
}
if (rand.nextBoolean()) {
particleGreen *= 2F;
} else if (rand.nextBoolean()) {
particleRed *= 3.9F;
}
}
}
public void renderParticle(BufferBuilder renderer, Entity e, float p_70539_2_, float p_70539_3_, float p_70539_4_, float p_70539_5_, float p_70539_6_, float p_70539_7_) {
float f6 = 1 - ((particleAge + p_70539_2_) / particleMaxAge);
f6 = 1 - f6 * f6;
particleScale = portalParticleScale * f6;
super.renderParticle(renderer, e, p_70539_2_, p_70539_3_, p_70539_4_, p_70539_5_, p_70539_6_, p_70539_7_);
}
public int getBrightnessForRender(float p_70070_1_) {
int i = super.getBrightnessForRender(p_70070_1_);
float f1 = (float)particleAge / (float)particleMaxAge;
f1 *= f1;
f1 *= f1;
int j = i & 255;
int k = i >> 16 & 255;
k += f1 * 15 * 16;
if (k > 240) k = 240;
return j | k << 16;
}
public void onUpdate() {
prevPosX = posX;
prevPosY = posY;
prevPosZ = posZ;
float var1 = (float)particleAge / (float)particleMaxAge;
var1 = 1 + var1 - var1 * var1 * 2;
posX = portalPosX + motionX * var1;
posY = portalPosY + motionY;
posZ = portalPosZ + motionZ * var1;
if (particleAge++ >= particleMaxAge) {
setExpired();
}
}
}

View file

@ -4,6 +4,7 @@ import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.util.GlAllocationUtils; import net.minecraft.client.util.GlAllocationUtils;
public class SphereModel { public class SphereModel {
@ -20,9 +21,9 @@ public class SphereModel {
protected float rotZ; protected float rotZ;
public void setPosition(double x, double y, double z) { public void setPosition(double x, double y, double z) {
posX = x - TileEntityRendererDispatcher.staticPlayerX; posX = x - BlockEntityRenderDispatcher.renderOffsetX;
posY = y - TileEntityRendererDispatcher.staticPlayerY; posY = y - BlockEntityRenderDispatcher.renderOffsetY;
posZ = z - TileEntityRendererDispatcher.staticPlayerZ; posZ = z - BlockEntityRenderDispatcher.renderOffsetZ;
} }
public void setRotation(float x, float y, float z) { public void setRotation(float x, float y, float z) {
@ -68,6 +69,7 @@ public class SphereModel {
} }
protected void drawShape() { protected void drawShape() {
Sphere sphere = new Sphere(); Sphere sphere = new Sphere();
sphere.setDrawStyle(GLU.GLU_FILL); sphere.setDrawStyle(GLU.GLU_FILL);

View file

@ -0,0 +1,12 @@
package com.minelittlepony.unicopia.core.ducks;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IFarmland {
/**
* Gets the state used to represent this block as a piece of dirt.
*/
BlockState getDirtState(BlockState state, World world, BlockPos pos);
}

View file

@ -1,6 +1,7 @@
package com.minelittlepony.unicopia.core.enchanting; package com.minelittlepony.unicopia.core.enchanting;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -16,7 +17,7 @@ public interface IPageOwner extends ITransmittable {
@Nonnull @Nonnull
Map<Identifier, PageState> getPageStates(); Map<Identifier, PageState> getPageStates();
default void setPageState(IPage page, PageState state) { default void setPageState(Page page, PageState state) {
if (state == PageState.LOCKED) { if (state == PageState.LOCKED) {
getPageStates().remove(page.getName()); getPageStates().remove(page.getName());
} else { } else {
@ -25,7 +26,17 @@ public interface IPageOwner extends ITransmittable {
sendCapabilities(true); sendCapabilities(true);
} }
default PageState getPageState(IPage page) { default PageState getPageState(Page page) {
return getPageStates().getOrDefault(page.getName(), page.getDefaultState()); return getPageStates().getOrDefault(page.getName(), page.getDefaultState());
} }
default boolean hasPageStateRelative(Page page, PageState state, Function<Page, Page> iter) {
while ((page = iter.apply(page)) != null) {
if (getPageState(page) == state) {
return true;
}
}
return false;
}
} }

View file

@ -5,7 +5,7 @@ import net.minecraft.util.Identifier;
/** /**
* A spellbook page * A spellbook page
*/ */
public interface IPage extends Comparable<IPage> { public interface Page extends Comparable<Page> {
/** /**
* Gets the index. * Gets the index.
* This is the position the page appears in the book gui. * This is the position the page appears in the book gui.
@ -34,7 +34,7 @@ public interface IPage extends Comparable<IPage> {
*/ */
PageState getDefaultState(); PageState getDefaultState();
IPage next(); Page next();
IPage prev(); Page prev();
} }

View file

@ -4,6 +4,7 @@ import javax.annotation.Nullable;
import com.minelittlepony.unicopia.core.InteractionManager; import com.minelittlepony.unicopia.core.InteractionManager;
import com.minelittlepony.unicopia.core.ability.IAbilityReceiver; import com.minelittlepony.unicopia.core.ability.IAbilityReceiver;
import com.minelittlepony.unicopia.core.enchanting.IPageOwner;
import com.minelittlepony.unicopia.core.entity.FlightControl; import com.minelittlepony.unicopia.core.entity.FlightControl;
import com.minelittlepony.unicopia.core.entity.RaceContainer; import com.minelittlepony.unicopia.core.entity.RaceContainer;
import com.minelittlepony.unicopia.core.magic.ICaster; import com.minelittlepony.unicopia.core.magic.ICaster;
@ -23,7 +24,7 @@ import net.minecraft.util.math.BlockPos;
* *
* This is the core of unicopia. * This is the core of unicopia.
*/ */
public interface IPlayer extends ICaster<PlayerEntity>, RaceContainer<PlayerEntity>, ITransmittable { public interface IPlayer extends ICaster<PlayerEntity>, RaceContainer<PlayerEntity>, ITransmittable, IPageOwner {
/** /**
* Gets the player's magical abilities delegate responsible for all spell casting and persisting/updating. * Gets the player's magical abilities delegate responsible for all spell casting and persisting/updating.

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.core.entity.player;
import java.util.UUID; import java.util.UUID;
import com.minelittlepony.unicopia.core.Race; import com.minelittlepony.unicopia.core.Race;
import com.minelittlepony.unicopia.core.mixin.IWalker; import com.minelittlepony.unicopia.core.mixin.Walker;
import com.minelittlepony.unicopia.core.util.HeavyInventoryUtils; import com.minelittlepony.unicopia.core.util.HeavyInventoryUtils;
import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.attribute.EntityAttributeInstance;
@ -26,7 +26,7 @@ public class PlayerAttributes {
public void applyAttributes(PlayerEntity entity, Race race) { public void applyAttributes(PlayerEntity entity, Race race) {
loadStrength = HeavyInventoryUtils.getContentsTotalWorth(entity.inventory, false); loadStrength = HeavyInventoryUtils.getContentsTotalWorth(entity.inventory, false);
((IWalker)entity.abilities).setWalkSpeed(0.1F - (float)(loadStrength / 100000)); ((Walker)entity.abilities).setWalkSpeed(0.1F - (float)(loadStrength / 100000));
applyAttribute(entity, EntityAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth()); applyAttribute(entity, EntityAttributes.ATTACK_DAMAGE, EARTH_PONY_STRENGTH, race.canUseEarth());
applyAttribute(entity, EntityAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth()); applyAttribute(entity, EntityAttributes.KNOCKBACK_RESISTANCE, EARTH_PONY_STRENGTH, race.canUseEarth());

View file

@ -10,7 +10,6 @@ import com.minelittlepony.unicopia.core.UEffects;
import com.minelittlepony.unicopia.core.UTags; import com.minelittlepony.unicopia.core.UTags;
import com.minelittlepony.unicopia.core.UnicopiaCore; import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.minelittlepony.unicopia.core.ability.IAbilityReceiver; import com.minelittlepony.unicopia.core.ability.IAbilityReceiver;
import com.minelittlepony.unicopia.core.enchanting.IPageOwner;
import com.minelittlepony.unicopia.core.enchanting.PageState; import com.minelittlepony.unicopia.core.enchanting.PageState;
import com.minelittlepony.unicopia.core.entity.FlightControl; import com.minelittlepony.unicopia.core.entity.FlightControl;
import com.minelittlepony.unicopia.core.entity.Trap; import com.minelittlepony.unicopia.core.entity.Trap;
@ -49,7 +48,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.Difficulty; import net.minecraft.world.Difficulty;
public class PlayerCapabilities implements IPlayer, IPageOwner { public class PlayerCapabilities implements IPlayer {
private static final TrackedData<Integer> PLAYER_RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER); private static final TrackedData<Integer> PLAYER_RACE = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT); private static final TrackedData<Float> ENERGY = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);

View file

@ -0,0 +1,28 @@
package com.minelittlepony.unicopia.core.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import com.minelittlepony.unicopia.core.ducks.IFarmland;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@Mixin(FarmlandBlock.class)
abstract class MixinFarmlandBlock extends Block {
MixinFarmlandBlock() { super(null); }
@Inject(
method = "setToDirt(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V",
at = @At("HEAD"),
cancellable = true)
public static void setToDirt(BlockState state, World world, BlockPos pos) {
if (state.getBlock() instanceof IFarmland) {
BlockState dirtState = ((IFarmland)state.getBlock()).getDirtState(state, world, pos);
world.setBlockState(pos, pushEntitiesUpBeforeBlockChange(state, dirtState, world, pos));
}
}
}

View file

@ -6,7 +6,7 @@ import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.entity.player.PlayerAbilities; import net.minecraft.entity.player.PlayerAbilities;
@Mixin(PlayerAbilities.class) @Mixin(PlayerAbilities.class)
public interface IWalker { public interface Walker {
@Accessor("walkSpeed") @Accessor("walkSpeed")
void setWalkSpeed(float speed); void setWalkSpeed(float speed);
} }

View file

@ -1 +0,0 @@
package com.minelittlepony.unicopia.core;

View file

@ -0,0 +1,68 @@
package com.minelittlepony.unicopia.core.util;
import java.util.List;
import java.util.Queue;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import net.minecraft.world.World;
public class AwaitTickQueue {
private static final Queue<Consumer<World>> tickTasks = Queues.newArrayDeque();
private static List<DelayedTask> delayedTasks = Lists.newArrayList();
private static final Object locker = new Object();
public static void enqueueTask(Consumer<World> task) {
synchronized (locker) {
tickTasks.add(task);
}
}
public static void scheduleTask(Consumer<World> task, int ticksLater) {
synchronized (locker) {
delayedTasks.add(new DelayedTask(task, ticksLater));
}
}
public void onUpdate(World world) {
synchronized (locker) {
delayedTasks = delayedTasks.stream().filter(DelayedTask::tick).collect(Collectors.toList());
Consumer<World> task;
while ((task = tickTasks.poll()) != null) {
try {
task.accept(world);
} catch (Exception e) {
UnicopiaCore.LOGGER.error(e);
}
}
}
}
private static class DelayedTask {
final Consumer<World> task;
int ticksDelay;
DelayedTask(Consumer<World> task, int ticks) {
this.task = task;
this.ticksDelay = ticks;
}
boolean tick() {
if (ticksDelay-- <= 0) {
tickTasks.add(task);
return false;
}
return true;
}
}
}

View file

@ -4,7 +4,6 @@ import java.util.List;
import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.redux.block.ITillable; import com.minelittlepony.unicopia.redux.block.ITillable;
import com.minelittlepony.unicopia.redux.block.UBlocks;
import com.minelittlepony.unicopia.redux.item.UItems; import com.minelittlepony.unicopia.redux.item.UItems;
import net.minecraft.block.Block; import net.minecraft.block.Block;

View file

@ -0,0 +1,92 @@
package com.minelittlepony.unicopia.redux;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.minelittlepony.unicopia.redux.block.BlockCloudDoor;
import com.minelittlepony.unicopia.redux.block.BlockGrowingCuccoon;
import com.minelittlepony.unicopia.redux.block.BlockTomatoPlant;
import com.minelittlepony.unicopia.redux.block.ChiselledChitinBlock;
import com.minelittlepony.unicopia.redux.block.ChitinBlock;
import com.minelittlepony.unicopia.redux.block.CloudAnvilBlock;
import com.minelittlepony.unicopia.redux.block.CloudBlock;
import com.minelittlepony.unicopia.redux.block.CloudFarmlandBlock;
import com.minelittlepony.unicopia.redux.block.CloudFenceBlock;
import com.minelittlepony.unicopia.redux.block.CloudSlabBlock;
import com.minelittlepony.unicopia.redux.block.CloudStairsBlock;
import com.minelittlepony.unicopia.redux.block.DiamondDoorBlock;
import com.minelittlepony.unicopia.redux.block.DutchDoorBlock;
import com.minelittlepony.unicopia.redux.block.FruitLeavesBlock;
import com.minelittlepony.unicopia.redux.block.GlowingGemBlock;
import com.minelittlepony.unicopia.redux.block.HiveWallBlock;
import com.minelittlepony.unicopia.redux.block.SlimeLayerBlock;
import com.minelittlepony.unicopia.redux.block.StickBlock;
import com.minelittlepony.unicopia.redux.block.SugarBlock;
import com.minelittlepony.unicopia.redux.block.TallCropBlock;
import com.minelittlepony.unicopia.redux.item.AppleItem;
import com.minelittlepony.unicopia.redux.item.UItems;
import com.minelittlepony.unicopia.redux.structure.CustomSaplingGenerator;
import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.Material;
import net.minecraft.block.SaplingBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public interface UBlocks {
CloudBlock normal_cloud = register(new CloudBlock(UMaterials.CLOUD, CloudType.NORMAL), "cloud_block");
CloudBlock enchanted_cloud = register(new CloudBlock(UMaterials.CLOUD, CloudType.ENCHANTED), "enchanted_cloud_block");
CloudBlock packed_cloud = register(new CloudBlock(UMaterials.CLOUD, CloudType.PACKED), "packed_cloud_block");
CloudStairsBlock cloud_stairs = register(new CloudStairsBlock(normal_cloud.getDefaultState(), FabricBlockSettings.of(UMaterials.CLOUD).build()), "cloud_stairs");
CloudSlabBlock<CloudBlock> cloud_slab = register(new CloudSlabBlock<>(normal_cloud, UMaterials.CLOUD), "cloud_slab");
CloudSlabBlock<CloudBlock> enchanted_cloud_slab = register(new CloudSlabBlock<>(enchanted_cloud, UMaterials.CLOUD), "enchanted_cloud_slab");
CloudSlabBlock<CloudBlock> packed_cloud_slab = register(new CloudSlabBlock<>(enchanted_cloud, UMaterials.CLOUD), "packed_cloud_slab");
BlockCloudDoor mist_door = register(new BlockCloudDoor(), "mist_door");
DutchDoorBlock library_door = register(new DutchDoorBlock(FabricBlockSettings.of(Material.WOOD).sounds(BlockSoundGroup.WOOD).hardness(3).build()), "library_door");
DutchDoorBlock bakery_door = register(new DutchDoorBlock(FabricBlockSettings.of(Material.WOOD).sounds(BlockSoundGroup.WOOD).hardness(3).build()), "bakery_door");
DiamondDoorBlock diamond_door = register(new DiamondDoorBlock(), "diamond_door");
GlowingGemBlock enchanted_torch = register(new GlowingGemBlock(), "enchanted_torch");
CloudAnvilBlock anvil = register(new CloudAnvilBlock(), "anvil");
CloudFenceBlock cloud_fence = register(new CloudFenceBlock(UMaterials.CLOUD, CloudType.NORMAL), "cloud_fence");
TallCropBlock alfalfa = register(new TallCropBlock(FabricBlockSettings.of(Material.PLANT).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.CROP).build()), "alfalfa");
StickBlock stick = register(new StickBlock(), "stick");
BlockTomatoPlant tomato_plant = register(new BlockTomatoPlant(), "tomato_plant");
CloudFarmlandBlock cloud_farmland = register(new CloudFarmlandBlock(FabricBlockSettings.of(UMaterials.CLOUD).noCollision().ticksRandomly().breakInstantly().sounds(BlockSoundGroup.WOOL).build()), "cloud_farmland");
HiveWallBlock hive = register(new HiveWallBlock(), "hive");
ChitinBlock chitin = register(new ChitinBlock(), "chitin_block");
Block chissled_chitin = register(new ChiselledChitinBlock(), "chissled_chitin");
BlockGrowingCuccoon cuccoon = register(new BlockGrowingCuccoon(), "cuccoon");
SlimeLayerBlock slime_layer = register(new SlimeLayerBlock(), "slime_layer");
Block sugar_block = register(new SugarBlock(), "sugar_block");
SaplingBlock apple_tree = register(new SaplingBlock(
new CustomSaplingGenerator(5, Blocks.OAK_LOG.getDefaultState(), UBlocks.apple_leaves.getDefaultState()),
FabricBlockSettings.of(Material.WOOD).build()
) {}, "apple_sapling");
Block apple_leaves = register(new FruitLeavesBlock()
.growthChance(1200)
.tint(0xFFEE81)
.fruit(AppleItem::getRandomItemStack)
.compost(w -> new ItemStack(UItems.rotten_apple)), "apple_leaves");
static <T extends Block> T register(T block, String name) {
return Registry.BLOCK.add(new Identifier(UnicopiaCore.MODID, name), block);
}
static void bootstrap() { }
}

View file

@ -2,15 +2,18 @@ package com.minelittlepony.unicopia.redux;
import com.minelittlepony.unicopia.core.UnicopiaCore; import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.minelittlepony.unicopia.redux.container.BagOfHoldingContainer; import com.minelittlepony.unicopia.redux.container.BagOfHoldingContainer;
import com.minelittlepony.unicopia.redux.container.SpellBookContainer;
import net.fabricmc.fabric.api.container.ContainerProviderRegistry; import net.fabricmc.fabric.api.container.ContainerProviderRegistry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class UContainers { public interface UContainers {
public static final Identifier BAG_OF_HOLDING = new Identifier(UnicopiaCore.MODID, "bag_of_holding"); Identifier BAG_OF_HOLDING = new Identifier(UnicopiaCore.MODID, "bag_of_holding");
Identifier SPELL_BOOK = new Identifier(UnicopiaCore.MODID, "spell_book");
public static void bootstrap() { static void bootstrap() {
ContainerProviderRegistry.INSTANCE.registerFactory(BAG_OF_HOLDING, BagOfHoldingContainer::new); ContainerProviderRegistry.INSTANCE.registerFactory(BAG_OF_HOLDING, BagOfHoldingContainer::new);
ContainerProviderRegistry.INSTANCE.registerFactory(SPELL_BOOK, SpellBookContainer::new);
} }
} }

View file

@ -25,30 +25,30 @@ import net.minecraft.world.biome.OceanBiome;
import net.minecraft.world.biome.PlainsBiome; import net.minecraft.world.biome.PlainsBiome;
import net.minecraft.world.biome.RiverBiome; import net.minecraft.world.biome.RiverBiome;
public class UEntities { public interface UEntities {
public static final EntityType<SpellbookEntity> SPELLBOOK = register("spellbook", EntityType.Builder.create(SpellbookEntity::new, EntityCategory.MISC).setDimensions(0.6f, 0.6f)); EntityType<SpellbookEntity> SPELLBOOK = register("spellbook", EntityType.Builder.create(SpellbookEntity::new, EntityCategory.MISC).setDimensions(0.6f, 0.6f));
public static final EntityType<SpellcastEntity> MAGIC_SPELL = register("magic_spell", EntityType.Builder.create(SpellcastEntity::new, EntityCategory.MISC).setDimensions(0.6F, 0.25F)); EntityType<SpellcastEntity> MAGIC_SPELL = register("magic_spell", EntityType.Builder.create(SpellcastEntity::new, EntityCategory.MISC).setDimensions(0.6F, 0.25F));
public static final EntityType<CloudEntity> CLOUD = register("cloud", EntityType.Builder.create(CloudEntity::new, EntityCategory.CREATURE)); EntityType<CloudEntity> CLOUD = register("cloud", EntityType.Builder.create(CloudEntity::new, EntityCategory.CREATURE));
public static final EntityType<WildCloudEntity> WILD_CLOUD = register("wild_cloud", EntityType.Builder.create(WildCloudEntity::new, EntityCategory.CREATURE)); EntityType<WildCloudEntity> WILD_CLOUD = register("wild_cloud", EntityType.Builder.create(WildCloudEntity::new, EntityCategory.CREATURE));
public static final EntityType<RacingCloudEntity> RACING_CLOUD = register("racing_cloud", EntityType.Builder.create(RacingCloudEntity::new, EntityCategory.CREATURE)); EntityType<RacingCloudEntity> RACING_CLOUD = register("racing_cloud", EntityType.Builder.create(RacingCloudEntity::new, EntityCategory.CREATURE));
public static final EntityType<ConstructionCloudEntity> CONSTRUCTION_CLOUD = register("construction_cloud", EntityType.Builder.create(ConstructionCloudEntity::new, EntityCategory.CREATURE)); EntityType<ConstructionCloudEntity> CONSTRUCTION_CLOUD = register("construction_cloud", EntityType.Builder.create(ConstructionCloudEntity::new, EntityCategory.CREATURE));
public static final EntityType<RainbowEntity> RAINBOW = register("rainbow", EntityType.Builder.create(RainbowEntity::new, EntityCategory.AMBIENT)); EntityType<RainbowEntity> RAINBOW = register("rainbow", EntityType.Builder.create(RainbowEntity::new, EntityCategory.AMBIENT));
public static final EntityType<RainbowEntity.Spawner> RAINBOW_SPAWNER = register("rainbow_spawner", EntityType.Builder.create(RainbowEntity.Spawner::new, EntityCategory.MISC)); EntityType<RainbowEntity.Spawner> RAINBOW_SPAWNER = register("rainbow_spawner", EntityType.Builder.create(RainbowEntity.Spawner::new, EntityCategory.MISC));
public static final EntityType<CuccoonEntity> CUCCOON = register("cuccoon", EntityType.Builder.create(CuccoonEntity::new, EntityCategory.MISC).setDimensions(1.5F, 1.6F)); EntityType<CuccoonEntity> CUCCOON = register("cuccoon", EntityType.Builder.create(CuccoonEntity::new, EntityCategory.MISC).setDimensions(1.5F, 1.6F));
public static final EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", EntityType.Builder.create(ButterflyEntity::new, EntityCategory.AMBIENT)); EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", EntityType.Builder.create(ButterflyEntity::new, EntityCategory.AMBIENT));
public static final EntityType<ProjectileEntity> THROWN_ITEM = register("thrown_item", EntityType.Builder.create(ProjectileEntity::new, EntityCategory.MISC)); EntityType<ProjectileEntity> THROWN_ITEM = register("thrown_item", EntityType.Builder.create(ProjectileEntity::new, EntityCategory.MISC));
public static final EntityType<SpearEntity> THROWN_SPEAR = register("thrown_spear", EntityType.Builder.create(SpearEntity::new, EntityCategory.MISC)); EntityType<SpearEntity> THROWN_SPEAR = register("thrown_spear", EntityType.Builder.create(SpearEntity::new, EntityCategory.MISC));
//builder.creature(CloudEntity.class, "cloud").withEgg(0x4169e1, 0x7fff00), //builder.creature(CloudEntity.class, "cloud").withEgg(0x4169e1, 0x7fff00),
//builder.creature(ButterflyEntity.class, "butterfly").withEgg(0x222200, 0xaaeeff), //builder.creature(ButterflyEntity.class, "butterfly").withEgg(0x222200, 0xaaeeff),
// builder.projectile(ProjectileEntity.class, "thrown_item", 100, 10), // builder.projectile(ProjectileEntity.class, "thrown_item", 100, 10),
// builder.projectile(SpearEntity.class, "spear", 100, 10) // builder.projectile(SpearEntity.class, "spear", 100, 10)
private static <T extends Entity> EntityType<T> register(String name, EntityType.Builder<T> builder) { static <T extends Entity> EntityType<T> register(String name, EntityType.Builder<T> builder) {
return Registry.register(Registry.ENTITY_TYPE, name, builder.build(name)); return Registry.register(Registry.ENTITY_TYPE, name, builder.build(name));
} }

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.redux;
import net.minecraft.block.Material; import net.minecraft.block.Material;
import net.minecraft.block.MaterialColor; import net.minecraft.block.MaterialColor;
public class UMaterials { public interface UMaterials {
public static final Material cloud = new Material.Builder(MaterialColor.WHITE).build(); Material CLOUD = new Material.Builder(MaterialColor.WHITE).build();
public static final Material hive = new Material.Builder(MaterialColor.NETHER).build(); Material HIVE = new Material.Builder(MaterialColor.NETHER).build();
} }

View file

@ -1,126 +0,0 @@
package com.minelittlepony.unicopia.redux;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import com.minelittlepony.jumpingcastle.Exceptions;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.minelittlepony.unicopia.redux.structure.CloudDungeon;
import com.minelittlepony.unicopia.redux.structure.CloudGen;
import com.minelittlepony.unicopia.redux.structure.GroundDungeon;
import com.minelittlepony.unicopia.redux.structure.StructuresGen;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.ChunkGeneratorOverworld;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.gen.structure.MapGenStructureIO;
import net.minecraftforge.fml.common.IWorldGenerator;
import net.minecraftforge.fml.common.registry.GameRegistry;
public class UWorld implements IWorldGenerator {
private static final UWorld instance = new UWorld();
public static UWorld instance() {
return instance;
}
private static final Queue<Consumer<World>> tickTasks = Queues.newArrayDeque();
private static List<DelayedTask> delayedTasks = Lists.newArrayList();
private static final Object locker = new Object();
public static void enqueueTask(Consumer<World> task) {
synchronized (locker) {
tickTasks.add(task);
}
}
public static void scheduleTask(Consumer<World> task, int ticksLater) {
synchronized (locker) {
delayedTasks.add(new DelayedTask(task, ticksLater));
}
}
private final BlockInteractions blocks = new BlockInteractions();
private final CloudGen cloudsGen = new CloudGen();
private final StructuresGen structuresGen = new StructuresGen();
public void init() {
GameRegistry.registerWorldGenerator(this, 1);
MapGenStructureIO.registerStructure(CloudGen.Start.class, "unicopia:clouds");
MapGenStructureIO.registerStructure(StructuresGen.Start.class, "unicopia:ruins");
MapGenStructureIO.registerStructureComponent(CloudDungeon.class, "unicopia:cloud_dungeon");
MapGenStructureIO.registerStructureComponent(GroundDungeon.class, "unicopia:ground_dungeon");
}
public void onUpdate(World world) {
synchronized (locker) {
delayedTasks = delayedTasks.stream().filter(DelayedTask::tick).collect(Collectors.toList());
Consumer<World> task;
while ((task = tickTasks.poll()) != null) {
Consumer<World> i = task;
Exceptions.logged(() -> i.accept(world), UnicopiaCore.LOGGER);
}
}
}
public BlockInteractions getBlocks() {
return blocks;
}
public void generateStructures(World world, int chunkX, int chunkZ, IChunkGenerator gen) {
if (gen instanceof ChunkGeneratorOverworld) {
if (world.getWorldInfo().isMapFeaturesEnabled()) {
ChunkPos pos = new ChunkPos(chunkX, chunkZ);
cloudsGen.generateStructure(world, world.rand, pos);
structuresGen.generateStructure(world, world.rand, pos);
}
}
}
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
if (chunkGenerator instanceof ChunkGeneratorOverworld) {
if (world.getWorldInfo().isMapFeaturesEnabled()) {
ChunkPrimer primer = new ChunkPrimer();
cloudsGen.generate(world, chunkX, chunkZ, primer);
structuresGen.generate(world, chunkX, chunkZ, primer);
}
}
}
private static class DelayedTask {
final Consumer<World> task;
int ticksDelay;
DelayedTask(Consumer<World> task, int ticks) {
this.task = task;
this.ticksDelay = ticks;
}
boolean tick() {
if (ticksDelay-- <= 0) {
tickTasks.add(task);
return false;
}
return true;
}
}
}

View file

@ -6,12 +6,10 @@ import net.fabricmc.fabric.api.registry.CommandRegistry;
import com.minelittlepony.unicopia.core.ability.PowersRegistry; import com.minelittlepony.unicopia.core.ability.PowersRegistry;
import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.redux.UContainers; import com.minelittlepony.unicopia.redux.UContainers;
import com.minelittlepony.unicopia.redux.UWorld;
import com.minelittlepony.unicopia.redux.ability.PowerCloudBase; import com.minelittlepony.unicopia.redux.ability.PowerCloudBase;
import com.minelittlepony.unicopia.redux.ability.PowerDisguise; import com.minelittlepony.unicopia.redux.ability.PowerDisguise;
import com.minelittlepony.unicopia.redux.ability.PowerEngulf; import com.minelittlepony.unicopia.redux.ability.PowerEngulf;
import com.minelittlepony.unicopia.redux.ability.PowerStomp; import com.minelittlepony.unicopia.redux.ability.PowerStomp;
import com.minelittlepony.unicopia.redux.block.UBlocks;
import com.minelittlepony.unicopia.redux.command.DisguiseCommand; import com.minelittlepony.unicopia.redux.command.DisguiseCommand;
import com.minelittlepony.unicopia.redux.enchanting.Pages; import com.minelittlepony.unicopia.redux.enchanting.Pages;
import com.minelittlepony.unicopia.redux.item.UItems; import com.minelittlepony.unicopia.redux.item.UItems;
@ -28,6 +26,7 @@ import com.minelittlepony.unicopia.redux.magic.spells.InfernoSpell;
import com.minelittlepony.unicopia.redux.magic.spells.PortalSpell; import com.minelittlepony.unicopia.redux.magic.spells.PortalSpell;
import com.minelittlepony.unicopia.redux.magic.spells.RevealingSpell; import com.minelittlepony.unicopia.redux.magic.spells.RevealingSpell;
import com.minelittlepony.unicopia.redux.magic.spells.ScorchSpell; import com.minelittlepony.unicopia.redux.magic.spells.ScorchSpell;
import com.minelittlepony.unicopia.redux.structure.UStructures;
public class UnicopiaRedux implements ModInitializer { public class UnicopiaRedux implements ModInitializer {
@Override @Override
@ -37,7 +36,7 @@ public class UnicopiaRedux implements ModInitializer {
UBlocks.bootstrap(); UBlocks.bootstrap();
UItems.bootstrap(); UItems.bootstrap();
UContainers.bootstrap(); UContainers.bootstrap();
UWorld.instance().init(); UStructures.bootstrap();
CommandRegistry.INSTANCE.register(false, DisguiseCommand::register); CommandRegistry.INSTANCE.register(false, DisguiseCommand::register);

View file

@ -11,13 +11,13 @@ import com.minelittlepony.unicopia.core.SpeciesList;
import com.minelittlepony.unicopia.core.ability.IPower; import com.minelittlepony.unicopia.core.ability.IPower;
import com.minelittlepony.unicopia.core.ability.Location; import com.minelittlepony.unicopia.core.ability.Location;
import com.minelittlepony.unicopia.core.entity.player.IPlayer; import com.minelittlepony.unicopia.core.entity.player.IPlayer;
import com.minelittlepony.unicopia.core.util.AwaitTickQueue;
import com.minelittlepony.unicopia.core.util.MagicalDamageSource; import com.minelittlepony.unicopia.core.util.MagicalDamageSource;
import com.minelittlepony.unicopia.core.util.PosHelper; import com.minelittlepony.unicopia.core.util.PosHelper;
import com.minelittlepony.unicopia.core.util.VecHelper; import com.minelittlepony.unicopia.core.util.VecHelper;
import com.minelittlepony.unicopia.core.util.WorldEvent; import com.minelittlepony.unicopia.core.util.WorldEvent;
import com.minelittlepony.unicopia.core.util.shape.IShape; import com.minelittlepony.unicopia.core.util.shape.IShape;
import com.minelittlepony.unicopia.core.util.shape.Sphere; import com.minelittlepony.unicopia.core.util.shape.Sphere;
import com.minelittlepony.unicopia.redux.UWorld;
import com.minelittlepony.unicopia.redux.item.AppleItem; import com.minelittlepony.unicopia.redux.item.AppleItem;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -182,7 +182,7 @@ public class PowerStomp implements IPower<PowerStomp.Data> {
if (harmed || player.world.random.nextInt(5) == 0) { if (harmed || player.world.random.nextInt(5) == 0) {
if (!harmed || player.world.random.nextInt(30) == 0) { if (!harmed || player.world.random.nextInt(30) == 0) {
UWorld.enqueueTask(w -> removeTree(w, data.pos())); AwaitTickQueue.enqueueTask(w -> removeTree(w, data.pos()));
} }
iplayer.subtractEnergyCost(3); iplayer.subtractEnergyCost(3);
@ -329,7 +329,7 @@ public class PowerStomp implements IPower<PowerStomp.Data> {
dropApplesPart(capturedDrops, new ArrayList<BlockPos>(), w, log, pos, 0); dropApplesPart(capturedDrops, new ArrayList<BlockPos>(), w, log, pos, 0);
UWorld.enqueueTask(wo -> { AwaitTickQueue.enqueueTask(wo -> {
capturedDrops.forEach(item -> { capturedDrops.forEach(item -> {
item.setToDefaultPickupDelay(); item.setToDefaultPickupDelay();
wo.spawnEntity(item); wo.spawnEntity(item);

View file

@ -19,7 +19,7 @@ public class BlockCloudDoor extends AbstractDoorBlock implements ICloudBlock {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public BlockCloudDoor() { public BlockCloudDoor() {
super(FabricBlockSettings.of(UMaterials.cloud) super(FabricBlockSettings.of(UMaterials.CLOUD)
.sounds(BlockSoundGroup.WOOL) .sounds(BlockSoundGroup.WOOL)
.hardness(3) .hardness(3)
.resistance(200) .resistance(200)

View file

@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.core.EquinePredicates;
import com.minelittlepony.unicopia.core.USounds; import com.minelittlepony.unicopia.core.USounds;
import com.minelittlepony.unicopia.core.util.MagicalDamageSource; import com.minelittlepony.unicopia.core.util.MagicalDamageSource;
import com.minelittlepony.unicopia.core.util.PosHelper; import com.minelittlepony.unicopia.core.util.PosHelper;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.UMaterials; import com.minelittlepony.unicopia.redux.UMaterials;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -47,7 +48,7 @@ public class BlockGrowingCuccoon extends Block {
}; };
public BlockGrowingCuccoon() { public BlockGrowingCuccoon() {
super(UMaterials.hive); super(UMaterials.HIVE);
setTranslationKey(name); setTranslationKey(name);
setRegistryName(domain, name); setRegistryName(domain, name);

View file

@ -185,7 +185,7 @@ public class BlockTomatoPlant extends CropBlock {
return getPlacedState(world, pos, world.getBlockState(pos)); return getPlacedState(world, pos, world.getBlockState(pos));
} }
if (state.getBlock() instanceof BlockCloudFarm) { if (state.getBlock() instanceof CloudFarmlandBlock) {
return getDefaultState().with(TYPE, Type.CLOUDSDALE); return getDefaultState().with(TYPE, Type.CLOUDSDALE);
} }

View file

@ -24,7 +24,7 @@ import net.minecraft.world.BlockView;
public class ChiselledChitinBlock extends Block { public class ChiselledChitinBlock extends Block {
public ChiselledChitinBlock() { public ChiselledChitinBlock() {
super(FabricBlockSettings.of(UMaterials.hive) super(FabricBlockSettings.of(UMaterials.HIVE)
.strength(50, 2000) .strength(50, 2000)
.materialColor(MaterialColor.BLACK) .materialColor(MaterialColor.BLACK)
.build() .build()

View file

@ -25,7 +25,7 @@ public class ChitinBlock extends Block {
public static final EnumProperty<Covering> COVERING = EnumProperty.of("covering", Covering.class); public static final EnumProperty<Covering> COVERING = EnumProperty.of("covering", Covering.class);
public ChitinBlock() { public ChitinBlock() {
super(FabricBlockSettings.of(UMaterials.hive) super(FabricBlockSettings.of(UMaterials.HIVE)
.hardness(50) .hardness(50)
.strength(2000, 2000) .strength(2000, 2000)
.materialColor(MaterialColor.BLACK) .materialColor(MaterialColor.BLACK)

View file

@ -1,57 +0,0 @@
package com.minelittlepony.unicopia.redux.block;
import java.util.List;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.redux.CloudType;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderLayer;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
public class CloudBanisterBlock extends CloudFenceBlock {
public static final float l = 11;
public static final float d = 5;
public static final float h = 2;
public static final Box SOUTH_AABB = new Box(d, 0, l, l, h, 1);
public static final Box WEST_AABB = new Box(0, 0, d, d, h, l);
public static final Box NORTH_AABB = new Box(d, 0, 0, l, h, d);
public static final Box EAST_AABB = new Box(l, 0, d, 1, h, l);
public CloudBanisterBlock(Material material) {
super(material, CloudType.ENCHANTED);
this.collisionShapes = this.createShapes(l, d, h, 0.0F, d);
this.boundingShapes = this.createShapes(l, d, h, 0.0F, d);
}
@Override
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.SOLID;
}
@Override
public boolean canConnect(BlockState myState, boolean bool, Direction facing) {
return myState.getBlock() instanceof CloudBanisterBlock
&& super.canConnect(myState, bool, facing);
}
@Override
public boolean canConnect(BlockView world, BlockPos pos, Direction facing) {
BlockState state = world.getBlockState(pos.offset(facing));
return state.getBlock() instanceof CloudBanisterBlock
&& state.getMaterial() == world.getBlockState(pos).getMaterial();
}
}

View file

@ -4,6 +4,7 @@ import java.util.Random;
import com.minelittlepony.unicopia.core.SpeciesList; import com.minelittlepony.unicopia.core.SpeciesList;
import com.minelittlepony.unicopia.redux.CloudType; import com.minelittlepony.unicopia.redux.CloudType;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.item.MossItem; import com.minelittlepony.unicopia.redux.item.MossItem;
import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.fabricmc.fabric.api.block.FabricBlockSettings;
@ -63,16 +64,6 @@ public class CloudBlock extends Block implements ICloudBlock, ITillable {
return variant == CloudType.NORMAL ? BlockRenderLayer.TRANSLUCENT : super.getRenderLayer(); return variant == CloudType.NORMAL ? BlockRenderLayer.TRANSLUCENT : super.getRenderLayer();
} }
/*@Deprecated
@Override
public boolean isSideSolid(BlockState base_state, BlockView world, BlockPos pos, Direction side) {
if (side == Direction.UP && (variant == CloudType.ENCHANTED || world.getBlockState(pos.up()).getBlock() instanceof ICloudBlock)) {
return true;
}
return super.isSideSolid(base_state, world, pos, side);
}*/
@Override @Override
public boolean isSideInvisible(BlockState state, BlockState beside, Direction face) { public boolean isSideInvisible(BlockState state, BlockState beside, Direction face) {
if (beside.getBlock() instanceof ICloudBlock) { if (beside.getBlock() instanceof ICloudBlock) {

View file

@ -1,34 +1,24 @@
package com.minelittlepony.unicopia.redux.block; package com.minelittlepony.unicopia.redux.block;
import java.util.List; import com.minelittlepony.unicopia.core.ducks.IFarmland;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.redux.CloudType; import com.minelittlepony.unicopia.redux.CloudType;
import com.minelittlepony.unicopia.redux.UBlocks;
import net.minecraft.block.BlockRenderLayer; import net.minecraft.block.BlockRenderLayer;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Direction.Axis; import net.minecraft.util.math.Direction.Axis;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockCloudFarm extends UFarmland implements ICloudBlock { public class CloudFarmlandBlock extends FarmlandBlock implements IFarmland, ICloudBlock {
public BlockCloudFarm() { public CloudFarmlandBlock(Settings settings) {
super(); super(settings);
setSoundType(SoundType.CLOTH);
}
@Override
public boolean isAir(BlockState state, BlockView world, BlockPos pos) {
return allowsFallingBlockToPass(state, world, pos);
} }
@Override @Override
@ -42,7 +32,7 @@ public class BlockCloudFarm extends UFarmland implements ICloudBlock {
if (beside.getBlock() instanceof ICloudBlock) { if (beside.getBlock() instanceof ICloudBlock) {
ICloudBlock cloud = ((ICloudBlock)beside.getBlock()); ICloudBlock cloud = ((ICloudBlock)beside.getBlock());
if ((face.getAxis() == Axis.Y || cloud == this)) { if (face.getAxis() == Axis.Y || cloud == this) {
if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) { if (cloud.getCloudMaterialType(beside) == getCloudMaterialType(state)) {
return true; return true;
} }
@ -53,9 +43,9 @@ public class BlockCloudFarm extends UFarmland implements ICloudBlock {
} }
@Override @Override
public void onFallenUpon(World world, BlockPos pos, Entity entityIn, float fallDistance) { public void onLandedUpon(World world, BlockPos pos, Entity entityIn, float fallDistance) {
if (!applyLanding(entityIn, fallDistance)) { if (!applyLanding(entityIn, fallDistance)) {
super.onFallenUpon(world, pos, entityIn, fallDistance); super.onLandedUpon(world, pos, entityIn, fallDistance);
} }
} }
@ -73,27 +63,6 @@ public class BlockCloudFarm extends UFarmland implements ICloudBlock {
} }
} }
@Override
public boolean canEntityDestroy(BlockState state, BlockView world, BlockPos pos, Entity entity) {
return getCanInteract(state, entity) && super.canEntityDestroy(state, world, pos, entity);
}
@Deprecated
@Override
public RayTraceResult collisionRayTrace(BlockState blockState, World worldIn, BlockPos pos, Vec3d start, Vec3d end) {
if (!handleRayTraceSpecialCases(worldIn, pos, blockState)) {
return super.collisionRayTrace(blockState, worldIn, pos, start, end);
}
return null;
}
@Deprecated
public void addCollisionBoxToList(BlockState state, World worldIn, BlockPos pos, Box entityBox, List<Box> collidingBoxes, @Nullable Entity entity, boolean p_185477_7_) {
if (getCanInteract(state, entity)) {
super.addCollisionBoxToList(state, worldIn, pos, entityBox, collidingBoxes, entity, p_185477_7_);
}
}
@Deprecated @Deprecated
@Override @Override
public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) { public float calcBlockBreakingDelta(BlockState state, PlayerEntity player, BlockView world, BlockPos pos) {
@ -103,14 +72,13 @@ public class BlockCloudFarm extends UFarmland implements ICloudBlock {
return -1; return -1;
} }
@Override @Override
public CloudType getCloudMaterialType(BlockState blockState) { public CloudType getCloudMaterialType(BlockState blockState) {
return CloudType.NORMAL; return CloudType.NORMAL;
} }
@Override @Override
protected BlockState getDroppedState(BlockState state) { public BlockState getDirtState(BlockState state, World world, BlockPos pos) {
return UBlocks.normal_cloud.getDefaultState(); return UBlocks.normal_cloud.getDefaultState();
} }
} }

View file

@ -11,7 +11,6 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -63,12 +62,6 @@ public class CloudFenceBlock extends FenceBlock implements ICloudBlock {
} }
} }
@Override
public boolean canConnect(BlockState state, boolean bool, Direction facing) {
return !(state.getBlock() instanceof CloudBanisterBlock)
&& super.canConnect(state, bool, facing);
}
@Override @Override
public void onEntityCollision(BlockState state, World w, BlockPos pos, Entity entity) { public void onEntityCollision(BlockState state, World w, BlockPos pos, Entity entity) {
if (!applyBouncyness(state, entity)) { if (!applyBouncyness(state, entity)) {

View file

@ -42,7 +42,7 @@ public class CloudSlabBlock<T extends Block & ICloudBlock> extends USlab<T> impl
SlabType half = state.get(TYPE); SlabType half = state.get(TYPE);
if (beside.getBlock() instanceof BlockCloudStairs) { if (beside.getBlock() instanceof CloudStairsBlock) {
return beside.get(StairsBlock.HALF).ordinal() == state.get(TYPE).ordinal() return beside.get(StairsBlock.HALF).ordinal() == state.get(TYPE).ordinal()
&& beside.get(Properties.FACING) == face; && beside.get(Properties.FACING) == face;
} }

View file

@ -1,9 +1,5 @@
package com.minelittlepony.unicopia.redux.block; package com.minelittlepony.unicopia.redux.block;
import java.util.List;
import javax.annotation.Nullable;
import com.minelittlepony.unicopia.redux.CloudType; import com.minelittlepony.unicopia.redux.CloudType;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -11,20 +7,14 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.SlabBlock; import net.minecraft.block.SlabBlock;
import net.minecraft.block.enums.BlockHalf; import net.minecraft.block.enums.BlockHalf;
import net.minecraft.block.enums.SlabType; import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.Entity; import net.minecraft.entity.EntityContext;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
public class BlockCloudStairs extends UStairs implements ICloudBlock { public class CloudStairsBlock extends UStairs implements ICloudBlock {
public BlockCloudStairs(BlockState inherited) { public CloudStairsBlock(BlockState inherited, Settings settings) {
super(inherited); super(inherited, settings);
} }
@Override @Override
@ -36,7 +26,7 @@ public class BlockCloudStairs extends UStairs implements ICloudBlock {
Direction front = state.get(FACING); Direction front = state.get(FACING);
BlockHalf half = state.get(HALF); BlockHalf half = state.get(HALF);
VoxelShape shape = state.getCollisionShape(world, pos); VoxelShape shape = getOutlineShape(state, null, null, EntityContext.absent());
boolean sideIsBack = Block.isFaceFullSquare(shape, face); boolean sideIsBack = Block.isFaceFullSquare(shape, face);
boolean sideIsFront = Block.isFaceFullSquare(shape, face.getOpposite()); boolean sideIsFront = Block.isFaceFullSquare(shape, face.getOpposite());
@ -53,7 +43,7 @@ public class BlockCloudStairs extends UStairs implements ICloudBlock {
); );
} }
VoxelShape shapeBeside = beside.getCollisionShape(world, pos); VoxelShape shapeBeside = getOutlineShape(beside, null, null, EntityContext.absent());
boolean bsideIsBack = Block.isFaceFullSquare(shapeBeside, face); boolean bsideIsBack = Block.isFaceFullSquare(shapeBeside, face);
boolean bsideIsFront = Block.isFaceFullSquare(shapeBeside, face.getOpposite()); boolean bsideIsFront = Block.isFaceFullSquare(shapeBeside, face.getOpposite());

View file

@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.core.entity.player.IPlayer;
import com.minelittlepony.unicopia.core.util.PosHelper; import com.minelittlepony.unicopia.core.util.PosHelper;
import com.minelittlepony.unicopia.core.util.shape.IShape; import com.minelittlepony.unicopia.core.util.shape.IShape;
import com.minelittlepony.unicopia.core.util.shape.Sphere; import com.minelittlepony.unicopia.core.util.shape.Sphere;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.UMaterials; import com.minelittlepony.unicopia.redux.UMaterials;
import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.fabricmc.fabric.api.block.FabricBlockSettings;
@ -45,7 +46,7 @@ public class HiveWallBlock extends FallingBlock {
private static final IShape shape = new Sphere(false, 1.5); private static final IShape shape = new Sphere(false, 1.5);
public HiveWallBlock() { public HiveWallBlock() {
super(FabricBlockSettings.of(UMaterials.hive) super(FabricBlockSettings.of(UMaterials.HIVE)
.noCollision() .noCollision()
.strength(10, 10) .strength(10, 10)
.hardness(2) .hardness(2)
@ -266,7 +267,7 @@ public class HiveWallBlock extends FallingBlock {
for (Direction facing : axis.getFacings()) { for (Direction facing : axis.getFacings()) {
BlockPos op = pos.offset(facing); BlockPos op = pos.offset(facing);
if (world.getBlockState(op).getMaterial() == UMaterials.hive) { if (world.getBlockState(op).getMaterial() == UMaterials.HIVE) {
if (one) { if (one) {
return true; return true;
} }

View file

@ -6,45 +6,50 @@ import javax.annotation.Nullable;
import com.minelittlepony.unicopia.redux.item.UItems; import com.minelittlepony.unicopia.redux.item.UItems;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.CropBlock; import net.minecraft.block.CropBlock;
import net.minecraft.entity.EntityContext;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.state.StateFactory;
import net.minecraft.item.Items;
import net.minecraft.state.property.EnumProperty; import net.minecraft.state.property.EnumProperty;
import net.minecraft.state.property.IntProperty; import net.minecraft.state.property.IntProperty;
import net.minecraft.util.StringIdentifiable; import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView; import net.minecraft.world.BlockView;
import net.minecraft.world.ViewableWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockAlfalfa extends CropBlock { public class TallCropBlock extends CropBlock {
public static final IntProperty AGE = IntProperty.of("age", 0, 4); public static final IntProperty AGE = IntProperty.of("age", 0, 4);
public static final EnumProperty<Half> HALF = EnumProperty.of("half", Half.class); public static final EnumProperty<Half> HALF = EnumProperty.of("half", Half.class);
private static final Box[] BOUNDS = new Box[] { private static final VoxelShape[] SHAPES = new VoxelShape[] {
new Box(0, 0, 0, 1, 0.1, 1), Block.createCuboidShape(0, 0, 0, 16, 1.6, 16),
new Box(0, 0, 0, 1, 0.2, 1), Block.createCuboidShape(0, 0, 0, 16, 3.2, 16),
new Box(0, 0, 0, 1, 0.4, 1), Block.createCuboidShape(0, 0, 0, 16, 4.4, 16),
new Box(0, 0, 0, 1, 0.6, 1), Block.createCuboidShape(0, 0, 0, 16, 9.6, 16),
new Box(0, 0, 0, 1, 0.8, 1), Block.createCuboidShape(0, 0, 0, 16, 12.8, 16),
new Box(0, 0, 0, 1, 1, 1), Block.createCuboidShape(0, 0, 0, 16, 16, 16),
new Box(0, 0, 0, 1, 1.2, 1), Block.createCuboidShape(0, 0, 0, 16, 17.6, 16),
new Box(0, 0, 0, 1, 1.4, 1), Block.createCuboidShape(0, 0, 0, 16, 19.2, 16),
new Box(0, 0, 0, 1, 1.6, 1), Block.createCuboidShape(0, 0, 0, 16, 20.4, 16),
new Box(0, 0, 0, 1, 1.8, 1), Block.createCuboidShape(0, 0, 0, 16, 25.6, 16),
new Box(0, 0, 0, 1, 2, 1), Block.createCuboidShape(0, 0, 0, 16, 32, 16),
new Box(0, 0, 0, 1, 2.2, 1), Block.createCuboidShape(0, 0, 0, 16, 33.6, 16),
new Box(0, 0, 0, 1, 2.4, 1), Block.createCuboidShape(0, 0, 0, 16, 38.4, 16),
new Box(0, 0, 0, 1, 2.6, 1), Block.createCuboidShape(0, 0, 0, 16, 67.6, 16),
new Box(0, 0, 0, 1, 2.8, 1), Block.createCuboidShape(0, 0, 0, 16, 44.8, 16),
new Box(0, 0, 0, 1, 3, 1) Block.createCuboidShape(0, 0, 0, 16, 48, 16)
}; };
public BlockAlfalfa() { public TallCropBlock(Settings settings) {
super(settings);
setDefaultState(getDefaultState().with(HALF, Half.BOTTOM)); setDefaultState(getDefaultState().with(HALF, Half.BOTTOM));
} }
@ -68,27 +73,18 @@ public class BlockAlfalfa extends CropBlock {
return UItems.alfalfa_seeds; return UItems.alfalfa_seeds;
} }
@Override
protected Item getCrop() {
return UItems.alfalfa_seeds;
}
@Override @Override
public void onScheduledTick(BlockState state, World world, BlockPos pos, Random rand) { public void onScheduledTick(BlockState state, World world, BlockPos pos, Random rand) {
checkAndDropBlock(world, pos, state); if (rand.nextInt(10) != 0 && world.isBlockLoaded(pos) && world.getLightLevel(pos.up()) >= 9) {
if (rand.nextInt(10) != 0) { if (canGrow(world, rand, pos, state)) {
growUpwards(world, pos, state, 1);
if (world.isBlockLoaded(pos) && world.getLightLevel(pos.up()) >= 9) {
if (canGrow(world, rand, pos, state)) {
growUpwards(world, pos, state, 1);
}
} }
} }
} }
@Override @Override
protected boolean canSustainBush(BlockState state) { protected boolean canPlantOnTop(BlockState state, BlockView view, BlockPos pos) {
return super.canSustainBush(state) || state.getBlock() == this; return state.getBlock() == this || super.canPlantOnTop(state, view, pos);
} }
protected void growUpwards(World world, BlockPos pos, BlockState state, int increase) { protected void growUpwards(World world, BlockPos pos, BlockState state, int increase) {
@ -127,36 +123,8 @@ public class BlockAlfalfa extends CropBlock {
} }
@Override @Override
public Item getItemDropped(BlockState state, Random rand, int fortune) { public boolean canPlaceAt(BlockState state, ViewableWorld world, BlockPos pos) {
if (state.get(HALF) != Half.BOTTOM) { return getHalf(state) != Half.BOTTOM || super.canPlaceAt(state, world, pos);
return Items.AIR;
}
return super.getItemDropped(state, rand, fortune);
}
@Override
public void getDrops(NonNullList<ItemStack> drops, BlockView world, BlockPos pos, BlockState state, int fortune) {
Random rand = world instanceof World ? ((World)world).random : RANDOM;
Item item = getItemDropped(state, rand, fortune);
if (item != Items.AIR) {
drops.add(new ItemStack(item, getFullAge(world, pos), damageDropped(state)));
if (isMaxAge(state)) {
drops.add(new ItemStack(UItems.alfalfa_leaves, rand.nextInt(10)));
}
}
}
@Override
public int quantityDropped(BlockState state, int fortune, Random random) {
return 1;
}
@Override
public boolean canBlockStay(World world, BlockPos pos, BlockState state) {
return getHalf(state) != Half.BOTTOM || super.canBlockStay(world, pos, state);
} }
public void onPlayerDestroy(World worldIn, BlockPos pos, BlockState state) { public void onPlayerDestroy(World worldIn, BlockPos pos, BlockState state) {
@ -164,7 +132,7 @@ public class BlockAlfalfa extends CropBlock {
} }
@Override @Override
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) { public void onBreak(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
breakConnectedBlocks(worldIn, pos, player); breakConnectedBlocks(worldIn, pos, player);
} }
@ -188,23 +156,27 @@ public class BlockAlfalfa extends CropBlock {
} }
@Override @Override
protected int getBonemealAgeIncrease(World world) { protected int getGrowthAmount(World world) {
return super.getBonemealAgeIncrease(world) / 2; return super.getGrowthAmount(world) / 2;
} }
@Override @Override
protected BlockStateContainer createBlockState() { protected void appendProperties(StateFactory.Builder<Block, BlockState> builder) {
return new BlockStateContainer(this, HALF, AGE); builder.add(AGE, HALF);
} }
@Override @Override
public boolean canCollideCheck(BlockState state, boolean hitIfLiquid) { public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, EntityContext context) {
return getHalf(state) != Half.MIDDLE; if (getHalf(state) != Half.MIDDLE) {
return VoxelShapes.empty();
}
return super.getCollisionShape(state, view, pos, context);
} }
@Override @Override
public Box getBoundingBox(BlockState state, BlockView source, BlockPos pos) { public VoxelShape getOutlineShape(BlockState state, BlockView view, BlockPos pos, EntityContext ePos) {
return BOUNDS[Math.min(BOUNDS.length - 1, getFullAge(source, pos))].offset(getOffset(state, source, pos)); Vec3d offset = getOffsetPos(state, view, pos);
return SHAPES[Math.min(SHAPES.length - 1, getFullAge(view, pos))].offset(offset.x, offset.y, offset.z);
} }
@Override @Override
@ -227,7 +199,7 @@ public class BlockAlfalfa extends CropBlock {
@Override @Override
public void applyGrowth(World world, BlockPos pos, BlockState state) { public void applyGrowth(World world, BlockPos pos, BlockState state) {
growUpwards(world, pos, state, getBonemealAgeIncrease(world)); growUpwards(world, pos, state, getGrowthAmount(world));
} }
protected BlockPos getTip(World world, BlockPos pos) { protected BlockPos getTip(World world, BlockPos pos) {
@ -273,7 +245,7 @@ public class BlockAlfalfa extends CropBlock {
@Override @Override
public String toString() { public String toString() {
return this == TOP ? "top" : this == MIDDLE ? "middle" : "bottom"; return super.toString().toLowerCase();
} }
@Override @Override

View file

@ -1,76 +0,0 @@
package com.minelittlepony.unicopia.redux.block;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.minelittlepony.unicopia.redux.CloudType;
import com.minelittlepony.unicopia.redux.UMaterials;
import com.minelittlepony.unicopia.redux.item.AppleItem;
import com.minelittlepony.unicopia.redux.item.UItems;
import com.minelittlepony.unicopia.redux.structure.CustomSaplingGenerator;
import net.fabricmc.fabric.api.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.Material;
import net.minecraft.block.SaplingBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class UBlocks {
public static final CloudBlock normal_cloud = register(new CloudBlock(UMaterials.cloud, CloudType.NORMAL), "cloud_block");
public static final CloudBlock enchanted_cloud = register(new CloudBlock(UMaterials.cloud, CloudType.ENCHANTED), "enchanted_cloud_block");
public static final CloudBlock packed_cloud = register(new CloudBlock(UMaterials.cloud, CloudType.PACKED), "packed_cloud_block");
public static final BlockCloudStairs cloud_stairs = register(new BlockCloudStairs(normal_cloud.getDefaultState()), "cloud_stairs");
public static final CloudSlabBlock<CloudBlock> cloud_slab = register(new CloudSlabBlock<>(normal_cloud, UMaterials.cloud), "cloud_slab");
public static final CloudSlabBlock<CloudBlock> enchanted_cloud_slab = register(new CloudSlabBlock<>(enchanted_cloud, UMaterials.cloud), "enchanted_cloud_slab");
public static final CloudSlabBlock<CloudBlock> packed_cloud_slab = register(new CloudSlabBlock<>(enchanted_cloud, UMaterials.cloud), "packed_cloud_slab");
public static final BlockCloudDoor mist_door = register(new BlockCloudDoor(), "mist_door");
public static final DutchDoorBlock library_door = register(new DutchDoorBlock(FabricBlockSettings.of(Material.WOOD).sounds(BlockSoundGroup.WOOD).hardness(3).build()), "library_door");
public static final DutchDoorBlock bakery_door = register(new DutchDoorBlock(FabricBlockSettings.of(Material.WOOD).sounds(BlockSoundGroup.WOOD).hardness(3).build()), "bakery_door");
public static final DiamondDoorBlock diamond_door = register(new DiamondDoorBlock(), "diamond_door");
public static final GlowingGemBlock enchanted_torch = register(new GlowingGemBlock(), "enchanted_torch");
public static final CloudAnvilBlock anvil = register(new CloudAnvilBlock(), "anvil");
public static final CloudFenceBlock cloud_fence = register(new CloudFenceBlock(UMaterials.cloud, CloudType.NORMAL), "cloud_fence");
public static final CloudBanisterBlock cloud_banister = register(new CloudBanisterBlock(UMaterials.cloud), "cloud_banister");
public static final BlockAlfalfa alfalfa = register(new BlockAlfalfa(), "alfalfa");
public static final StickBlock stick = register(new StickBlock(), "stick");
public static final BlockTomatoPlant tomato_plant = register(new BlockTomatoPlant(), "tomato_plant");
public static final BlockCloudFarm cloud_farmland = register(new BlockCloudFarm(), "cloud_farmland");
public static final HiveWallBlock hive = register(new HiveWallBlock(), "hive");
public static final ChitinBlock chitin = register(new ChitinBlock(), "chitin_block");
public static final Block chissled_chitin = register(new ChiselledChitinBlock(), "chissled_chitin");
public static final BlockGrowingCuccoon cuccoon = register(new BlockGrowingCuccoon(), "cuccoon");
public static final SlimeLayerBlock slime_layer = register(new SlimeLayerBlock(), "slime_layer");
public static final Block sugar_block = register(new SugarBlock(), "sugar_block");
public static final UPot flower_pot = register(new UPot(), "flower_pot");
public static final SaplingBlock apple_tree = register(new SaplingBlock(
new CustomSaplingGenerator(5, Blocks.OAK_LOG.getDefaultState(), UBlocks.apple_leaves.getDefaultState()),
FabricBlockSettings.of(Material.WOOD).build()
) {}, "apple_sapling");
public static final Block apple_leaves = register(new FruitLeavesBlock()
.growthChance(1200)
.tint(0xFFEE81)
.fruit(AppleItem::getRandomItemStack)
.compost(w -> new ItemStack(UItems.rotten_apple)), "apple_leaves");
private static <T extends Block> T register(T block, String name) {
return Registry.BLOCK.add(new Identifier(UnicopiaCore.MODID, name), block);
}
public static void bootstrap() { }
}

View file

@ -1,140 +0,0 @@
package com.minelittlepony.unicopia.redux.block;
import java.util.Random;
import com.minelittlepony.unicopia.core.util.PosHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.block.Fertilizable;
import net.minecraft.block.Material;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
public abstract class UFarmland extends FarmlandBlock {
public UFarmland(String domain, String name) {
setTranslationKey(name);
setRegistryName(domain, name);
setHardness(0.6F);
setSoundType(SoundType.GROUND);
}
@Override
public void updateTick(World world, BlockPos pos, BlockState state, Random rand) {
int i = state.get(MOISTURE);
if (!hasWater(world, pos) && !world.hasRain(pos.up())) {
if (i > 0) {
world.setBlockState(pos, state.with(MOISTURE, i - 1), 2);
} else if (!hasCrops(world, pos)) {
turnToDirt(world, pos, state);
}
} else if (i < 7) {
world.setBlockState(pos, state.with(MOISTURE, 7), 2);
}
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance) {
if (shouldTrample(world, pos, entity, fallDistance)) {
turnToDirt(world, pos, world.getBlockState(pos));
}
entity.handleFallDamage(fallDistance, 1);
}
@Override
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos) {
if (shouldTurnToDirt(world, pos, state)) {
turnToDirt(world, pos, state);
}
}
@Override
public void onBlockAdded(World world, BlockPos pos, BlockState state) {
if (shouldTurnToDirt(world, pos, state)) {
turnToDirt(world, pos, state);
}
}
public boolean hasCrops(World worldIn, BlockPos pos) {
Block block = worldIn.getBlockState(pos.up()).getBlock();
return block instanceof Fertilizable
&& canSustainPlant(worldIn.getBlockState(pos), worldIn, pos, Direction.UP, (Fertilizable)block);
}
public boolean hasWater(World world, BlockPos pos) {
return PosHelper.inRegion(pos.add(-4, 0, -4), pos.add(4, 1, 4)).anyMatch(p ->
world.getBlockState(p).getMaterial() == Material.WATER
);
}
@Override
public boolean canSustainPlant(BlockState state, BlockView world, BlockPos pos, Direction direction, Fertilizable plantable) {
return super.canSustainPlant(state, world, pos, direction, plantable)
|| plantable.getPlantType(world, pos.offset(direction)) == EnumPlantType.Crop;
}
@Override
public Item getItemDropped(BlockState state, Random rand, int fortune) {
BlockState dirtState = getDroppedState(state);
return dirtState.getBlock().getItemDropped(dirtState, rand, fortune);
}
/**
* Determines if this farmland should be trampled when an entity walks on it.
*/
public boolean shouldTrample(World world, BlockPos pos, Entity entity, float fallDistance) {
return !world.isClient && entity.canTrample(world, this, pos, fallDistance);
}
/**
* Determines if this farmland meets all the conditions for turning into dirt.
*/
public boolean shouldTurnToDirt(World world, BlockPos pos, BlockState state) {
return world.getBlockState(pos.up()).getMaterial().isSolid();
}
/**
* Turns this farmland into dirt or its dirt equivalent.
*/
public void turnToDirt(World world, BlockPos pos, BlockState state) {
world.setBlockState(pos, getDirtState(world, pos, state));
Box bounds = getUpdateCollissionBounds(world, pos, state);
if (bounds != null) {
// Update entity positions so they don't fall through the block
for (Entity entity : world.getEntities(Entity.class, bounds)) {
double offset = Math.min(bounds.maxY - bounds.minY, bounds.maxY - entity.getBoundingBox().minY);
entity.setPosition(entity.x, entity.y + offset + 0.001D, entity.z);
}
}
}
protected Box getUpdateCollissionBounds(World world, BlockPos pos, BlockState state) {
return field_194405_c.offset(pos);
}
protected BlockState getDroppedState(BlockState state) {
return Blocks.DIRT.getDefaultState();
}
/**
* Gets the state used to represent this block as a piece of dirt.
*/
protected BlockState getDirtState(World world, BlockPos pos, BlockState state) {
return getDroppedState(state);
}
}

View file

@ -1,36 +0,0 @@
package com.minelittlepony.unicopia.redux.block;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.block.FlowerPotBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class UPot extends FlowerPotBlock {
public UPot() {
setHardness(0);
setSoundType(SoundType.STONE);
}
enum Plant {
EMPTY("minecraft:air", -1),
QUILL("minecraft:feather", -1),
MEADOWBROOK("unicopia:staff_meadow_brook", -1);
public final Identifier item;
Plant(String item, int damage) {
this.item = new Identifier(item);
}
public boolean isEmpty() {
return this == EMPTY;
}
}
}

View file

@ -14,7 +14,7 @@ public class UStairs extends StairsBlock {
protected final Block baseBlock; protected final Block baseBlock;
protected final BlockState baseBlockState; protected final BlockState baseBlockState;
public UStairs(BlockState inherited, Block.Settings settings) { public UStairs(BlockState inherited, Settings settings) {
super(inherited, settings); super(inherited, settings);
baseBlock = inherited.getBlock(); baseBlock = inherited.getBlock();
baseBlockState = inherited; baseBlockState = inherited;

View file

@ -1,11 +1,11 @@
package com.minelittlepony.unicopia.redux.client; package com.minelittlepony.unicopia.redux.client;
import com.minelittlepony.unicopia.core.UParticles; import com.minelittlepony.unicopia.core.UParticles;
import com.minelittlepony.unicopia.core.client.particle.ParticleChangelingMagic; import com.minelittlepony.unicopia.core.client.particle.ChangelingMagicParticle;
import com.minelittlepony.unicopia.core.client.particle.DiskParticle; import com.minelittlepony.unicopia.core.client.particle.DiskParticle;
import com.minelittlepony.unicopia.core.client.particle.RaindropsParticle; import com.minelittlepony.unicopia.core.client.particle.RaindropsParticle;
import com.minelittlepony.unicopia.core.client.particle.SphereParticle; import com.minelittlepony.unicopia.core.client.particle.SphereParticle;
import com.minelittlepony.unicopia.core.client.particle.ParticleUnicornMagic; import com.minelittlepony.unicopia.core.client.particle.MagicParticle;
import com.minelittlepony.unicopia.core.util.collection.ListHelper; import com.minelittlepony.unicopia.core.util.collection.ListHelper;
import com.minelittlepony.unicopia.redux.client.render.ButterflyEntityRenderer; import com.minelittlepony.unicopia.redux.client.render.ButterflyEntityRenderer;
import com.minelittlepony.unicopia.redux.client.render.RenderCloud; import com.minelittlepony.unicopia.redux.client.render.RenderCloud;
@ -37,7 +37,7 @@ import net.minecraft.world.biome.OceanBiome;
import net.minecraft.world.biome.PlainsBiome; import net.minecraft.world.biome.PlainsBiome;
import net.minecraft.world.biome.RiverBiome; import net.minecraft.world.biome.RiverBiome;
public class URenderers { public interface URenderers {
static void bootstrap() { static void bootstrap() {
EntityRendererRegistry.INSTANCE.register(CloudEntity.class, RenderCloud::new); EntityRendererRegistry.INSTANCE.register(CloudEntity.class, RenderCloud::new);
EntityRendererRegistry.INSTANCE.register(SpellcastEntity.class, SpellcastEntityRenderer::new); EntityRendererRegistry.INSTANCE.register(SpellcastEntity.class, SpellcastEntityRenderer::new);
@ -48,8 +48,8 @@ public class URenderers {
EntityRendererRegistry.INSTANCE.register(CuccoonEntity.class, RenderCuccoon::new); EntityRendererRegistry.INSTANCE.register(CuccoonEntity.class, RenderCuccoon::new);
EntityRendererRegistry.INSTANCE.register(SpearEntity.class, RenderSpear::new); EntityRendererRegistry.INSTANCE.register(SpearEntity.class, RenderSpear::new);
ParticleFactoryRegistry.instance().register(UParticles.UNICORN_MAGIC, ParticleUnicornMagic::new); ParticleFactoryRegistry.instance().register(UParticles.UNICORN_MAGIC, MagicParticle::new);
ParticleFactoryRegistry.instance().register(UParticles.CHANGELING_MAGIC, ParticleChangelingMagic::new); ParticleFactoryRegistry.instance().register(UParticles.CHANGELING_MAGIC, ChangelingMagicParticle::new);
ParticleFactoryRegistry.instance().register(UParticles.RAIN_DROPS, RaindropsParticle::new); ParticleFactoryRegistry.instance().register(UParticles.RAIN_DROPS, RaindropsParticle::new);
ParticleFactoryRegistry.instance().register(UParticles.SPHERE, SphereParticle::new); ParticleFactoryRegistry.instance().register(UParticles.SPHERE, SphereParticle::new);
ParticleFactoryRegistry.instance().register(UParticles.DISK, DiskParticle::new); ParticleFactoryRegistry.instance().register(UParticles.DISK, DiskParticle::new);

View file

@ -5,8 +5,8 @@ import static com.minelittlepony.unicopia.core.EquinePredicates.MAGI;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.block.IColourful; import com.minelittlepony.unicopia.redux.block.IColourful;
import com.minelittlepony.unicopia.redux.block.UBlocks;
import com.minelittlepony.unicopia.redux.item.UItems; import com.minelittlepony.unicopia.redux.item.UItems;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.render.ColorProviderRegistry; import net.fabricmc.fabric.api.client.render.ColorProviderRegistry;

View file

@ -1,21 +1,21 @@
package com.minelittlepony.unicopia.redux.client.render; package com.minelittlepony.unicopia.redux.client.render;
import com.minelittlepony.unicopia.redux.client.render.model.ModelSpellbook; import com.minelittlepony.unicopia.redux.client.render.model.SpellbookModel;
import com.minelittlepony.unicopia.redux.entity.SpellbookEntity; import com.minelittlepony.unicopia.redux.entity.SpellbookEntity;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class RenderSpellbook extends RenderLiving<SpellbookEntity> { public class RenderSpellbook extends LivingEntityRenderer<SpellbookEntity, SpellbookModel> {
private static final Identifier BLUE = new Identifier("unicopia", "textures/entity/enchanting_table_book_blue.png"); private static final Identifier BLUE = new Identifier("unicopia", "textures/entity/enchanting_table_book_blue.png");
private static final Identifier NORMAL = new Identifier("unicopia", "textures/entity/enchanting_table_book.png"); private static final Identifier NORMAL = new Identifier("unicopia", "textures/entity/enchanting_table_book.png");
public RenderSpellbook(RenderManager rendermanagerIn) { public RenderSpellbook(EntityRenderDispatcher rendermanagerIn) {
super(rendermanagerIn, new ModelSpellbook(), 0); super(rendermanagerIn, new SpellbookModel(), 0);
} }
@Override @Override
@ -40,20 +40,20 @@ public class RenderSpellbook extends RenderLiving<SpellbookEntity> {
if (first_page_rot > 1) first_page_rot = 1; if (first_page_rot > 1) first_page_rot = 1;
if (second_page_rot > 1) second_page_rot = 1; if (second_page_rot > 1) second_page_rot = 1;
if (!((SpellbookEntity)entity).getIsOpen()) { if (!entity.getIsOpen()) {
GlStateManager.translate(0, 1.44f, 0); GlStateManager.translatef(0, 1.44f, 0);
} else { } else {
GlStateManager.translate(0, 1.2f + breath, 0); GlStateManager.translatef(0, 1.2f + breath, 0);
} }
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
if (!((SpellbookEntity)entity).getIsOpen()) { if (!entity.getIsOpen()) {
first_page_rot = second_page_rot = open_angle = 0; first_page_rot = second_page_rot = open_angle = 0;
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); GlStateManager.rotatef(90.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(90.0F, 0.0F, 0.0F, 1.0F); GlStateManager.rotatef(90.0F, 0.0F, 0.0F, 1.0F);
GlStateManager.translate(-0.25f, 0, 0); GlStateManager.translatef(-0.25f, 0, 0);
} else { } else {
GlStateManager.rotate(-60.0F, 0.0F, 0.0F, 1.0F); GlStateManager.rotatef(-60.0F, 0.0F, 0.0F, 1.0F);
} }
GlStateManager.enableCull(); GlStateManager.enableCull();

View file

@ -1,13 +0,0 @@
package com.minelittlepony.unicopia.redux.client.render.model;
import net.minecraft.client.model.ModelBook;
import net.minecraft.client.model.ModelRenderer;
public class ModelSpellbook extends ModelBook {
public ModelSpellbook() {
super();
bookSpine = (new ModelRenderer(this)).setTextureOffset(12, 0);
bookSpine.addBox(-1, -5, 0, 2, 10, 0, 0.1f);
bookSpine.rotateAngleY = ((float)Math.PI / 2F);
}
}

View file

@ -0,0 +1,10 @@
package com.minelittlepony.unicopia.redux.client.render.model;
import net.minecraft.client.render.entity.model.BookModel;
public class SpellbookModel extends BookModel {
public SpellbookModel() {
}
}

View file

@ -14,8 +14,8 @@ public class BagOfHoldingContainer extends Container {
private ItemStack sourceStack; private ItemStack sourceStack;
public BagOfHoldingContainer(int num, Identifier id, PlayerEntity player, PacketByteBuf buff) { public BagOfHoldingContainer(int sync, Identifier id, PlayerEntity player, PacketByteBuf buf) {
super(null, num); super(null, sync);
sourceStack = player.getStackInHand(Hand.MAIN_HAND); sourceStack = player.getStackInHand(Hand.MAIN_HAND);
inventory = BagOfHoldingInventory.getInventoryFromStack(sourceStack); inventory = BagOfHoldingInventory.getInventoryFromStack(sourceStack);

View file

@ -1,14 +1,15 @@
package com.minelittlepony.unicopia.redux.container; package com.minelittlepony.unicopia.redux.container;
import java.io.IOException; import com.minelittlepony.common.client.gui.element.Scrollbar;
import com.minelittlepony.unicopia.redux.item.BagOfHoldingItem;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.gui.screen.ingame.ContainerScreen9; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class BagOfHoldingScreen extends ContainerScreen9 { public class BagOfHoldingScreen extends AbstractContainerScreen<BagOfHoldingContainer> {
private static final Identifier CHEST_GUI_TEXTURE = new Identifier("textures/gui/container/generic_54.png"); private static final Identifier CHEST_GUI_TEXTURE = new Identifier("textures/gui/container/generic_54.png");
private final int inventoryRows; private final int inventoryRows;
@ -16,34 +17,33 @@ public class BagOfHoldingScreen extends ContainerScreen9 {
private final Scrollbar scrollbar = new Scrollbar(); private final Scrollbar scrollbar = new Scrollbar();
public BagOfHoldingScreen(IInteractionObject interaction) { public BagOfHoldingScreen(PlayerEntity player, BagOfHoldingItem.ContainerProvider provider) {
super(interaction.createContainer(MinecraftClient.getInstance().player.inventory, MinecraftClient.getInstance().player)); super(provider.createMenu(0, player.inventory, player), player.inventory, provider.getDisplayName());
playerRows = MinecraftClient.getInstance().player.inventory.getSizeInventory() / 9; playerRows = playerInventory.getInvSize() / 9;
inventoryRows = (inventorySlots.inventorySlots.size() / 9) - 1; inventoryRows = (container.slotList.size() / 9) - 1;
} }
@Override @Override
public void initGui() { public void init() {
super.init();
super.initGui();
scrollbar.reposition( scrollbar.reposition(
guiLeft + xSize, left + containerWidth,
guiTop, top,
ySize, containerHeight,
(inventoryRows + 1) * 18 + 17); (inventoryRows + 1) * 18 + 17);
children.add(scrollbar);
} }
@Override @Override
public void onGuiClosed() { public void onClose() {
super.onGuiClosed(); super.onClose();
mc.player.playSound(SoundEvents.BLOCK_ENDERCHEST_OPEN, 0.5F, 0.5F); minecraft.player.playSound(SoundEvents.BLOCK_ENDER_CHEST_OPEN, 0.5F, 0.5F);
} }
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void render(int mouseX, int mouseY, float partialTicks) {
drawDefaultBackground(); renderBackground();
scrollbar.render(mouseX, mouseY, partialTicks); scrollbar.render(mouseX, mouseY, partialTicks);
@ -52,58 +52,50 @@ public class BagOfHoldingScreen extends ContainerScreen9 {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translatef(0, scroll, 0); GlStateManager.translatef(0, scroll, 0);
super.drawScreen(mouseX, mouseY - scroll, partialTicks); super.render(mouseX, mouseY - scroll, partialTicks);
int h = height; int h = height;
height = Integer.MAX_VALUE; height = Integer.MAX_VALUE;
renderHoveredToolTip(mouseX, mouseY - scroll); drawMouseoverTooltip(mouseX, mouseY - scroll);
height = h; height = h;
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { public boolean mouseClicked(double x, double y, int button) {
scrollbar.performAction(mouseX, mouseY); return super.mouseClicked(x, y + scrollbar.getScrollAmount(), button);
super.mouseClicked(mouseX, mouseY + scrollbar.getScrollAmount(), mouseButton);
} }
@Override @Override
protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { public boolean mouseDragged(double x, double y, int button, double dx, double dy) {
super.mouseClickMove(mouseX, mouseY + scrollbar.getScrollAmount(), clickedMouseButton, timeSinceLastClick); return super.mouseDragged(x, y + scrollbar.getScrollAmount(), button, dx, dy);
if (!dragSplitting) {
scrollbar.mouseMove(mouseX, mouseY, timeSinceLastClick);
}
} }
@Override @Override
protected void mouseReleased(int mouseX, int mouseY, int state) { public boolean mouseReleased(double x, double y, int button) {
super.mouseReleased(mouseX, mouseY + scrollbar.getScrollAmount(), state); return super.mouseReleased(x, y + scrollbar.getScrollAmount(), button);
scrollbar.mouseUp(mouseX, mouseY);
} }
@Override @Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { protected void drawForeground(int mouseX, int mouseY) {
BagOfHoldingContainer coh = (BagOfHoldingContainer)inventorySlots; font.draw(title.asString(), 8, 6, 0x404040);
fontRenderer.drawString(coh.getName(), 8, 6, 0x404040);
} }
@Override @Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { protected void drawBackground(float partialTicks, int mouseX, int mouseY) {
GlStateManager.color4f(1, 1, 1, 1); GlStateManager.color4f(1, 1, 1, 1);
mc.getTextureManager().bindTexture(CHEST_GUI_TEXTURE); minecraft.getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
int midX = (width - xSize) / 2; int midX = (width - containerWidth) / 2;
int midY = (height - ySize) / 2; int midY = (height - containerHeight) / 2;
drawTexturedModalRect(midX, midY, 0, 0, xSize, 18); blit(midX, midY, 0, 0, containerWidth, 18);
for (int i = 0; i < inventoryRows - (playerRows - 1); i++) { for (int i = 0; i < inventoryRows - (playerRows - 1); i++) {
drawTexturedModalRect(midX, midY + (18 * (i + 1)), 0, 18, xSize, 18); blit(midX, midY + (18 * (i + 1)), 0, 18, containerWidth, 18);
} }
drawTexturedModalRect(midX, midY + (18 * (inventoryRows - (playerRows - 2))) - 1, 0, 131, xSize, 98); blit(midX, midY + (18 * (inventoryRows - (playerRows - 2))) - 1, 0, 131, containerWidth, 98);
} }
} }

View file

@ -5,13 +5,11 @@ import javax.annotation.Nonnull;
import com.minelittlepony.unicopia.core.EquinePredicates; import com.minelittlepony.unicopia.core.EquinePredicates;
import com.minelittlepony.unicopia.core.SpeciesList; import com.minelittlepony.unicopia.core.SpeciesList;
import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry; import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.redux.UWorld; import com.minelittlepony.unicopia.core.util.AwaitTickQueue;
import com.minelittlepony.unicopia.redux.enchanting.IPageUnlockListener; import com.minelittlepony.unicopia.redux.enchanting.IPageUnlockListener;
import net.minecraft.container.Container; import net.minecraft.container.Container;
import net.minecraft.container.Slot; import net.minecraft.container.Slot;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.BasicInventory; import net.minecraft.inventory.BasicInventory;
import net.minecraft.inventory.Inventory; import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -19,7 +17,8 @@ import net.minecraft.particle.ParticleTypes;
import net.minecraft.recipe.Recipe; import net.minecraft.recipe.Recipe;
import net.minecraft.recipe.RecipeType; import net.minecraft.recipe.RecipeType;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.Identifier;
import net.minecraft.util.PacketByteBuf;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.explosion.Explosion.DestructionType; import net.minecraft.world.explosion.Explosion.DestructionType;
@ -37,15 +36,15 @@ public class SpellBookContainer extends Container {
private final PlayerEntity player; private final PlayerEntity player;
public SpellBookContainer(PlayerInventory inventory, World world, BlockPos pos) { public SpellBookContainer(int sync, Identifier id, PlayerEntity player, PacketByteBuf buf) {
super(null, 0);// TODO super(null, 0);
worldObj = world; worldObj = player.world;
player = inventory.player; this.player = player;
initCraftingSlots(); initCraftingSlots();
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
addSlot(new Slot(inventory, i, 121 + i * 18, 195)); addSlot(new Slot(player.inventory, i, 121 + i * 18, 195));
} }
onContentChanged(craftMatrix); onContentChanged(craftMatrix);
@ -94,9 +93,7 @@ public class SpellBookContainer extends Container {
worldObj.createExplosion(null, player.x, player.y, player.z, 0, DestructionType.NONE); worldObj.createExplosion(null, player.x, player.y, player.z, 0, DestructionType.NONE);
worldObj.addParticle(ParticleTypes.EXPLOSION, player.x, player.y, player.z, 1, 0, 0); worldObj.addParticle(ParticleTypes.EXPLOSION, player.x, player.y, player.z, 1, 0, 0);
UWorld.enqueueTask(w -> { AwaitTickQueue.enqueueTask(w -> player.container.close(player));
player.container.close(player);
});
return; return;
} }

View file

@ -1,24 +1,28 @@
package com.minelittlepony.unicopia.redux.container; package com.minelittlepony.unicopia.redux.container;
import java.io.IOException;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import com.minelittlepony.common.client.gui.element.Button;
import com.minelittlepony.unicopia.core.SpeciesList; import com.minelittlepony.unicopia.core.SpeciesList;
import com.minelittlepony.unicopia.core.UnicopiaCore; import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.minelittlepony.unicopia.core.enchanting.IPage; import com.minelittlepony.unicopia.core.enchanting.Page;
import com.minelittlepony.unicopia.core.enchanting.PageState; import com.minelittlepony.unicopia.core.enchanting.PageState;
import com.minelittlepony.unicopia.core.entity.player.IPlayer; import com.minelittlepony.unicopia.core.entity.player.IPlayer;
import com.minelittlepony.unicopia.redux.container.SpellBookContainer.SpellbookSlot;
import com.minelittlepony.unicopia.redux.enchanting.IPageUnlockListener; import com.minelittlepony.unicopia.redux.enchanting.IPageUnlockListener;
import com.minelittlepony.unicopia.redux.enchanting.Pages; import com.minelittlepony.unicopia.redux.enchanting.Pages;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
import net.minecraft.client.texture.MissingSprite;
import net.minecraft.container.Slot;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class SpellBookScreen extends ContainerScreen implements IPageUnlockListener { public class SpellBookScreen extends AbstractContainerScreen<SpellBookContainer> implements IPageUnlockListener {
private static IPage currentIPage; private static Page currentPage;
public static final Identifier spellBookGuiTextures = new Identifier("unicopia", "textures/gui/container/book.png"); public static final Identifier spellBookGuiTextures = new Identifier("unicopia", "textures/gui/container/book.png");
@ -28,64 +32,58 @@ public class SpellBookScreen extends ContainerScreen implements IPageUnlockListe
private PageButton prevPage; private PageButton prevPage;
public SpellBookScreen(PlayerEntity player) { public SpellBookScreen(PlayerEntity player) {
super(new SpellBookContainer(player.inventory, player.world, new BlockPos(player))); super(
player.openContainer = inventorySlots; new SpellBookContainer(0, null, player, null),
player.inventory,
new LiteralText("item.spellbook.name")
);
player.container = container;
xSize = 405; containerWidth = 405;
ySize = 219; containerHeight = 219;
allowUserInput = true;
playerExtension = SpeciesList.instance().getPlayer(player); playerExtension = SpeciesList.instance().getPlayer(player);
} }
@Override @Override
public void initGui() { public void init() {
super.initGui(); super.init();
buttonList.clear();
int x = (width - xSize) / 2; addButton(nextPage = new PageButton(left + 360, top + 185, true)).onClick(v -> {
int y = (height - ySize) / 2; currentPage = currentPage.next();
onPageChange();
});
addButton(prevPage = new PageButton(left + 20, top + 185, false)).onClick(v -> {
currentPage = currentPage.prev();
onPageChange();
});
buttonList.add(nextPage = new PageButton(1, x + 360, y + 185, true)); if (currentPage == null) {
buttonList.add(prevPage = new PageButton(2, x + 20, y + 185, false)); currentPage = Pages.instance().getByIndex(0);
if (currentIPage == null) {
currentIPage = Pages.instance().getByIndex(0);
} }
onPageChange(); onPageChange();
if (playerExtension.hasPageStateRelative(currentIPage, PageState.UNREAD, 1)) { if (playerExtension.hasPageStateRelative(currentPage, PageState.UNREAD, Page::next)) {
nextPage.triggerShake(); nextPage.triggerShake();
} }
if (playerExtension.hasPageStateRelative(currentIPage, PageState.UNREAD, -1)) { if (playerExtension.hasPageStateRelative(currentPage, PageState.UNREAD, Page::prev)) {
prevPage.triggerShake(); prevPage.triggerShake();
} }
} }
@Override
protected void actionPerformed(GuiButton button) throws IOException {
if (button.id == 1) {
currentIPage = currentIPage.next();
} else {
currentIPage = currentIPage.prev();
}
onPageChange();
}
protected void onPageChange() { protected void onPageChange() {
prevPage.enabled = currentIPage.getIndex() > 0; prevPage.setEnabled(currentPage.getIndex() > 0);
nextPage.enabled = currentIPage.getIndex() < Pages.instance().getTotalPages() - 1; nextPage.setEnabled(currentPage.getIndex() < Pages.instance().getTotalPages() - 1);
if (playerExtension.getPageState(currentIPage) == PageState.UNREAD) { if (playerExtension.getPageState(currentPage) == PageState.UNREAD) {
playerExtension.setPageState(currentIPage, PageState.READ); playerExtension.setPageState(currentPage, PageState.READ);
} }
} }
@Override @Override
public boolean onPageUnlocked(IPage page) { public boolean onPageUnlocked(Page page) {
int i = currentIPage.compareTo(page); int i = currentPage.compareTo(page);
if (i <= 0) { if (i <= 0) {
prevPage.triggerShake(); prevPage.triggerShake();
@ -99,11 +97,9 @@ public class SpellBookScreen extends ContainerScreen implements IPageUnlockListe
} }
@Override @Override
protected void drawGradientRect(int left, int top, int width, int height, int startColor, int endColor) { protected void fillGradient(int left, int top, int width, int height, int startColor, int endColor) {
Slot slot = getSlotUnderMouse(); if (focusedSlot == null || left != focusedSlot.xPosition || top != focusedSlot.yPosition || !drawSlotOverlay(focusedSlot)) {
super.fillGradient(left, top, width, height, startColor, endColor);
if (slot == null || left != slot.xPos || top != slot.yPos || !drawSlotOverlay(slot)) {
super.drawGradientRect(left, top, width, height, startColor, endColor);
} }
} }
@ -112,8 +108,8 @@ public class SpellBookScreen extends ContainerScreen implements IPageUnlockListe
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GL11.glDisable(GL11.GL_ALPHA_TEST); GL11.glDisable(GL11.GL_ALPHA_TEST);
mc.getTextureManager().bindTexture(spellBookGuiTextures); minecraft.getTextureManager().bindTexture(spellBookGuiTextures);
drawModalRectWithCustomSizedTexture(slot.xPos - 1, slot.yPos - 1, 74, 223, 18, 18, 512, 256); blit(slot.xPosition - 1, slot.yPosition - 1, 74, 223, 18, 18, 512, 256);
GL11.glEnable(GL11.GL_ALPHA_TEST); GL11.glEnable(GL11.GL_ALPHA_TEST);
GlStateManager.disableBlend(); GlStateManager.disableBlend();
@ -124,47 +120,48 @@ public class SpellBookScreen extends ContainerScreen implements IPageUnlockListe
return false; return false;
} }
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
super.drawScreen(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY); @Override
public void render(int mouseX, int mouseY, float partialTicks) {
super.render(mouseX, mouseY, partialTicks);
drawMouseoverTooltip(mouseX, mouseY);
} }
@Override @Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { protected void drawForeground(int mouseX, int mouseY) {
String text = String.format("%d / %d", currentIPage.getIndex() + 1, Pages.instance().getTotalPages()); String text = String.format("%d / %d", currentPage.getIndex() + 1, Pages.instance().getTotalPages());
fontRenderer.drawString(text, 70 - fontRenderer.getStringWidth(text)/2, 190, 0x0); font.draw(text, 70 - font.getStringWidth(text)/2, 190, 0x0);
} }
@Override @Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { protected void drawBackground(float partialTicks, int mouseX, int mouseY) {
drawWorldBackground(0); renderBackground(0);
GlStateManager.color(1, 1, 1, 1); GlStateManager.color4f(1, 1, 1, 1);
int left = (width - xSize) / 2; int left = (width - containerWidth) / 2;
int top = (height - ySize) / 2; int top = (height - containerHeight) / 2;
mc.getTextureManager().bindTexture(spellBookGuiTextures); minecraft.getTextureManager().bindTexture(spellBookGuiTextures);
drawModalRectWithCustomSizedTexture(left, top, 0, 0, xSize, ySize, 512, 256); blit(left, top, 0, 0, containerWidth, containerHeight, 512, 256);
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GL11.glDisable(GL11.GL_ALPHA_TEST); GL11.glDisable(GL11.GL_ALPHA_TEST);
mc.getTextureManager().bindTexture(spellBookGuiTextures); minecraft.getTextureManager().bindTexture(spellBookGuiTextures);
drawModalRectWithCustomSizedTexture(left + 147, top + 49, 407, 2, 100, 101, 512, 256); blit(left + 147, top + 49, 407, 2, 100, 101, 512, 256);
if (playerExtension.getPageState(currentIPage) != PageState.LOCKED) { if (playerExtension.getPageState(currentPage) != PageState.LOCKED) {
Identifier texture = currentIPage.getTexture(); Identifier texture = currentPage.getTexture();
if (mc.getTextureManager().getTexture(texture) != TextureUtil.MISSING_TEXTURE) { if (minecraft.getTextureManager().getTexture(texture) != MissingSprite.getMissingSpriteTexture()) {
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
mc.getTextureManager().bindTexture(texture); minecraft.getTextureManager().bindTexture(texture);
drawModalRectWithCustomSizedTexture(left, top, 0, 0, xSize, ySize, 512, 256); blit(left, top, 0, 0, containerWidth, containerHeight, 512, 256);
} else { } else {
if (playerExtension.getWorld().rand.nextInt(100) == 0) { if (playerExtension.getWorld().random.nextInt(100) == 0) {
UnicopiaCore.LOGGER.fatal("Missing texture " + texture); UnicopiaCore.LOGGER.fatal("Missing texture " + texture);
} }
} }
@ -174,19 +171,19 @@ public class SpellBookScreen extends ContainerScreen implements IPageUnlockListe
GlStateManager.disableBlend(); GlStateManager.disableBlend();
} }
static class PageButton extends GuiButton { class PageButton extends Button {
private final boolean direction; private final boolean direction;
private int shakesLeft = 0; private int shakesLeft = 0;
private float shakeCount = 0; private float shakeCount = 0;
public PageButton(int id, int x, int y, boolean direction) { public PageButton(int x, int y, boolean direction) {
super(id, x, y, 23, 13, ""); super(x, y, 23, 13);
this.direction = direction; this.direction = direction;
} }
@Override @Override
public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { public void renderButton(int mouseX, int mouseY, float partialTicks) {
if (visible) { if (visible) {
boolean shaking = false; boolean shaking = false;
@ -207,8 +204,8 @@ public class SpellBookScreen extends ContainerScreen implements IPageUnlockListe
y -= (int)(Math.sin(shakeCount) * 3); y -= (int)(Math.sin(shakeCount) * 3);
} }
GlStateManager.color(1, 1, 1, 1); GlStateManager.color4f(1, 1, 1, 1);
mc.getTextureManager().bindTexture(spellBookGuiTextures); minecraft.getTextureManager().bindTexture(spellBookGuiTextures);
int u = 0; int u = 0;
int v = 220; int v = 220;
@ -225,12 +222,13 @@ public class SpellBookScreen extends ContainerScreen implements IPageUnlockListe
v += 13; v += 13;
} }
drawModalRectWithCustomSizedTexture(x, y, u, v, 23, 13, 512, 256); blit(x, y, u, v, 23, 13, 512, 256);
} }
} }
public boolean isMouseOver(int mouseX, int mouseY) { @Override
return enabled && mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height; public boolean isMouseOver(double mouseX, double mouseY) {
return visible && mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height;
} }

View file

@ -1,6 +1,6 @@
package com.minelittlepony.unicopia.redux.enchanting; package com.minelittlepony.unicopia.redux.enchanting;
import com.minelittlepony.unicopia.core.enchanting.IPage; import com.minelittlepony.unicopia.core.enchanting.Page;
@FunctionalInterface @FunctionalInterface
public interface IPageUnlockListener { public interface IPageUnlockListener {
@ -10,5 +10,5 @@ public interface IPageUnlockListener {
* @param page The page that has been unlocked * @param page The page that has been unlocked
* @return True to allow, false to block. * @return True to allow, false to block.
*/ */
boolean onPageUnlocked(IPage page); boolean onPageUnlocked(Page page);
} }

View file

@ -5,14 +5,14 @@ import javax.annotation.Nullable;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import com.minelittlepony.unicopia.core.enchanting.IPage; import com.minelittlepony.unicopia.core.enchanting.Page;
import com.minelittlepony.unicopia.core.enchanting.IPageOwner; import com.minelittlepony.unicopia.core.enchanting.IPageOwner;
import com.minelittlepony.unicopia.core.enchanting.IUnlockEvent; import com.minelittlepony.unicopia.core.enchanting.IUnlockEvent;
import com.minelittlepony.unicopia.core.enchanting.PageState; import com.minelittlepony.unicopia.core.enchanting.PageState;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
class PageInstance implements IPage { class PageInstance implements Page {
int index; int index;
@ -85,13 +85,13 @@ class PageInstance implements IPage {
} }
@Override @Override
public IPage next() { public Page next() {
int i = Math.min(Pages.instance().getTotalPages() - 1, index + 1); int i = Math.min(Pages.instance().getTotalPages() - 1, index + 1);
return Pages.instance().getByIndex(i); return Pages.instance().getByIndex(i);
} }
@Override @Override
public IPage prev() { public Page prev() {
if (index <= 0) { if (index <= 0) {
return this; return this;
} }
@ -100,12 +100,12 @@ class PageInstance implements IPage {
} }
@Override @Override
public int compareTo(IPage o) { public int compareTo(Page o) {
return getIndex() - o.getIndex(); return getIndex() - o.getIndex();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
return o instanceof IPage && getName().equals(((IPage)o).getName()); return o instanceof Page && getName().equals(((Page)o).getName());
} }
} }

View file

@ -1,7 +1,7 @@
package com.minelittlepony.unicopia.redux.enchanting; package com.minelittlepony.unicopia.redux.enchanting;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.minelittlepony.unicopia.core.enchanting.IPage; import com.minelittlepony.unicopia.core.enchanting.Page;
import com.minelittlepony.unicopia.core.enchanting.IPageOwner; import com.minelittlepony.unicopia.core.enchanting.IPageOwner;
import com.minelittlepony.unicopia.core.enchanting.IUnlockEvent; import com.minelittlepony.unicopia.core.enchanting.IUnlockEvent;
import com.minelittlepony.unicopia.core.enchanting.PageState; import com.minelittlepony.unicopia.core.enchanting.PageState;
@ -24,7 +24,7 @@ public class PageStateCondition implements IUnlockCondition<IUnlockEvent> {
@Override @Override
public boolean matches(IPageOwner owner, IUnlockEvent event) { public boolean matches(IPageOwner owner, IUnlockEvent event) {
IPage ipage = Pages.instance().getByName(page); Page ipage = Pages.instance().getByName(page);
if (ipage != null) { if (ipage != null) {
return owner.getPageState(ipage) == state; return owner.getPageState(ipage) == state;

View file

@ -12,7 +12,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.minelittlepony.unicopia.core.enchanting.IPage; import com.minelittlepony.unicopia.core.enchanting.Page;
import com.minelittlepony.unicopia.core.enchanting.IPageOwner; import com.minelittlepony.unicopia.core.enchanting.IPageOwner;
import com.minelittlepony.unicopia.core.enchanting.IUnlockEvent; import com.minelittlepony.unicopia.core.enchanting.IUnlockEvent;
import com.minelittlepony.unicopia.core.enchanting.PageState; import com.minelittlepony.unicopia.core.enchanting.PageState;
@ -90,17 +90,17 @@ public class Pages {
} }
@Nullable @Nullable
public IPage getByName(Identifier name) { public Page getByName(Identifier name) {
return pages.get(name); return pages.get(name);
} }
@Nullable @Nullable
public IPage getByIndex(int index) { public Page getByIndex(int index) {
return pagesByIndex.get(index); return pagesByIndex.get(index);
} }
public Stream<IPage> getUnlockablePages(Predicate<IPage> predicate) { public Stream<Page> getUnlockablePages(Predicate<Page> predicate) {
return pages.values().stream().map(IPage.class::cast).filter(predicate); return pages.values().stream().map(Page.class::cast).filter(predicate);
} }
public void triggerUnlockEvent(IPageOwner owner, IUnlockEvent event, @Nullable IPageUnlockListener unlockListener) { public void triggerUnlockEvent(IPageOwner owner, IUnlockEvent event, @Nullable IPageUnlockListener unlockListener) {
@ -109,7 +109,7 @@ public class Pages {
.forEach(page -> unlockPage(owner, page, unlockListener)); .forEach(page -> unlockPage(owner, page, unlockListener));
} }
public void unlockPage(IPageOwner owner, IPage page, @Nullable IPageUnlockListener unlockListener) { public void unlockPage(IPageOwner owner, Page page, @Nullable IPageUnlockListener unlockListener) {
if (owner.getPageState(page).isLocked()) { if (owner.getPageState(page).isLocked()) {
if (unlockListener == null || unlockListener.onPageUnlocked(page)) { if (unlockListener == null || unlockListener.onPageUnlocked(page)) {
owner.setPageState(page, PageState.UNREAD); owner.setPageState(page, PageState.UNREAD);

View file

@ -10,8 +10,8 @@ import com.minelittlepony.unicopia.core.SpeciesList;
import com.minelittlepony.unicopia.core.UParticles; import com.minelittlepony.unicopia.core.UParticles;
import com.minelittlepony.unicopia.core.entity.InAnimate; import com.minelittlepony.unicopia.core.entity.InAnimate;
import com.minelittlepony.unicopia.core.util.particles.ParticleEmitter; import com.minelittlepony.unicopia.core.util.particles.ParticleEmitter;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.ability.PowerCloudBase.ICloudEntity; import com.minelittlepony.unicopia.redux.ability.PowerCloudBase.ICloudEntity;
import com.minelittlepony.unicopia.redux.block.UBlocks;
import com.minelittlepony.unicopia.redux.item.UItems; import com.minelittlepony.unicopia.redux.item.UItems;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -24,6 +24,8 @@ import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments; import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityData; import net.minecraft.entity.EntityData;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.ItemEntity; import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LightningEntity; import net.minecraft.entity.LightningEntity;
@ -35,7 +37,6 @@ import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.mob.FlyingEntity; import net.minecraft.entity.mob.FlyingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ShovelItem; import net.minecraft.item.ShovelItem;
@ -50,7 +51,6 @@ import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box; import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.Heightmap; import net.minecraft.world.Heightmap;
@ -72,9 +72,6 @@ public class CloudEntity extends FlyingEntity implements ICloudEntity, InAnimate
protected int directionX; protected int directionX;
protected int directionZ; protected int directionZ;
private final double baseWidth = 3f;
private final double baseHeight = 0.8f;
public CloudEntity(EntityType<? extends CloudEntity> type, World world) { public CloudEntity(EntityType<? extends CloudEntity> type, World world) {
super(type, world); super(type, world);
ignoreCameraFrustum = true; ignoreCameraFrustum = true;
@ -690,26 +687,17 @@ public class CloudEntity extends FlyingEntity implements ICloudEntity, InAnimate
} }
public int getCloudSize() { public int getCloudSize() {
int size = dataTracker.get(SCALE); return dataTracker.get(SCALE);
updateSize(size);
return size;
}
private void updateSize(int scale) {
setSize((float)baseWidth * scale, (float)baseHeight * scale);
} }
@Override @Override
protected void setSize(float width, float height) { public EntityDimensions getDimensions(EntityPose pose) {
if (width != this.width || height != this.height) { return super.getDimensions(pose).scaled(getCloudSize());
super.setSize(width, height);
setPosition(x, y, z);
}
} }
public void setCloudSize(int val) { public void setCloudSize(int val) {
val = Math.max(1, val); val = Math.max(1, val);
updateSize(val);
dataTracker.set(SCALE, val); dataTracker.set(SCALE, val);
calculateDimensions();
} }
} }

View file

@ -5,8 +5,6 @@ import java.util.UUID;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import com.minelittlepony.unicopia.core.EquinePredicates; import com.minelittlepony.unicopia.core.EquinePredicates;
import com.minelittlepony.unicopia.core.Race; import com.minelittlepony.unicopia.core.Race;
import com.minelittlepony.unicopia.core.entity.InAnimate; import com.minelittlepony.unicopia.core.entity.InAnimate;
@ -20,9 +18,9 @@ import com.minelittlepony.unicopia.redux.item.UItems;
import com.minelittlepony.unicopia.redux.magic.ICastable; import com.minelittlepony.unicopia.redux.magic.ICastable;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityCategory; import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
@ -31,9 +29,7 @@ import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.mob.MobEntityWithAi; import net.minecraft.entity.mob.MobEntityWithAi;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -43,7 +39,6 @@ import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameRules; import net.minecraft.world.GameRules;
@ -76,6 +71,10 @@ public class SpellcastEntity extends MobEntityWithAi implements IMagicals, ICast
return goalSelector; return goalSelector;
} }
public GoalSelector getTargets() {
return targetSelector;
}
@Override @Override
public boolean cannotDespawn() { public boolean cannotDespawn() {
return true; return true;
@ -209,7 +208,6 @@ public class SpellcastEntity extends MobEntityWithAi implements IMagicals, ICast
} }
if (getEffect().allowAI()) { if (getEffect().allowAI()) {
dimensions.height = 1.5F;
super.tickMovement(); super.tickMovement();
} }
} }
@ -238,6 +236,17 @@ public class SpellcastEntity extends MobEntityWithAi implements IMagicals, ICast
} }
} }
@Override
public EntityDimensions getDimensions(EntityPose pose) {
EntityDimensions dims = super.getDimensions(pose);
if (hasEffect() && getEffect().allowAI()) {
return EntityDimensions.changing(dims.width, 1.5F);
}
return dims;
}
public boolean overLevelCap() { public boolean overLevelCap() {
return getCurrentLevel() > getMaxLevel(); return getCurrentLevel() > getMaxLevel();
} }

View file

@ -12,10 +12,9 @@ import com.minelittlepony.unicopia.core.entity.ItemEntityCapabilities;
import com.minelittlepony.unicopia.core.entity.player.IPlayer; import com.minelittlepony.unicopia.core.entity.player.IPlayer;
import com.minelittlepony.unicopia.core.magic.Affinity; import com.minelittlepony.unicopia.core.magic.Affinity;
import com.minelittlepony.unicopia.core.magic.IDependable; import com.minelittlepony.unicopia.core.magic.IDependable;
import com.minelittlepony.unicopia.core.util.AwaitTickQueue;
import com.minelittlepony.unicopia.core.util.MagicalDamageSource; import com.minelittlepony.unicopia.core.util.MagicalDamageSource;
import com.minelittlepony.unicopia.core.util.VecHelper; import com.minelittlepony.unicopia.core.util.VecHelper;
import com.minelittlepony.unicopia.redux.UWorld;
import net.minecraft.util.ChatUtil; import net.minecraft.util.ChatUtil;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
@ -218,7 +217,7 @@ public class AlicornAmuletItem extends ArmorItem implements IDependable, ItemEnt
player.world.createExplosion(player, pos.x, pos.y, pos.z, 10, DestructionType.NONE); player.world.createExplosion(player, pos.x, pos.y, pos.z, 10, DestructionType.NONE);
UWorld.scheduleTask(w -> { AwaitTickQueue.scheduleTask(w -> {
w.createExplosion(player, pos.x, pos.y, pos.z, 6, DestructionType.BREAK); w.createExplosion(player, pos.x, pos.y, pos.z, 6, DestructionType.BREAK);
}, 50); }, 50);
} }

View file

@ -10,12 +10,12 @@ import com.minelittlepony.unicopia.core.magic.Affinity;
import com.minelittlepony.unicopia.core.magic.IMagicalItem; import com.minelittlepony.unicopia.core.magic.IMagicalItem;
import com.minelittlepony.unicopia.core.util.VecHelper; import com.minelittlepony.unicopia.core.util.VecHelper;
import com.minelittlepony.unicopia.redux.UContainers; import com.minelittlepony.unicopia.redux.UContainers;
import com.minelittlepony.unicopia.redux.container.BagOfHoldingContainer;
import com.minelittlepony.unicopia.redux.container.BagOfHoldingInventory; import com.minelittlepony.unicopia.redux.container.BagOfHoldingInventory;
import net.fabricmc.fabric.api.container.ContainerProviderRegistry; import net.fabricmc.fabric.api.container.ContainerProviderRegistry;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.item.TooltipContext; import net.minecraft.client.item.TooltipContext;
import net.minecraft.container.Container;
import net.minecraft.container.NameableContainerProvider; import net.minecraft.container.NameableContainerProvider;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.ItemEntity; import net.minecraft.entity.ItemEntity;
@ -127,7 +127,7 @@ public class BagOfHoldingItem extends Item implements IMagicalItem {
return true; return true;
} }
class ContainerProvider implements NameableContainerProvider { public static class ContainerProvider implements NameableContainerProvider {
private Text customname = null; private Text customname = null;
@ -146,8 +146,8 @@ public class BagOfHoldingItem extends Item implements IMagicalItem {
} }
@Override @Override
public Container createMenu(int id, PlayerInventory playerInventory, PlayerEntity player) { public BagOfHoldingContainer createMenu(int id, PlayerInventory inv, PlayerEntity player) {
return null; return new BagOfHoldingContainer(id, null, player, null);
} }
} }
} }

View file

@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.redux.item;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.minelittlepony.unicopia.redux.block.UBlocks; import com.minelittlepony.unicopia.redux.UBlocks;
import net.minecraft.advancement.criterion.Criterions; import net.minecraft.advancement.criterion.Criterions;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;

View file

@ -1,7 +1,7 @@
package com.minelittlepony.unicopia.redux.item; package com.minelittlepony.unicopia.redux.item;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.block.StickBlock; import com.minelittlepony.unicopia.redux.block.StickBlock;
import com.minelittlepony.unicopia.redux.block.UBlocks;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;

View file

@ -1,7 +1,7 @@
package com.minelittlepony.unicopia.redux.item; package com.minelittlepony.unicopia.redux.item;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.UEntities; import com.minelittlepony.unicopia.redux.UEntities;
import com.minelittlepony.unicopia.redux.block.UBlocks;
import com.minelittlepony.unicopia.redux.magic.spells.ScorchSpell; import com.minelittlepony.unicopia.redux.magic.spells.ScorchSpell;
import com.minelittlepony.unicopia.redux.toxin.DynamicToxicBlockItem; import com.minelittlepony.unicopia.redux.toxin.DynamicToxicBlockItem;
import com.minelittlepony.unicopia.redux.toxin.DynamicToxicItem; import com.minelittlepony.unicopia.redux.toxin.DynamicToxicItem;
@ -51,7 +51,6 @@ public class UItems {
public static final Item cloud_stairs = register(new PredicatedBlockItem(UBlocks.cloud_stairs, new Item.Settings().group(ItemGroup.BUILDING_BLOCKS), INTERACT_WITH_CLOUDS), "cloud_stairs"); public static final Item cloud_stairs = register(new PredicatedBlockItem(UBlocks.cloud_stairs, new Item.Settings().group(ItemGroup.BUILDING_BLOCKS), INTERACT_WITH_CLOUDS), "cloud_stairs");
public static final Item cloud_fence = register(new PredicatedBlockItem(UBlocks.cloud_fence, new Item.Settings().group(ItemGroup.DECORATIONS), INTERACT_WITH_CLOUDS), "cloud_fence"); public static final Item cloud_fence = register(new PredicatedBlockItem(UBlocks.cloud_fence, new Item.Settings().group(ItemGroup.DECORATIONS), INTERACT_WITH_CLOUDS), "cloud_fence");
public static final Item cloud_banister = register(new PredicatedBlockItem(UBlocks.cloud_banister, new Item.Settings().group(ItemGroup.DECORATIONS), INTERACT_WITH_CLOUDS), "cloud_banister");
public static final Item anvil = register(new PredicatedBlockItem(UBlocks.anvil, new Item.Settings().group(ItemGroup.DECORATIONS), INTERACT_WITH_CLOUDS), "cloud_anvil"); public static final Item anvil = register(new PredicatedBlockItem(UBlocks.anvil, new Item.Settings().group(ItemGroup.DECORATIONS), INTERACT_WITH_CLOUDS), "cloud_anvil");

View file

@ -10,8 +10,8 @@ import com.minelittlepony.unicopia.core.magic.CasterUtils;
import com.minelittlepony.unicopia.core.magic.IAttachedEffect; import com.minelittlepony.unicopia.core.magic.IAttachedEffect;
import com.minelittlepony.unicopia.core.magic.ICaster; import com.minelittlepony.unicopia.core.magic.ICaster;
import com.minelittlepony.unicopia.core.util.WorldEvent; import com.minelittlepony.unicopia.core.util.WorldEvent;
import com.minelittlepony.unicopia.redux.UBlocks;
import com.minelittlepony.unicopia.redux.UEntities; import com.minelittlepony.unicopia.redux.UEntities;
import com.minelittlepony.unicopia.redux.block.UBlocks;
import com.minelittlepony.unicopia.redux.entity.CuccoonEntity; import com.minelittlepony.unicopia.redux.entity.CuccoonEntity;
import com.minelittlepony.unicopia.redux.magic.ITossedEffect; import com.minelittlepony.unicopia.redux.magic.ITossedEffect;

View file

@ -206,7 +206,7 @@ public class DarknessSpell extends AbstractAttachableSpell {
public boolean isAreaOccupied(ICaster<?> source, Vec3d pos) { public boolean isAreaOccupied(ICaster<?> source, Vec3d pos) {
if (source.getWorld().isAir(new BlockPos(pos).down())) { if (source.getWorld().isAir(new BlockPos(pos).down())) {
return source.findAllSpells().anyMatch(spell -> { return source.findAllSpellsInRange(100).anyMatch(spell -> {
ShieldSpell effect = spell.getEffect(ShieldSpell.class, false); ShieldSpell effect = spell.getEffect(ShieldSpell.class, false);
if (effect != null) { if (effect != null) {

View file

@ -20,7 +20,6 @@ import com.minelittlepony.unicopia.core.magic.IAttachedEffect;
import com.minelittlepony.unicopia.core.magic.ICaster; import com.minelittlepony.unicopia.core.magic.ICaster;
import com.minelittlepony.unicopia.core.magic.IMagicEffect; import com.minelittlepony.unicopia.core.magic.IMagicEffect;
import com.minelittlepony.unicopia.core.magic.ISuppressable; import com.minelittlepony.unicopia.core.magic.ISuppressable;
import com.minelittlepony.unicopia.core.mixin.MixinEntity;
import com.minelittlepony.unicopia.core.util.projectile.ProjectileUtil; import com.minelittlepony.unicopia.core.util.projectile.ProjectileUtil;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
@ -30,11 +29,12 @@ import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.FallingBlockEntity; import net.minecraft.entity.FallingBlockEntity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.ai.RangedAttackMob;
import net.minecraft.entity.boss.dragon.EnderDragonEntity; import net.minecraft.entity.boss.dragon.EnderDragonEntity;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.decoration.AbstractDecorationEntity; import net.minecraft.entity.decoration.AbstractDecorationEntity;
import net.minecraft.entity.mob.AmbientEntity; import net.minecraft.entity.mob.AmbientEntity;
import net.minecraft.entity.mob.FlyingEntity; import net.minecraft.entity.mob.FlyingEntity;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.mob.ShulkerEntity; import net.minecraft.entity.mob.ShulkerEntity;
import net.minecraft.entity.mob.VexEntity; import net.minecraft.entity.mob.VexEntity;
import net.minecraft.entity.passive.TameableEntity; import net.minecraft.entity.passive.TameableEntity;
@ -44,7 +44,6 @@ import net.minecraft.entity.projectile.ShulkerBulletEntity;
import net.minecraft.entity.vehicle.MinecartEntity; import net.minecraft.entity.vehicle.MinecartEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.UseAction;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISuppressable, IFlyingPredicate, IHeightPredicate { public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISuppressable, IFlyingPredicate, IHeightPredicate {
@ -248,26 +247,26 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
to.prevPitch = from.prevPitch; to.prevPitch = from.prevPitch;
to.prevYaw = from.prevYaw; to.prevYaw = from.prevYaw;
to.distanceWalkedOnStepModified = from.distanceWalkedOnStepModified; //to.distanceWalkedOnStepModified = from.distanceWalkedOnStepModified;
to.distanceWalkedModified = from.distanceWalkedModified; //to.distanceWalkedModified = from.distanceWalkedModified;
to.prevDistanceWalkedModified = from.prevDistanceWalkedModified; //to.prevDistanceWalkedModified = from.prevDistanceWalkedModified;
if (to instanceof LivingEntity) { if (to instanceof LivingEntity) {
LivingEntity l = (LivingEntity)to; LivingEntity l = (LivingEntity)to;
l.rotationYawHead = from.rotationYawHead; l.headYaw = from.headYaw;
l.prevRotationYawHead = from.prevRotationYawHead; l.prevHeadYaw = from.prevHeadYaw;
l.renderYawOffset = from.renderYawOffset; //l.renderYawOffset = from.renderYawOffset;
l.prevRenderYawOffset = from.prevRenderYawOffset; //l.prevRenderYawOffset = from.prevRenderYawOffset;
l.limbSwing = from.limbSwing; l.limbDistance = from.limbDistance;
l.limbSwingAmount = from.limbSwingAmount; l.limbAngle = from.limbAngle;
l.prevLimbSwingAmount = from.prevLimbSwingAmount; l.lastLimbDistance = from.lastLimbDistance;
l.swingingHand = from.swingingHand; l.handSwingProgress = from.handSwingProgress;
l.swingProgress = from.swingProgress; l.lastHandSwingProgress = from.lastHandSwingProgress;
l.swingProgressInt = from.swingProgressInt; l.handSwingTicks = from.handSwingTicks;
l.isSwingInProgress = from.isSwingInProgress; l.isHandSwinging = from.isHandSwinging;
l.hurtTime = from.hurtTime; l.hurtTime = from.hurtTime;
l.deathTime = from.deathTime; l.deathTime = from.deathTime;
@ -282,11 +281,11 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
} }
} }
if (to instanceof RangedAttackMob) { /*if (to instanceof RangedAttackMob) {
ItemStack activeItem = from.getActiveItem(); ItemStack activeItem = from.getActiveItem();
((RangedAttackMob)to).setSwingingArms(!activeItem.isEmpty() && activeItem.getUseAction() == UseAction.BOW); ((RangedAttackMob)to).setSwingingArms(!activeItem.isEmpty() && activeItem.getUseAction() == UseAction.BOW);
} }*/
if (to instanceof TameableEntity) { if (to instanceof TameableEntity) {
((TameableEntity)to).setSitting(from.isSneaking()); ((TameableEntity)to).setSitting(from.isSneaking());
@ -310,7 +309,6 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
return update(caster); return update(caster);
} }
@SuppressWarnings("unchecked")
@Override @Override
public boolean update(ICaster<?> source) { public boolean update(ICaster<?> source) {
LivingEntity owner = source.getOwner(); LivingEntity owner = source.getOwner();
@ -347,12 +345,12 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
} }
entity.noClip = true; entity.noClip = true;
entity.updateBlocked = true; //entity.updateBlocked = true;
entity.getEntityData().setBoolean("disguise", true); //entity.getEntityData().setBoolean("disguise", true);
if (entity instanceof LivingEntity) { if (entity instanceof MobEntity) {
((LivingEntity)entity).setNoAI(true); ((MobEntity)entity).setAiDisabled(true);
} }
entity.setInvisible(false); entity.setInvisible(false);
@ -368,10 +366,10 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
ShulkerEntity shulker = ((ShulkerEntity)entity); ShulkerEntity shulker = ((ShulkerEntity)entity);
shulker.yaw = 0; shulker.yaw = 0;
shulker.renderYawOffset = 0; //shulker.renderYawOffset = 0;
shulker.prevRenderYawOffset = 0; //shulker.prevRenderYawOffset = 0;
shulker.setAttachmentPos(null); shulker.setAttachedBlock(null);
if (source.isClient() && source instanceof IPlayer) { if (source.isClient() && source instanceof IPlayer) {
IPlayer player = (IPlayer)source; IPlayer player = (IPlayer)source;
@ -380,14 +378,14 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
float peekAmount = 0.3F; float peekAmount = 0.3F;
if (!owner.isSneaking()) { if (!owner.isSneaking()) {
float speed = (float)Math.sqrt(Math.pow(owner.motionX, 2) + Math.pow(owner.motionZ, 2)); double speed = Math.sqrt(Entity.squaredHorizontalLength(owner.getVelocity()));
peekAmount = MathHelper.clamp(speed * 30, 0, 1); peekAmount = (float)MathHelper.clamp(speed * 30, 0, 1);
} }
peekAmount = player.getInterpolator().interpolate("peek", peekAmount, 5); peekAmount = player.getInterpolator().interpolate("peek", peekAmount, 5);
shulker.setPeekAmount(peekAmount); shulker.setPeekAmount((int)peekAmount);
} }
} }
@ -407,7 +405,7 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
} }
if (entity instanceof PlayerEntity) { if (entity instanceof PlayerEntity) {
entity.getDataTracker().set(MixinEntity.Player.getModelFlag(), owner.getDataTracker().get(MixinEntity.Player.getModelFlag())); entity.getDataTracker().set(Player.getModelBitFlag(), owner.getDataTracker().get(Player.getModelBitFlag()));
} }
if (player.isClientPlayer() && InteractionManager.instance().getViewMode() == 0) { if (player.isClientPlayer() && InteractionManager.instance().getViewMode() == 0) {
@ -482,6 +480,7 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
} }
if (entity instanceof Owned) { if (entity instanceof Owned) {
@SuppressWarnings("unchecked")
IPlayer iplayer = SpeciesList.instance().getPlayer(((Owned<PlayerEntity>)entity).getOwner()); IPlayer iplayer = SpeciesList.instance().getPlayer(((Owned<PlayerEntity>)entity).getOwner());
return iplayer != null && iplayer.getSpecies().canFly(); return iplayer != null && iplayer.getSpecies().canFly();
@ -528,4 +527,11 @@ public class DisguiseSpell extends AbstractSpell implements IAttachedEffect, ISu
|| entity instanceof AbstractDecorationEntity || entity instanceof AbstractDecorationEntity
|| entity instanceof FallingBlockEntity; || entity instanceof FallingBlockEntity;
} }
static abstract class Player extends PlayerEntity {
public Player() { super(null, null); }
static TrackedData<Byte> getModelBitFlag() {
return PLAYER_MODEL_BIT_MASK;
}
}
} }

View file

@ -10,9 +10,15 @@ import com.minelittlepony.unicopia.core.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.redux.entity.SpellcastEntity; import com.minelittlepony.unicopia.redux.entity.SpellcastEntity;
import com.minelittlepony.unicopia.redux.entity.ai.FollowCasterGoal; import com.minelittlepony.unicopia.redux.entity.ai.FollowCasterGoal;
import net.minecraft.entity.ai.goal.SwimGoal;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.Box; import net.minecraft.util.math.Box;
/**
* Spike The Dragon, but in rock form.
*
* It follows you around and can pick up/carry other gems.
*/
public class FaithfulAssistantSpell extends AbstractSpell { public class FaithfulAssistantSpell extends AbstractSpell {
private static final Box EFFECT_BOUNDS = new Box(-2, -2, -2, 2, 2, 2); private static final Box EFFECT_BOUNDS = new Box(-2, -2, -2, 2, 2, 2);
@ -59,14 +65,15 @@ public class FaithfulAssistantSpell extends AbstractSpell {
return super.isDirty() || (piggyBackSpell != null && piggyBackSpell.isDirty()); return super.isDirty() || (piggyBackSpell != null && piggyBackSpell.isDirty());
} }
@SuppressWarnings("unchecked")
@Override @Override
public void onPlaced(ICaster<?> caster) { public void onPlaced(ICaster<?> caster) {
if (caster.getEntity() instanceof SpellcastEntity) { if (caster.getEntity() instanceof SpellcastEntity) {
SpellcastEntity living = (SpellcastEntity)caster.getEntity(); SpellcastEntity living = (SpellcastEntity)caster.getEntity();
((PathNavigateGround)living.getNavigator()).setCanSwim(false); living.getNavigation().setCanSwim(false);
living.tasks.addTask(1, new EntityAISwimming(living)); living.getGoals().add(1, new SwimGoal(living));
living.tasks.addTask(2, new FollowCasterGoal<>(caster, 1, 4, 70)); living.getGoals().add(2, new FollowCasterGoal<>((ICaster<SpellcastEntity>)caster, 1, 4, 70));
living.setPosition(living.x, living.y, living.z); living.setPosition(living.x, living.y, living.z);
} }

View file

@ -8,8 +8,10 @@ import com.minelittlepony.unicopia.core.magic.IHeldEffect;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.LightType;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.light.ChunkBlockLightProvider;
import net.minecraft.world.chunk.light.ChunkLightingView;
public class GlowingSpell extends GenericSpell implements IHeldEffect { public class GlowingSpell extends GenericSpell implements IHeldEffect {
@ -30,7 +32,15 @@ public class GlowingSpell extends GenericSpell implements IHeldEffect {
super.setDead(); super.setDead();
if (lastPos != null) { if (lastPos != null) {
source.getWorld().checkLight(lastPos); ChunkLightingView view = source.getWorld().getChunkManager().getLightingProvider().get(LightType.BLOCK);
if (!(view instanceof ChunkBlockLightProvider)) {
return;
}
ChunkBlockLightProvider provider = (ChunkBlockLightProvider)view;
provider.queueLightCheck(lastPos);
} }
} }
@ -49,43 +59,50 @@ public class GlowingSpell extends GenericSpell implements IHeldEffect {
World world = source.getWorld(); World world = source.getWorld();
ChunkLightingView view = world.getChunkManager().getLightingProvider().get(LightType.BLOCK);
if (!(view instanceof ChunkBlockLightProvider)) {
return true;
}
ChunkBlockLightProvider provider = (ChunkBlockLightProvider)view;
if (lastPos != null && !lastPos.equals(pos)) { if (lastPos != null && !lastPos.equals(pos)) {
world.checkLight(lastPos); provider.queueLightCheck(lastPos);
} }
lastPos = pos; lastPos = pos;
int light = provider.getLightLevel(pos);
int light = world.getLightFor(EnumSkyBlock.BLOCK, pos);
if (light < 8) { if (light < 8) {
world.setLightFor(EnumSkyBlock.BLOCK, pos, 8); provider.method_15514(pos, 8);
world.notifyLightSet(pos); provider.queueLightCheck(pos);
world.checkLight(pos.up());
} }
return true; return true;
} }
@Override @Override
public void writeToNBT(CompoundTag compound) { public void toNBT(CompoundTag compound) {
super.toNBT(compound); super.toNBT(compound);
if (compound.hasKey("lastX")) { if (compound.containsKey("lastX")) {
lastPos = new BlockPos(compound.getInteger("lastX"), compound.getInteger("lastY"), compound.getInteger("lastZ")); lastPos = new BlockPos(compound.getInt("lastX"), compound.getInt("lastY"), compound.getInt("lastZ"));
} else { } else {
lastPos = null; lastPos = null;
} }
} }
@Override @Override
public void readFromNBT(CompoundTag compound) { public void fromNBT(CompoundTag compound) {
super.fromNBT(compound); super.fromNBT(compound);
if (lastPos != null) { if (lastPos != null) {
compound.setInteger("lastX", lastPos.getX()); compound.putInt("lastX", lastPos.getX());
compound.setInteger("lastY", lastPos.getY()); compound.putInt("lastY", lastPos.getY());
compound.setInteger("lastZ", lastPos.getZ()); compound.putInt("lastZ", lastPos.getZ());
} }
} }
} }

View file

@ -149,7 +149,7 @@ public class IceSpell extends AbstractSpell.RangedAreaSpell implements IUseable,
if (!state.equals(converted)) { if (!state.equals(converted)) {
world.setBlockState(pos, converted, 3); world.setBlockState(pos, converted, 3);
} else if (state.getMaterial() != UMaterials.cloud && world.doesBlockHaveSolidTopSurface(pos, owner) } else if (state.getMaterial() != UMaterials.CLOUD && world.doesBlockHaveSolidTopSurface(pos, owner)
|| (id == Blocks.SNOW) || (id == Blocks.SNOW)
|| state.matches(BlockTags.LEAVES)) { || state.matches(BlockTags.LEAVES)) {
incrementIce(world, pos.up()); incrementIce(world, pos.up());

View file

@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.core.util.shape.Sphere;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.Vec3d;
public class RevealingSpell extends AbstractSpell { public class RevealingSpell extends AbstractSpell {
@ -48,10 +49,10 @@ public class RevealingSpell extends AbstractSpell {
IShape area = new Sphere(false, 15); IShape area = new Sphere(false, 15);
source.spawnParticles(area, 5, pos -> { source.spawnParticles(area, 5, pos -> {
ParticleTypeRegistry.getTnstance().spawnParticle(UParticles.UNICORN_MAGIC, false, pos, 0, 0, 0, getTint()); source.addParticle(UParticles.UNICORN_MAGIC, pos, Vec3d.ZERO); // getTint()
}); });
source.spawnParticles(UParticles.UNICORN_MAGIC, 5, getTint()); source.spawnParticles(UParticles.UNICORN_MAGIC, 5); //getTint()
} }
@Override @Override

View file

@ -8,7 +8,6 @@ import com.minelittlepony.unicopia.core.magic.ICaster;
import com.minelittlepony.unicopia.core.magic.spell.FireSpell; import com.minelittlepony.unicopia.core.magic.spell.FireSpell;
import com.minelittlepony.unicopia.core.util.PosHelper; import com.minelittlepony.unicopia.core.util.PosHelper;
import com.minelittlepony.unicopia.core.util.shape.Sphere; import com.minelittlepony.unicopia.core.util.shape.Sphere;
import com.minelittlepony.unicopia.redux.entity.ProjectileEntity;
import com.minelittlepony.unicopia.redux.magic.ITossedEffect; import com.minelittlepony.unicopia.redux.magic.ITossedEffect;
import com.minelittlepony.unicopia.redux.util.projectile.IAdvancedProjectile; import com.minelittlepony.unicopia.redux.util.projectile.IAdvancedProjectile;
@ -58,7 +57,7 @@ public class ScorchSpell extends FireSpell implements ITossedEffect {
@Override @Override
public void render(ICaster<?> source) { public void render(ICaster<?> source) {
source.spawnParticles(ParticleTypes.FLAME, 3); source.spawnParticles(ParticleTypes.FLAME, 3);
source.spawnParticles(UParticles.UNICORN_MAGIC, 3, getTint()); source.spawnParticles(UParticles.UNICORN_MAGIC, 3); // getTint()
} }
@Override @Override

View file

@ -1,138 +0,0 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Random;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.structure.StructureBoundingBox;
import net.minecraft.world.gen.structure.StructureComponent;
import net.minecraft.world.gen.structure.StructureStart;
import net.minecraft.world.gen.structure.template.TemplateManager;
public abstract class AbstractFeature extends StructureComponent {
protected int width;
protected int height;
protected int depth;
protected int verticalPos = -1;
public AbstractFeature() {
}
protected AbstractFeature(Random rand, int x, int y, int z, int sizeX, int sizeY, int sizeZ) {
super(0);
width = sizeX;
height = sizeY;
depth = sizeZ;
setCoordBaseMode(Direction.Plane.HORIZONTAL.random(rand));
if (getCoordBaseMode().getAxis() == Direction.Axis.Z) {
boundingBox = new StructureBoundingBox(x, y, z, x + sizeX - 1, y + sizeY - 1, z + sizeZ - 1);
} else {
boundingBox = new StructureBoundingBox(x, y, z, x + sizeZ - 1, y + sizeY - 1, z + sizeX - 1);
}
}
@Override
protected void writeStructureToNBT(CompoundTag tagCompound) {
tagCompound.setInteger("Width", width);
tagCompound.setInteger("Height", height);
tagCompound.setInteger("Depth", depth);
tagCompound.setInteger("HPos", verticalPos);
}
@Override
protected void readStructureFromNBT(CompoundTag tagCompound, TemplateManager templater) {
width = tagCompound.getInteger("Width");
height = tagCompound.getInteger("Height");
depth = tagCompound.getInteger("Depth");
verticalPos = tagCompound.getInteger("HPos");
}
protected int getAverageStructureAltitude() {
return 64;
}
/**
* Offsets this component to the average ground level, sliding it down hill if needed.
* Called to make structures 'lay on top' of the land and also prevent floating houses.
*
* @param world The world
* @param bounds The structure bounding box
* @param yOffset Offset from ground level. (default: -1)
*
* @return Trues true if we can generate here.
*/
protected boolean tryFitTerrain(World world, StructureBoundingBox bounds, int yOffset) {
if (verticalPos >= 0) {
return true;
}
int xOff = 0;
int offsetIncrements = 0;
int targetY = getAverageStructureAltitude();
MutableBlockPos pos = new MutableBlockPos();
for (int z = boundingBox.minZ; z <= boundingBox.maxZ; ++z) {
for (int x = boundingBox.minX; x <= boundingBox.maxX; ++x) {
pos.setPos(x, targetY, z);
if (bounds.isVecInside(pos)) {
xOff += Math.max(world.getTopSolidOrLiquidBlock(pos).getY(), world.provider.getAverageGroundLevel());
offsetIncrements++;
}
}
}
if (offsetIncrements == 0) {
return false;
}
verticalPos = xOff / offsetIncrements;
boundingBox.offset(0, verticalPos - boundingBox.minY + yOffset, 0);
return true;
}
public abstract static class Start extends StructureStart {
public Start() {
}
public Start(World world, Random rand, int x, int z) {
this(world, rand, x, z, world.getBiome(new BlockPos(x * 16 + 8, 0, z * 16 + 8)));
}
public Start(World world, Random rand, int x, int z, Biome biome) {
super(x, z);
addComponents(world, rand, x, z, biome);
updateBoundingBox();
init(world, rand, x, z, biome);
}
protected void init(World world, Random rand, int x, int z, Biome biome) {
}
public void offset(int x, int y, int z) {
boundingBox.offset(x, y, z);
for (StructureComponent structurecomponent : components) {
structurecomponent.offset(x, y, z);
}
}
protected abstract void addComponents(World world, Random ran, int x, int z, Biome biome);
}
}

View file

@ -1,76 +0,0 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Map;
import java.util.Random;
import java.util.Map.Entry;
import javax.annotation.Nonnull;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
public abstract class AbstractFeaturesGen extends MapGenStructure {
protected int maxDistance;
protected int minDistance;
public AbstractFeaturesGen(int min, int max) {
maxDistance = max;
minDistance = min;
}
public AbstractFeaturesGen(Map<String, String> properties) {
for (Entry<String, String> entry : properties.entrySet()) {
if (entry.getKey().equals("distance")) {
maxDistance = MathHelper.parseInt(entry.getValue(), maxDistance, 9);
}
if (entry.getKey().equals("MinDistance")) {
minDistance = MathHelper.parseInt(entry.getValue(), minDistance, 9);
}
}
}
protected abstract int getRandomSeed();
protected abstract boolean canSpawnInBiome(@Nonnull Biome biome);
@Override
protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) {
int i = chunkX;
int j = chunkZ;
if (chunkX < 0) {
chunkX -= maxDistance - 1;
}
if (chunkZ < 0) {
chunkZ -= maxDistance - 1;
}
int k = chunkX / maxDistance;
int l = chunkZ / maxDistance;
Random random = world.setRandomSeed(k, l, getRandomSeed());
k = k * maxDistance;
l = l * maxDistance;
k = k + random.nextInt(maxDistance - 8);
l = l + random.nextInt(maxDistance - 8);
if (i == k && j == l) {
Biome biome = world.getBiomeProvider().getBiome(new BlockPos(i * 16 + 8, 0, j * 16 + 8));
return biome != null && canSpawnInBiome(biome);
}
return false;
}
@Override
public BlockPos getNearestStructurePos(World world, BlockPos pos, boolean findUnexplored) {
this.world = world;
return findNearestStructurePosBySpacing(world, this, pos, maxDistance, 8, getRandomSeed(), false, 100, findUnexplored);
}
}

View file

@ -0,0 +1,39 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nonnull;
import com.mojang.datafixers.Dynamic;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.AbstractTempleFeature;
import net.minecraft.world.gen.feature.FeatureConfig;
public abstract class BiomeWhitelistedFeature<C extends FeatureConfig> extends AbstractTempleFeature<C> {
public BiomeWhitelistedFeature(Function<Dynamic<?>, ? extends C> function_1) {
super(function_1);
}
@Override
public boolean shouldStartAt(ChunkGenerator<?> generator, Random rand, int x, int z) {
ChunkPos pos = getStart(generator, rand, x, z, 0, 0);
if (x == pos.x && z == pos.z) {
Biome biome = generator.getBiomeSource().getBiome(new BlockPos(x * 16 + 9, 0, z * 16 + 9));
if (canSpawnInBiome(biome)) {
return true;
}
}
return false;
}
protected abstract boolean canSpawnInBiome(@Nonnull Biome biome);
}

View file

@ -1,43 +0,0 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Random;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.StructureBoundingBox;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraft.world.gen.structure.template.TemplateManager;
public class CloudDungeon extends TemplateBasedFeature {
private static final Identifier[] VARIANTS = new Identifier[] {
new Identifier(UnicopiaCore.MODID, "cloud/temple_small"),
new Identifier(UnicopiaCore.MODID, "cloud/house_small"),
new Identifier(UnicopiaCore.MODID, "cloud/island_small")
};
public CloudDungeon() {
}
public CloudDungeon(Random rand, int x, int z) {
super(rand, x, 0, z, 7, 5, 8);
}
@Override
public boolean addComponentParts(World world, BlockPos startPos, TemplateManager templates, PlacementSettings placement) {
int index = world.rand.nextInt(VARIANTS.length);
applyTemplate(world, startPos, templates, placement, VARIANTS[index]);
return true;
}
@Override
protected boolean tryFitTerrain(World world, StructureBoundingBox bounds, int yOffset) {
return true;
}
}

View file

@ -0,0 +1,140 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nonnull;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.mojang.datafixers.Dynamic;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.structure.SimpleStructurePiece;
import net.minecraft.structure.StructureManager;
import net.minecraft.structure.StructurePlacementData;
import net.minecraft.structure.StructureStart;
import net.minecraft.structure.processor.BlockIgnoreStructureProcessor;
import net.minecraft.util.BlockMirror;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MutableIntBoundingBox;
import net.minecraft.world.IWorld;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
public class CloudDungeonFeature extends BiomeWhitelistedFeature<DefaultFeatureConfig> {
private static final BlockPos POS = new BlockPos(4, 0, 15);
private static final Identifier[] VARIANTS = new Identifier[] {
new Identifier(UnicopiaCore.MODID, "cloud/temple_small"),
new Identifier(UnicopiaCore.MODID, "cloud/house_small"),
new Identifier(UnicopiaCore.MODID, "cloud/island_small")
};
private static final List<Biome> ALLOWED_BIOMES = Arrays.<Biome>asList(
Biomes.OCEAN,
Biomes.WOODED_BADLANDS_PLATEAU,
Biomes.DESERT,
Biomes.DESERT_HILLS,
Biomes.JUNGLE,
Biomes.JUNGLE_HILLS,
Biomes.SWAMP,
Biomes.SWAMP_HILLS,
Biomes.ICE_SPIKES,
Biomes.TAIGA
);
public CloudDungeonFeature(Function<Dynamic<?>, ? extends DefaultFeatureConfig> func) {
super(func);
}
@Override
protected int getSeedModifier() {
return 143592;
}
@Override
public String getName() {
return "unicopia:clouds";
}
@Override
public int getRadius() {
return 12;
}
@Override
protected boolean canSpawnInBiome(@Nonnull Biome biome) {
return ALLOWED_BIOMES.contains(biome);
}
@Override
public StructureStartFactory getStructureStartFactory() {
return Start::new;
}
public static class Start extends StructureStart {
public Start(StructureFeature<?> feature, int x, int z, Biome biome, MutableIntBoundingBox bound, int var6, long var7) {
super(feature, x, z, biome, bound, var6, var7);
}
@Override
public void initialize(ChunkGenerator<?> generator, StructureManager manager, int x, int z, Biome biome) {
BlockRotation rotation = BlockRotation.values()[random.nextInt(BlockRotation.values().length)];
BlockPos pos = new BlockPos(x * 16, 150, z * 16);
Identifier template = VARIANTS[random.nextInt(VARIANTS.length) % VARIANTS.length];
children.add(new Piece(manager, template, pos, rotation));
setBoundingBoxFromChildren();
}
}
public static class Piece extends SimpleStructurePiece {
private final BlockRotation rotation;
private final Identifier template;
public Piece(StructureManager manager, Identifier template, BlockPos pos, BlockRotation rotation) {
super(UStructures.CLOUD_HOUSE, 0);
this.pos = pos;
this.rotation = rotation;
this.template = template;
init(manager);
}
public Piece(StructureManager manager, CompoundTag tag) {
super(UStructures.CLOUD_HOUSE, tag);
this.template = new Identifier(tag.getString("Template"));
this.rotation = BlockRotation.valueOf(tag.getString("Rot"));
init(manager);
}
@Override
protected void toNbt(CompoundTag compoundTag_1) {
super.toNbt(compoundTag_1);
compoundTag_1.putString("Template", template.toString());
compoundTag_1.putString("Rot", rotation.name());
}
private void init(StructureManager manager) {
setStructureData(manager.getStructureOrBlank(template), pos, new StructurePlacementData()
.setRotation(rotation)
.setMirrored(BlockMirror.NONE)
.setPosition(POS)
.addProcessor(BlockIgnoreStructureProcessor.IGNORE_AIR_AND_STRUCTURE_BLOCKS));
}
@Override
protected void handleMetadata(String var1, BlockPos var2, IWorld var3, Random var4, MutableIntBoundingBox var5) {
}
}
}

View file

@ -1,69 +0,0 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
public class CloudGen extends AbstractFeaturesGen {
private static final List<Biome> BIOMELIST = Arrays.<Biome>asList(
Biomes.OCEAN,
Biomes.MESA,
Biomes.DESERT, Biomes.DESERT_HILLS,
Biomes.JUNGLE, Biomes.JUNGLE_HILLS,
Biomes.SWAMP, Biomes.SWAMP_HILLS,
Biomes.ICE_SPIKES, Biomes.COLD_TAIGA
);
public CloudGen() {
super(8, 32);
}
@Override
public String getStructureName() {
return "unicopia:clouds";
}
@Override
protected int getRandomSeed() {
return 143592;
}
@Override
protected boolean canSpawnInBiome(@Nonnull Biome biome) {
return BIOMELIST.contains(biome);
}
@Override
protected StructureStart getStructureStart(int chunkX, int chunkZ) {
return new Start(world, rand, chunkX, chunkZ);
}
public static class Start extends AbstractFeature.Start {
public Start() {
}
public Start(World world, Random rand, int x, int z) {
super(world, rand, x, z);
}
@Override
protected void init(World world, Random rand, int x, int z, Biome biome) {
setRandomHeight(world, rand, 150, world.getActualHeight() - getBoundingBox().getYSize());
}
@Override
protected void addComponents(World world, Random rand, int x, int z, Biome biome) {
components.add(new CloudDungeon(rand, x * 16, z * 16));
}
}
}

View file

@ -1,39 +0,0 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Random;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraft.world.gen.structure.template.TemplateManager;
public class GroundDungeon extends TemplateBasedFeature {
private static final Identifier[] VARIANTS = new Identifier[] {
new Identifier(UnicopiaCore.MODID, "ground/tower"),
new Identifier(UnicopiaCore.MODID, "ground/temple_with_book"),
new Identifier(UnicopiaCore.MODID, "ground/temple_without_book"),
new Identifier(UnicopiaCore.MODID, "ground/wizard_tower_red"),
new Identifier(UnicopiaCore.MODID, "ground/wizard_tower_blue")
};
public GroundDungeon() {
}
public GroundDungeon(Random rand, int x, int z) {
super(rand, x, 64, z, 7, 5, 8);
}
@Override
public boolean addComponentParts(World world, BlockPos startPos, TemplateManager templates, PlacementSettings placement) {
int index = world.rand.nextInt(VARIANTS.length);
applyTemplate(world, startPos, templates, placement, VARIANTS[index]);
return true;
}
}

View file

@ -0,0 +1,141 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import com.mojang.datafixers.Dynamic;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.structure.SimpleStructurePiece;
import net.minecraft.structure.StructureManager;
import net.minecraft.structure.StructurePlacementData;
import net.minecraft.structure.StructureStart;
import net.minecraft.structure.processor.BlockIgnoreStructureProcessor;
import net.minecraft.util.BlockMirror;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MutableIntBoundingBox;
import net.minecraft.world.IWorld;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
public class RuinFeature extends BiomeWhitelistedFeature<DefaultFeatureConfig> {
private static final BlockPos POS = new BlockPos(4, 0, 15);
private static final Identifier[] VARIANTS = new Identifier[] {
new Identifier(UnicopiaCore.MODID, "ground/tower"),
new Identifier(UnicopiaCore.MODID, "ground/temple_with_book"),
new Identifier(UnicopiaCore.MODID, "ground/temple_without_book"),
new Identifier(UnicopiaCore.MODID, "ground/wizard_tower_red"),
new Identifier(UnicopiaCore.MODID, "ground/wizard_tower_blue")
};
private static final List<Biome> BIOMELIST = Arrays.<Biome>asList(
Biomes.TAIGA,
Biomes.TAIGA_HILLS,
Biomes.GIANT_TREE_TAIGA,
Biomes.GIANT_TREE_TAIGA_HILLS,
Biomes.SNOWY_TAIGA,
Biomes.SNOWY_TAIGA_HILLS,
Biomes.GIANT_SPRUCE_TAIGA,
Biomes.GIANT_TREE_TAIGA_HILLS,
Biomes.SNOWY_TAIGA_MOUNTAINS,
Biomes.DARK_FOREST,
Biomes.DARK_FOREST_HILLS
);
public RuinFeature(Function<Dynamic<?>, ? extends DefaultFeatureConfig> func) {
super(func);
}
@Override
public String getName() {
return "unicopia:ruins";
}
@Override
public int getRadius() {
return 12;
}
@Override
protected int getSeedModifier() {
return 39548;
}
@Override
protected boolean canSpawnInBiome(Biome biome) {
return BIOMELIST.contains(biome);
}
@Override
public StructureStartFactory getStructureStartFactory() {
return Start::new;
}
public static class Start extends StructureStart {
public Start(StructureFeature<?> feature, int x, int z, Biome biome, MutableIntBoundingBox bound, int var6, long var7) {
super(feature, x, z, biome, bound, var6, var7);
}
@Override
public void initialize(ChunkGenerator<?> generator, StructureManager manager, int x, int z, Biome biome) {
BlockRotation rotation = BlockRotation.values()[random.nextInt(BlockRotation.values().length)];
BlockPos pos = new BlockPos(x * 16, 150, z * 16);
Identifier template = VARIANTS[random.nextInt(VARIANTS.length) % VARIANTS.length];
children.add(new Piece(manager, template, pos, rotation));
setBoundingBoxFromChildren();
}
}
public static class Piece extends SimpleStructurePiece {
private final BlockRotation rotation;
private final Identifier template;
public Piece(StructureManager manager, Identifier template, BlockPos pos, BlockRotation rotation) {
super(UStructures.RUIN, 0);
this.pos = pos;
this.rotation = rotation;
this.template = template;
init(manager);
}
public Piece(StructureManager manager, CompoundTag tag) {
super(UStructures.RUIN, tag);
this.template = new Identifier(tag.getString("Template"));
this.rotation = BlockRotation.valueOf(tag.getString("Rot"));
init(manager);
}
@Override
protected void toNbt(CompoundTag compoundTag_1) {
super.toNbt(compoundTag_1);
compoundTag_1.putString("Template", template.toString());
compoundTag_1.putString("Rot", rotation.name());
}
private void init(StructureManager manager) {
setStructureData(manager.getStructureOrBlank(template), pos, new StructurePlacementData()
.setRotation(rotation)
.setMirrored(BlockMirror.NONE)
.setPosition(POS)
.addProcessor(BlockIgnoreStructureProcessor.IGNORE_AIR_AND_STRUCTURE_BLOCKS));
}
@Override
protected void handleMetadata(String var1, BlockPos var2, IWorld var3, Random var4, MutableIntBoundingBox var5) {
}
}
}

View file

@ -1,63 +0,0 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
public class StructuresGen extends AbstractFeaturesGen {
private static final List<Biome> BIOMELIST = Arrays.<Biome>asList(
Biomes.TAIGA,
Biomes.TAIGA_HILLS,
Biomes.EXTREME_HILLS_WITH_TREES,
Biomes.COLD_TAIGA,
Biomes.COLD_TAIGA_HILLS,
Biomes.MUTATED_TAIGA,
Biomes.MUTATED_TAIGA_COLD,
Biomes.MUTATED_EXTREME_HILLS_WITH_TREES,
Biomes.ROOFED_FOREST
);
public StructuresGen() {
super(8, 16);
}
@Override
public String getStructureName() {
return "unicopia:ruins";
}
@Override
protected int getRandomSeed() {
return 39548;
}
@Override
protected boolean canSpawnInBiome(Biome biome) {
return BIOMELIST.contains(biome);
}
@Override
protected StructureStart getStructureStart(int chunkX, int chunkZ) {
return new Start(world, rand, chunkX, chunkZ);
}
public static class Start extends AbstractFeature.Start {
public Start() {
}
public Start(World world, Random rand, int x, int z) {
super(world, rand, x, z);
}
@Override
protected void addComponents(World world, Random rand, int x, int z, Biome biome) {
components.add(new GroundDungeon(rand, x * 16, z * 16));
}
}
}

View file

@ -1,90 +0,0 @@
package com.minelittlepony.unicopia.redux.structure;
import java.util.Map;
import java.util.Random;
import javax.annotation.Nullable;
import java.util.Map.Entry;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityLockableLoot;
import net.minecraft.util.Identifier;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.StructureBoundingBox;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraft.world.gen.structure.template.Template;
import net.minecraft.world.gen.structure.template.TemplateManager;
import net.minecraft.world.storage.loot.LootTableList;
public abstract class TemplateBasedFeature extends AbstractFeature {
public TemplateBasedFeature() {}
protected TemplateBasedFeature(Random rand, int x, int y, int z, int sizeX, int sizeY, int sizeZ) {
super(rand, x, y, z, sizeX, sizeY, sizeX);
}
@Override
public boolean addComponentParts(World world, Random rand, StructureBoundingBox bounds) {
if (!tryFitTerrain(world, bounds, -1)) {
return false;
}
bounds = getBoundingBox();
BlockPos startPos = new BlockPos(bounds.minX, bounds.minY, bounds.minZ);
Rotation[] orientations = Rotation.values();
TemplateManager templates = world.getSaveHandler().getStructureTemplateManager();
PlacementSettings placement = new PlacementSettings()
.setRotation(orientations[rand.nextInt(orientations.length)])
.setReplacedBlock(Blocks.STRUCTURE_VOID)
.setBoundingBox(bounds);
return addComponentParts(world, startPos, templates, placement);
}
protected void applyTemplate(World world, BlockPos startPos, TemplateManager templates, PlacementSettings placement, Identifier templateId) {
Template template = templates.getTemplate(world.getMinecraftServer(), templateId);
template.addBlocksToWorldChunk(world, startPos, placement);
Map<BlockPos, String> map = template.getDataBlocks(startPos, placement);
for (Entry<BlockPos, String> entry : map.entrySet()) {
applyLootTables(world, entry.getKey(), entry.getValue());
}
}
protected void applyLootTables(World world, BlockPos pos, String blockId) {
Identifier lootTable = getLootTable(blockId);
if (lootTable != null) {
world.setBlockState(pos, Blocks.AIR.getDefaultState(), 3);
TileEntity tileentity = world.getTileEntity(pos.down());
if (tileentity instanceof TileEntityLockableLoot) {
((TileEntityLockableLoot)tileentity).setLootTable(lootTable, world.rand.nextLong());
}
}
}
@Nullable
protected Identifier getLootTable(String blockId) {
if ("chest".equals(blockId)) {
return LootTableList.CHESTS_STRONGHOLD_LIBRARY;
}
return null;
}
public abstract boolean addComponentParts(World world, BlockPos startPos, TemplateManager templates, PlacementSettings placement);
}

View file

@ -0,0 +1,20 @@
package com.minelittlepony.unicopia.redux.structure;
import com.minelittlepony.unicopia.core.UnicopiaCore;
import net.minecraft.structure.StructurePieceType;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public interface UStructures {
StructurePieceType CLOUD_HOUSE = register(CloudDungeonFeature.Piece::new, new Identifier(UnicopiaCore.MODID, "cloud_house"));
StructurePieceType RUIN = register(RuinFeature.Piece::new, new Identifier(UnicopiaCore.MODID, "ruin"));
static StructurePieceType register(StructurePieceType type, Identifier id) {
return Registry.register(Registry.STRUCTURE_PIECE, id, type);
}
static void bootstrap() {}
}