Add support for custom elytra (#7202)
This commit is contained in:
parent
20702456ac
commit
399bc6c9c3
12 changed files with 307 additions and 9 deletions
|
@ -46,6 +46,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag1) {
|
if (flag1) {
|
||||||
|
@@ -689,7 +697,7 @@
|
||||||
|
|
||||||
|
if (this.field_71158_b.field_78901_c && !flag7 && !flag && !this.field_71075_bZ.field_75100_b && !this.func_184218_aH() && !this.func_70617_f_()) {
|
||||||
|
ItemStack itemstack = this.func_184582_a(EquipmentSlotType.CHEST);
|
||||||
|
- if (itemstack.func_77973_b() == Items.field_185160_cR && ElytraItem.func_185069_d(itemstack) && this.func_226566_ei_()) {
|
||||||
|
+ if (itemstack.canElytraFly(this) && this.func_226566_ei_()) {
|
||||||
|
this.field_71174_a.func_147297_a(new CEntityActionPacket(this, CEntityActionPacket.Action.START_FALL_FLYING));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -985,4 +993,16 @@
|
@@ -985,4 +993,16 @@
|
||||||
return this.field_204230_bP;
|
return this.field_204230_bP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
--- a/net/minecraft/client/renderer/entity/layers/ElytraLayer.java
|
||||||
|
+++ b/net/minecraft/client/renderer/entity/layers/ElytraLayer.java
|
||||||
|
@@ -29,7 +29,7 @@
|
||||||
|
|
||||||
|
public void func_225628_a_(MatrixStack p_225628_1_, IRenderTypeBuffer p_225628_2_, int p_225628_3_, T p_225628_4_, float p_225628_5_, float p_225628_6_, float p_225628_7_, float p_225628_8_, float p_225628_9_, float p_225628_10_) {
|
||||||
|
ItemStack itemstack = p_225628_4_.func_184582_a(EquipmentSlotType.CHEST);
|
||||||
|
- if (itemstack.func_77973_b() == Items.field_185160_cR) {
|
||||||
|
+ if (shouldRender(itemstack, p_225628_4_)) {
|
||||||
|
ResourceLocation resourcelocation;
|
||||||
|
if (p_225628_4_ instanceof AbstractClientPlayerEntity) {
|
||||||
|
AbstractClientPlayerEntity abstractclientplayerentity = (AbstractClientPlayerEntity)p_225628_4_;
|
||||||
|
@@ -38,10 +38,10 @@
|
||||||
|
} else if (abstractclientplayerentity.func_152122_n() && abstractclientplayerentity.func_110303_q() != null && abstractclientplayerentity.func_175148_a(PlayerModelPart.CAPE)) {
|
||||||
|
resourcelocation = abstractclientplayerentity.func_110303_q();
|
||||||
|
} else {
|
||||||
|
- resourcelocation = field_188355_a;
|
||||||
|
+ resourcelocation = getElytraTexture(itemstack, p_225628_4_);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- resourcelocation = field_188355_a;
|
||||||
|
+ resourcelocation = getElytraTexture(itemstack, p_225628_4_);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_225628_1_.func_227860_a_();
|
||||||
|
@@ -53,4 +53,29 @@
|
||||||
|
p_225628_1_.func_227865_b_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Determines if the ElytraLayer should render.
|
||||||
|
+ * ItemStack and Entity are provided for modder convenience,
|
||||||
|
+ * For example, using the same ElytraLayer for multiple custom Elytra.
|
||||||
|
+ *
|
||||||
|
+ * @param stack The Elytra ItemStack
|
||||||
|
+ * @param entity The entity being rendered.
|
||||||
|
+ * @return If the ElytraLayer should render.
|
||||||
|
+ */
|
||||||
|
+ public boolean shouldRender(ItemStack stack, T entity) {
|
||||||
|
+ return stack.func_77973_b() == Items.field_185160_cR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the texture to use with this ElytraLayer.
|
||||||
|
+ * This assumes the vanilla Elytra model.
|
||||||
|
+ *
|
||||||
|
+ * @param stack The Elytra ItemStack.
|
||||||
|
+ * @param entity The entity being rendered.
|
||||||
|
+ * @return The texture.
|
||||||
|
+ */
|
||||||
|
+ public ResourceLocation getElytraTexture(ItemStack stack, T entity) {
|
||||||
|
+ return field_188355_a;
|
||||||
|
+ }
|
||||||
|
}
|
|
@ -360,7 +360,16 @@
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
map = Maps.newEnumMap(EquipmentSlotType.class);
|
map = Maps.newEnumMap(EquipmentSlotType.class);
|
||||||
}
|
}
|
||||||
@@ -2658,8 +2693,16 @@
|
@@ -2434,6 +2469,8 @@
|
||||||
|
boolean flag = this.func_70083_f(7);
|
||||||
|
if (flag && !this.field_70122_E && !this.func_184218_aH() && !this.func_70644_a(Effects.field_188424_y)) {
|
||||||
|
ItemStack itemstack = this.func_184582_a(EquipmentSlotType.CHEST);
|
||||||
|
+ flag = itemstack.canElytraFly(this) && itemstack.elytraFlightTick(this, this.field_184629_bo);
|
||||||
|
+ if (false) //Forge: Moved to ElytraItem
|
||||||
|
if (itemstack.func_77973_b() == Items.field_185160_cR && ElytraItem.func_185069_d(itemstack)) {
|
||||||
|
flag = true;
|
||||||
|
if (!this.field_70170_p.field_72995_K && (this.field_184629_bo + 1) % 20 == 0) {
|
||||||
|
@@ -2658,8 +2695,16 @@
|
||||||
|
|
||||||
private void func_184608_ct() {
|
private void func_184608_ct() {
|
||||||
if (this.func_184587_cr()) {
|
if (this.func_184587_cr()) {
|
||||||
|
@ -379,7 +388,7 @@
|
||||||
this.field_184627_bm.func_222121_b(this.field_70170_p, this, this.func_184605_cv());
|
this.field_184627_bm.func_222121_b(this.field_70170_p, this, this.func_184605_cv());
|
||||||
if (this.func_226299_p_()) {
|
if (this.func_226299_p_()) {
|
||||||
this.func_226293_b_(this.field_184627_bm, 5);
|
this.func_226293_b_(this.field_184627_bm, 5);
|
||||||
@@ -2707,8 +2750,10 @@
|
@@ -2707,8 +2752,10 @@
|
||||||
public void func_184598_c(Hand p_184598_1_) {
|
public void func_184598_c(Hand p_184598_1_) {
|
||||||
ItemStack itemstack = this.func_184586_b(p_184598_1_);
|
ItemStack itemstack = this.func_184586_b(p_184598_1_);
|
||||||
if (!itemstack.func_190926_b() && !this.func_184587_cr()) {
|
if (!itemstack.func_190926_b() && !this.func_184587_cr()) {
|
||||||
|
@ -391,7 +400,7 @@
|
||||||
if (!this.field_70170_p.field_72995_K) {
|
if (!this.field_70170_p.field_72995_K) {
|
||||||
this.func_204802_c(1, true);
|
this.func_204802_c(1, true);
|
||||||
this.func_204802_c(2, p_184598_1_ == Hand.OFF_HAND);
|
this.func_204802_c(2, p_184598_1_ == Hand.OFF_HAND);
|
||||||
@@ -2768,6 +2813,9 @@
|
@@ -2768,6 +2815,9 @@
|
||||||
vector3d1 = vector3d1.func_178789_a(-this.field_70125_A * ((float)Math.PI / 180F));
|
vector3d1 = vector3d1.func_178789_a(-this.field_70125_A * ((float)Math.PI / 180F));
|
||||||
vector3d1 = vector3d1.func_178785_b(-this.field_70177_z * ((float)Math.PI / 180F));
|
vector3d1 = vector3d1.func_178785_b(-this.field_70177_z * ((float)Math.PI / 180F));
|
||||||
vector3d1 = vector3d1.func_72441_c(this.func_226277_ct_(), this.func_226280_cw_(), this.func_226281_cx_());
|
vector3d1 = vector3d1.func_72441_c(this.func_226277_ct_(), this.func_226280_cw_(), this.func_226281_cx_());
|
||||||
|
@ -401,7 +410,7 @@
|
||||||
this.field_70170_p.func_195594_a(new ItemParticleData(ParticleTypes.field_197591_B, p_195062_1_), vector3d1.field_72450_a, vector3d1.field_72448_b, vector3d1.field_72449_c, vector3d.field_72450_a, vector3d.field_72448_b + 0.05D, vector3d.field_72449_c);
|
this.field_70170_p.func_195594_a(new ItemParticleData(ParticleTypes.field_197591_B, p_195062_1_), vector3d1.field_72450_a, vector3d1.field_72448_b, vector3d1.field_72449_c, vector3d.field_72450_a, vector3d.field_72448_b + 0.05D, vector3d.field_72449_c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2779,7 +2827,9 @@
|
@@ -2779,7 +2829,9 @@
|
||||||
} else {
|
} else {
|
||||||
if (!this.field_184627_bm.func_190926_b() && this.func_184587_cr()) {
|
if (!this.field_184627_bm.func_190926_b() && this.func_184587_cr()) {
|
||||||
this.func_226293_b_(this.field_184627_bm, 16);
|
this.func_226293_b_(this.field_184627_bm, 16);
|
||||||
|
@ -412,7 +421,7 @@
|
||||||
this.func_184602_cy();
|
this.func_184602_cy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2800,7 +2850,11 @@
|
@@ -2800,7 +2852,11 @@
|
||||||
|
|
||||||
public void func_184597_cx() {
|
public void func_184597_cx() {
|
||||||
if (!this.field_184627_bm.func_190926_b()) {
|
if (!this.field_184627_bm.func_190926_b()) {
|
||||||
|
@ -424,7 +433,7 @@
|
||||||
if (this.field_184627_bm.func_222122_m()) {
|
if (this.field_184627_bm.func_222122_m()) {
|
||||||
this.func_184608_ct();
|
this.func_184608_ct();
|
||||||
}
|
}
|
||||||
@@ -2949,8 +3003,8 @@
|
@@ -2949,8 +3005,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockState blockstate = this.field_70170_p.func_180495_p(p_213342_1_);
|
BlockState blockstate = this.field_70170_p.func_180495_p(p_213342_1_);
|
||||||
|
@ -435,7 +444,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.func_213301_b(Pose.SLEEPING);
|
this.func_213301_b(Pose.SLEEPING);
|
||||||
@@ -2966,15 +3020,15 @@
|
@@ -2966,15 +3022,15 @@
|
||||||
|
|
||||||
private boolean func_213359_p() {
|
private boolean func_213359_p() {
|
||||||
return this.func_213374_dv().map((p_241350_1_) -> {
|
return this.func_213374_dv().map((p_241350_1_) -> {
|
||||||
|
@ -454,7 +463,7 @@
|
||||||
Vector3d vector3d1 = BedBlock.func_220172_a(this.func_200600_R(), this.field_70170_p, p_241348_1_, 0).orElseGet(() -> {
|
Vector3d vector3d1 = BedBlock.func_220172_a(this.func_200600_R(), this.field_70170_p, p_241348_1_, 0).orElseGet(() -> {
|
||||||
BlockPos blockpos = p_241348_1_.func_177984_a();
|
BlockPos blockpos = p_241348_1_.func_177984_a();
|
||||||
return new Vector3d((double)blockpos.func_177958_n() + 0.5D, (double)blockpos.func_177956_o() + 0.1D, (double)blockpos.func_177952_p() + 0.5D);
|
return new Vector3d((double)blockpos.func_177958_n() + 0.5D, (double)blockpos.func_177956_o() + 0.1D, (double)blockpos.func_177952_p() + 0.5D);
|
||||||
@@ -2993,7 +3047,9 @@
|
@@ -2993,7 +3049,9 @@
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public Direction func_213376_dz() {
|
public Direction func_213376_dz() {
|
||||||
BlockPos blockpos = this.func_213374_dv().orElse((BlockPos)null);
|
BlockPos blockpos = this.func_213374_dv().orElse((BlockPos)null);
|
||||||
|
@ -465,7 +474,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean func_70094_T() {
|
public boolean func_70094_T() {
|
||||||
@@ -3062,4 +3118,58 @@
|
@@ -3062,4 +3120,58 @@
|
||||||
public void func_213334_d(Hand p_213334_1_) {
|
public void func_213334_d(Hand p_213334_1_) {
|
||||||
this.func_213361_c(p_213334_1_ == Hand.MAIN_HAND ? EquipmentSlotType.MAINHAND : EquipmentSlotType.OFFHAND);
|
this.func_213361_c(p_213334_1_ == Hand.MAIN_HAND ? EquipmentSlotType.MAINHAND : EquipmentSlotType.OFFHAND);
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,15 @@
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (p_225503_1_ >= 2.0F) {
|
if (p_225503_1_ >= 2.0F) {
|
||||||
|
@@ -1434,7 +1467,7 @@
|
||||||
|
public boolean func_226566_ei_() {
|
||||||
|
if (!this.field_70122_E && !this.func_184613_cA() && !this.func_70090_H() && !this.func_70644_a(Effects.field_188424_y)) {
|
||||||
|
ItemStack itemstack = this.func_184582_a(EquipmentSlotType.CHEST);
|
||||||
|
- if (itemstack.func_77973_b() == Items.field_185160_cR && ElytraItem.func_185069_d(itemstack)) {
|
||||||
|
+ if (itemstack.canElytraFly(this)) {
|
||||||
|
this.func_226567_ej_();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -1475,6 +1508,10 @@
|
@@ -1475,6 +1508,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
patches/minecraft/net/minecraft/item/ElytraItem.java.patch
Normal file
20
patches/minecraft/net/minecraft/item/ElytraItem.java.patch
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
--- a/net/minecraft/item/ElytraItem.java
|
||||||
|
+++ b/net/minecraft/item/ElytraItem.java
|
||||||
|
@@ -35,4 +35,17 @@
|
||||||
|
return ActionResult.func_226251_d_(itemstack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean canElytraFly(ItemStack stack, net.minecraft.entity.LivingEntity entity) {
|
||||||
|
+ return ElytraItem.func_185069_d(stack);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean elytraFlightTick(ItemStack stack, net.minecraft.entity.LivingEntity entity, int flightTicks) {
|
||||||
|
+ if (!entity.field_70170_p.field_72995_K && (flightTicks + 1) % 20 == 0) {
|
||||||
|
+ stack.func_222118_a(1, entity, e -> e.func_213361_c(net.minecraft.inventory.EquipmentSlotType.CHEST));
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
}
|
|
@ -819,4 +819,33 @@ public interface IForgeItem
|
||||||
return stack.getItem() == Blocks.CARVED_PUMPKIN.asItem();
|
return stack.getItem() == Blocks.CARVED_PUMPKIN.asItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine if the player can use Elytra flight.
|
||||||
|
* This is called Client and Server side.
|
||||||
|
*
|
||||||
|
* @param stack The ItemStack in the Chest slot of the entity.
|
||||||
|
* @param entity The entity trying to fly.
|
||||||
|
* @return True if the entity can use Elytra flight.
|
||||||
|
*/
|
||||||
|
default boolean canElytraFly(ItemStack stack, LivingEntity entity)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine if the player can continue Elytra flight,
|
||||||
|
* this is called each tick, and can be used to apply ItemStack damage,
|
||||||
|
* consume Energy, or what have you.
|
||||||
|
* For example the Vanilla implementation of this, applies damage to the
|
||||||
|
* ItemStack every 20 ticks.
|
||||||
|
*
|
||||||
|
* @param stack ItemStack in the Chest slot of the entity.
|
||||||
|
* @param entity The entity currently in Elytra flight.
|
||||||
|
* @param flightTicks The number of ticks the entity has been Elytra flying for.
|
||||||
|
* @return True if the entity should continue Elytra flight or False to stop.
|
||||||
|
*/
|
||||||
|
default boolean elytraFlightTick(ItemStack stack, LivingEntity entity, int flightTicks)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,4 +476,32 @@ public interface IForgeItemStack extends ICapabilitySerializable<CompoundNBT>
|
||||||
{
|
{
|
||||||
return getStack().getItem().isEnderMask(getStack(), player, endermanEntity);
|
return getStack().getItem().isEnderMask(getStack(), player, endermanEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine if the player can use Elytra flight.
|
||||||
|
* This is called Client and Server side.
|
||||||
|
*
|
||||||
|
* @param entity The entity trying to fly.
|
||||||
|
* @return True if the entity can use Elytra flight.
|
||||||
|
*/
|
||||||
|
default boolean canElytraFly(LivingEntity entity)
|
||||||
|
{
|
||||||
|
return getStack().getItem().canElytraFly(getStack(), entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine if the player can continue Elytra flight,
|
||||||
|
* this is called each tick, and can be used to apply ItemStack damage,
|
||||||
|
* consume Energy, or what have you.
|
||||||
|
* For example the Vanilla implementation of this, applies damage to the
|
||||||
|
* ItemStack every 20 ticks.
|
||||||
|
*
|
||||||
|
* @param entity The entity currently in Elytra flight.
|
||||||
|
* @param flightTicks The number of ticks the entity has been Elytra flying for.
|
||||||
|
* @return True if the entity should continue Elytra flight or False to stop.
|
||||||
|
*/
|
||||||
|
default boolean elytraFlightTick(LivingEntity entity, int flightTicks)
|
||||||
|
{
|
||||||
|
return getStack().getItem().elytraFlightTick(getStack(), entity, flightTicks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016-2019.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.debug.item;
|
||||||
|
|
||||||
|
import net.minecraft.block.DispenserBlock;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
|
||||||
|
import net.minecraft.client.renderer.entity.IEntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.PlayerRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.layers.ElytraLayer;
|
||||||
|
import net.minecraft.client.renderer.entity.model.ElytraModel;
|
||||||
|
import net.minecraft.client.renderer.entity.model.PlayerModel;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.*;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.SoundEvent;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.RegistryObject;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.thread.EffectiveSide;
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
import net.minecraftforge.registries.DeferredRegister;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@Mod(CustomElytraTest.MOD_ID)
|
||||||
|
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = CustomElytraTest.MOD_ID)
|
||||||
|
public class CustomElytraTest
|
||||||
|
{
|
||||||
|
public static final String MOD_ID = "custom_elytra_test";
|
||||||
|
private static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID);
|
||||||
|
private static final RegistryObject<Item> TEST_ELYTRA = ITEMS.register("test_elytra",() -> new CustomElytra(new Item.Properties().maxDamage(100).group(ItemGroup.MISC)));
|
||||||
|
|
||||||
|
public CustomElytraTest()
|
||||||
|
{
|
||||||
|
final IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||||
|
ITEMS.register(modBus);
|
||||||
|
modBus.addListener(this::onClientSetup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onClientSetup(FMLClientSetupEvent event)
|
||||||
|
{
|
||||||
|
registerElytraLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private void registerElytraLayer()
|
||||||
|
{
|
||||||
|
Minecraft.getInstance().getRenderManager().getSkinMap().values().forEach(player -> player.addLayer(new CustomElytraLayer(player)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CustomElytra extends Item
|
||||||
|
{
|
||||||
|
|
||||||
|
public CustomElytra(Properties properties)
|
||||||
|
{
|
||||||
|
super(properties);
|
||||||
|
DispenserBlock.registerDispenseBehavior(this, ArmorItem.DISPENSER_BEHAVIOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public EquipmentSlotType getEquipmentSlot(ItemStack stack)
|
||||||
|
{
|
||||||
|
return EquipmentSlotType.CHEST; //Or you could just extend ItemArmor
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canElytraFly(ItemStack stack, LivingEntity entity)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean elytraFlightTick(ItemStack stack, LivingEntity entity, int flightTicks)
|
||||||
|
{
|
||||||
|
//Adding 1 to ticksElytraFlying prevents damage on the very first tick.
|
||||||
|
if (!entity.world.isRemote && (flightTicks + 1) % 20 == 0)
|
||||||
|
{
|
||||||
|
stack.damageItem(1, entity, e -> e.sendBreakAnimation(EquipmentSlotType.CHEST));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static class CustomElytraLayer extends ElytraLayer<AbstractClientPlayerEntity, PlayerModel<AbstractClientPlayerEntity>>
|
||||||
|
{
|
||||||
|
private static final ResourceLocation TEXTURE_ELYTRA = new ResourceLocation(MOD_ID, "textures/entity/custom_elytra.png");
|
||||||
|
|
||||||
|
public CustomElytraLayer(IEntityRenderer<AbstractClientPlayerEntity, PlayerModel<AbstractClientPlayerEntity>> rendererIn)
|
||||||
|
{
|
||||||
|
super(rendererIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldRender(ItemStack stack, AbstractClientPlayerEntity entity)
|
||||||
|
{
|
||||||
|
return stack.getItem() == TEST_ELYTRA.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResourceLocation getElytraTexture(ItemStack stack, AbstractClientPlayerEntity entity)
|
||||||
|
{
|
||||||
|
return TEXTURE_ELYTRA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -76,3 +76,5 @@ license="LGPL v2.1"
|
||||||
modId="player_name_event_test"
|
modId="player_name_event_test"
|
||||||
[[mods]]
|
[[mods]]
|
||||||
modId="modded_overworld_biomes_test"
|
modId="modded_overworld_biomes_test"
|
||||||
|
[[mods]]
|
||||||
|
modId="custom_elytra_test"
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "custom_elytra_test:item/custom_elytra"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
Loading…
Reference in a new issue