Fix custom item entities not showing on the client

Fix crystal growth not syncing
This commit is contained in:
Sebastian Hartte
2020-06-13 20:25:00 +02:00
parent b9381fc2e1
commit 0db7e70722
19 changed files with 111 additions and 51 deletions
@@ -1,11 +1,19 @@
package appeng.bootstrap; package appeng.bootstrap;
import appeng.api.features.AEFeature; import appeng.api.features.AEFeature;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IEntityRegistrationComponent; import appeng.bootstrap.components.IEntityRegistrationComponent;
import appeng.core.AppEng; import appeng.core.AppEng;
import appeng.entity.EntityFloatingItem;
import appeng.entity.EntityTinyTNTPrimed;
import appeng.entity.RenderFloatingItem;
import appeng.entity.RenderTinyTNTPrimed;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityClassification; import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
@@ -27,7 +35,7 @@ public class EntityBuilder<T extends Entity> {
public EntityBuilder(FeatureFactory factory, String id, EntityType.IFactory<T> entityFactory, EntityClassification classification) { public EntityBuilder(FeatureFactory factory, String id, EntityType.IFactory<T> entityFactory, EntityClassification classification) {
this.factory = factory; this.factory = factory;
this.id = id; this.id = id;
this.builder = EntityType.Builder.<T>create(entityFactory, classification); this.builder = EntityType.Builder.create(entityFactory, classification);
} }
public EntityBuilder<T> features(AEFeature... features) { public EntityBuilder<T> features(AEFeature... features) {
@@ -46,10 +54,12 @@ public class EntityBuilder<T extends Entity> {
return this; return this;
} }
public void build() { public EntityType<T> build() {
EntityType<T> entityType = builder.build("appliedenergistics2:" + id);
entityType.setRegistryName(AppEng.MOD_ID, id);
factory.addBootstrapComponent((IEntityRegistrationComponent) r -> { factory.addBootstrapComponent((IEntityRegistrationComponent) r -> {
EntityType<T> entityType = builder.build("appliedenergistics2:" + id); r.register(entityType);
r.register( entityType.setRegistryName(AppEng.MOD_ID, id) );
}); });
return entityType;
} }
} }
+9 -8
View File
@@ -40,12 +40,15 @@ import appeng.core.features.registries.PartModels;
import appeng.core.stats.AdvancementTriggers; import appeng.core.stats.AdvancementTriggers;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.worlddata.WorldData; import appeng.core.worlddata.WorldData;
import appeng.entity.*;
import appeng.hooks.TickHandler; import appeng.hooks.TickHandler;
import appeng.parts.PartPlacement; import appeng.parts.PartPlacement;
import appeng.parts.automation.PlaneModelLoader; import appeng.parts.automation.PlaneModelLoader;
import appeng.server.ServerHelper; import appeng.server.ServerHelper;
import com.google.common.base.Stopwatch; import com.google.common.base.Stopwatch;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@@ -73,6 +76,7 @@ import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.CrashReportExtender; import net.minecraftforge.fml.CrashReportExtender;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.config.ModConfig;
@@ -180,14 +184,11 @@ public final class AppEng
((ClientHelper) proxy).clientInit(); ((ClientHelper) proxy).clientInit();
// Do not register the Fullbright hacks if Optifine is present or if the Forge lighting is disabled RenderingRegistry.registerEntityRenderingHandler(EntityTinyTNTPrimed.TYPE, RenderTinyTNTPrimed::new);
// FIXME if( !FMLClientHandler.instance().hasOptifine() && ForgeModContainer.forgeLightPipelineEnabled ) RenderingRegistry.registerEntityRenderingHandler(EntityFloatingItem.TYPE, RenderFloatingItem::new);
// FIXME { RenderingRegistry.registerEntityRenderingHandler(EntitySingularity.TYPE, m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer()));
// FIXME ModelLoaderRegistry.registerLoader( UVLModelLoader.INSTANCE ); RenderingRegistry.registerEntityRenderingHandler(EntityGrowingCrystal.TYPE, m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer()));
// FIXME } RenderingRegistry.registerEntityRenderingHandler(EntityChargedQuartz.TYPE, m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer()));
// FIXME RenderingRegistry.registerEntityRenderingHandler( EntityTinyTNTPrimed.class, manager -> new RenderTinyTNTPrimed( manager ) );
// FIXME RenderingRegistry.registerEntityRenderingHandler( EntityFloatingItem.class, manager -> new RenderFloatingItem( manager ) );
// TODO: Do not use the internal API // TODO: Do not use the internal API
final ApiDefinitions definitions = Api.INSTANCE.definitions(); final ApiDefinitions definitions = Api.INSTANCE.definitions();
+6 -1
View File
@@ -56,6 +56,7 @@ import appeng.core.features.registries.cell.CreativeCellHandler;
import appeng.core.stats.AdvancementTriggers; import appeng.core.stats.AdvancementTriggers;
import appeng.core.stats.AeStats; import appeng.core.stats.AeStats;
import appeng.core.stats.PartItemPredicate; import appeng.core.stats.PartItemPredicate;
import appeng.entity.EntityFloatingItem;
import appeng.fluids.client.gui.*; import appeng.fluids.client.gui.*;
import appeng.fluids.container.*; import appeng.fluids.container.*;
import appeng.fluids.registries.BasicFluidCellGuiHandler; import appeng.fluids.registries.BasicFluidCellGuiHandler;
@@ -76,6 +77,7 @@ import appeng.worldgen.MeteoriteWorldGen;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScreenManager; import net.minecraft.client.gui.ScreenManager;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.Item; import net.minecraft.item.Item;
@@ -527,9 +529,12 @@ final class Registration
CraftingHelper.register( FeaturesEnabled.Serializer.INSTANCE ); CraftingHelper.register( FeaturesEnabled.Serializer.INSTANCE );
} }
public void registerEntities( RegistryEvent.Register<EntityType<?>> event ) public void registerEntities( RegistryEvent.Register<EntityType<?>> event )
{ {
// Special case only used on the client-side
EntityFloatingItem.TYPE = EntityType.Builder.<EntityFloatingItem>create(EntityFloatingItem::new, EntityClassification.MISC)
.build("appliedenergistics2:floating_item");
final IForgeRegistry<EntityType<?>> registry = event.getRegistry(); final IForgeRegistry<EntityType<?>> registry = event.getRegistry();
// TODO: Do not use the internal API // TODO: Do not use the internal API
final ApiDefinitions definitions = Api.INSTANCE.definitions(); final ApiDefinitions definitions = Api.INSTANCE.definitions();
@@ -318,20 +318,17 @@ public final class ApiBlocks implements IBlocks
} ) } )
.build() ) .build() )
.build(); .build();
EntityTinyTNTPrimed.TYPE = registry.<EntityTinyTNTPrimed>entity("tiny_tnt_primed", EntityTinyTNTPrimed::new, EntityClassification.MISC)
.customize(p -> p.setTrackingRange(16)
.setUpdateInterval(4)
.setShouldReceiveVelocityUpdates(true))
.build();
this.tinyTNT = registry.block( "tiny_tnt", BlockTinyTNT::new ) this.tinyTNT = registry.block( "tiny_tnt", BlockTinyTNT::new )
.features( AEFeature.TINY_TNT ) .features( AEFeature.TINY_TNT )
.bootstrap( ( block, item ) -> (IInitComponent) () -> DispenserBlock.registerDispenseBehavior( item, .bootstrap( ( block, item ) -> (IInitComponent) () -> DispenserBlock.registerDispenseBehavior( item,
new DispenserBehaviorTinyTNT() ) ) new DispenserBehaviorTinyTNT() ) )
.bootstrap( ( block, item ) -> (IEntityRegistrationComponent) r ->
{
r.register(EntityType.Builder.<EntityTinyTNTPrimed>create(EntityTinyTNTPrimed::new, EntityClassification.MISC)
.setTrackingRange(16)
.setUpdateInterval(4)
.setShouldReceiveVelocityUpdates(true)
.build(AppEng.MOD_ID + ":tiny_tnt_primed")
.setRegistryName(AppEng.MOD_ID + ":tiny_tnt_primed")
);
} )
.build(); .build();
this.securityStation = registry.block( "security_station", BlockSecurityStation::new ) this.securityStation = registry.block( "security_station", BlockSecurityStation::new )
.features( AEFeature.SECURITY ) .features( AEFeature.SECURITY )
@@ -282,10 +282,8 @@ public final class ApiItems implements IItems
.features( AEFeature.CRYSTAL_SEEDS ) .features( AEFeature.CRYSTAL_SEEDS )
.build(); .build();
registry.<EntityGrowingCrystal>entity("growing_crystal", EntityGrowingCrystal::new, EntityClassification.MISC) EntityGrowingCrystal.TYPE = registry.<EntityGrowingCrystal>entity("growing_crystal", EntityGrowingCrystal::new, EntityClassification.MISC)
.customize(builder -> builder.setTrackingRange(16) .customize(builder -> builder.size(0.25F, 0.25F))
.setUpdateInterval(4)
.setShouldReceiveVelocityUpdates(true))
.build(); .build();
// rv1 // rv1
@@ -120,11 +120,11 @@ public final class ApiMaterials implements IMaterials
{ {
this.registry = registry; this.registry = registry;
registry.<EntitySingularity>entity("singularity", EntitySingularity::new, EntityClassification.MISC) EntitySingularity.TYPE = registry.<EntitySingularity>entity("singularity", EntitySingularity::new, EntityClassification.MISC)
.customize(builder -> builder.setTrackingRange(16).setUpdateInterval(4).setShouldReceiveVelocityUpdates(true)) .customize(builder -> builder.setTrackingRange(16).setUpdateInterval(4).setShouldReceiveVelocityUpdates(true))
.build(); .build();
registry.<EntityChargedQuartz>entity("charged_quartz", EntityChargedQuartz::new, EntityClassification.MISC) EntityChargedQuartz.TYPE = registry.<EntityChargedQuartz>entity("charged_quartz", EntityChargedQuartz::new, EntityClassification.MISC)
.customize(builder -> builder.setTrackingRange(16).setUpdateInterval(4).setShouldReceiveVelocityUpdates(true)) .customize(builder -> builder.setTrackingRange(16).setUpdateInterval(4).setShouldReceiveVelocityUpdates(true))
.build(); .build();
@@ -25,25 +25,38 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.IPacket;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;
public abstract class AEBaseEntityItem extends ItemEntity public abstract class AEBaseEntityItem extends ItemEntity
{ {
public AEBaseEntityItem( EntityType<? extends AEBaseEntityItem> entityType, final World world ) protected AEBaseEntityItem( EntityType<? extends AEBaseEntityItem> entityType, final World world )
{ {
super( entityType, world ); super( entityType, world );
} }
public AEBaseEntityItem( final World world, final double x, final double y, final double z, final ItemStack stack ) protected AEBaseEntityItem( EntityType<? extends AEBaseEntityItem> entityType, final World world, final double x, final double y, final double z, final ItemStack stack )
{ {
super( world, x, y, z, stack ); this(entityType, world);
this.setPosition(x, y, z);
this.rotationYaw = this.rand.nextFloat() * 360.0F;
this.setMotion(this.rand.nextDouble() * 0.2D - 0.1D, 0.2D, this.rand.nextDouble() * 0.2D - 0.1D);
this.setItem(stack);
this.lifespan = stack.getEntityLifespan(world);
} }
protected List<Entity> getCheckedEntitiesWithinAABBExcludingEntity( final AxisAlignedBB region ) protected List<Entity> getCheckedEntitiesWithinAABBExcludingEntity( final AxisAlignedBB region )
{ {
return this.world.getEntitiesWithinAABBExcludingEntity( this, region ); return this.world.getEntitiesWithinAABBExcludingEntity( this, region );
} }
@Override
public IPacket<?> createSpawnPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
} }
@@ -45,6 +45,8 @@ import appeng.util.Platform;
public final class EntityChargedQuartz extends AEBaseEntityItem public final class EntityChargedQuartz extends AEBaseEntityItem
{ {
public static EntityType<EntityChargedQuartz> TYPE;
private int delay = 0; private int delay = 0;
private int transformTime = 0; private int transformTime = 0;
@@ -54,7 +56,7 @@ public final class EntityChargedQuartz extends AEBaseEntityItem
public EntityChargedQuartz(final World w, final double x, final double y, final double z, final ItemStack is ) public EntityChargedQuartz(final World w, final double x, final double y, final double z, final ItemStack is )
{ {
super( w, x, y, z, is ); super( TYPE, w, x, y, z, is );
} }
@Override @Override
@@ -19,28 +19,33 @@
package appeng.entity; package appeng.entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
// This is not supposed to ever spawn on the server-side
public final class EntityFloatingItem extends ItemEntity public final class EntityFloatingItem extends AEBaseEntityItem
{ {
private final ICanDie parent; public static EntityType<EntityFloatingItem> TYPE;
private ICanDie parent;
private int superDeath = 0; private int superDeath = 0;
private float progress = 0; private float progress = 0;
public EntityFloatingItem( final ICanDie parent, final World world, final double x, final double y, final double z, final ItemStack stack ) public EntityFloatingItem(EntityType<? extends AEBaseEntityItem> entityType, World world) {
super(entityType, world);
}
public EntityFloatingItem(final ICanDie parent, final World world, final double x, final double y, final double z, final ItemStack stack )
{ {
super( world, x, y, z, stack ); super( TYPE, world, x, y, z, stack );
this.setMotion( 0, 0, 0 ); this.setMotion( 0, 0, 0 );
this.rotationYaw = 0; this.rotationYaw = 0;
this.parent = parent; this.parent = parent;
} }
// public boolean isEntityAlive()
@Override @Override
public void tick() public void tick()
{ {
@@ -39,9 +39,11 @@ import appeng.api.features.AEFeature;
import appeng.util.Platform; import appeng.util.Platform;
public final class EntityGrowingCrystal extends ItemEntity public final class EntityGrowingCrystal extends AEBaseEntityItem
{ {
public static EntityType<EntityGrowingCrystal> TYPE;
private int progress_1000 = 0; private int progress_1000 = 0;
public EntityGrowingCrystal(EntityType<? extends EntityGrowingCrystal> type, World world) { public EntityGrowingCrystal(EntityType<? extends EntityGrowingCrystal> type, World world) {
@@ -50,7 +52,7 @@ public final class EntityGrowingCrystal extends ItemEntity
public EntityGrowingCrystal(final World w, final double x, final double y, final double z, final ItemStack is ) public EntityGrowingCrystal(final World w, final double x, final double y, final double z, final ItemStack is )
{ {
super( w, x, y, z, is ); super( TYPE, w, x, y, z, is );
this.setNoDespawn(); this.setNoDespawn();
} }
@@ -143,7 +145,10 @@ public final class EntityGrowingCrystal extends ItemEntity
if( this.progress_1000 > 1000 ) if( this.progress_1000 > 1000 )
{ {
this.progress_1000 -= 1000; this.progress_1000 -= 1000;
this.setItem( cry.triggerGrowth( is ) ); // We need to copy the stack or the change detection will not work and not sync
// this new stack to the client
ItemStack newItem = cry.triggerGrowth(is.copy());
this.setItem(newItem);
} }
} }
} }
@@ -195,4 +200,11 @@ public final class EntityGrowingCrystal extends ItemEntity
return te instanceof ICrystalGrowthAccelerator && ( (ICrystalGrowthAccelerator) te ).isPowered(); return te instanceof ICrystalGrowthAccelerator && ( (ICrystalGrowthAccelerator) te ).isPowered();
} }
// Don't let seeds "float" on water surface
@Override
protected void applyFloatMotion() {
}
} }
@@ -42,6 +42,8 @@ import appeng.util.Platform;
public final class EntitySingularity extends AEBaseEntityItem public final class EntitySingularity extends AEBaseEntityItem
{ {
public static EntityType<EntitySingularity> TYPE;
private static int randTickSeed = 0; private static int randTickSeed = 0;
public EntitySingularity(EntityType<? extends EntitySingularity> entityType, final World w ) public EntitySingularity(EntityType<? extends EntitySingularity> entityType, final World w )
@@ -51,7 +53,7 @@ public final class EntitySingularity extends AEBaseEntityItem
public EntitySingularity( final World w, final double x, final double y, final double z, final ItemStack is ) public EntitySingularity( final World w, final double x, final double y, final double z, final ItemStack is )
{ {
super( w, x, y, z, is ); super( TYPE, w, x, y, z, is );
} }
@Override @Override
@@ -54,6 +54,8 @@ import appeng.util.Platform;
public final class EntityTinyTNTPrimed extends TNTEntity implements IEntityAdditionalSpawnData public final class EntityTinyTNTPrimed extends TNTEntity implements IEntityAdditionalSpawnData
{ {
public static EntityType<EntityTinyTNTPrimed> TYPE;
public EntityTinyTNTPrimed( EntityType<? extends EntityTinyTNTPrimed> type, World worldIn ) public EntityTinyTNTPrimed( EntityType<? extends EntityTinyTNTPrimed> type, World worldIn )
{ {
super( type, worldIn ); super( type, worldIn );
@@ -19,8 +19,15 @@
package appeng.integration.modules.waila; package appeng.integration.modules.waila;
import appeng.entity.EntityGrowingCrystal;
import appeng.items.misc.ItemCrystalSeed;
import mcp.mobius.waila.api.*; import mcp.mobius.waila.api.*;
import appeng.tile.AEBaseTile; import appeng.tile.AEBaseTile;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import java.util.List;
@WailaPlugin @WailaPlugin
public class WailaModule implements IWailaPlugin public class WailaModule implements IWailaPlugin
@@ -20,7 +20,6 @@ package appeng.items.misc;
import appeng.api.implementations.items.IGrowableCrystal; import appeng.api.implementations.items.IGrowableCrystal;
import appeng.core.AppEng;
import appeng.core.localization.ButtonToolTips; import appeng.core.localization.ButtonToolTips;
import appeng.entity.EntityGrowingCrystal; import appeng.entity.EntityGrowingCrystal;
import appeng.items.AEBaseItem; import appeng.items.AEBaseItem;
@@ -111,12 +110,16 @@ public class ItemCrystalSeed extends AEBaseItem implements IGrowableCrystal
public void addInformation(final ItemStack stack, final World world, final List<ITextComponent> lines, final ITooltipFlag advancedTooltips ) public void addInformation(final ItemStack stack, final World world, final List<ITextComponent> lines, final ITooltipFlag advancedTooltips )
{ {
lines.add( ButtonToolTips.DoesntDespawn.getTranslationKey() ); lines.add( ButtonToolTips.DoesntDespawn.getTranslationKey() );
final int progress = getGrowthTicks( stack ); lines.add(getGrowthTooltipItem(stack));
lines.add( new StringTextComponent( Math.round( 100 * progress / (float) GROWTH_TICKS_REQUIRED ) + "%" ) );
super.addInformation( stack, world, lines, advancedTooltips ); super.addInformation( stack, world, lines, advancedTooltips );
} }
public ITextComponent getGrowthTooltipItem(ItemStack stack) {
final int progress = getGrowthTicks( stack );
return new StringTextComponent( Math.round( 100 * progress / (float) GROWTH_TICKS_REQUIRED ) + "%" );
}
@Override @Override
public int getEntityLifespan( final ItemStack itemStack, final World world ) public int getEntityLifespan( final ItemStack itemStack, final World world )
{ {
@@ -13,3 +13,6 @@ public-f net.minecraft.inventory.container.Slot field_75221_f # yPos
# For JEI registration # For JEI registration
public net.minecraft.item.crafting.RecipeManager func_215366_a(Lnet/minecraft/item/crafting/IRecipeType;)Ljava/util/Map; # getRecipes public net.minecraft.item.crafting.RecipeManager func_215366_a(Lnet/minecraft/item/crafting/IRecipeType;)Ljava/util/Map; # getRecipes
# To disable water-bobbing of item entities (for growing crystals)
protected net.minecraft.entity.item.ItemEntity func_203043_v()V # applyFloatMotion
@@ -1,4 +1,4 @@
{ {
"loader": "appliedenergistics2:crafting_cube", "loader": "appliedenergistics2:crafting_cube",
"type": "16k_storage" "type": "storage_16k"
} }
@@ -1,4 +1,4 @@
{ {
"loader": "appliedenergistics2:crafting_cube", "loader": "appliedenergistics2:crafting_cube",
"type": "1k_storage" "type": "storage_1k"
} }
@@ -1,4 +1,4 @@
{ {
"loader": "appliedenergistics2:crafting_cube", "loader": "appliedenergistics2:crafting_cube",
"type": "4k_storage" "type": "storage_4k"
} }
@@ -1,4 +1,4 @@
{ {
"loader": "appliedenergistics2:crafting_cube", "loader": "appliedenergistics2:crafting_cube",
"type": "64k_storage" "type": "storage_64k"
} }