Added custom elytra support (#6791)

This commit is contained in:
brandon3055 authored and GitHub committed 2020-09-08 12:07:54 -07:00
1 parent 5224533d45
commit a753a3eddc
12 files changed
+309 -9

No files matched your search

@@ -46,6 +46,15 @@
}
boolean flag4 = (float)this.func_71024_bL().func_75116_a() > 6.0F || this.field_71075_bZ.field_75101_c;
@@ -667,7 +675,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));
}
}
@@ -961,4 +969,16 @@
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;
+ }
}
@@ -367,7 +367,16 @@
if (!itemstack.func_190926_b()) {
this.func_110140_aT().func_111148_a(itemstack.func_111283_C(equipmentslottype));
}
@@ -2474,13 +2518,22 @@
@@ -2258,6 +2302,8 @@
boolean flag = this.func_70083_f(7);
if (flag && !this.field_70122_E && !this.func_184218_aH()) {
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) {
@@ -2474,13 +2520,22 @@
private void func_184608_ct() {
if (this.func_184587_cr()) {
@@ -392,7 +401,7 @@
this.func_71036_o();
}
} else {
@@ -2522,8 +2575,10 @@
@@ -2522,8 +2577,10 @@
public void func_184598_c(Hand p_184598_1_) {
ItemStack itemstack = this.func_184586_b(p_184598_1_);
if (!itemstack.func_190926_b() && !this.func_184587_cr()) {
@@ -404,7 +413,7 @@
if (!this.field_70170_p.field_72995_K) {
this.func_204802_c(1, true);
this.func_204802_c(2, p_184598_1_ == Hand.OFF_HAND);
@@ -2583,6 +2638,9 @@
@@ -2583,6 +2640,9 @@
vec3d1 = vec3d1.func_178789_a(-this.field_70125_A * ((float)Math.PI / 180F));
vec3d1 = vec3d1.func_178785_b(-this.field_70177_z * ((float)Math.PI / 180F));
vec3d1 = vec3d1.func_72441_c(this.func_226277_ct_(), this.func_226280_cw_(), this.func_226281_cx_());
@@ -414,7 +423,7 @@
this.field_70170_p.func_195594_a(new ItemParticleData(ParticleTypes.field_197591_B, p_195062_1_), vec3d1.field_72450_a, vec3d1.field_72448_b, vec3d1.field_72449_c, vec3d.field_72450_a, vec3d.field_72448_b + 0.05D, vec3d.field_72449_c);
}
@@ -2594,7 +2652,9 @@
@@ -2594,7 +2654,9 @@
} else {
if (!this.field_184627_bm.func_190926_b() && this.func_184587_cr()) {
this.func_226293_b_(this.field_184627_bm, 16);
@@ -425,7 +434,7 @@
this.func_184602_cy();
}
@@ -2615,7 +2675,11 @@
@@ -2615,7 +2677,11 @@
public void func_184597_cx() {
if (!this.field_184627_bm.func_190926_b()) {
@@ -437,7 +446,7 @@
if (this.field_184627_bm.func_222122_m()) {
this.func_184608_ct();
}
@@ -2772,16 +2836,16 @@
@@ -2772,16 +2838,16 @@
private boolean func_213359_p() {
return this.func_213374_dv().map((p_213347_1_) -> {
@@ -458,7 +467,7 @@
BlockPos blockpos = p_213368_1_.func_177984_a();
return new Vec3d((double)blockpos.func_177958_n() + 0.5D, (double)blockpos.func_177956_o() + 0.1D, (double)blockpos.func_177952_p() + 0.5D);
});
@@ -2797,7 +2861,9 @@
@@ -2797,7 +2863,9 @@
@OnlyIn(Dist.CLIENT)
public Direction func_213376_dz() {
BlockPos blockpos = this.func_213374_dv().orElse((BlockPos)null);
@@ -469,7 +478,7 @@
}
public boolean func_70094_T() {
@@ -2866,4 +2932,58 @@
@@ -2866,4 +2934,58 @@
public void func_213334_d(Hand p_213334_1_) {
this.func_213361_c(p_213334_1_ == Hand.MAIN_HAND ? EquipmentSlotType.MAINHAND : EquipmentSlotType.OFFHAND);
}
@@ -415,6 +415,15 @@
return false;
} else {
if (p_225503_1_ >= 2.0F) {
@@ -1519,7 +1636,7 @@
public boolean func_226566_ei_() {
if (!this.field_70122_E && !this.func_184613_cA() && !this.func_70090_H()) {
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;
}
@@ -1560,6 +1677,10 @@
}
@@ -0,0 +1,20 @@
--- a/net/minecraft/item/ElytraItem.java
+++ b/net/minecraft/item/ElytraItem.java
@@ -38,4 +38,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;
+ }
}
@@ -784,4 +784,35 @@ public interface IForgeItem
default <T extends LivingEntity> int damageItem(ItemStack stack, int amount, T entity, Consumer<T> onBroken) {
return amount;
}
/**
* 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;
}
}
@@ -448,4 +448,32 @@ public interface IForgeItemStack extends ICapabilitySerializable<CompoundNBT>
{
return getStack().getItem().isRepairable(getStack());
}
/**
* 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;
}
}
}
+3 -1
View File
@@ -69,4 +69,6 @@ loaderVersion="[28,)"
[[mods]]
modId="deferred_registry_test"
[[mods]]
modId="player_name_event_test"
modId="player_name_event_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.0 KiB