mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-14 05:44:52 +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: 'parchment', version: "${mapping_version}-${mc_version}"
|
||||||
mappings channel: 'official', version: mc_version
|
// mappings channel: 'official', version: mc_version
|
||||||
|
|
||||||
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
|
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||||
accessTransformer file('src/testMod/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}"
|
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
||||||
annotationProcessor 'org.spongepowered:mixin:0.8.4:processor'
|
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-forge-api:11.0.0.211")
|
||||||
extraModsCompileOnly fg.deobf("mezz.jei:jei-1.19-common-api:11.0.0.206")
|
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.206")
|
extraModsRuntimeOnly fg.deobf("mezz.jei:jei-1.19-forge:11.0.0.211")
|
||||||
|
|
||||||
shade 'org.squiddev:Cobalt:0.5.5'
|
shade 'org.squiddev:Cobalt:0.5.5'
|
||||||
shade 'io.netty:netty-codec-http:4.1.76.Final'
|
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)
|
# Minecraft properties (update mods.toml when changing)
|
||||||
mc_version=1.19
|
mc_version=1.19
|
||||||
mapping_version=2022.03.13
|
mapping_version=1.18.2-2022.07.03
|
||||||
forge_version=41.0.38
|
forge_version=41.0.98
|
||||||
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING
|
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING
|
||||||
|
@ -7,7 +7,7 @@ package dan200.computercraft.api.pocket;
|
|||||||
|
|
||||||
import dan200.computercraft.api.upgrades.UpgradeDataProvider;
|
import dan200.computercraft.api.upgrades.UpgradeDataProvider;
|
||||||
import net.minecraft.data.DataGenerator;
|
import net.minecraft.data.DataGenerator;
|
||||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
import net.minecraftforge.data.event.GatherDataEvent;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -47,6 +47,7 @@ public interface PocketUpgradeSerialiser<T extends IPocketUpgrade> extends Upgra
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The associated registry.
|
* The associated registry.
|
||||||
|
*
|
||||||
* @return The registry for pocket upgrade serialisers.
|
* @return The registry for pocket upgrade serialisers.
|
||||||
* @see #REGISTRY_ID
|
* @see #REGISTRY_ID
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,7 @@ import net.minecraft.world.item.ItemStack;
|
|||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
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.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
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.entity.ai.attributes.Attributes;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.level.block.Block;
|
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 net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -140,7 +140,10 @@ public abstract class TurtleUpgradeDataProvider extends UpgradeDataProvider<ITur
|
|||||||
add.accept( new Upgrade<>( id, serialiser, s -> {
|
add.accept( new Upgrade<>( id, serialiser, s -> {
|
||||||
s.addProperty( "item", ForgeRegistries.ITEMS.getKey( toolItem ).toString() );
|
s.addProperty( "item", ForgeRegistries.ITEMS.getKey( toolItem ).toString() );
|
||||||
if( adjective != null ) s.addProperty( "adjective", adjective );
|
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( damageMultiplier != null ) s.addProperty( "damageMultiplier", damageMultiplier );
|
||||||
if( breakable != null ) s.addProperty( "breakable", breakable.location().toString() );
|
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
|
* This is largely intended for use with Forge Registry methods/classes, such as {@link DeferredRegister} and
|
||||||
* {@link RegistryManager#getRegistry(ResourceKey)}.
|
* {@link RegistryManager#getRegistry(ResourceKey)}.
|
||||||
|
*
|
||||||
* @see #registry()
|
* @see #registry()
|
||||||
*/
|
*/
|
||||||
ResourceKey<Registry<TurtleUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade_serialiser" ) );
|
ResourceKey<Registry<TurtleUpgradeSerialiser<?>>> REGISTRY_ID = ResourceKey.createRegistryKey( new ResourceLocation( ComputerCraft.MOD_ID, "turtle_upgrade_serialiser" ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The associated registry.
|
* The associated registry.
|
||||||
|
*
|
||||||
* @return The registry for pocket upgrade serialisers.
|
* @return The registry for pocket upgrade serialisers.
|
||||||
* @see #REGISTRY_ID
|
* @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
|
* @param stack The stack to check. This is guaranteed to be non-empty and have the same item as
|
||||||
* {@link #getCraftingItem()}.
|
* {@link #getCraftingItem()}.
|
||||||
* @return If this stack may be used to equip this upgrade.
|
* @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.
|
* check.
|
||||||
*/
|
*/
|
||||||
default boolean isItemSuitable( @Nonnull ItemStack stack )
|
default boolean isItemSuitable( @Nonnull ItemStack stack )
|
||||||
|
@ -10,7 +10,7 @@ import dan200.computercraft.client.sound.SpeakerManager;
|
|||||||
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
import dan200.computercraft.shared.peripheral.monitor.ClientMonitor;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
|
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.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
@ -18,9 +18,9 @@ import net.minecraftforge.fml.common.Mod;
|
|||||||
public class ClientHooks
|
public class ClientHooks
|
||||||
{
|
{
|
||||||
@SubscribeEvent
|
@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();
|
ClientMonitor.destroyAll();
|
||||||
SpeakerManager.reset();
|
SpeakerManager.reset();
|
||||||
@ -28,13 +28,13 @@ public class ClientHooks
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLogIn( ClientPlayerNetworkEvent.LoggedInEvent event )
|
public static void onLogIn( ClientPlayerNetworkEvent.LoggingIn event )
|
||||||
{
|
{
|
||||||
ComputerCraft.clientComputerRegistry.reset();
|
ComputerCraft.clientComputerRegistry.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLogOut( ClientPlayerNetworkEvent.LoggedOutEvent event )
|
public static void onLogOut( ClientPlayerNetworkEvent.LoggingOut event )
|
||||||
{
|
{
|
||||||
ComputerCraft.clientComputerRegistry.reset();
|
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.pocket.items.ItemPocketComputer;
|
||||||
import dan200.computercraft.shared.util.Colour;
|
import dan200.computercraft.shared.util.Colour;
|
||||||
import net.minecraft.client.gui.screens.MenuScreens;
|
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.blockentity.BlockEntityRenderers;
|
||||||
import net.minecraft.client.renderer.item.ItemProperties;
|
import net.minecraft.client.renderer.item.ItemProperties;
|
||||||
import net.minecraft.client.renderer.item.ItemPropertyFunction;
|
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.resources.ResourceLocation;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.client.event.ColorHandlerEvent;
|
import net.minecraftforge.client.event.ModelEvent;
|
||||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
import net.minecraftforge.client.event.RegisterColorHandlersEvent;
|
||||||
import net.minecraftforge.client.model.ForgeModelBakery;
|
|
||||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
@ -69,17 +65,22 @@ public final class ClientRegistry
|
|||||||
private ClientRegistry() {}
|
private ClientRegistry() {}
|
||||||
|
|
||||||
@SubscribeEvent
|
@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 )
|
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
|
@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 )
|
if( Registry.ModItems.DISK == null || Registry.ModBlocks.TURTLE_NORMAL == null )
|
||||||
{
|
{
|
||||||
@ -87,17 +88,17 @@ public final class ClientRegistry
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.getItemColors().register(
|
event.register(
|
||||||
( stack, layer ) -> layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF,
|
( stack, layer ) -> layer == 1 ? ((ItemDisk) stack.getItem()).getColour( stack ) : 0xFFFFFF,
|
||||||
Registry.ModItems.DISK.get()
|
Registry.ModItems.DISK.get()
|
||||||
);
|
);
|
||||||
|
|
||||||
event.getItemColors().register(
|
event.register(
|
||||||
( stack, layer ) -> layer == 1 ? ItemTreasureDisk.getColour( stack ) : 0xFFFFFF,
|
( stack, layer ) -> layer == 1 ? ItemTreasureDisk.getColour( stack ) : 0xFFFFFF,
|
||||||
Registry.ModItems.TREASURE_DISK.get()
|
Registry.ModItems.TREASURE_DISK.get()
|
||||||
);
|
);
|
||||||
|
|
||||||
event.getItemColors().register( ( stack, layer ) -> {
|
event.register( ( stack, layer ) -> {
|
||||||
switch( layer )
|
switch( layer )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -123,14 +124,6 @@ public final class ClientRegistry
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void setupClient( FMLClientSetupEvent event )
|
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
|
// Setup TESRs
|
||||||
BlockEntityRenderers.register( Registry.ModBlockEntities.MONITOR_NORMAL.get(), TileEntityMonitorRenderer::new );
|
BlockEntityRenderers.register( Registry.ModBlockEntities.MONITOR_NORMAL.get(), TileEntityMonitorRenderer::new );
|
||||||
BlockEntityRenderers.register( Registry.ModBlockEntities.MONITOR_ADVANCED.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.Vec3;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
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.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ public final class CableHighlightRenderer
|
|||||||
* @see net.minecraft.client.renderer.LevelRenderer#renderHitOutline
|
* @see net.minecraft.client.renderer.LevelRenderer#renderHitOutline
|
||||||
*/
|
*/
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void drawHighlight( DrawSelectionEvent.HighlightBlock event )
|
public static void drawHighlight( RenderHighlightEvent.Block event )
|
||||||
{
|
{
|
||||||
BlockHitResult hit = event.getTarget();
|
BlockHitResult hit = event.getTarget();
|
||||||
BlockPos pos = hit.getBlockPos();
|
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.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
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.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ import java.util.List;
|
|||||||
public class DebugOverlay
|
public class DebugOverlay
|
||||||
{
|
{
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onRenderText( RenderGameOverlayEvent.Text event )
|
public static void onRenderText( CustomizeGuiOverlayEvent.DebugText event )
|
||||||
{
|
{
|
||||||
Minecraft minecraft = Minecraft.getInstance();
|
Minecraft minecraft = Minecraft.getInstance();
|
||||||
if( !minecraft.options.renderDebug || minecraft.level == null ) return;
|
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.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
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.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ public final class MonitorHighlightRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void drawHighlight( DrawSelectionEvent.HighlightBlock event )
|
public static void drawHighlight( RenderHighlightEvent.Block event )
|
||||||
{
|
{
|
||||||
// Preserve normal behaviour when crouching.
|
// Preserve normal behaviour when crouching.
|
||||||
if( event.getCamera().getEntity().isCrouching() ) return;
|
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.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
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 javax.annotation.Nonnull;
|
||||||
import java.util.List;
|
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 )
|
private void renderModel( @Nonnull PoseStack transform, @Nonnull VertexConsumer renderer, int lightmapCoord, int overlayLight, BakedModel model, int[] tints )
|
||||||
{
|
{
|
||||||
random.setSeed( 0 );
|
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 )
|
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()];
|
if( idx >= 0 && idx < tints.length ) tint = tints[bakedquad.getTintIndex()];
|
||||||
}
|
}
|
||||||
|
|
||||||
float f = (float) (tint >> 16 & 255) / 255.0F;
|
float r = (float) (tint >> 16 & 255) / 255.0F;
|
||||||
float f1 = (float) (tint >> 8 & 255) / 255.0F;
|
float g = (float) (tint >> 8 & 255) / 255.0F;
|
||||||
float f2 = (float) (tint & 255) / 255.0F;
|
float b = (float) (tint & 255) / 255.0F;
|
||||||
buffer.putBulkData( matrix, bakedquad, f, f1, f2, lightmapCoord, overlayLight, true );
|
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.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.client.resources.model.*;
|
import net.minecraft.client.resources.model.*;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
|
||||||
import net.minecraft.util.GsonHelper;
|
import net.minecraft.util.GsonHelper;
|
||||||
import net.minecraftforge.client.model.IModelConfiguration;
|
import net.minecraftforge.client.model.geometry.IGeometryBakingContext;
|
||||||
import net.minecraftforge.client.model.IModelLoader;
|
import net.minecraftforge.client.model.geometry.IGeometryLoader;
|
||||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
import net.minecraftforge.client.model.geometry.IUnbakedGeometry;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -25,7 +24,7 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
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" );
|
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
|
@Nonnull
|
||||||
@Override
|
@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" ) );
|
ResourceLocation model = new ResourceLocation( GsonHelper.getAsString( modelContents, "model" ) );
|
||||||
return new TurtleModel( 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;
|
private final ResourceLocation family;
|
||||||
|
|
||||||
@ -58,7 +52,7 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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<>();
|
Set<Material> materials = new HashSet<>();
|
||||||
materials.addAll( modelGetter.apply( family ).getMaterials( modelGetter, missingTextureErrors ) );
|
materials.addAll( modelGetter.apply( family ).getMaterials( modelGetter, missingTextureErrors ) );
|
||||||
@ -67,7 +61,7 @@ public final class TurtleModelLoader implements IModelLoader<TurtleModelLoader.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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(
|
return new TurtleSmartItemModel(
|
||||||
bakery.bake( family, transform, spriteGetter ),
|
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.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Transformation;
|
import com.mojang.math.Transformation;
|
||||||
import dan200.computercraft.api.client.TransformedModel;
|
|
||||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||||
import dan200.computercraft.api.turtle.TurtleSide;
|
import dan200.computercraft.api.turtle.TurtleSide;
|
||||||
import dan200.computercraft.shared.turtle.items.ItemTurtle;
|
import dan200.computercraft.shared.turtle.items.ItemTurtle;
|
||||||
import dan200.computercraft.shared.util.Holiday;
|
import dan200.computercraft.shared.util.Holiday;
|
||||||
import dan200.computercraft.shared.util.HolidayUtil;
|
import dan200.computercraft.shared.util.HolidayUtil;
|
||||||
import net.minecraft.client.Minecraft;
|
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.block.model.ItemTransforms;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.client.resources.model.ModelManager;
|
import net.minecraft.client.resources.model.ModelManager;
|
||||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
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.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraftforge.client.model.BakedModelWrapper;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
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;
|
private static final Transformation identity, flip;
|
||||||
|
|
||||||
@ -49,7 +41,7 @@ public class TurtleSmartItemModel implements BakedModel
|
|||||||
flip = new Transformation( stack.last().pose() );
|
flip = new Transformation( stack.last().pose() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static record TurtleModelCombination(
|
private record TurtleModelCombination(
|
||||||
boolean colour,
|
boolean colour,
|
||||||
ITurtleUpgrade leftUpgrade,
|
ITurtleUpgrade leftUpgrade,
|
||||||
ITurtleUpgrade rightUpgrade,
|
ITurtleUpgrade rightUpgrade,
|
||||||
@ -63,112 +55,64 @@ public class TurtleSmartItemModel implements BakedModel
|
|||||||
private final BakedModel familyModel;
|
private final BakedModel familyModel;
|
||||||
private final BakedModel colourModel;
|
private final BakedModel colourModel;
|
||||||
|
|
||||||
private final HashMap<TurtleModelCombination, BakedModel> cachedModels = new HashMap<>();
|
private final Map<TurtleModelCombination, List<BakedModel>> cachedModels = new HashMap<>();
|
||||||
private final ItemOverrides overrides;
|
|
||||||
|
|
||||||
public TurtleSmartItemModel( BakedModel familyModel, BakedModel colourModel )
|
public TurtleSmartItemModel( BakedModel familyModel, BakedModel colourModel )
|
||||||
{
|
{
|
||||||
|
super( familyModel );
|
||||||
this.familyModel = familyModel;
|
this.familyModel = familyModel;
|
||||||
this.colourModel = colourModel;
|
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 )
|
|
||||||
{
|
|
||||||
ItemTurtle turtle = (ItemTurtle) stack.getItem();
|
|
||||||
int colour = turtle.getColour( stack );
|
|
||||||
ITurtleUpgrade leftUpgrade = turtle.getUpgrade( stack, TurtleSide.LEFT );
|
|
||||||
ITurtleUpgrade rightUpgrade = turtle.getUpgrade( stack, TurtleSide.RIGHT );
|
|
||||||
ResourceLocation overlay = turtle.getOverlay( stack );
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ItemOverrides getOverrides()
|
public BakedModel applyTransform( @Nonnull ItemTransforms.TransformType cameraTransformType, @Nonnull PoseStack poseStack, boolean applyLeftHandTransform )
|
||||||
{
|
{
|
||||||
return overrides;
|
originalModel.applyTransform( cameraTransformType, poseStack, applyLeftHandTransform );
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BakedModel buildModel( TurtleModelCombination combo )
|
@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 );
|
||||||
|
ResourceLocation overlay = turtle.getOverlay( stack );
|
||||||
|
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 );
|
||||||
|
return cachedModels.computeIfAbsent( combo, this::buildModel );
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BakedModel> buildModel( TurtleModelCombination combo )
|
||||||
{
|
{
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager();
|
ModelManager modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager();
|
||||||
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay, combo.christmas );
|
|
||||||
|
|
||||||
BakedModel baseModel = combo.colour ? colourModel : familyModel;
|
var transformation = combo.flip ? flip : identity;
|
||||||
BakedModel overlayModel = overlayModelLocation != null ? modelManager.getModel( overlayModelLocation ) : null;
|
ArrayList<BakedModel> parts = new ArrayList<>( 4 );
|
||||||
Transformation transform = combo.flip ? flip : identity;
|
parts.add( new TransformedBakedModel( combo.colour() ? colourModel : familyModel, transformation ) );
|
||||||
TransformedModel leftModel = combo.leftUpgrade != null ? combo.leftUpgrade.getModel( null, TurtleSide.LEFT ) : null;
|
|
||||||
TransformedModel rightModel = combo.rightUpgrade != null ? combo.rightUpgrade.getModel( null, TurtleSide.RIGHT ) : null;
|
ModelResourceLocation overlayModelLocation = TileEntityTurtleRenderer.getTurtleOverlayModel( combo.overlay(), combo.christmas() );
|
||||||
return new TurtleMultiModel( baseModel, overlayModel, transform, leftModel, rightModel );
|
if( overlayModelLocation != null )
|
||||||
|
{
|
||||||
|
parts.add( new TransformedBakedModel( modelManager.getModel( overlayModelLocation ), transformation ) );
|
||||||
|
}
|
||||||
|
if( combo.leftUpgrade() != null )
|
||||||
|
{
|
||||||
|
parts.add( new TransformedBakedModel( combo.leftUpgrade().getModel( null, TurtleSide.LEFT ) ).composeWith( transformation ) );
|
||||||
|
}
|
||||||
|
if( combo.rightUpgrade() != null )
|
||||||
|
{
|
||||||
|
parts.add( new TransformedBakedModel( combo.rightUpgrade().getModel( null, TurtleSide.RIGHT ) ).composeWith( transformation ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand )
|
|
||||||
{
|
|
||||||
return familyModel.getQuads( state, facing, rand );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public List<BakedQuad> getQuads( BlockState state, Direction facing, @Nonnull RandomSource rand, @Nonnull IModelData data )
|
|
||||||
{
|
|
||||||
return familyModel.getQuads( state, facing, rand, data );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useAmbientOcclusion()
|
|
||||||
{
|
|
||||||
return familyModel.useAmbientOcclusion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isGui3d()
|
|
||||||
{
|
|
||||||
return familyModel.isGui3d();
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 dan200.computercraft.shared.Registry;
|
||||||
import net.minecraft.data.DataGenerator;
|
import net.minecraft.data.DataGenerator;
|
||||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
import net.minecraftforge.data.event.GatherDataEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber( bus = Mod.EventBusSubscriber.Bus.MOD )
|
@Mod.EventBusSubscriber( bus = Mod.EventBusSubscriber.Bus.MOD )
|
||||||
public class Generators
|
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.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
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.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
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.
|
* 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 )
|
@Mixin( BlockRenderDispatcher.class )
|
||||||
public class BlockRenderDispatcherMixin
|
public class BlockRenderDispatcherMixin
|
||||||
@ -53,13 +53,13 @@ public class BlockRenderDispatcherMixin
|
|||||||
private ModelBlockRenderer modelRenderer;
|
private ModelBlockRenderer modelRenderer;
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "name=/^renderBreakingTexture/ desc=/IModelData;\\)V$/",
|
method = "name=/^renderBreakingTexture/ desc=/ModelData;\\)V$/",
|
||||||
at = @At( "HEAD" ),
|
at = @At( "HEAD" ),
|
||||||
cancellable = true,
|
cancellable = true,
|
||||||
require = 0 // This isn't critical functionality, so don't worry if we can't apply it.
|
require = 0 // This isn't critical functionality, so don't worry if we can't apply it.
|
||||||
)
|
)
|
||||||
public void renderBlockDamage(
|
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
|
CallbackInfo info
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -85,6 +85,6 @@ public class BlockRenderDispatcherMixin
|
|||||||
|
|
||||||
BakedModel model = blockModelShaper.getBlockModel( newState );
|
BakedModel model = blockModelShaper.getBlockModel( newState );
|
||||||
long seed = newState.getSeed( pos );
|
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();
|
IComputer computer = ((IContainerComputer) container).getComputer();
|
||||||
if( computer instanceof ServerComputer )
|
if( computer instanceof ServerComputer )
|
||||||
{
|
{
|
||||||
((ServerComputer) computer).sendTerminalState( event.getPlayer() );
|
((ServerComputer) computer).sendTerminalState( event.getEntity() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
package dan200.computercraft.shared;
|
package dan200.computercraft.shared;
|
||||||
|
|
||||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
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.ComputerCraft;
|
||||||
import dan200.computercraft.core.apis.http.NetworkUtils;
|
import dan200.computercraft.core.apis.http.NetworkUtils;
|
||||||
import dan200.computercraft.core.apis.http.options.Action;
|
import dan200.computercraft.core.apis.http.options.Action;
|
||||||
@ -367,6 +365,4 @@ public final class Config
|
|||||||
{
|
{
|
||||||
sync( event.getConfig() );
|
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.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
|
import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
|
||||||
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
|
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.ColourableRecipe;
|
||||||
import dan200.computercraft.shared.common.ContainerHeldItem;
|
import dan200.computercraft.shared.common.ContainerHeldItem;
|
||||||
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
|
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
|
||||||
@ -164,7 +167,7 @@ public final class Registry
|
|||||||
|
|
||||||
public static class ModBlockEntities
|
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 )
|
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
|
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",
|
public static final RegistryObject<MenuType<ContainerComputerBase>> COMPUTER = CONTAINERS.register( "computer",
|
||||||
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
() -> ContainerData.toType( ComputerContainerData::new, ComputerMenuWithoutInventory::new ) );
|
||||||
@ -317,7 +320,7 @@ public final class Registry
|
|||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
private static <T extends ArgumentType<?>> void registerUnsafe( String name, Class<T> type, ArgumentTypeInfo<?, ?> serializer )
|
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 )
|
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 )
|
network.messageBuilder( type, id, direction )
|
||||||
.encoder( NetworkMessage::toBytes )
|
.encoder( NetworkMessage::toBytes )
|
||||||
.decoder( decoder )
|
.decoder( decoder )
|
||||||
.consumer( ( packet, contextSup ) -> {
|
.consumerMainThread( ( packet, contextSup ) -> {
|
||||||
NetworkEvent.Context context = contextSup.get();
|
NetworkEvent.Context context = contextSup.get();
|
||||||
context.enqueueWork( () -> packet.handle( context ) );
|
context.enqueueWork( () -> packet.handle( context ) );
|
||||||
context.setPacketHandled( true );
|
context.setPacketHandled( true );
|
||||||
|
@ -30,7 +30,7 @@ public interface ContainerData
|
|||||||
|
|
||||||
default void open( Player player, MenuProvider owner )
|
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 )
|
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
|
// Open the GUI
|
||||||
if( !getLevel().isClientSide && isUsable( player ) )
|
if( !getLevel().isClientSide && isUsable( player ) )
|
||||||
{
|
{
|
||||||
NetworkHooks.openGui( (ServerPlayer) player, this );
|
NetworkHooks.openScreen( (ServerPlayer) player, this );
|
||||||
}
|
}
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ class GenericPeripheral implements IDynamicPeripheral
|
|||||||
|
|
||||||
GenericPeripheral( BlockEntity tile, String name, Set<String> additionalTypes, List<SaturatedMethod> methods )
|
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.tile = tile;
|
||||||
this.type = name != null ? name : (type != null ? type.toString() : "unknown");
|
this.type = name != null ? name : (type != null ? type.toString() : "unknown");
|
||||||
this.additionalTypes = additionalTypes;
|
this.additionalTypes = additionalTypes;
|
||||||
|
@ -11,13 +11,11 @@ import dan200.computercraft.shared.network.client.MonitorClientMessage;
|
|||||||
import dan200.computercraft.shared.network.client.TerminalState;
|
import dan200.computercraft.shared.network.client.TerminalState;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
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.Level;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
import net.minecraftforge.event.TickEvent;
|
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.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
@ -28,7 +26,6 @@ import java.util.Queue;
|
|||||||
public final class MonitorWatcher
|
public final class MonitorWatcher
|
||||||
{
|
{
|
||||||
private static final Queue<TileMonitor> watching = new ArrayDeque<>();
|
private static final Queue<TileMonitor> watching = new ArrayDeque<>();
|
||||||
private static final Queue<PlayerUpdate> playerUpdates = new ArrayDeque<>();
|
|
||||||
|
|
||||||
private MonitorWatcher()
|
private MonitorWatcher()
|
||||||
{
|
{
|
||||||
@ -46,47 +43,28 @@ public final class MonitorWatcher
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onWatch( ChunkWatchEvent.Watch event )
|
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
|
// Find all origin monitors who are not already on the queue and send the
|
||||||
// monitor will have no contents, and so we won't need to send an update anyway.
|
// monitor data to the player.
|
||||||
ChunkPos chunkPos = event.getPos();
|
for( BlockEntity te : event.getChunk().getBlockEntities().values() )
|
||||||
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.
|
|
||||||
if( !(te instanceof TileMonitor monitor) ) continue;
|
if( !(te instanceof TileMonitor monitor) ) continue;
|
||||||
|
|
||||||
ServerMonitor serverMonitor = getMonitor( monitor );
|
ServerMonitor serverMonitor = getMonitor( monitor );
|
||||||
if( serverMonitor == null || monitor.enqueued ) continue;
|
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.
|
TerminalState state = monitor.cached;
|
||||||
playerUpdates.add( new PlayerUpdate( event.getPlayer(), monitor ) );
|
if( state == null ) state = monitor.cached = serverMonitor.write();
|
||||||
|
NetworkHandler.sendToPlayer( event.getPlayer(), new MonitorClientMessage( monitor.getBlockPos(), state ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onTick( TickEvent.ServerTickEvent event )
|
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;
|
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;
|
long limit = ComputerCraft.monitorBandwidth;
|
||||||
boolean obeyLimit = limit > 0;
|
boolean obeyLimit = limit > 0;
|
||||||
|
|
||||||
@ -125,16 +103,4 @@ public final class MonitorWatcher
|
|||||||
if( state == null ) state = tile.cached = monitor.write();
|
if( state == null ) state = tile.cached = monitor.write();
|
||||||
return state;
|
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 ) )
|
if( !getLevel().isClientSide && isUsable( player ) )
|
||||||
{
|
{
|
||||||
NetworkHooks.openGui( (ServerPlayer) player, this );
|
NetworkHooks.openScreen( (ServerPlayer) player, this );
|
||||||
}
|
}
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
|
|||||||
ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false );
|
ItemStack stack = turtle.getItemHandler().extractItem( slot, limit, false );
|
||||||
int fuelToGive = fuelPerItem * stack.getCount();
|
int fuelToGive = fuelPerItem * stack.getCount();
|
||||||
// Store the replacement item in the inventory
|
// Store the replacement item in the inventory
|
||||||
ItemStack replacementStack = stack.getItem().getContainerItem( stack );
|
ItemStack replacementStack = ForgeHooks.getCraftingRemainingItem( stack );
|
||||||
if( !replacementStack.isEmpty() )
|
if( !replacementStack.isEmpty() )
|
||||||
{
|
{
|
||||||
ItemStack remainder = InventoryUtil.storeItems( replacementStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
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.MinecraftForge;
|
||||||
import net.minecraftforge.common.ToolActions;
|
import net.minecraftforge.common.ToolActions;
|
||||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
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 org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
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.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.phys.AABB;
|
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.event.entity.living.LivingDropsEvent;
|
||||||
import net.minecraftforge.eventbus.api.EventPriority;
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
@ -80,10 +80,10 @@ public final class DropConsumer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent( priority = EventPriority.HIGHEST )
|
@SubscribeEvent( priority = EventPriority.HIGHEST )
|
||||||
public static void onEntitySpawn( EntityJoinWorldEvent event )
|
public static void onEntitySpawn( EntityJoinLevelEvent event )
|
||||||
{
|
{
|
||||||
// Capture any nearby item spawns
|
// 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() ) )
|
&& dropBounds.contains( event.getEntity().position() ) )
|
||||||
{
|
{
|
||||||
handleDrops( ((ItemEntity) event.getEntity()).getItem() );
|
handleDrops( ((ItemEntity) event.getEntity()).getItem() );
|
||||||
|
@ -21,6 +21,6 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a
|
|||||||
[[dependencies.computercraft]]
|
[[dependencies.computercraft]]
|
||||||
modId="forge"
|
modId="forge"
|
||||||
mandatory=true
|
mandatory=true
|
||||||
versionRange="[41.0.38,42)"
|
versionRange="[41.0.98,42)"
|
||||||
ordering="NONE"
|
ordering="NONE"
|
||||||
side="BOTH"
|
side="BOTH"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"parent": "block/cube",
|
"parent": "block/cube",
|
||||||
|
"render_type": "cutout",
|
||||||
"textures": {
|
"textures": {
|
||||||
"particle": "#front",
|
"particle": "#front",
|
||||||
"down": "#top",
|
"down": "#top",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"parent": "block/block",
|
"parent": "block/block",
|
||||||
|
"render_type": "translucent",
|
||||||
"textures": {
|
"textures": {
|
||||||
"particle": "#texture"
|
"particle": "#texture"
|
||||||
},
|
},
|
||||||
|
@ -137,7 +137,7 @@ fun GameTestHelper.sequence(run: GameTestSequence.() -> GameTestSequence) {
|
|||||||
run(startSequence()).thenSucceed()
|
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 {
|
fun <T : BlockEntity> GameTestHelper.getBlockEntity(pos: BlockPos, type: BlockEntityType<T>): T {
|
||||||
val tile = getBlockEntity(pos)
|
val tile = getBlockEntity(pos)
|
||||||
|
@ -29,7 +29,7 @@ public final class ClientHooks
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onGuiInit( ScreenEvent.InitScreenEvent event )
|
public static void onGuiInit( ScreenEvent.Init event )
|
||||||
{
|
{
|
||||||
if( triggered || !(event.getScreen() instanceof TitleScreen) ) return;
|
if( triggered || !(event.getScreen() instanceof TitleScreen) ) return;
|
||||||
triggered = true;
|
triggered = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user