mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-10 11:59:59 +00:00
Update to latest Forge
- Lots of refactoring/cleanup to Forge's events and client APIs. - Render types/layers for blocks are now set on the model rather than in code. - Models now can work with multiple render types. As this would massively complicate the implementation of the turtle item model, we now implement a much simpler version, which makes use of Forge's BakedModel.getRenderPasses to return a separate model for the core turtle and each upgrade. - Send monitor contents to players immediately when they start watching the chunk. ChunkWatchEvent.Watch is now fired from a more sensible location, so this is much easier to implement!
This commit is contained in:
parent
e906f3ebc3
commit
4a273ae8e5
10
build.gradle
10
build.gradle
@ -109,8 +109,8 @@ minecraft {
|
||||
}
|
||||
}
|
||||
|
||||
// mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
|
||||
mappings channel: 'official', version: mc_version
|
||||
mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
|
||||
// mappings channel: 'official', version: mc_version
|
||||
|
||||
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
|
||||
@ -149,9 +149,9 @@ dependencies {
|
||||
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
||||
annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
|
||||
|
||||
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-forge-api:11.0.0.206")
|
||||
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-common-api:11.0.0.206")
|
||||
extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.19-forge:11.0.0.206")
|
||||
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-forge-api:11.0.0.211")
|
||||
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-common-api:11.0.0.211")
|
||||
extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.19-forge:11.0.0.211")
|
||||
|
||||
shade 'org.squiddev:Cobalt:0.5.5'
|
||||
shade 'io.netty:netty-codec-http:4.1.76.Final'
|
||||
|
@ -6,6 +6,6 @@ mod_version=1.100.8
|
||||
|
||||
# Minecraft properties (update mods.toml when changing)
|
||||
mc_version=1.19
|
||||
mapping_version=2022.03.13
|
||||
forge_version=41.0.38
|
||||
mapping_version=1.18.2-2022.07.03
|
||||
forge_version=41.0.98
|
||||
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING
|
||||
|
@ -7,7 +7,7 @@ package dan200.computercraft.api.pocket;
|
||||
|
||||
import dan200.computercraft.api.upgrades.UpgradeDataProvider;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.data.event.GatherDataEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -47,6 +47,7 @@ public interface PocketUpgradeSerialiser<T extends IPocketUpgrade> extends Upgra
|
||||
|
||||
/**
|
||||
* The associated registry.
|
||||
*
|
||||
* @return The registry for pocket upgrade serialisers.
|
||||
* @see #REGISTRY_ID
|
||||
*/
|
||||
|
@ -14,7 +14,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.level.BlockEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -14,7 +14,7 @@ import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.data.event.GatherDataEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -140,7 +140,10 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITur
|
||||
add.accept( new Upgrade<>( id, serialiser, s -> {
|
||||
s.addProperty( "item", ForgeRegistries.ITEMS.getKey( toolItem ).toString() );
|
||||
if( adjective != null ) s.addProperty( "adjective", adjective );
|
||||
if( craftingItem != null ) s.addProperty( "craftItem", ForgeRegistries.ITEMS.getKey( craftingItem ).toString() );
|
||||
if( craftingItem != null )
|
||||
{
|
||||
s.addProperty( "craftItem", ForgeRegistries.ITEMS.getKey( craftingItem ).toString() );
|
||||
}
|
||||
if( damageMultiplier != null ) s.addProperty( "damageMultiplier", damageMultiplier );
|
||||
if( breakable != null ) s.addProperty( "breakable", breakable.location().toString() );
|
||||
} ) );
|
||||
|
@ -67,12 +67,14 @@ public interface TurtleUpgradeSerialiser<T extends ITurtleUpgrade> extends Upgra
|
||||
*
|
||||
* This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
|
||||
* {@link RegistryManager#getRegistry(ResourceKey)}.
|
||||
*
|
||||
* @see #registry()
|
||||
*/
|
||||
ResourceKey<Registry<TurtleUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade_serialiser" ) );
|
||||
|
||||
/**
|
||||
* The associated registry.
|
||||
*
|
||||
* @return The registry for pocket upgrade serialisers.
|
||||
* @see #REGISTRY_ID
|
||||
*/
|
||||
|
@ -68,7 +68,7 @@ public interface IUpgradeBase
|
||||
* @param stack The stack to check. This is guaranteed to be non-empty and have the same item as
|
||||
* {@link #getCraftingItem()}.
|
||||
* @return If this stack may be used to equip this upgrade.
|
||||
* @see net.minecraftforge.common.crafting.NBTIngredient#test(ItemStack) For the implementation of the default
|
||||
* @see net.minecraftforge.common.crafting.StrictNBTIngredient#test(ItemStack) For the implementation of the default
|
||||
* check.
|
||||
*/
|
||||
default boolean isItemSuitable( @Nonnull ItemStack stack )
|
||||
|
@ -10,7 +10,7 @@ import dan200.computercraft.client.sound.SpeakerManager;
|
||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@ -18,9 +18,9 @@ import net.minecraftforge.fml.common.Mod;
|
||||
public class ClientHooks
|
||||
{
|
||||
@SubscribeEvent
|
||||
public static void onWorldUnload( WorldEvent.Unload event )
|
||||
public static void onWorldUnload( LevelEvent.Unload event )
|
||||
{
|
||||
if( event.getWorld().isClientSide() )
|
||||
if( event.getLevel().isClientSide() )
|
||||
{
|
||||
ClientMonitor.destroyAll();
|
||||
SpeakerManager.reset();
|
||||
@ -28,13 +28,13 @@ public class ClientHooks
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLogIn( ClientPlayerNetworkEvent.LoggedInEvent event )
|
||||
public static void onLogIn( ClientPlayerNetworkEvent.LoggingIn event )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.reset();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLogOut( ClientPlayerNetworkEvent.LoggedOutEvent event )
|
||||
public static void onLogOut( ClientPlayerNetworkEvent.LoggingOut event )
|
||||
{
|
||||
ComputerCraft.clientComputerRegistry.reset();
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ import dan200.computercraft.shared.media.items.ItemTreasureDisk;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.client.gui.screens.MenuScreens;
|
||||
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
|
||||
import net.minecraft.client.renderer.item.ItemProperties;
|
||||
import net.minecraft.client.renderer.item.ItemPropertyFunction;
|
||||
@ -28,10 +26,8 @@ import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.ColorHandlerEvent;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.client.model.ForgeModelBakery;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.client.event.ModelEvent;
|
||||
import net.minecraftforge.client.event.RegisterColorHandlersEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
@ -69,17 +65,22 @@ public final class ClientRegistry
|
||||
private ClientRegistry() {}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerModels( ModelRegistryEvent event )
|
||||
public static void registerModelLoaders( ModelEvent.RegisterGeometryLoaders event )
|
||||
{
|
||||
event.register( "turtle", TurtleModelLoader.INSTANCE );
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerModels( ModelEvent.RegisterAdditional event )
|
||||
{
|
||||
ModelLoaderRegistry.registerLoader( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ), TurtleModelLoader.INSTANCE );
|
||||
for( String model : EXTRA_MODELS )
|
||||
{
|
||||
ForgeModelBakery.addSpecialModel( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ) );
|
||||
event.register( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onItemColours( ColorHandlerEvent.Item event )
|
||||
public static void onItemColours( RegisterColorHandlersEvent.Item event )
|
||||
{
|
||||
if( Registry.ModItems.DISK == null || Registry.ModBlocks.TURTLE_NORMAL == null )
|
||||
{
|
||||
@ -87,17 +88,17 @@ public final class ClientRegistry
|
||||
return;
|
||||
}
|
||||
|
||||
event.getItemColors().register(
|
||||
event.register(
|
||||
( stack, layer ) -> layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF,
|
||||
Registry.ModItems.DISK.get()
|
||||
);
|
||||
|
||||
event.getItemColors().register(
|
||||
event.register(
|
||||
( stack, layer ) -> layer == 1 ? ItemTreasureDisk.getColour( stack ) : 0xFFFFFF,
|
||||
Registry.ModItems.TREASURE_DISK.get()
|
||||
);
|
||||
|
||||
event.getItemColors().register( ( stack, layer ) -> {
|
||||
event.register( ( stack, layer ) -> {
|
||||
switch( layer )
|
||||
{
|
||||
case 0:
|
||||
@ -123,14 +124,6 @@ public final class ClientRegistry
|
||||
@SubscribeEvent
|
||||
public static void setupClient( FMLClientSetupEvent event )
|
||||
{
|
||||
// While turtles themselves are not transparent, their upgrades may be.
|
||||
ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.TURTLE_NORMAL.get(), RenderType.translucent() );
|
||||
ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.TURTLE_ADVANCED.get(), RenderType.translucent() );
|
||||
|
||||
// Monitors' textures have transparent fronts and so count as cutouts.
|
||||
ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.MONITOR_NORMAL.get(), RenderType.cutout() );
|
||||
ItemBlockRenderTypes.setRenderLayer( Registry.ModBlocks.MONITOR_ADVANCED.get(), RenderType.cutout() );
|
||||
|
||||
// Setup TESRs
|
||||
BlockEntityRenderers.register( Registry.ModBlockEntities.MONITOR_NORMAL.get(), TileEntityMonitorRenderer::new );
|
||||
BlockEntityRenderers.register( Registry.ModBlockEntities.MONITOR_ADVANCED.get(), TileEntityMonitorRenderer::new );
|
||||
|
@ -23,7 +23,7 @@ import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.DrawSelectionEvent;
|
||||
import net.minecraftforge.client.event.RenderHighlightEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@ -41,7 +41,7 @@ public final class CableHighlightRenderer
|
||||
* @see net.minecraft.client.renderer.LevelRenderer#renderHitOutline
|
||||
*/
|
||||
@SubscribeEvent
|
||||
public static void drawHighlight( DrawSelectionEvent.HighlightBlock event )
|
||||
public static void drawHighlight( RenderHighlightEvent.Block event )
|
||||
{
|
||||
BlockHitResult hit = event.getTarget();
|
||||
BlockPos pos = hit.getBlockPos();
|
||||
|
@ -15,7 +15,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import net.minecraftforge.client.event.CustomizeGuiOverlayEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@ -25,7 +25,7 @@ import java.util.List;
|
||||
public class DebugOverlay
|
||||
{
|
||||
@SubscribeEvent
|
||||
public static void onRenderText( RenderGameOverlayEvent.Text event )
|
||||
public static void onRenderText( CustomizeGuiOverlayEvent.DebugText event )
|
||||
{
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
if( !minecraft.options.renderDebug || minecraft.level == null ) return;
|
||||
|
@ -18,7 +18,7 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.DrawSelectionEvent;
|
||||
import net.minecraftforge.client.event.RenderHighlightEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@ -38,7 +38,7 @@ public final class MonitorHighlightRenderer
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void drawHighlight( DrawSelectionEvent.HighlightBlock event )
|
||||
public static void drawHighlight( RenderHighlightEvent.Block event )
|
||||
{
|
||||
// Preserve normal behaviour when crouching.
|
||||
if( event.getCamera().getEntity().isCrouching() ) return;
|
||||
|
@ -34,7 +34,7 @@ import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
@ -165,10 +165,10 @@ public class TileEntityTurtleRenderer implements BlockEntityRenderer<TileTurtle>
|
||||
private void renderModel( @Nonnull PoseStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, BakedModel model, int[] tints )
|
||||
{
|
||||
random.setSeed( 0 );
|
||||
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, null, random, EmptyModelData.INSTANCE ), tints );
|
||||
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, null, random, ModelData.EMPTY, null ), tints );
|
||||
for( Direction facing : DirectionUtil.FACINGS )
|
||||
{
|
||||
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, facing, random, EmptyModelData.INSTANCE ), tints );
|
||||
renderQuads( transform, renderer, lightmapCoord, overlayLight, model.getQuads( null, facing, random, ModelData.EMPTY, null ), tints );
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,10 +185,10 @@ public class TileEntityTurtleRenderer implements BlockEntityRenderer<TileTurtle>
|
||||
if( idx >= 0 && idx < tints.length ) tint = tints[bakedquad.getTintIndex()];
|
||||
}
|
||||
|
||||
float f = (float) (tint >> 16 & 255) / 255.0F;
|
||||
float f1 = (float) (tint >> 8 & 255) / 255.0F;
|
||||
float f2 = (float) (tint & 255) / 255.0F;
|
||||
buffer.putBulkData( matrix, bakedquad, f, f1, f2, lightmapCoord, overlayLight, true );
|
||||
float r = (float) (tint >> 16 & 255) / 255.0F;
|
||||
float g = (float) (tint >> 8 & 255) / 255.0F;
|
||||
float b = (float) (tint & 255) / 255.0F;
|
||||
buffer.putBulkData( matrix, bakedquad, r, g, b, lightmapCoord, overlayLight );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import com.mojang.math.Transformation;
|
||||
import dan200.computercraft.api.client.TransformedModel;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.model.BakedModelWrapper;
|
||||
import net.minecraftforge.client.model.IQuadTransformer;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
public class TransformedBakedModel extends BakedModelWrapper<BakedModel>
|
||||
{
|
||||
private final Transformation transformation;
|
||||
private final boolean isIdentity;
|
||||
|
||||
public TransformedBakedModel( BakedModel model, Transformation transformation )
|
||||
{
|
||||
super( model );
|
||||
this.transformation = transformation;
|
||||
isIdentity = transformation.isIdentity();
|
||||
}
|
||||
|
||||
public TransformedBakedModel( TransformedModel model )
|
||||
{
|
||||
this( model.getModel(), model.getMatrix() );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, @Nonnull RandomSource rand )
|
||||
{
|
||||
return getQuads( state, side, rand, ModelData.EMPTY, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, @NotNull RandomSource rand, @NotNull ModelData extraData, @Nullable RenderType renderType )
|
||||
{
|
||||
List<BakedQuad> quads = originalModel.getQuads( state, side, rand, extraData, renderType );
|
||||
return isIdentity ? quads : IQuadTransformer.applying( transformation ).process( quads );
|
||||
}
|
||||
|
||||
public TransformedBakedModel composeWith( Transformation other )
|
||||
{
|
||||
return new TransformedBakedModel( originalModel, other.compose( transformation ) );
|
||||
}
|
||||
}
|
@ -13,11 +13,10 @@ import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.*;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraftforge.client.model.IModelConfiguration;
|
||||
import net.minecraftforge.client.model.IModelLoader;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
||||
import net.minecraftforge.client.model.geometry.IGeometryBakingContext;
|
||||
import net.minecraftforge.client.model.geometry.IGeometryLoader;
|
||||
import net.minecraftforge.client.model.geometry.IUnbakedGeometry;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
@ -25,7 +24,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.TurtleModel>
|
||||
public final class TurtleModelLoader implements IGeometryLoader<TurtleModelLoader.TurtleModel>
|
||||
{
|
||||
private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation( ComputerCraft.MOD_ID, "block/turtle_colour" );
|
||||
|
||||
@ -35,20 +34,15 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload( @Nonnull ResourceManager manager )
|
||||
{
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public TurtleModel read( @Nonnull JsonDeserializationContext deserializationContext, @Nonnull JsonObject modelContents )
|
||||
public TurtleModel read( @Nonnull JsonObject modelContents, @Nonnull JsonDeserializationContext deserializationContext )
|
||||
{
|
||||
ResourceLocation model = new ResourceLocation( GsonHelper.getAsString( modelContents, "model" ) );
|
||||
return new TurtleModel( model );
|
||||
}
|
||||
|
||||
public static final class TurtleModel implements IModelGeometry<TurtleModel>
|
||||
public static final class TurtleModel implements IUnbakedGeometry<TurtleModel>
|
||||
{
|
||||
private final ResourceLocation family;
|
||||
|
||||
@ -58,7 +52,7 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Material> getTextures( IModelConfiguration owner, Function<ResourceLocation, UnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
|
||||
public Collection<Material> getMaterials( IGeometryBakingContext context, Function<ResourceLocation, UnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
|
||||
{
|
||||
Set<Material> materials = new HashSet<>();
|
||||
materials.addAll( modelGetter.apply( family ).getMaterials( modelGetter, missingTextureErrors ) );
|
||||
@ -67,7 +61,7 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
|
||||
}
|
||||
|
||||
@Override
|
||||
public BakedModel bake( IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, ModelState transform, ItemOverrides overrides, ResourceLocation modelLocation )
|
||||
public BakedModel bake( IGeometryBakingContext owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, ModelState transform, ItemOverrides overrides, ResourceLocation modelLocation )
|
||||
{
|
||||
return new TurtleSmartItemModel(
|
||||
bakery.bake( family, transform, spriteGetter ),
|
||||
|
@ -1,153 +0,0 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.client.render;
|
||||
|
||||
import com.mojang.math.Transformation;
|
||||
import dan200.computercraft.api.client.TransformedModel;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
|
||||
import net.minecraftforge.client.model.pipeline.TRSRTransformer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TurtleMultiModel implements BakedModel
|
||||
{
|
||||
private final BakedModel baseModel;
|
||||
private final BakedModel overlayModel;
|
||||
private final Transformation generalTransform;
|
||||
private final TransformedModel leftUpgradeModel;
|
||||
private final TransformedModel rightUpgradeModel;
|
||||
private List<BakedQuad> generalQuads = null;
|
||||
private final Map<Direction, List<BakedQuad>> faceQuads = new EnumMap<>( Direction.class );
|
||||
|
||||
public TurtleMultiModel( BakedModel baseModel, BakedModel overlayModel, Transformation generalTransform, TransformedModel leftUpgradeModel, TransformedModel rightUpgradeModel )
|
||||
{
|
||||
// Get the models
|
||||
this.baseModel = baseModel;
|
||||
this.overlayModel = overlayModel;
|
||||
this.leftUpgradeModel = leftUpgradeModel;
|
||||
this.rightUpgradeModel = rightUpgradeModel;
|
||||
this.generalTransform = generalTransform;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@Deprecated
|
||||
public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull RandomSource rand )
|
||||
{
|
||||
return getQuads( state, side, rand, EmptyModelData.INSTANCE );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<BakedQuad> getQuads( BlockState state, Direction side, @Nonnull RandomSource rand, @Nonnull IModelData data )
|
||||
{
|
||||
if( side != null )
|
||||
{
|
||||
if( !faceQuads.containsKey( side ) ) faceQuads.put( side, buildQuads( state, side, rand ) );
|
||||
return faceQuads.get( side );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( generalQuads == null ) generalQuads = buildQuads( state, side, rand );
|
||||
return generalQuads;
|
||||
}
|
||||
}
|
||||
|
||||
private List<BakedQuad> buildQuads( BlockState state, Direction side, RandomSource rand )
|
||||
{
|
||||
ArrayList<BakedQuad> quads = new ArrayList<>();
|
||||
|
||||
|
||||
transformQuadsTo( quads, baseModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform );
|
||||
if( overlayModel != null )
|
||||
{
|
||||
transformQuadsTo( quads, overlayModel.getQuads( state, side, rand, EmptyModelData.INSTANCE ), generalTransform );
|
||||
}
|
||||
if( leftUpgradeModel != null )
|
||||
{
|
||||
Transformation upgradeTransform = generalTransform.compose( leftUpgradeModel.getMatrix() );
|
||||
transformQuadsTo( quads, leftUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
|
||||
}
|
||||
if( rightUpgradeModel != null )
|
||||
{
|
||||
Transformation upgradeTransform = generalTransform.compose( rightUpgradeModel.getMatrix() );
|
||||
transformQuadsTo( quads, rightUpgradeModel.getModel().getQuads( state, side, rand, EmptyModelData.INSTANCE ), upgradeTransform );
|
||||
}
|
||||
quads.trimToSize();
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion()
|
||||
{
|
||||
return baseModel.useAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return baseModel.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomRenderer()
|
||||
{
|
||||
return baseModel.isCustomRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight()
|
||||
{
|
||||
return baseModel.usesBlockLight();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@Deprecated
|
||||
public TextureAtlasSprite getParticleIcon()
|
||||
{
|
||||
return baseModel.getParticleIcon();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@Deprecated
|
||||
public net.minecraft.client.renderer.block.model.ItemTransforms getTransforms()
|
||||
{
|
||||
return baseModel.getTransforms();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemOverrides getOverrides()
|
||||
{
|
||||
return ItemOverrides.EMPTY;
|
||||
}
|
||||
|
||||
private void transformQuadsTo( List<BakedQuad> output, List<BakedQuad> quads, Transformation transform )
|
||||
{
|
||||
for( BakedQuad quad : quads )
|
||||
{
|
||||
BakedQuadBuilder builder = new BakedQuadBuilder();
|
||||
TRSRTransformer transformer = new TRSRTransformer( builder, transform );
|
||||
quad.pipe( transformer );
|
||||
output.add( builder.build() );
|
||||
}
|
||||
}
|
||||
}
|
@ -7,35 +7,27 @@ package dan200.computercraft.client.render;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Transformation;
|
||||
import dan200.computercraft.api.client.TransformedModel;
|
||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||
import dan200.computercraft.api.turtle.TurtleSide;
|
||||
import dan200.computercraft.shared.turtle.items.ItemTurtle;
|
||||
import dan200.computercraft.shared.util.Holiday;
|
||||
import dan200.computercraft.shared.util.HolidayUtil;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.BakedModelWrapper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TurtleSmartItemModel implements BakedModel
|
||||
public class TurtleSmartItemModel extends BakedModelWrapper<BakedModel>
|
||||
{
|
||||
private static final Transformation identity, flip;
|
||||
|
||||
@ -49,7 +41,7 @@ public class TurtleSmartItemModel implements BakedModel
|
||||
flip = new Transformation( stack.last().pose() );
|
||||
}
|
||||
|
||||
private static record TurtleModelCombination(
|
||||
private record TurtleModelCombination(
|
||||
boolean colour,
|
||||
ITurtleUpgrade leftUpgrade,
|
||||
ITurtleUpgrade rightUpgrade,
|
||||
@ -63,21 +55,29 @@ public class TurtleSmartItemModel implements BakedModel
|
||||
private final BakedModel familyModel;
|
||||
private final BakedModel colourModel;
|
||||
|
||||
private final HashMap<TurtleModelCombination, BakedModel> cachedModels = new HashMap<>();
|
||||
private final ItemOverrides overrides;
|
||||
private final Map<TurtleModelCombination, List<BakedModel>> cachedModels = new HashMap<>();
|
||||
|
||||
public TurtleSmartItemModel( BakedModel familyModel, BakedModel colourModel )
|
||||
{
|
||||
super( familyModel );
|
||||
this.familyModel = familyModel;
|
||||
this.colourModel = colourModel;
|
||||
}
|
||||
|
||||
overrides = new ItemOverrides()
|
||||
{
|
||||
@Nonnull
|
||||
@Override
|
||||
public BakedModel resolve( @Nonnull BakedModel originalModel, @Nonnull ItemStack stack, @Nullable ClientLevel world, @Nullable LivingEntity entity, int random )
|
||||
public BakedModel applyTransform( @Nonnull ItemTransforms.TransformType cameraTransformType, @Nonnull PoseStack poseStack, boolean applyLeftHandTransform )
|
||||
{
|
||||
originalModel.applyTransform( cameraTransformType, poseStack, applyLeftHandTransform );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<BakedModel> getRenderPasses( ItemStack stack, boolean fabulous )
|
||||
{
|
||||
ItemTurtle turtle = (ItemTurtle) stack.getItem();
|
||||
|
||||
int colour = turtle.getColour( stack );
|
||||
ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.LEFT );
|
||||
ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.RIGHT );
|
||||
@ -85,90 +85,34 @@ public class TurtleSmartItemModel implements BakedModel
|
||||
boolean christmas = HolidayUtil.getCurrentHoliday() == Holiday.CHRISTMAS;
|
||||
String label = turtle.getLabel( stack );
|
||||
boolean flip = label != null && (label.equals( "Dinnerbone" ) || label.equals( "Grumm" ));
|
||||
|
||||
TurtleModelCombination combo = new TurtleModelCombination( colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip );
|
||||
|
||||
BakedModel model = cachedModels.get( combo );
|
||||
if( model == null ) cachedModels.put( combo, model = buildModel( combo ) );
|
||||
return model;
|
||||
}
|
||||
};
|
||||
return cachedModels.computeIfAbsent( combo, this::buildModel );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ItemOverrides getOverrides()
|
||||
{
|
||||
return overrides;
|
||||
}
|
||||
|
||||
private BakedModel buildModel( TurtleModelCombination combo )
|
||||
private List<BakedModel> buildModel( TurtleModelCombination combo )
|
||||
{
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager();
|
||||
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay, combo.christmas );
|
||||
|
||||
BakedModel baseModel = combo.colour ? colourModel : familyModel;
|
||||
BakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null;
|
||||
Transformation transform = combo.flip ? flip : identity;
|
||||
TransformedModel leftModel = combo.leftUpgrade != null ? combo.leftUpgrade.getModel( null, TurtleSide.LEFT ) : null;
|
||||
TransformedModel rightModel = combo.rightUpgrade != null ? combo.rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null;
|
||||
return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel );
|
||||
}
|
||||
var transformation = combo.flip ? flip : identity;
|
||||
ArrayList<BakedModel> parts = new ArrayList<>( 4 );
|
||||
parts.add( new TransformedBakedModel( combo.colour() ? colourModel : familyModel, transformation ) );
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@Deprecated
|
||||
public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand )
|
||||
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay(), combo.christmas() );
|
||||
if( overlayModelLocation != null )
|
||||
{
|
||||
return familyModel.getQuads( state, facing, rand );
|
||||
parts.add( new TransformedBakedModel( modelManager.getModel( overlayModelLocation ), transformation ) );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@Deprecated
|
||||
public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand, @Nonnull IModelData data )
|
||||
if( combo.leftUpgrade() != null )
|
||||
{
|
||||
return familyModel.getQuads( state, facing, rand, data );
|
||||
parts.add( new TransformedBakedModel( combo.leftUpgrade().getModel( null, TurtleSide.LEFT ) ).composeWith( transformation ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion()
|
||||
if( combo.rightUpgrade() != null )
|
||||
{
|
||||
return familyModel.useAmbientOcclusion();
|
||||
parts.add( new TransformedBakedModel( combo.rightUpgrade().getModel( null, TurtleSide.RIGHT ) ).composeWith( transformation ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return familyModel.isGui3d();
|
||||
return parts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomRenderer()
|
||||
{
|
||||
return familyModel.isCustomRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight()
|
||||
{
|
||||
return familyModel.usesBlockLight();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@Deprecated
|
||||
public TextureAtlasSprite getParticleIcon()
|
||||
{
|
||||
return familyModel.getParticleIcon();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@Deprecated
|
||||
public ItemTransforms getTransforms()
|
||||
{
|
||||
return familyModel.getTransforms();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ package dan200.computercraft.data;
|
||||
import dan200.computercraft.shared.Registry;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
import net.minecraftforge.data.event.GatherDataEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
||||
|
||||
@Mod.EventBusSubscriber( bus = Mod.EventBusSubscriber.Bus.MOD )
|
||||
public class Generators
|
||||
|
@ -24,7 +24,7 @@ import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -35,7 +35,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
/**
|
||||
* Provides custom block breaking progress for modems, so it only applies to the current part.
|
||||
*
|
||||
* @see BlockRenderDispatcher#renderBreakingTexture(BlockState, BlockPos, BlockAndTintGetter, PoseStack, VertexConsumer, IModelData)
|
||||
* @see BlockRenderDispatcher#renderBreakingTexture(BlockState, BlockPos, BlockAndTintGetter, PoseStack, VertexConsumer, ModelData)
|
||||
*/
|
||||
@Mixin( BlockRenderDispatcher.class )
|
||||
public class BlockRenderDispatcherMixin
|
||||
@ -53,13 +53,13 @@ public class BlockRenderDispatcherMixin
|
||||
private ModelBlockRenderer modelRenderer;
|
||||
|
||||
@Inject(
|
||||
method = "name=/^renderBreakingTexture/ desc=/IModelData;\\)V$/",
|
||||
method = "name=/^renderBreakingTexture/ desc=/ModelData;\\)V$/",
|
||||
at = @At( "HEAD" ),
|
||||
cancellable = true,
|
||||
require = 0 // This isn't critical functionality, so don't worry if we can't apply it.
|
||||
)
|
||||
public void renderBlockDamage(
|
||||
BlockState state, BlockPos pos, BlockAndTintGetter world, PoseStack pose, VertexConsumer buffers, IModelData modelData,
|
||||
BlockState state, BlockPos pos, BlockAndTintGetter world, PoseStack pose, VertexConsumer buffers, ModelData modelData,
|
||||
CallbackInfo info
|
||||
)
|
||||
{
|
||||
@ -85,6 +85,6 @@ public class BlockRenderDispatcherMixin
|
||||
|
||||
BakedModel model = blockModelShaper.getBlockModel( newState );
|
||||
long seed = newState.getSeed( pos );
|
||||
modelRenderer.tesselateBlock( world, model, newState, pos, pose, buffers, true, random, seed, OverlayTexture.NO_OVERLAY, modelData );
|
||||
modelRenderer.tesselateBlock( world, model, newState, pos, pose, buffers, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, null );
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public final class CommonHooks
|
||||
IComputer computer = ((IContainerComputer) container).getComputer();
|
||||
if( computer instanceof ServerComputer )
|
||||
{
|
||||
((ServerComputer) computer).sendTerminalState( event.getPlayer() );
|
||||
((ServerComputer) computer).sendTerminalState( event.getEntity() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,6 @@
|
||||
package dan200.computercraft.shared;
|
||||
|
||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Converter;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.core.apis.http.NetworkUtils;
|
||||
import dan200.computercraft.core.apis.http.options.Action;
|
||||
@ -367,6 +365,4 @@ public final class Config
|
||||
{
|
||||
sync( event.getConfig() );
|
||||
}
|
||||
|
||||
private static final Converter<String, String> converter = CaseFormat.LOWER_CAMEL.converterTo( CaseFormat.UPPER_UNDERSCORE );
|
||||
}
|
||||
|
@ -13,7 +13,10 @@ import dan200.computercraft.api.network.wired.IWiredElement;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
|
||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
|
||||
import dan200.computercraft.shared.command.arguments.*;
|
||||
import dan200.computercraft.shared.command.arguments.ComputerArgumentType;
|
||||
import dan200.computercraft.shared.command.arguments.ComputersArgumentType;
|
||||
import dan200.computercraft.shared.command.arguments.RepeatArgumentType;
|
||||
import dan200.computercraft.shared.command.arguments.TrackingFieldArgumentType;
|
||||
import dan200.computercraft.shared.common.ColourableRecipe;
|
||||
import dan200.computercraft.shared.common.ContainerHeldItem;
|
||||
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
|
||||
@ -164,7 +167,7 @@ public final class Registry
|
||||
|
||||
public static class ModBlockEntities
|
||||
{
|
||||
static final DeferredRegister<BlockEntityType<?>> TILES = DeferredRegister.create( ForgeRegistries.BLOCK_ENTITIES, ComputerCraft.MOD_ID );
|
||||
static final DeferredRegister<BlockEntityType<?>> TILES = DeferredRegister.create( ForgeRegistries.BLOCK_ENTITY_TYPES, ComputerCraft.MOD_ID );
|
||||
|
||||
private static <T extends BlockEntity> RegistryObject<BlockEntityType<T>> ofBlock( RegistryObject<? extends Block> block, FixedPointTileEntityType.FixedPointBlockEntitySupplier<T> factory )
|
||||
{
|
||||
@ -283,7 +286,7 @@ public final class Registry
|
||||
|
||||
public static class ModContainers
|
||||
{
|
||||
static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create( ForgeRegistries.CONTAINERS, ComputerCraft.MOD_ID );
|
||||
static final DeferredRegister<MenuType<?>> CONTAINERS = DeferredRegister.create( ForgeRegistries.MENU_TYPES, ComputerCraft.MOD_ID );
|
||||
|
||||
public static final RegistryObject<MenuType<ContainerComputerBase>> COMPUTER = CONTAINERS.register( "computer",
|
||||
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
||||
@ -317,7 +320,7 @@ public final class Registry
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private static <T extends ArgumentType<?>> void registerUnsafe( String name, Class<T> type, ArgumentTypeInfo<?, ?> serializer )
|
||||
{
|
||||
ARGUMENT_TYPES.register( name, () -> ArgumentTypeInfos.registerByClass( type, (ArgumentTypeInfo<T, ?>)serializer ) );
|
||||
ARGUMENT_TYPES.register( name, () -> ArgumentTypeInfos.registerByClass( type, (ArgumentTypeInfo<T, ?>) serializer ) );
|
||||
}
|
||||
|
||||
private static <T extends ArgumentType<?>> void register( String name, Class<T> type, ArgumentTypeInfo<T, ?> serializer )
|
||||
|
@ -104,7 +104,7 @@ public final class NetworkHandler
|
||||
network.messageBuilder( type, id, direction )
|
||||
.encoder( NetworkMessage::toBytes )
|
||||
.decoder( decoder )
|
||||
.consumer( ( packet, contextSup ) -> {
|
||||
.consumerMainThread( ( packet, contextSup ) -> {
|
||||
NetworkEvent.Context context = contextSup.get();
|
||||
context.enqueueWork( () -> packet.handle( context ) );
|
||||
context.setPacketHandled( true );
|
||||
|
@ -30,7 +30,7 @@ public interface ContainerData
|
||||
|
||||
default void open( Player player, MenuProvider owner )
|
||||
{
|
||||
NetworkHooks.openGui( (ServerPlayer) player, owner, this::toBytes );
|
||||
NetworkHooks.openScreen( (ServerPlayer) player, owner, this::toBytes );
|
||||
}
|
||||
|
||||
static <C extends AbstractContainerMenu, T extends ContainerData> MenuType<C> toType( Function<FriendlyByteBuf, T> reader, Factory<C, T> factory )
|
||||
|
@ -120,7 +120,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
|
||||
// Open the GUI
|
||||
if( !getLevel().isClientSide && isUsable( player ) )
|
||||
{
|
||||
NetworkHooks.openGui( (ServerPlayer) player, this );
|
||||
NetworkHooks.openScreen( (ServerPlayer) player, this );
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class GenericPeripheral implements IDynamicPeripheral
|
||||
|
||||
GenericPeripheral( BlockEntity tile, String name, Set<String> additionalTypes, List<SaturatedMethod> methods )
|
||||
{
|
||||
ResourceLocation type = ForgeRegistries.BLOCK_ENTITIES.getKey( tile.getType() );
|
||||
ResourceLocation type = ForgeRegistries.BLOCK_ENTITY_TYPES.getKey( tile.getType() );
|
||||
this.tile = tile;
|
||||
this.type = name != null ? name : (type != null ? type.toString() : "unknown");
|
||||
this.additionalTypes = additionalTypes;
|
||||
|
@ -11,13 +11,11 @@ import dan200.computercraft.shared.network.client.MonitorClientMessage;
|
||||
import dan200.computercraft.shared.network.client.TerminalState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.event.world.ChunkWatchEvent;
|
||||
import net.minecraftforge.event.level.ChunkWatchEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@ -28,7 +26,6 @@ import java.util.Queue;
|
||||
public final class MonitorWatcher
|
||||
{
|
||||
private static final Queue<TileMonitor> watching = new ArrayDeque<>();
|
||||
private static final Queue<PlayerUpdate> playerUpdates = new ArrayDeque<>();
|
||||
|
||||
private MonitorWatcher()
|
||||
{
|
||||
@ -46,47 +43,28 @@ public final class MonitorWatcher
|
||||
@SubscribeEvent
|
||||
public static void onWatch( ChunkWatchEvent.Watch event )
|
||||
{
|
||||
// Get the current chunk if it has been loaded. This is safe as, if the chunk hasn't been loaded yet, then the
|
||||
// monitor will have no contents, and so we won't need to send an update anyway.
|
||||
ChunkPos chunkPos = event.getPos();
|
||||
LevelChunk chunk = event.getWorld().getChunkSource().getChunkNow( chunkPos.x, chunkPos.z );
|
||||
if( chunk == null ) return;
|
||||
|
||||
for( BlockEntity te : chunk.getBlockEntities().values() )
|
||||
// Find all origin monitors who are not already on the queue and send the
|
||||
// monitor data to the player.
|
||||
for( BlockEntity te : event.getChunk().getBlockEntities().values() )
|
||||
{
|
||||
// Find all origin monitors who are not already on the queue.
|
||||
if( !(te instanceof TileMonitor monitor) ) continue;
|
||||
|
||||
ServerMonitor serverMonitor = getMonitor( monitor );
|
||||
if( serverMonitor == null || monitor.enqueued ) continue;
|
||||
|
||||
// The chunk hasn't been sent to the client yet, so we can't send an update. Do it on tick end.
|
||||
playerUpdates.add( new PlayerUpdate( event.getPlayer(), monitor ) );
|
||||
TerminalState state = monitor.cached;
|
||||
if( state == null ) state = monitor.cached = serverMonitor.write();
|
||||
NetworkHandler.sendToPlayer( event.getPlayer(), new MonitorClientMessage( monitor.getBlockPos(), state ) );
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onTick( TickEvent.ServerTickEvent event )
|
||||
{
|
||||
// Find all enqueued monitors and send their contents to all nearby players.
|
||||
|
||||
if( event.phase != TickEvent.Phase.END ) return;
|
||||
|
||||
PlayerUpdate playerUpdate;
|
||||
while( (playerUpdate = playerUpdates.poll()) != null )
|
||||
{
|
||||
TileMonitor tile = playerUpdate.monitor;
|
||||
if( tile.enqueued || tile.isRemoved() ) continue;
|
||||
|
||||
ServerMonitor monitor = getMonitor( tile );
|
||||
if( monitor == null ) continue;
|
||||
|
||||
// Some basic sanity checks to the player. It's possible they're no longer within range, but that's harder
|
||||
// to track efficiently.
|
||||
ServerPlayer player = playerUpdate.player;
|
||||
if( !player.isAlive() || player.getLevel() != tile.getLevel() ) continue;
|
||||
|
||||
NetworkHandler.sendToPlayer( playerUpdate.player, new MonitorClientMessage( tile.getBlockPos(), getState( tile, monitor ) ) );
|
||||
}
|
||||
|
||||
long limit = ComputerCraft.monitorBandwidth;
|
||||
boolean obeyLimit = limit > 0;
|
||||
|
||||
@ -125,16 +103,4 @@ public final class MonitorWatcher
|
||||
if( state == null ) state = tile.cached = monitor.write();
|
||||
return state;
|
||||
}
|
||||
|
||||
private static final class PlayerUpdate
|
||||
{
|
||||
final ServerPlayer player;
|
||||
final TileMonitor monitor;
|
||||
|
||||
private PlayerUpdate( ServerPlayer player, TileMonitor monitor )
|
||||
{
|
||||
this.player = player;
|
||||
this.monitor = monitor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
|
||||
|
||||
if( !getLevel().isClientSide && isUsable( player ) )
|
||||
{
|
||||
NetworkHooks.openGui( (ServerPlayer) player, this );
|
||||
NetworkHooks.openScreen( (ServerPlayer) player, this );
|
||||
}
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
|
||||
ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false );
|
||||
int fuelToGive = fuelPerItem * stack.getCount();
|
||||
// Store the replacement item in the inventory
|
||||
ItemStack replacementStack = stack.getItem().getContainerItem( stack );
|
||||
ItemStack replacementStack = ForgeHooks.getCraftingRemainingItem( stack );
|
||||
if( !replacementStack.isEmpty() )
|
||||
{
|
||||
ItemStack remainder = InventoryUtil.storeItems( replacementStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
|
@ -42,7 +42,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.ToolActions;
|
||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.event.level.BlockEvent;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
@ -80,10 +80,10 @@ public final class DropConsumer
|
||||
}
|
||||
|
||||
@SubscribeEvent( priority = EventPriority.HIGHEST )
|
||||
public static void onEntitySpawn( EntityJoinWorldEvent event )
|
||||
public static void onEntitySpawn( EntityJoinLevelEvent event )
|
||||
{
|
||||
// Capture any nearby item spawns
|
||||
if( dropWorld == event.getWorld() && event.getEntity() instanceof ItemEntity
|
||||
if( dropWorld == event.getLevel() && event.getEntity() instanceof ItemEntity
|
||||
&& dropBounds.contains( event.getEntity().position() ) )
|
||||
{
|
||||
handleDrops( ((ItemEntity) event.getEntity()).getItem() );
|
||||
|
@ -21,6 +21,6 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a
|
||||
[[dependencies.computercraft]]
|
||||
modId="forge"
|
||||
mandatory=true
|
||||
versionRange="[41.0.38,42)"
|
||||
versionRange="[41.0.98,42)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"parent": "block/cube",
|
||||
"render_type": "cutout",
|
||||
"textures": {
|
||||
"particle": "#front",
|
||||
"down": "#top",
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"parent": "block/block",
|
||||
"render_type": "translucent",
|
||||
"textures": {
|
||||
"particle": "#texture"
|
||||
},
|
||||
|
@ -137,7 +137,7 @@ fun GameTestHelper.sequence(run: GameTestSequence.() -> GameTestSequence) {
|
||||
run(startSequence()).thenSucceed()
|
||||
}
|
||||
|
||||
private fun getName(type: BlockEntityType<*>): ResourceLocation = ForgeRegistries.BLOCK_ENTITIES.getKey(type)!!
|
||||
private fun getName(type: BlockEntityType<*>): ResourceLocation = ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(type)!!
|
||||
|
||||
fun <T : BlockEntity> GameTestHelper.getBlockEntity(pos: BlockPos, type: BlockEntityType<T>): T {
|
||||
val tile = getBlockEntity(pos)
|
||||
|
@ -29,7 +29,7 @@ public final class ClientHooks
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onGuiInit( ScreenEvent.InitScreenEvent event )
|
||||
public static void onGuiInit( ScreenEvent.Init event )
|
||||
{
|
||||
if( triggered || !(event.getScreen() instanceof TitleScreen) ) return;
|
||||
triggered = true;
|
||||
|
Loading…
Reference in New Issue
Block a user