mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Re-added spellbooks
This commit is contained in:
parent
38e3693384
commit
48a45e6268
17 changed files with 498 additions and 5 deletions
|
@ -15,11 +15,12 @@ import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer;
|
import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.BatWingsFeatureRenderer;
|
import com.minelittlepony.unicopia.client.render.BatWingsFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
|
import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.ButterflyEntityRenderer;
|
|
||||||
import com.minelittlepony.unicopia.client.render.CastSpellEntityRenderer;
|
|
||||||
import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer;
|
import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.IcarusWingsFeatureRenderer;
|
import com.minelittlepony.unicopia.client.render.IcarusWingsFeatureRenderer;
|
||||||
import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer;
|
import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer;
|
||||||
|
import com.minelittlepony.unicopia.client.render.entity.ButterflyEntityRenderer;
|
||||||
|
import com.minelittlepony.unicopia.client.render.entity.CastSpellEntityRenderer;
|
||||||
|
import com.minelittlepony.unicopia.client.render.entity.SpellbookEntityRenderer;
|
||||||
import com.minelittlepony.unicopia.entity.UEntities;
|
import com.minelittlepony.unicopia.entity.UEntities;
|
||||||
import com.minelittlepony.unicopia.item.ChameleonItem;
|
import com.minelittlepony.unicopia.item.ChameleonItem;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||||
|
@ -69,6 +70,7 @@ public interface URenderers {
|
||||||
EntityRendererRegistry.INSTANCE.register(UEntities.BUTTERFLY, ButterflyEntityRenderer::new);
|
EntityRendererRegistry.INSTANCE.register(UEntities.BUTTERFLY, ButterflyEntityRenderer::new);
|
||||||
EntityRendererRegistry.INSTANCE.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new);
|
EntityRendererRegistry.INSTANCE.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new);
|
||||||
EntityRendererRegistry.INSTANCE.register(UEntities.CAST_SPELL, CastSpellEntityRenderer::new);
|
EntityRendererRegistry.INSTANCE.register(UEntities.CAST_SPELL, CastSpellEntityRenderer::new);
|
||||||
|
EntityRendererRegistry.INSTANCE.register(UEntities.SPELLBOOK, SpellbookEntityRenderer::new);
|
||||||
|
|
||||||
ColorProviderRegistry.ITEM.register((stack, i) -> i > 0 ? -1 : ((DyeableItem)stack.getItem()).getColor(stack), UItems.FRIENDSHIP_BRACELET);
|
ColorProviderRegistry.ITEM.register((stack, i) -> i > 0 ? -1 : ((DyeableItem)stack.getItem()).getColor(stack), UItems.FRIENDSHIP_BRACELET);
|
||||||
BuiltinItemRendererRegistry.INSTANCE.register(UItems.FILLED_JAR, (stack, mode, matrices, vertexConsumers, light, overlay) -> {
|
BuiltinItemRendererRegistry.INSTANCE.register(UItems.FILLED_JAR, (stack, mode, matrices, vertexConsumers, light, overlay) -> {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.client.render;
|
package com.minelittlepony.unicopia.client.render.entity;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||||
import com.minelittlepony.unicopia.entity.ButterflyEntity;
|
import com.minelittlepony.unicopia.entity.ButterflyEntity;
|
||||||
|
|
||||||
import net.minecraft.client.model.ModelData;
|
import net.minecraft.client.model.ModelData;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.minelittlepony.unicopia.client.render;
|
package com.minelittlepony.unicopia.client.render.entity;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.minelittlepony.unicopia.client.render.entity;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3f;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.SpellbookEntity;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||||
|
import net.minecraft.client.render.entity.LivingEntityRenderer;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class SpellbookEntityRenderer extends LivingEntityRenderer<SpellbookEntity, SpellbookModel> {
|
||||||
|
private static final Identifier BLUE = new Identifier("unicopia", "textures/entity/spellbook/blue.png");
|
||||||
|
private static final Identifier NORMAL = new Identifier("unicopia", "textures/entity/spellbook/normal.png");
|
||||||
|
|
||||||
|
public SpellbookEntityRenderer(EntityRendererFactory.Context context) {
|
||||||
|
super(context, new SpellbookModel(SpellbookModel.getTexturedModelData().createModel()), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier getTexture(SpellbookEntity entity) {
|
||||||
|
return entity.getIsAltered() ? BLUE : NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getLyingAngle(SpellbookEntity entity) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupTransforms(SpellbookEntity entity, MatrixStack matrices, float f, float g, float partialTicks) {
|
||||||
|
super.setupTransforms(entity, matrices, f, g + 90, partialTicks);
|
||||||
|
|
||||||
|
if (entity.getIsOpen()) {
|
||||||
|
matrices.translate(-1.25F, -0.35F, 0);
|
||||||
|
|
||||||
|
float floatPosition = MathHelper.sin((entity.age + partialTicks + entity.getId()) / 20) * 0.04F;
|
||||||
|
|
||||||
|
matrices.translate(0, floatPosition, 0);
|
||||||
|
matrices.multiply(Vec3f.NEGATIVE_Z.getDegreesQuaternion(60));
|
||||||
|
} else {
|
||||||
|
matrices.translate(-1.5F, 0.1F, 0.2F);
|
||||||
|
matrices.multiply(Vec3f.NEGATIVE_Z.getDegreesQuaternion(90));
|
||||||
|
matrices.multiply(Vec3f.NEGATIVE_Y.getDegreesQuaternion(90));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean hasLabel(SpellbookEntity targetEntity) {
|
||||||
|
return super.hasLabel(targetEntity)
|
||||||
|
&& (targetEntity.isCustomNameVisible()
|
||||||
|
|| targetEntity.hasCustomName()
|
||||||
|
&& targetEntity == dispatcher.targetedEntity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.minelittlepony.unicopia.client.render.entity;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.entity.SpellbookEntity;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.ModelPart;
|
||||||
|
import net.minecraft.client.model.TexturedModelData;
|
||||||
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
|
import net.minecraft.client.render.entity.model.BookModel;
|
||||||
|
import net.minecraft.client.render.entity.model.EntityModel;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
public class SpellbookModel extends EntityModel<SpellbookEntity> {
|
||||||
|
|
||||||
|
private final BookModel book;
|
||||||
|
|
||||||
|
public SpellbookModel(ModelPart root) {
|
||||||
|
book = new BookModel(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TexturedModelData getTexturedModelData() {
|
||||||
|
return BookModel.getTexturedModelData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, float blue, float alpha) {
|
||||||
|
book.render(matrices, vertexConsumer, light, overlay, red, green, blue, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setPageAngles(float breath, float leftPageRot, float rightPageRot, float openAngle) {
|
||||||
|
book.setPageAngles(breath, leftPageRot, rightPageRot, openAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAngles(SpellbookEntity entity, float limbAngle, float limbDistance, float customAngle, float headYaw, float headPitch) {
|
||||||
|
float breath = MathHelper.sin((entity.age + customAngle) / 20) * 0.01F + 0.1F;
|
||||||
|
|
||||||
|
float first_page_rot = limbDistance + (breath * 10);
|
||||||
|
float second_page_rot = 1 - first_page_rot;
|
||||||
|
float open_angle = 0.9f - limbDistance;
|
||||||
|
|
||||||
|
if (first_page_rot > 1) first_page_rot = 1;
|
||||||
|
if (second_page_rot > 1) second_page_rot = 1;
|
||||||
|
|
||||||
|
if (!entity.getIsOpen()) {
|
||||||
|
first_page_rot = second_page_rot = open_angle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
book.setPageAngles(breath, first_page_rot, second_page_rot, open_angle);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.minelittlepony.unicopia.container;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
|
||||||
|
public class SpellBookScreenHandler extends ScreenHandler {
|
||||||
|
|
||||||
|
protected SpellBookScreenHandler(int syncId, PlayerInventory inv) {
|
||||||
|
super(UScreenHandlers.SPELL_BOOK, syncId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUse(PlayerEntity player) {
|
||||||
|
return EquinePredicates.IS_CASTER.test(player);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.minelittlepony.unicopia.container;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
||||||
|
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry.SimpleClientHandlerFactory;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public interface UScreenHandlers {
|
||||||
|
ScreenHandlerType<SpellBookScreenHandler> SPELL_BOOK = register("spell_book", SpellBookScreenHandler::new);
|
||||||
|
|
||||||
|
static <T extends ScreenHandler> ScreenHandlerType<T> register(String name, SimpleClientHandlerFactory<T> factory) {
|
||||||
|
return ScreenHandlerRegistry.registerSimple(new Identifier("unicopia", name), factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bootstrap() { }
|
||||||
|
}
|
|
@ -0,0 +1,202 @@
|
||||||
|
package com.minelittlepony.unicopia.entity;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
|
import com.minelittlepony.unicopia.container.UScreenHandlers;
|
||||||
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
import net.minecraft.entity.data.DataTracker;
|
||||||
|
import net.minecraft.entity.data.TrackedData;
|
||||||
|
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
|
||||||
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.particle.ParticleTypes;
|
||||||
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
|
import net.minecraft.screen.SimpleNamedScreenHandlerFactory;
|
||||||
|
import net.minecraft.sound.BlockSoundGroup;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.GameRules;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class SpellbookEntity extends MobEntity {
|
||||||
|
private static final TrackedData<Boolean> OPENED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||||
|
private static final TrackedData<Boolean> ALTERED = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||||
|
private static final TrackedData<Byte> OPENED_USER = DataTracker.registerData(SpellbookEntity.class, TrackedDataHandlerRegistry.BYTE);
|
||||||
|
|
||||||
|
public SpellbookEntity(EntityType<SpellbookEntity> type, World world) {
|
||||||
|
super(type, world);
|
||||||
|
setPersistent();
|
||||||
|
|
||||||
|
if (world.random.nextInt(3) == 0) {
|
||||||
|
setAltered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initDataTracker() {
|
||||||
|
super.initDataTracker();
|
||||||
|
dataTracker.startTracking(OPENED, true);
|
||||||
|
dataTracker.startTracking(OPENED_USER, (byte)1);
|
||||||
|
dataTracker.startTracking(ALTERED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getPickBlockStack() {
|
||||||
|
return new ItemStack(UItems.SPELLBOOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPushable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doesRenderOnFire() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsAltered() {
|
||||||
|
return dataTracker.get(ALTERED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAltered() {
|
||||||
|
dataTracker.set(ALTERED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getIsOpen() {
|
||||||
|
return dataTracker.get(OPENED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getUserSetState() {
|
||||||
|
byte state = dataTracker.get(OPENED_USER);
|
||||||
|
return state == 1 ? null : state == 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsOpen(boolean val) {
|
||||||
|
dataTracker.set(OPENED, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserSetState(Boolean val) {
|
||||||
|
dataTracker.set(OPENED_USER, val == null ? (byte)1 : val == true ? (byte)2 : (byte)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
boolean open = getIsOpen();
|
||||||
|
jumping = open && isTouchingWater();
|
||||||
|
super.tick();
|
||||||
|
if (open && world.isClient) {
|
||||||
|
for (int offX = -2; offX <= 1; ++offX) {
|
||||||
|
for (int offZ = -2; offZ <= 1; ++offZ) {
|
||||||
|
if (offX > -1 && offX < 1 && offZ == -1) {
|
||||||
|
offZ = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (random.nextInt(320) == 0) {
|
||||||
|
for (int offY = 0; offY <= 1; ++offY) {
|
||||||
|
world.addParticle(ParticleTypes.ENCHANT,
|
||||||
|
getX(), getY(), getZ(),
|
||||||
|
offX/2F + random.nextFloat(),
|
||||||
|
offY/2F - random.nextFloat() + 0.5f,
|
||||||
|
offZ/2F + random.nextFloat()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (open) {
|
||||||
|
world.getOtherEntities(this, getBoundingBox().expand(2), EntityPredicates.EXCEPT_SPECTATOR.and(e -> e instanceof PlayerEntity)).stream().findFirst().ifPresent(player -> {
|
||||||
|
Vec3d diff = player.getPos().subtract(getPos());
|
||||||
|
double yaw = Math.atan2(diff.z, diff.x) * 180D / Math.PI - 90;
|
||||||
|
|
||||||
|
setHeadYaw((float)yaw);
|
||||||
|
setYaw((float)yaw);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world.random.nextInt(30) == 0) {
|
||||||
|
float celest = world.getSkyAngleRadians(1) * 4;
|
||||||
|
|
||||||
|
boolean isDay = celest > 3 || celest < 1;
|
||||||
|
|
||||||
|
Boolean userState = getUserSetState();
|
||||||
|
|
||||||
|
boolean canToggle = (isDay != open) && (userState == null || userState == isDay);
|
||||||
|
|
||||||
|
if (canToggle) {
|
||||||
|
setUserSetState(null);
|
||||||
|
setIsOpen(isDay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userState != null && (isDay == open) && (userState == open)) {
|
||||||
|
setUserSetState(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean damage(DamageSource source, float amount) {
|
||||||
|
if (!world.isClient) {
|
||||||
|
remove(Entity.RemovalReason.KILLED);
|
||||||
|
|
||||||
|
BlockSoundGroup sound = BlockSoundGroup.WOOD;
|
||||||
|
|
||||||
|
world.playSound(getX(), getY(), getZ(), sound.getBreakSound(), SoundCategory.BLOCKS, sound.getVolume(), sound.getPitch(), true);
|
||||||
|
|
||||||
|
if (world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) {
|
||||||
|
dropItem(UItems.SPELLBOOK, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult interactAt(PlayerEntity player, Vec3d vec, Hand hand) {
|
||||||
|
if (player.isSneaking()) {
|
||||||
|
boolean open = !getIsOpen();
|
||||||
|
|
||||||
|
setIsOpen(open);
|
||||||
|
setUserSetState(open);
|
||||||
|
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EquinePredicates.PLAYER_UNICORN.test(player)) {
|
||||||
|
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((syncId, inv, ply) -> UScreenHandlers.SPELL_BOOK.create(syncId, inv), getDisplayName()));
|
||||||
|
player.playSound(SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, 2, 1);
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActionResult.PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readCustomDataFromNbt(NbtCompound compound) {
|
||||||
|
super.readCustomDataFromNbt(compound);
|
||||||
|
|
||||||
|
setIsOpen(compound.getBoolean("open"));
|
||||||
|
setUserSetState(compound.contains("force_open") ? compound.getBoolean("force_open") : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeCustomDataToNbt(NbtCompound compound) {
|
||||||
|
super.writeCustomDataToNbt(compound);
|
||||||
|
compound.putBoolean("open", getIsOpen());
|
||||||
|
|
||||||
|
Boolean state = getUserSetState();
|
||||||
|
|
||||||
|
if (state != null) {
|
||||||
|
compound.putBoolean("force_open", state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,6 @@ import net.minecraft.world.biome.Biome.Category;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public interface UEntities {
|
public interface UEntities {
|
||||||
|
|
||||||
EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new)
|
EntityType<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new)
|
||||||
.dimensions(EntityDimensions.fixed(0.25F, 0.25F)));
|
.dimensions(EntityDimensions.fixed(0.25F, 0.25F)));
|
||||||
EntityType<MagicProjectileEntity> THROWN_ITEM = register("thrown_item", FabricEntityTypeBuilder.<MagicProjectileEntity>create(SpawnGroup.MISC, MagicProjectileEntity::new)
|
EntityType<MagicProjectileEntity> THROWN_ITEM = register("thrown_item", FabricEntityTypeBuilder.<MagicProjectileEntity>create(SpawnGroup.MISC, MagicProjectileEntity::new)
|
||||||
|
@ -33,6 +32,9 @@ public interface UEntities {
|
||||||
EntityType<CastSpellEntity> CAST_SPELL = register("cast_spell", FabricEntityTypeBuilder.create(SpawnGroup.MISC, CastSpellEntity::new)
|
EntityType<CastSpellEntity> CAST_SPELL = register("cast_spell", FabricEntityTypeBuilder.create(SpawnGroup.MISC, CastSpellEntity::new)
|
||||||
.trackRangeBlocks(200)
|
.trackRangeBlocks(200)
|
||||||
.dimensions(EntityDimensions.fixed(1, 1)));
|
.dimensions(EntityDimensions.fixed(1, 1)));
|
||||||
|
EntityType<SpellbookEntity> SPELLBOOK = register("spellbook", FabricEntityTypeBuilder.create(SpawnGroup.MISC, SpellbookEntity::new)
|
||||||
|
.trackRangeBlocks(200)
|
||||||
|
.dimensions(EntityDimensions.fixed(1, 1)));
|
||||||
|
|
||||||
static <T extends Entity> EntityType<T> register(String name, FabricEntityTypeBuilder<T> builder) {
|
static <T extends Entity> EntityType<T> register(String name, FabricEntityTypeBuilder<T> builder) {
|
||||||
EntityType<T> type = builder.build();
|
EntityType<T> type = builder.build();
|
||||||
|
@ -41,6 +43,7 @@ public interface UEntities {
|
||||||
|
|
||||||
static void bootstrap() {
|
static void bootstrap() {
|
||||||
FabricDefaultAttributeRegistry.register(BUTTERFLY, ButterflyEntity.createButterflyAttributes());
|
FabricDefaultAttributeRegistry.register(BUTTERFLY, ButterflyEntity.createButterflyAttributes());
|
||||||
|
FabricDefaultAttributeRegistry.register(SPELLBOOK, SpellbookEntity.createMobAttributes());
|
||||||
|
|
||||||
final Predicate<BiomeSelectionContext> butterflySpawnable = BiomeSelectors.foundInOverworld()
|
final Predicate<BiomeSelectionContext> butterflySpawnable = BiomeSelectors.foundInOverworld()
|
||||||
.and(ctx -> ctx.getBiome().getPrecipitation() == Biome.Precipitation.RAIN);
|
.and(ctx -> ctx.getBiome().getPrecipitation() == Biome.Precipitation.RAIN);
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
|
import com.minelittlepony.unicopia.entity.SpellbookEntity;
|
||||||
|
import com.minelittlepony.unicopia.entity.UEntities;
|
||||||
|
import com.minelittlepony.unicopia.util.Dispensable;
|
||||||
|
|
||||||
|
import net.minecraft.block.DispenserBlock;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.BookItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemUsageContext;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
import net.minecraft.util.math.BlockPointer;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class SpellbookItem extends BookItem implements Dispensable {
|
||||||
|
public SpellbookItem(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
DispenserBlock.registerBehavior(this, createDispenserBehaviour());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypedActionResult<ItemStack> dispenseStack(BlockPointer source, ItemStack stack) {
|
||||||
|
Direction facing = source.getBlockState().get(DispenserBlock.FACING);
|
||||||
|
BlockPos pos = source.getBlockPos().offset(facing);
|
||||||
|
|
||||||
|
float yaw = facing.getOpposite().asRotation();
|
||||||
|
placeBook(source.getWorld(), pos.getX(), pos.getY(), pos.getZ(), yaw);
|
||||||
|
stack.decrement(1);
|
||||||
|
|
||||||
|
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult useOnBlock(ItemUsageContext context) {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
PlayerEntity player = context.getPlayer();
|
||||||
|
|
||||||
|
if (!context.getWorld().isClient && EquinePredicates.PLAYER_UNICORN.test(player)) {
|
||||||
|
BlockPos pos = context.getBlockPos().offset(context.getSide());
|
||||||
|
|
||||||
|
placeBook(context.getWorld(), pos.getX(), pos.getY(), pos.getZ(), context.getPlayerYaw() + 180);
|
||||||
|
|
||||||
|
if (!player.getAbilities().creativeMode) {
|
||||||
|
player.getStackInHand(context.getHand()).decrement(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
return ActionResult.PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void placeBook(World world, int x, int y, int z, float yaw) {
|
||||||
|
SpellbookEntity book = UEntities.SPELLBOOK.create(world);
|
||||||
|
|
||||||
|
book.refreshPositionAndAngles(x + 0.5, y, z + 0.5, 0, 0);
|
||||||
|
book.setHeadYaw(yaw);
|
||||||
|
book.setYaw(yaw);
|
||||||
|
world.spawnEntity(book);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ public interface UItems {
|
||||||
Item BUTTERFLY_SPAWN_EGG = register("butterfly_spawn_egg", new SpawnEggItem(UEntities.BUTTERFLY, 0x222200, 0xaaeeff, new Item.Settings().group(ItemGroup.MISC)));
|
Item BUTTERFLY_SPAWN_EGG = register("butterfly_spawn_egg", new SpawnEggItem(UEntities.BUTTERFLY, 0x222200, 0xaaeeff, new Item.Settings().group(ItemGroup.MISC)));
|
||||||
Item BUTTERFLY = register("butterfly", new Item(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.INSECTS)));
|
Item BUTTERFLY = register("butterfly", new Item(new Item.Settings().group(ItemGroup.FOOD).food(UFoodComponents.INSECTS)));
|
||||||
|
|
||||||
|
Item SPELLBOOK = register("spellbook", new SpellbookItem(new Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON).group(ItemGroup.TOOLS)));
|
||||||
|
|
||||||
AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new AmuletItem(new FabricItemSettings()
|
AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new AmuletItem(new FabricItemSettings()
|
||||||
.maxCount(1)
|
.maxCount(1)
|
||||||
.maxDamage(890)
|
.maxDamage(890)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.minelittlepony.unicopia.util;
|
||||||
|
|
||||||
|
import net.minecraft.block.dispenser.DispenserBehavior;
|
||||||
|
import net.minecraft.block.dispenser.ItemDispenserBehavior;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
import net.minecraft.util.math.BlockPointer;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
|
||||||
|
public interface Dispensable {
|
||||||
|
default DispenserBehavior createDispenserBehaviour() {
|
||||||
|
return new ItemDispenserBehavior() {
|
||||||
|
private ActionResult result;
|
||||||
|
@Override
|
||||||
|
protected ItemStack dispenseSilently(BlockPointer source, ItemStack stack) {
|
||||||
|
TypedActionResult<ItemStack> result = dispenseStack(source, stack);
|
||||||
|
this.result = result.getResult();
|
||||||
|
|
||||||
|
if (!this.result.isAccepted()) {
|
||||||
|
return super.dispenseSilently(source, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void playSound(BlockPointer pointer) {
|
||||||
|
if (!result.isAccepted()) {
|
||||||
|
super.playSound(pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void spawnParticles(BlockPointer pointer, Direction side) {
|
||||||
|
if (!result.isAccepted()) {
|
||||||
|
super.spawnParticles(pointer, side);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to dispense this stack.
|
||||||
|
*/
|
||||||
|
TypedActionResult<ItemStack> dispenseStack(BlockPointer source, ItemStack stack);
|
||||||
|
}
|
|
@ -15,6 +15,8 @@
|
||||||
"item.unicopia.friendship_bracelet.issuer": "Signed by %s",
|
"item.unicopia.friendship_bracelet.issuer": "Signed by %s",
|
||||||
"item.unicopia.friendship_bracelet.glowing": "Glowing",
|
"item.unicopia.friendship_bracelet.glowing": "Glowing",
|
||||||
|
|
||||||
|
"item.unicopia.spellbook": "Spellbook",
|
||||||
|
|
||||||
"item.unicopia.butterfly_spawn_egg": "Butterfly Spawn Egg",
|
"item.unicopia.butterfly_spawn_egg": "Butterfly Spawn Egg",
|
||||||
"item.unicopia.butterfly": "Butterfly",
|
"item.unicopia.butterfly": "Butterfly",
|
||||||
|
|
||||||
|
@ -79,6 +81,7 @@
|
||||||
"entity.unicopia.butterfly": "Butterfly",
|
"entity.unicopia.butterfly": "Butterfly",
|
||||||
"entity.unicopia.cast_spell": "Cast Spell",
|
"entity.unicopia.cast_spell": "Cast Spell",
|
||||||
"entity.unicopia.cast_spell.by": "a spell cast by %s",
|
"entity.unicopia.cast_spell.by": "a spell cast by %s",
|
||||||
|
"entity.unicopia.spellbook": "Spellbook",
|
||||||
|
|
||||||
"unicopia.effect.tribe.stage.initial": "It appears to have no effect.",
|
"unicopia.effect.tribe.stage.initial": "It appears to have no effect.",
|
||||||
"unicopia.effect.tribe.stage.crawling": "You feel the skin crawling on your back.",
|
"unicopia.effect.tribe.stage.crawling": "You feel the skin crawling on your back.",
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/spellbook"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 471 B |
Binary file not shown.
After Width: | Height: | Size: 1,015 B |
BIN
src/main/resources/assets/unicopia/textures/item/spellbook.png
Normal file
BIN
src/main/resources/assets/unicopia/textures/item/spellbook.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
Loading…
Reference in a new issue