mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-23 11:28:10 +01:00
Merge branch 'master' into mc1.15/dev
This commit is contained in:
commit
901c530f62
208 changed files with 4163 additions and 1550 deletions
33
README.md
33
README.md
|
@ -1,18 +1,23 @@
|
|||
# Create
|
||||
<p align="center"><img src="https://i.imgur.com/35JmqWB.gif" alt="Logo" width="100"></p>
|
||||
<h1 align="center">Create<br>
|
||||
<a href="https://www.patreon.com/simibubi"><img src="https://img.shields.io/badge/Supporters-30-ff5733" alt="Patreon"></a>
|
||||
<a href="https://www.curseforge.com/minecraft/mc-mods/create/files"><img src="https://img.shields.io/badge/Available%20for-MC%201.14-c70039" alt="Supported Versions"></a>
|
||||
<a href="https://github.com/Creators-of-Create/Create/blob/master/LICENSE"><img src="https://img.shields.io/github/license/Creators-of-Create/Create?style=flat&color=900c3f" alt="License"></a>
|
||||
<a href="https://discord.gg/hmaD7Se"><img src="https://img.shields.io/discord/620934202875183104?color=844685&label=Feedback%20%26%20Help&style=flat" alt="Discord"></a>
|
||||
<a href="https://www.curseforge.com/minecraft/mc-mods/create"><img src="http://cf.way2muchnoise.eu/short_create.svg" alt="Curseforge Downloads"></a><br><br>
|
||||
</h1>
|
||||
|
||||
Welcome to Create, a mod offering a variety of tools and blocks for Building, Decoration and Aesthetic Automation.
|
||||
|
||||
The added elements of tech are designed to leave as many design choices to the player as possible, where item processing doesn't happen inside a single block with funny textures, it requires a set of actors working together in many possible arrangements.
|
||||
|
||||
Check out the wiki and in-game Tool-tips for further info on how to use these features, and stay tuned for an ever-growing selection of possibilities for Creative and Survival Minecraft.
|
||||
|
||||
## Links
|
||||
[<img src="https://i.imgur.com/0lLX9Oy.jpg" width="320">](https://github.com/simibubi/Create/issues "Report Issues")
|
||||
[<img src="https://i.imgur.com/bjEZraY.jpg" width="320">](https://www.youtube.com/playlist?list=PLyADkcfPLU8ywCXZPaDbQ_JZJL0CGDN5Z "Watch Videos")
|
||||
[<img src="https://i.imgur.com/aWrjfKJ.jpg" width="320">](https://discord.gg/hmaD7Se "Feedback & Help")
|
||||
[<img src="https://i.imgur.com/xj8o2xC.jpg" width="320">](https://www.patreon.com/simibubi "Support Us")
|
||||
[<img src="https://i.imgur.com/0lLX9Oy.jpg" width="210">](https://github.com/simibubi/Create/issues "Report Issues")
|
||||
[<img src="https://i.imgur.com/bjEZraY.jpg" width="210">](https://www.youtube.com/playlist?list=PLyADkcfPLU8ywCXZPaDbQ_JZJL0CGDN5Z "Watch Videos")
|
||||
[<img src="https://i.imgur.com/aWrjfKJ.jpg" width="210">](https://discord.gg/hmaD7Se "Feedback & Help")
|
||||
[<img src="https://i.imgur.com/xj8o2xC.jpg" width="210">](https://www.patreon.com/simibubi "Support Us")
|
||||
|
||||
## Current Progress
|
||||
- Create 0.2.2 is coming soon with more bug-fixes. Thank you for testing Create with us!
|
||||
- Support for Minecraft 1.12: Not planned
|
||||
- Support for Minecraft 1.15: Porting work is in Progress!
|
||||
- Support for Fabric: Not planned
|
||||
|
@ -25,14 +30,4 @@ Check out the wiki and in-game Tool-tips for further info on how to use these fe
|
|||
- simibubi - Developer & Artist
|
||||
- tterrag - Developer & Port-Meister
|
||||
|
||||
## Localization
|
||||
|
||||
| Code | Version | Language | Author |
|
||||
|-------|---------|------------|--------------------------|
|
||||
| en_us | 0.2.2 | English US | |
|
||||
| de_de | 0.1 | German | Vexatos & Azratosh |
|
||||
| nl_nl | 0.1 | Dutch | Prusias |
|
||||
| fr_fr | 0.2.1 | French | Kiro |
|
||||
| zh_cn | 0.2.1 | Chinese | noptia & spider_stranger |
|
||||
| ru_ru | 0.1 | Russian | sirabein |
|
||||
| pt_br | 0.1 | Brazilian | lucassabreu |
|
||||
### For more information, check out our [Project Page](https://www.curseforge.com/minecraft/mc-mods/create)
|
||||
|
|
|
@ -72,6 +72,7 @@ import com.simibubi.create.modules.logistics.block.diodes.ToggleLatchBlock;
|
|||
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.funnel.FunnelBlock;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.CreativeCrateBlock;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
|
||||
import com.simibubi.create.modules.logistics.block.transposer.LinkedTransposerBlock;
|
||||
import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock;
|
||||
|
@ -125,7 +126,7 @@ public enum AllBlocks implements NonNullSupplier<Block> {
|
|||
GEARBOX(GearboxBlock::new),
|
||||
CLUTCH(ClutchBlock::new),
|
||||
GEARSHIFT(GearshiftBlock::new),
|
||||
|
||||
|
||||
ENCASED_BELT(EncasedBeltBlock::new),
|
||||
ADJUSTABLE_PULLEY(AdjustablePulleyBlock::new),
|
||||
BELT(BeltBlock::new, ComesWith.NO_BLOCKITEM),
|
||||
|
@ -180,11 +181,12 @@ public enum AllBlocks implements NonNullSupplier<Block> {
|
|||
ROTATION_SPEED_CONTROLLER(SpeedControllerBlock::new),
|
||||
|
||||
_2_(Sections.LOGISTICS),
|
||||
|
||||
|
||||
CONTACT(ContactBlock::new),
|
||||
REDSTONE_BRIDGE(RedstoneLinkBlock::new),
|
||||
STOCKSWITCH(StockswitchBlock::new),
|
||||
FLEXCRATE(FlexcrateBlock::new),
|
||||
CREATIVE_CRATE(() -> new CreativeCrateBlock(Properties.from(Blocks.CHEST))),
|
||||
EXTRACTOR(ExtractorBlock::new),
|
||||
VERTICAL_EXTRACTOR(ExtractorBlock.Vertical::new, ComesWith.NO_BLOCKITEM),
|
||||
LINKED_EXTRACTOR(LinkedExtractorBlock::new),
|
||||
|
@ -202,9 +204,9 @@ public enum AllBlocks implements NonNullSupplier<Block> {
|
|||
FLEXPULSEPEATER(FlexpeaterBlock::new),
|
||||
REDSTONE_LATCH(LatchBlock::new),
|
||||
TOGGLE_LATCH(ToggleLatchBlock::new),
|
||||
|
||||
|
||||
_3_(Sections.MATERIALS),
|
||||
|
||||
|
||||
COPPER_ORE(() -> new OxidizingBlock(Properties.from(Blocks.IRON_ORE), 1),
|
||||
ITaggable.create().withForgeTags("ores/copper")),
|
||||
ZINC_ORE(() -> new Block(Properties.from(Blocks.GOLD_ORE).harvestLevel(2).harvestTool(ToolType.PICKAXE)),
|
||||
|
@ -226,13 +228,13 @@ public enum AllBlocks implements NonNullSupplier<Block> {
|
|||
COCOA_LOG(CocoaLogBlock::new, ITaggable.create().withVanillaTags(ITaggable.BLOCK, "jungle_logs")),
|
||||
|
||||
_5_(Sections.SCHEMATICS),
|
||||
|
||||
|
||||
// SCHEMATICANNON(SchematicannonBlock::new),
|
||||
// CREATIVE_CRATE(CreativeCrateBlock::new),
|
||||
// SCHEMATIC_TABLE(SchematicTableBlock::new),
|
||||
|
||||
|
||||
_6_(Sections.PALETTES),
|
||||
|
||||
|
||||
TILED_GLASS(() -> new GlassBlock(Properties.from(Blocks.GLASS)),
|
||||
ITaggable.create().withVanillaTags(ITaggable.BLOCK, "impermeable").withForgeTags("glass")),
|
||||
FRAMED_GLASS(() -> new CTGlassBlock(AllCTs.FRAMED_GLASS, false)),
|
||||
|
|
|
@ -21,12 +21,10 @@ import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
|||
|
||||
public enum AllEntities {
|
||||
|
||||
CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 3, true,
|
||||
ContraptionEntity::build),
|
||||
STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 40,
|
||||
false, ContraptionEntity::build),
|
||||
SUPER_GLUE(SuperGlueEntity::new, EntityClassification.MISC, 30, Integer.MAX_VALUE, false, SuperGlueEntity::build),
|
||||
|
||||
CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 5, 3, true, ContraptionEntity::build),
|
||||
STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 20, 40, false, ContraptionEntity::build),
|
||||
SUPER_GLUE(SuperGlueEntity::new, EntityClassification.MISC, 10, Integer.MAX_VALUE, false, SuperGlueEntity::build),
|
||||
|
||||
;
|
||||
|
||||
private IFactory<?> factory;
|
||||
|
@ -53,8 +51,10 @@ public enum AllEntities {
|
|||
for (AllEntities entity : values()) {
|
||||
String id = Lang.asId(entity.name());
|
||||
ResourceLocation resourceLocation = new ResourceLocation(Create.ID, id);
|
||||
Builder<? extends Entity> builder = EntityType.Builder.create(entity.factory, entity.group)
|
||||
.setTrackingRange(entity.range).setUpdateInterval(entity.updateFrequency)
|
||||
Builder<? extends Entity> builder = EntityType.Builder
|
||||
.create(entity.factory, entity.group)
|
||||
.setTrackingRange(entity.range)
|
||||
.setUpdateInterval(entity.updateFrequency)
|
||||
.setShouldReceiveVelocityUpdates(entity.sendVelocity);
|
||||
if (entity.propertyBuilder != null)
|
||||
builder = entity.propertyBuilder.apply(builder);
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.simibubi.create.modules.curiosities.TreeFertilizerItem;
|
|||
import com.simibubi.create.modules.curiosities.deforester.DeforesterItem;
|
||||
import com.simibubi.create.modules.curiosities.symmetry.SymmetryWandItem;
|
||||
import com.simibubi.create.modules.curiosities.tools.AllToolTiers;
|
||||
import com.simibubi.create.modules.curiosities.tools.BlazingSwordItem;
|
||||
import com.simibubi.create.modules.curiosities.tools.BlazingToolItem;
|
||||
import com.simibubi.create.modules.curiosities.tools.RoseQuartzToolItem;
|
||||
import com.simibubi.create.modules.curiosities.tools.SandPaperItem;
|
||||
|
@ -123,7 +124,7 @@ public enum AllItems {
|
|||
BLAZING_PICKAXE(p -> new BlazingToolItem(1, -2.8F, p, PICKAXE)),
|
||||
BLAZING_SHOVEL(p -> new BlazingToolItem(1.5F, -3.0F, p, SHOVEL)),
|
||||
BLAZING_AXE(p -> new BlazingToolItem(5.0F, -3.0F, p, AXE)),
|
||||
BLAZING_SWORD(p -> new SwordItem(AllToolTiers.BLAZING, 3, -2.4F, p)),
|
||||
BLAZING_SWORD(p -> new BlazingSwordItem(AllToolTiers.BLAZING, 3, -2.4F, p)),
|
||||
|
||||
ROSE_QUARTZ_PICKAXE(p -> new RoseQuartzToolItem(1, -2.8F, p, PICKAXE)),
|
||||
ROSE_QUARTZ_SHOVEL(p -> new RoseQuartzToolItem(1.5F, -3.0F, p, SHOVEL)),
|
||||
|
|
|
@ -83,6 +83,7 @@ import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntityRe
|
|||
import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.funnel.FunnelTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.CreativeCrateTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.transposer.LinkedTransposerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.transposer.TransposerTileEntity;
|
||||
|
@ -155,6 +156,7 @@ public enum AllTileEntities {
|
|||
REDSTONE_BRIDGE(RedstoneLinkTileEntity::new, AllBlocks.REDSTONE_BRIDGE),
|
||||
STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH),
|
||||
FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE),
|
||||
CREATIVE_CRATE(CreativeCrateTileEntity::new, AllBlocks.CREATIVE_CRATE),
|
||||
EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR, AllBlocks.VERTICAL_EXTRACTOR),
|
||||
LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR, AllBlocks.VERTICAL_LINKED_EXTRACTOR),
|
||||
TRANSPOSER(TransposerTileEntity::new, AllBlocks.TRANSPOSER, AllBlocks.VERTICAL_TRANSPOSER),
|
||||
|
@ -238,6 +240,7 @@ public enum AllTileEntities {
|
|||
bind(FURNACE_ENGINE, EngineRenderer::new);
|
||||
bind(ROTATION_SPEED_CONTROLLER, SpeedControllerRenderer::new);
|
||||
|
||||
bind(CREATIVE_CRATE, SmartTileEntityRenderer::new);
|
||||
bind(REDSTONE_BRIDGE, SmartTileEntityRenderer::new);
|
||||
bind(EXTRACTOR, SmartTileEntityRenderer::new);
|
||||
bind(LINKED_EXTRACTOR, SmartTileEntityRenderer::new);
|
||||
|
@ -247,9 +250,6 @@ public enum AllTileEntities {
|
|||
bind(BELT_TUNNEL, BeltTunnelTileEntityRenderer::new);
|
||||
bind(ENTITY_DETECTOR, BeltObserverTileEntityRenderer::new);
|
||||
bind(FLEXPEATER, FlexpeaterTileEntityRenderer::new);
|
||||
|
||||
// bind(LogisticalController, LogisticalControllerTileEntityRenderer::new);
|
||||
// bind(LogisticiansTable, LogisticiansTableTileEntityRenderer::new);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // TODO 1.15 this generic stuff is incompatible with the enum system - need strong types
|
||||
|
|
|
@ -26,6 +26,7 @@ public enum ScreenResources {
|
|||
SCHEMATICANNON_PROGRESS_2("schematicannon.png", 122, 161, 16, 15),
|
||||
SCHEMATICANNON_HIGHLIGHT("schematicannon.png", 0, 182, 28, 28),
|
||||
SCHEMATICANNON_FUEL("schematicannon.png", 0, 215, 82, 4),
|
||||
SCHEMATICANNON_FUEL_CREATIVE("schematicannon.png", 0, 219, 82, 4),
|
||||
|
||||
FLEXCRATE("flex_crate_and_stockpile_switch.png", 125, 129),
|
||||
FLEXCRATE_DOUBLE("double_flexcrate.png", 197, 129),
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.simibubi.create.compat.jei.category.SawingCategory;
|
|||
import com.simibubi.create.compat.jei.category.SmokingViaFanCategory;
|
||||
import com.simibubi.create.compat.jei.category.SplashingCategory;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCraftingRecipe;
|
||||
import com.simibubi.create.modules.contraptions.components.mixer.MixingRecipe;
|
||||
import com.simibubi.create.modules.contraptions.components.press.MechanicalPressTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen;
|
||||
|
@ -66,8 +65,7 @@ public class CreateJEI implements IModPlugin {
|
|||
private PackingCategory packingCategory;
|
||||
private PolishingCategory polishingCategory;
|
||||
private MysteriousItemConversionCategory mysteryConversionCategory;
|
||||
private MechanicalCraftingCategory smallMechanicalCraftingCategory;
|
||||
private MechanicalCraftingCategory largeMechanicalCraftingCategory;
|
||||
private MechanicalCraftingCategory mechanicalCraftingCategory;
|
||||
|
||||
@Override
|
||||
public ResourceLocation getPluginUid() {
|
||||
|
@ -88,8 +86,7 @@ public class CreateJEI implements IModPlugin {
|
|||
packingCategory = new PackingCategory();
|
||||
polishingCategory = new PolishingCategory();
|
||||
mysteryConversionCategory = new MysteriousItemConversionCategory();
|
||||
smallMechanicalCraftingCategory = new MechanicalCraftingCategory(false);
|
||||
largeMechanicalCraftingCategory = new MechanicalCraftingCategory(true);
|
||||
mechanicalCraftingCategory = new MechanicalCraftingCategory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,10 +96,11 @@ public class CreateJEI implements IModPlugin {
|
|||
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
registration.addRecipeCategories(millingCategory, crushingCategory, splashingCategory, pressingCategory,
|
||||
smokingCategory, blastingCategory, blockzapperCategory, mixingCategory, sawingCategory,
|
||||
blockCuttingCategory, packingCategory, polishingCategory, mysteryConversionCategory,
|
||||
smallMechanicalCraftingCategory, largeMechanicalCraftingCategory);
|
||||
registration
|
||||
.addRecipeCategories(millingCategory, crushingCategory, splashingCategory, pressingCategory,
|
||||
smokingCategory, blastingCategory, blockzapperCategory, mixingCategory, sawingCategory,
|
||||
blockCuttingCategory, packingCategory, polishingCategory, mysteryConversionCategory,
|
||||
mechanicalCraftingCategory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -132,33 +130,28 @@ public class CreateJEI implements IModPlugin {
|
|||
packingCategory.getUid());
|
||||
registration.addRecipes(findRecipes(AllRecipes.SANDPAPER_POLISHING), polishingCategory.getUid());
|
||||
registration.addRecipes(MysteriousItemConversionCategory.getRecipes(), mysteryConversionCategory.getUid());
|
||||
|
||||
registration.addRecipes(findRecipes(
|
||||
r -> (r instanceof MechanicalCraftingRecipe) && MechanicalCraftingCategory.isSmall((ShapedRecipe) r)),
|
||||
smallMechanicalCraftingCategory.getUid());
|
||||
registration.addRecipes(
|
||||
findRecipes(
|
||||
r -> (r.getType() == IRecipeType.CRAFTING || r.getType() == AllRecipes.MECHANICAL_CRAFTING.type)
|
||||
&& (r instanceof ShapedRecipe) && !(r instanceof MechanicalCraftingRecipe)
|
||||
&& MechanicalCraftingCategory.isSmall((ShapedRecipe) r)),
|
||||
smallMechanicalCraftingCategory.getUid());
|
||||
registration.addRecipes(findRecipes(
|
||||
r -> (r.getType() == IRecipeType.CRAFTING || r.getType() == AllRecipes.MECHANICAL_CRAFTING.type)
|
||||
&& (r instanceof ShapedRecipe) && !MechanicalCraftingCategory.isSmall((ShapedRecipe) r)),
|
||||
largeMechanicalCraftingCategory.getUid());
|
||||
|
||||
registration.addRecipes(findRecipes(r -> (r.getType() == AllRecipes.MECHANICAL_CRAFTING.type)),
|
||||
mechanicalCraftingCategory.getUid());
|
||||
registration.addRecipes(findRecipes(r -> (r.getType() == IRecipeType.CRAFTING
|
||||
&& r.getType() != AllRecipes.MECHANICAL_CRAFTING.type) && (r instanceof ShapedRecipe)),
|
||||
mechanicalCraftingCategory.getUid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
ItemStack fan = new ItemStack(AllBlocks.ENCASED_FAN.get());
|
||||
|
||||
ItemStack splashingFan = fan.copy()
|
||||
ItemStack splashingFan = fan
|
||||
.copy()
|
||||
.setDisplayName(new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.splashing.fan")));
|
||||
ItemStack smokingFan = fan.copy().setDisplayName(
|
||||
new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.smokingViaFan.fan")));
|
||||
ItemStack blastingFan = fan.copy().setDisplayName(
|
||||
new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan")));
|
||||
ItemStack smokingFan = fan
|
||||
.copy()
|
||||
.setDisplayName(
|
||||
new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.smokingViaFan.fan")));
|
||||
ItemStack blastingFan = fan
|
||||
.copy()
|
||||
.setDisplayName(
|
||||
new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan")));
|
||||
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MILLSTONE.get()), millingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.CRUSHING_WHEEL.get()), crushingCategory.getUid());
|
||||
|
@ -176,10 +169,9 @@ public class CreateJEI implements IModPlugin {
|
|||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.BASIN.get()), packingCategory.getUid());
|
||||
registration.addRecipeCatalyst(AllItems.SAND_PAPER.asStack(), polishingCategory.getUid());
|
||||
registration.addRecipeCatalyst(AllItems.RED_SAND_PAPER.asStack(), polishingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()),
|
||||
smallMechanicalCraftingCategory.getUid());
|
||||
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()),
|
||||
largeMechanicalCraftingCategory.getUid());
|
||||
registration
|
||||
.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()),
|
||||
mechanicalCraftingCategory.getUid());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -193,18 +185,30 @@ public class CreateJEI implements IModPlugin {
|
|||
}
|
||||
|
||||
private static List<IRecipe<?>> findRecipes(Predicate<IRecipe<?>> pred) {
|
||||
return Minecraft.getInstance().world.getRecipeManager().getRecipes().stream().filter(pred)
|
||||
return Minecraft.getInstance().world
|
||||
.getRecipeManager()
|
||||
.getRecipes()
|
||||
.stream()
|
||||
.filter(pred)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<IRecipe<?>> findRecipesByType(IRecipeType<?> type) {
|
||||
return Minecraft.getInstance().world.getRecipeManager().getRecipes().stream().filter(r -> r.getType() == type)
|
||||
return Minecraft.getInstance().world
|
||||
.getRecipeManager()
|
||||
.getRecipes()
|
||||
.stream()
|
||||
.filter(r -> r.getType() == type)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<IRecipe<?>> findRecipesById(ResourceLocation id) {
|
||||
return Minecraft.getInstance().world.getRecipeManager().getRecipes().stream()
|
||||
.filter(r -> r.getSerializer().getRegistryName().equals(id)).collect(Collectors.toList());
|
||||
return Minecraft.getInstance().world
|
||||
.getRecipeManager()
|
||||
.getRecipes()
|
||||
.stream()
|
||||
.filter(r -> r.getSerializer().getRegistryName().equals(id))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<IRecipe<?>> findRecipesByTypeExcluding(IRecipeType<?> type, IRecipeType<?> excludingType) {
|
||||
|
|
|
@ -1,39 +1,103 @@
|
|||
package com.simibubi.create.compat.jei.category;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.ScreenResources;
|
||||
import com.simibubi.create.compat.jei.category.animations.AnimatedCrafter;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import mezz.jei.api.constants.VanillaTypes;
|
||||
import mezz.jei.api.gui.IRecipeLayout;
|
||||
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
|
||||
import mezz.jei.api.ingredients.IIngredientRenderer;
|
||||
import mezz.jei.api.ingredients.IIngredients;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Rarity;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.item.crafting.ShapedRecipe;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
public class MechanicalCraftingCategory extends CreateRecipeCategory<ShapedRecipe> {
|
||||
|
||||
private AnimatedCrafter crafter;
|
||||
private boolean large;
|
||||
private final class CrafterIngredientRenderer implements IIngredientRenderer<ItemStack> {
|
||||
|
||||
public MechanicalCraftingCategory(boolean large) {
|
||||
super("mechanical_crafting" + (large ? "_large" : ""), itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()),
|
||||
emptyBackground(large ? 177 : 177, large ? 235 : 81));
|
||||
this.large = large;
|
||||
crafter = new AnimatedCrafter(large);
|
||||
private ShapedRecipe recipe;
|
||||
|
||||
public CrafterIngredientRenderer(ShapedRecipe recipe) {
|
||||
this.recipe = recipe;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(int xPosition, int yPosition, ItemStack ingredient) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(xPosition, yPosition, 0);
|
||||
float scale = getScale(recipe);
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
|
||||
if (ingredient != null) {
|
||||
GlStateManager.enableDepthTest();
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
FontRenderer font = getFontRenderer(minecraft, ingredient);
|
||||
ItemRenderer itemRenderer = minecraft.getItemRenderer();
|
||||
itemRenderer.renderItemAndEffectIntoGUI(null, ingredient, 0, 0);
|
||||
itemRenderer.renderItemOverlayIntoGUI(font, ingredient, 0, 0, null);
|
||||
GlStateManager.disableBlend();
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTooltip(ItemStack ingredient, ITooltipFlag tooltipFlag) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
PlayerEntity player = minecraft.player;
|
||||
List<String> list;
|
||||
try {
|
||||
list = ingredient
|
||||
.getTooltip(player, tooltipFlag)
|
||||
.stream()
|
||||
.map(ITextComponent::getFormattedText)
|
||||
.collect(Collectors.toList());
|
||||
} catch (RuntimeException | LinkageError e) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
Rarity rarity;
|
||||
try {
|
||||
rarity = ingredient.getRarity();
|
||||
} catch (RuntimeException | LinkageError e) {
|
||||
rarity = Rarity.COMMON;
|
||||
}
|
||||
|
||||
for (int k = 0; k < list.size(); ++k) {
|
||||
if (k == 0) {
|
||||
list.set(k, rarity.color + list.get(k));
|
||||
} else {
|
||||
list.set(k, TextFormatting.GRAY + list.get(k));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSmall(ShapedRecipe recipe) {
|
||||
return Math.max((recipe).getWidth(), (recipe).getHeight()) <= 4;
|
||||
}
|
||||
private AnimatedCrafter crafter = new AnimatedCrafter();
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return Lang.translate("recipe.mechanical_crafting");
|
||||
public MechanicalCraftingCategory() {
|
||||
super("mechanical_crafting", itemIcon(AllBlocks.MECHANICAL_CRAFTER.get()), emptyBackground(177, 107));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,45 +111,79 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<ShapedRecip
|
|||
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
|
||||
NonNullList<Ingredient> recipeIngredients = recipe.getIngredients();
|
||||
|
||||
itemStacks.init(0, false, large ? 136 : 141, large ? 196 : 50);
|
||||
itemStacks.init(0, false, 133, 80);
|
||||
itemStacks.set(0, recipe.getRecipeOutput().getStack());
|
||||
|
||||
int x = getGridX(recipe);
|
||||
int y = getGridY(recipe);
|
||||
int x = getXPadding(recipe);
|
||||
int y = getYPadding(recipe);
|
||||
float scale = getScale(recipe);
|
||||
int size = recipeIngredients.size();
|
||||
IIngredientRenderer<ItemStack> renderer = new CrafterIngredientRenderer(recipe);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
itemStacks.init(i + 1, true, x + (i % recipe.getWidth()) * 19, y + (i / recipe.getWidth()) * 19);
|
||||
float f = 19 * scale;
|
||||
int slotSize = (int) (16 * scale);
|
||||
int xPosition = (int) (x + 1 + (i % recipe.getWidth()) * f);
|
||||
int yPosition = (int) (y + 1 + (i / recipe.getWidth()) * f);
|
||||
itemStacks.init(i + 1, true, renderer, xPosition, yPosition, slotSize, slotSize, 0, 0);
|
||||
itemStacks.set(i + 1, Arrays.asList(recipeIngredients.get(i).getMatchingStacks()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getGridY(ShapedRecipe recipe) {
|
||||
return 3 + (int) (((large ? 9 : 4) - recipe.getRecipeHeight()) * 19 / 2f);
|
||||
static int maxSize = 100;
|
||||
|
||||
public static float getScale(ShapedRecipe recipe) {
|
||||
int w = recipe.getWidth();
|
||||
int h = recipe.getHeight();
|
||||
return Math.min(1, maxSize / (19f * Math.max(w, h)));
|
||||
}
|
||||
|
||||
public int getGridX(ShapedRecipe recipe) {
|
||||
return 3 + (int) (((large ? 9 : 4) - recipe.getRecipeWidth()) * 19 / 2f);
|
||||
public static int getYPadding(ShapedRecipe recipe) {
|
||||
return 3 + 50 - (int) (getScale(recipe) * recipe.getHeight() * 19 * .5);
|
||||
}
|
||||
|
||||
public static int getXPadding(ShapedRecipe recipe) {
|
||||
return 3 + 50 - (int) (getScale(recipe) * recipe.getWidth() * 19 * .5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(ShapedRecipe recipe, double mouseX, double mouseY) {
|
||||
int x = getGridX(recipe);
|
||||
int y = getGridY(recipe);
|
||||
GlStateManager.pushMatrix();
|
||||
float scale = getScale(recipe);
|
||||
GlStateManager.translated(getXPadding(recipe), getYPadding(recipe), 0);
|
||||
|
||||
for (int row = 0; row < recipe.getHeight(); row++)
|
||||
for (int col = 0; col < recipe.getWidth(); col++)
|
||||
if (!recipe.getIngredients().get(row * recipe.getWidth() + col).hasNoMatchingItems())
|
||||
ScreenResources.JEI_SLOT.draw(x + col * 19, y + row * 19);
|
||||
if (!recipe.getIngredients().get(row * recipe.getWidth() + col).hasNoMatchingItems()) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated((int) col * 19 * scale, (int) row * 19 * scale, 0);
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
ScreenResources.JEI_SLOT.draw(0, 0);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
ScreenResources.JEI_SLOT.draw(large ? 136 : 141, large ? 196 : 50);
|
||||
if (large)
|
||||
ScreenResources.JEI_ARROW.draw(86, 200);
|
||||
else
|
||||
ScreenResources.JEI_DOWN_ARROW.draw(136, 32);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
ScreenResources.JEI_SHADOW.draw(large ? 20 : 84, large ? 223 : 68);
|
||||
crafter.draw(large ? 105 : 185, large ? 189 : -1);
|
||||
ScreenResources.JEI_SLOT.draw(133, 80);
|
||||
ScreenResources.JEI_DOWN_ARROW.draw(128, 59);
|
||||
ScreenResources.JEI_SHADOW.draw(116, 36);
|
||||
crafter.draw(219, 8);
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(0, 0, 200);
|
||||
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
int amount = 0;
|
||||
for (Ingredient ingredient : recipe.getIngredients()) {
|
||||
if (Ingredient.EMPTY == ingredient)
|
||||
continue;
|
||||
amount++;
|
||||
}
|
||||
Minecraft.getInstance().fontRenderer
|
||||
.drawStringWithShadow(amount + "", 142, 39, 0xFFFFFF);
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,12 +12,6 @@ import net.minecraft.util.Direction;
|
|||
|
||||
public class AnimatedCrafter extends AnimatedKinetics {
|
||||
|
||||
boolean four;
|
||||
|
||||
public AnimatedCrafter(boolean four) {
|
||||
this.four = four;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return 50;
|
||||
|
@ -40,23 +34,6 @@ public class AnimatedCrafter extends AnimatedKinetics {
|
|||
|
||||
ScreenElementRenderer.renderModel(() -> cogwheel(true));
|
||||
ScreenElementRenderer.renderBlock(this::body);
|
||||
RenderSystem.translatef(0, 50, 0);
|
||||
ScreenElementRenderer.renderModel(() -> cogwheel(false));
|
||||
ScreenElementRenderer.renderBlock(this::body);
|
||||
|
||||
if (four) {
|
||||
RenderSystem.translatef(50, -50, 0);
|
||||
ScreenElementRenderer.renderModel(() -> cogwheel(false));
|
||||
ScreenElementRenderer.renderBlock(this::body);
|
||||
RenderSystem.translatef(0, 50, 0);
|
||||
ScreenElementRenderer.renderModel(() -> cogwheel(true));
|
||||
ScreenElementRenderer.renderBlock(this::body);
|
||||
|
||||
} else {
|
||||
RenderSystem.translatef(0, 50, 0);
|
||||
ScreenElementRenderer.renderModel(() -> cogwheel(true));
|
||||
ScreenElementRenderer.renderBlock(this::body);
|
||||
}
|
||||
|
||||
RenderSystem.popMatrix();
|
||||
}
|
||||
|
@ -71,8 +48,10 @@ public class AnimatedCrafter extends AnimatedKinetics {
|
|||
}
|
||||
|
||||
private BlockState body() {
|
||||
return AllBlocks.MECHANICAL_CRAFTER.get().getDefaultState().with(MechanicalCrafterBlock.HORIZONTAL_FACING,
|
||||
Direction.WEST);
|
||||
return AllBlocks.MECHANICAL_CRAFTER
|
||||
.get()
|
||||
.getDefaultState()
|
||||
.with(MechanicalCrafterBlock.HORIZONTAL_FACING, Direction.WEST);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
359
src/main/java/com/simibubi/create/data/CreateAdvancements.java
Normal file
359
src/main/java/com/simibubi/create/data/CreateAdvancements.java
Normal file
|
@ -0,0 +1,359 @@
|
|||
package com.simibubi.create.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.advancement.KineticBlockTrigger;
|
||||
import com.simibubi.create.modules.curiosities.zapper.blockzapper.BlockzapperItem;
|
||||
import com.simibubi.create.modules.curiosities.zapper.blockzapper.BlockzapperItem.ComponentTier;
|
||||
import com.simibubi.create.modules.curiosities.zapper.blockzapper.BlockzapperItem.Components;
|
||||
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.Advancement.Builder;
|
||||
import net.minecraft.advancements.FrameType;
|
||||
import net.minecraft.advancements.criterion.InventoryChangeTrigger;
|
||||
import net.minecraft.advancements.criterion.PlacedBlockTrigger;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.DirectoryCache;
|
||||
import net.minecraft.data.IDataProvider;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.IItemProvider;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
|
||||
@SuppressWarnings("unused") // dont warn about unused avancements
|
||||
public class CreateAdvancements implements IDataProvider {
|
||||
|
||||
static final String LANG = "advancement." + Create.ID + ".";
|
||||
|
||||
public void register(Consumer<Advancement> t) {
|
||||
String id = Create.ID;
|
||||
|
||||
Advancement root = Advancement.Builder
|
||||
.builder()
|
||||
.withDisplay(AllItems.BRASS_HAND.asStack(), new TranslationTextComponent(LANG + "root"),
|
||||
new TranslationTextComponent(LANG + "root.desc"),
|
||||
new ResourceLocation(Create.ID, "textures/block/scoria_bricks.png"), FrameType.TASK, false,
|
||||
false, false)
|
||||
.withCriterion("0", InventoryChangeTrigger.Instance.forItems(new IItemProvider[] {}))
|
||||
.register(t, id + ":root");
|
||||
|
||||
Advancement andesite_alloy = advancement("andesite_alloy", AllItems.ANDESITE_ALLOY.get(), TaskType.NORMAL)
|
||||
.withParent(root)
|
||||
.withCriterion("0", itemGathered(AllItems.ANDESITE_ALLOY.get()))
|
||||
.register(t, id + ":andesite_alloy");
|
||||
|
||||
kineticsBranch(t, andesite_alloy);
|
||||
|
||||
Advancement water_wheel = advancement("water_wheel", AllBlocks.WATER_WHEEL.get(), TaskType.NORMAL)
|
||||
.withParent(andesite_alloy)
|
||||
.withCriterion("0", placeBlock(AllBlocks.WATER_WHEEL.get()))
|
||||
.withCriterion("1", AllTriggers.WATER_WHEEL.instance())
|
||||
.register(t, id + ":water_wheel");
|
||||
|
||||
Advancement lava_wheel = advancement("lava_wheel", Items.LAVA_BUCKET, TaskType.SECRET)
|
||||
.withParent(water_wheel)
|
||||
.withCriterion("0", AllTriggers.LAVA_WHEEL.instance())
|
||||
.register(t, id + ":lava_wheel");
|
||||
|
||||
Advancement millstone = kinecticAdvancement("millstone", AllBlocks.MILLSTONE, TaskType.NORMAL)
|
||||
.withParent(andesite_alloy)
|
||||
.register(t, id + ":millstone");
|
||||
|
||||
Advancement andesite_casing = advancement("andesite_casing", AllBlocks.ANDESITE_CASING.get(), TaskType.GOAL)
|
||||
.withParent(andesite_alloy)
|
||||
.withCriterion("0", itemGathered(AllBlocks.ANDESITE_CASING.get()))
|
||||
.register(t, id + ":andesite_casing");
|
||||
|
||||
andesiteExpertLane(t, andesite_casing);
|
||||
|
||||
Advancement drill = kinecticAdvancement("drill", AllBlocks.DRILL, TaskType.NORMAL)
|
||||
.withParent(andesite_casing)
|
||||
.register(t, id + ":drill");
|
||||
|
||||
Advancement press = advancement("press", AllBlocks.MECHANICAL_PRESS.get(), TaskType.MILESTONE)
|
||||
.withParent(andesite_casing)
|
||||
.withCriterion("0", AllTriggers.BONK.instance())
|
||||
.register(t, id + ":press");
|
||||
|
||||
Advancement rose_quartz =
|
||||
itemAdvancement("polished_rose_quartz", AllItems.POLISHED_ROSE_QUARTZ, TaskType.NORMAL)
|
||||
.withParent(andesite_casing)
|
||||
.register(t, id + ":polished_rose_quartz");
|
||||
|
||||
Advancement electron_tube = itemAdvancement("electron_tube", AllItems.ELECTRON_TUBE, TaskType.NORMAL)
|
||||
.withParent(rose_quartz)
|
||||
.register(t, id + ":electron_tube");
|
||||
|
||||
Advancement saw =
|
||||
kinecticAdvancement("saw", AllBlocks.SAW, TaskType.NORMAL).withParent(press).register(t, id + ":saw");
|
||||
|
||||
Advancement basin = advancement("basin", AllBlocks.BASIN.get(), TaskType.NORMAL)
|
||||
.withParent(press)
|
||||
.withCriterion("0", placeBlock(AllBlocks.BASIN.get()))
|
||||
.withCriterion("1", AllTriggers.BASIN_THROW.instance())
|
||||
.register(t, id + ":basin");
|
||||
|
||||
Advancement mixer = advancement("mixer", AllBlocks.MECHANICAL_MIXER.get(), TaskType.MILESTONE)
|
||||
.withCriterion("0", placeBlock(AllBlocks.MECHANICAL_MIXER.get()))
|
||||
.withCriterion("1", isPowered(AllBlocks.MECHANICAL_MIXER.get()))
|
||||
.withCriterion("2", AllTriggers.MIXER_MIX.instance())
|
||||
.withParent(basin)
|
||||
.register(t, id + ":mixer");
|
||||
|
||||
Advancement compact = advancement("compact", Blocks.IRON_BLOCK, TaskType.NORMAL)
|
||||
.withCriterion("0", AllTriggers.PRESS_COMPACT.instance())
|
||||
.withParent(basin)
|
||||
.register(t, id + ":compact");
|
||||
|
||||
Advancement brass = itemAdvancement("brass", AllItems.BRASS_INGOT, TaskType.NORMAL)
|
||||
.withParent(mixer)
|
||||
.register(t, id + ":brass");
|
||||
|
||||
brassAge(t, brass);
|
||||
copperAge(t, press);
|
||||
}
|
||||
|
||||
void kineticsBranch(Consumer<Advancement> t, Advancement root) {
|
||||
String id = Create.ID;
|
||||
|
||||
Advancement its_alive = advancement("its_alive", AllBlocks.COGWHEEL.get(), TaskType.NORMAL)
|
||||
.withParent(root)
|
||||
.withCriterion("0", AllTriggers.ROTATION.instance())
|
||||
.register(t, id + ":its_alive");
|
||||
|
||||
Advancement belt = advancement("belt", AllItems.BELT_CONNECTOR.get(), TaskType.NORMAL)
|
||||
.withParent(its_alive)
|
||||
.withCriterion("0", AllTriggers.CONNECT_BELT.instance())
|
||||
.register(t, id + ":belt");
|
||||
|
||||
Advancement wrench = itemAdvancement("wrench", AllItems.WRENCH, TaskType.NORMAL)
|
||||
.withParent(its_alive)
|
||||
.register(t, id + ":wrench");
|
||||
|
||||
Advancement goggles = itemAdvancement("goggles", AllItems.GOGGLES, TaskType.NORMAL)
|
||||
.withParent(its_alive)
|
||||
.register(t, id + ":goggles");
|
||||
|
||||
Advancement speed_gauge = kinecticAdvancement("speed_gauge", AllBlocks.SPEED_GAUGE, TaskType.NORMAL)
|
||||
.withParent(goggles)
|
||||
.register(t, id + ":speed_gauge");
|
||||
|
||||
Advancement stress_gauge = kinecticAdvancement("stress_gauge", AllBlocks.STRESS_GAUGE, TaskType.NORMAL)
|
||||
.withParent(goggles)
|
||||
.register(t, id + ":stress_gauge");
|
||||
|
||||
Advancement shifting_gears = advancement("shifting_gears", AllBlocks.LARGE_COGWHEEL.get(), TaskType.NORMAL)
|
||||
.withParent(its_alive)
|
||||
.withCriterion("0", AllTriggers.SHIFTING_GEARS.instance())
|
||||
.register(t, id + ":shifting_gears");
|
||||
|
||||
Advancement overstressed = advancement("overstressed", Items.BARRIER, TaskType.SECRET)
|
||||
.withParent(its_alive)
|
||||
.withCriterion("0", AllTriggers.OVERSTRESSED.instance())
|
||||
.register(t, id + ":overstressed");
|
||||
|
||||
}
|
||||
|
||||
void copperAge(Consumer<Advancement> t, Advancement root) {
|
||||
String id = Create.ID;
|
||||
|
||||
Advancement copper_casing = advancement("copper_casing", AllBlocks.COPPER_CASING.get(), TaskType.GOAL)
|
||||
.withParent(root)
|
||||
.withCriterion("0", itemGathered(AllBlocks.COPPER_CASING.get()))
|
||||
.register(t, id + ":copper_casing");
|
||||
|
||||
Advancement copper_end = deadEnd()
|
||||
.withParent(copper_casing)
|
||||
.withCriterion("0", itemGathered(AllBlocks.COPPER_CASING.get()))
|
||||
.register(t, id + ":copper_end");
|
||||
}
|
||||
|
||||
void brassAge(Consumer<Advancement> t, Advancement root) {
|
||||
String id = Create.ID;
|
||||
|
||||
Advancement brass_casing = advancement("brass_casing", AllBlocks.BRASS_CASING.get(), TaskType.GOAL)
|
||||
.withParent(root)
|
||||
.withCriterion("0", itemGathered(AllBlocks.BRASS_CASING.get()))
|
||||
.register(t, id + ":brass_casing");
|
||||
|
||||
Advancement crafter = kinecticAdvancement("crafter", AllBlocks.MECHANICAL_CRAFTER, TaskType.MILESTONE)
|
||||
.withParent(brass_casing)
|
||||
.register(t, id + ":crafter");
|
||||
|
||||
Advancement deployer = kinecticAdvancement("deployer", AllBlocks.DEPLOYER, TaskType.GOAL)
|
||||
.withParent(brass_casing)
|
||||
.register(t, id + ":deployer");
|
||||
|
||||
Advancement fist_bump = advancement("fist_bump", AllBlocks.DEPLOYER.get(), TaskType.SECRET)
|
||||
.withParent(deployer)
|
||||
.withCriterion("0", AllTriggers.DEPLOYER_BOOP.instance())
|
||||
.register(t, id + ":fist_bump");
|
||||
|
||||
Advancement crushing_wheel = advancement("crushing_wheel", AllBlocks.CRUSHING_WHEEL.get(), TaskType.MILESTONE)
|
||||
.withParent(crafter)
|
||||
.withCriterion("0", itemGathered(AllBlocks.CRUSHING_WHEEL.get()))
|
||||
.register(t, id + ":crushing_wheel");
|
||||
|
||||
Advancement chromatic_compound =
|
||||
itemAdvancement("chromatic_compound", AllItems.CHROMATIC_COMPOUND, TaskType.NORMAL)
|
||||
.withParent(crushing_wheel)
|
||||
.register(t, id + ":chromatic_compound");
|
||||
|
||||
Advancement shadow_steel = itemAdvancement("shadow_steel", AllItems.SHADOW_STEEL, TaskType.GOAL)
|
||||
.withParent(chromatic_compound)
|
||||
.register(t, id + ":shadow_steel");
|
||||
|
||||
Advancement refined_radiance = itemAdvancement("refined_radiance", AllItems.REFINED_RADIANCE, TaskType.GOAL)
|
||||
.withParent(chromatic_compound)
|
||||
.register(t, id + ":refined_radiance");
|
||||
|
||||
Advancement deforester = itemAdvancement("deforester", AllItems.DEFORESTER, TaskType.NORMAL)
|
||||
.withParent(refined_radiance)
|
||||
.register(t, id + ":deforester");
|
||||
|
||||
Advancement zapper = itemAdvancement("zapper", AllItems.PLACEMENT_HANDGUN, TaskType.NORMAL)
|
||||
.withParent(refined_radiance)
|
||||
.register(t, id + ":zapper");
|
||||
|
||||
ItemStack gunWithPurpurStuff = AllItems.PLACEMENT_HANDGUN.asStack();
|
||||
for (Components c : Components.values())
|
||||
BlockzapperItem.setTier(c, ComponentTier.Chromatic, gunWithPurpurStuff);
|
||||
Advancement upgraded_zapper = advancement("upgraded_zapper", gunWithPurpurStuff, TaskType.CHALLENGE)
|
||||
.withCriterion("0", AllTriggers.UPGRADED_ZAPPER.instance())
|
||||
.withParent(zapper)
|
||||
.register(t, id + ":upgraded_zapper");
|
||||
|
||||
Advancement symmetry_wand = itemAdvancement("symmetry_wand", AllItems.SYMMETRY_WAND, TaskType.NORMAL)
|
||||
.withParent(refined_radiance)
|
||||
.register(t, id + ":symmetry_wand");
|
||||
|
||||
Advancement shadow_end = deadEnd()
|
||||
.withParent(shadow_steel)
|
||||
.withCriterion("0", itemGathered(AllItems.SHADOW_STEEL.get()))
|
||||
.register(t, id + ":shadow_end");
|
||||
}
|
||||
|
||||
private void andesiteExpertLane(Consumer<Advancement> t, Advancement root) {
|
||||
String id = Create.ID;
|
||||
}
|
||||
|
||||
// Datagen
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().create();
|
||||
private final DataGenerator generator;
|
||||
|
||||
public CreateAdvancements(DataGenerator generatorIn) {
|
||||
this.generator = generatorIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(DirectoryCache cache) throws IOException {
|
||||
Path path = this.generator.getOutputFolder();
|
||||
Set<ResourceLocation> set = Sets.newHashSet();
|
||||
Consumer<Advancement> consumer = (p_204017_3_) -> {
|
||||
if (!set.add(p_204017_3_.getId()))
|
||||
throw new IllegalStateException("Duplicate advancement " + p_204017_3_.getId());
|
||||
|
||||
Path path1 = getPath(path, p_204017_3_);
|
||||
|
||||
try {
|
||||
IDataProvider.save(GSON, cache, p_204017_3_.copy().serialize(), path1);
|
||||
} catch (IOException ioexception) {
|
||||
LOGGER.error("Couldn't save advancement {}", path1, ioexception);
|
||||
}
|
||||
};
|
||||
|
||||
register(consumer);
|
||||
}
|
||||
|
||||
private static Path getPath(Path pathIn, Advancement advancementIn) {
|
||||
return pathIn
|
||||
.resolve("data/" + advancementIn.getId().getNamespace() + "/advancements/"
|
||||
+ advancementIn.getId().getPath() + ".json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "CreateAdvancements";
|
||||
}
|
||||
|
||||
public PlacedBlockTrigger.Instance placeBlock(Block block) {
|
||||
return PlacedBlockTrigger.Instance.placedBlock(block);
|
||||
}
|
||||
|
||||
public KineticBlockTrigger.Instance isPowered(Block block) {
|
||||
return AllTriggers.KINETIC_BLOCK.forBlock(block);
|
||||
}
|
||||
|
||||
public InventoryChangeTrigger.Instance itemGathered(IItemProvider itemprovider) {
|
||||
return InventoryChangeTrigger.Instance.forItems(itemprovider);
|
||||
}
|
||||
|
||||
static enum TaskType {
|
||||
|
||||
NORMAL(FrameType.TASK, true, false, false),
|
||||
MILESTONE(FrameType.TASK, true, true, false),
|
||||
GOAL(FrameType.GOAL, true, true, false),
|
||||
SECRET(FrameType.GOAL, true, true, true),
|
||||
SILENT_GATE(FrameType.CHALLENGE, false, false, false),
|
||||
CHALLENGE(FrameType.CHALLENGE, true, true, false),
|
||||
|
||||
;
|
||||
|
||||
private FrameType frame;
|
||||
private boolean toast;
|
||||
private boolean announce;
|
||||
private boolean hide;
|
||||
|
||||
private TaskType(FrameType frame, boolean toast, boolean announce, boolean hide) {
|
||||
this.frame = frame;
|
||||
this.toast = toast;
|
||||
this.announce = announce;
|
||||
this.hide = hide;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder kinecticAdvancement(String name, AllBlocks block, TaskType type) {
|
||||
return advancement(name, block.get(), type)
|
||||
.withCriterion("0", placeBlock(block.get()))
|
||||
.withCriterion("1", isPowered(block.get()));
|
||||
}
|
||||
|
||||
public Builder advancement(String name, IItemProvider icon, TaskType type) {
|
||||
return advancement(name, new ItemStack(icon), type);
|
||||
}
|
||||
|
||||
public Builder deadEnd() {
|
||||
return advancement("eob", Items.OAK_SAPLING, TaskType.SILENT_GATE);
|
||||
}
|
||||
|
||||
public Builder advancement(String name, ItemStack icon, TaskType type) {
|
||||
return Advancement.Builder
|
||||
.builder()
|
||||
.withDisplay(icon, new TranslationTextComponent(LANG + name),
|
||||
new TranslationTextComponent(LANG + name + ".desc"), null, type.frame, type.toast,
|
||||
type.announce, type.hide);
|
||||
}
|
||||
|
||||
public Builder itemAdvancement(String name, AllItems item, TaskType type) {
|
||||
return advancement(name, item.get(), type).withCriterion("0", itemGathered(item.get()));
|
||||
}
|
||||
|
||||
}
|
|
@ -15,17 +15,28 @@ public class AllTriggers {
|
|||
|
||||
private static List<CriterionTriggerBase<?>> triggers = new LinkedList<>();
|
||||
|
||||
public static SandpaperUseTrigger SANDPAPER_USE = add(new SandpaperUseTrigger("sandpaper_use"));
|
||||
public static SimpleTrigger DEPLOYER_BOOP = simple("deployer");
|
||||
public static SimpleTrigger ABSORBED_LIGHT = simple("light_absorbed");
|
||||
public static SimpleTrigger SPEED_READ = simple("speed_read");
|
||||
public static SimpleTrigger OVERSTRESSED = simple("overstressed");
|
||||
public static SimpleTrigger ROTATION = simple("rotation");
|
||||
public static KineticBlockTrigger KINETIC_BLOCK = add(new KineticBlockTrigger("kinetic_block"));
|
||||
|
||||
public static SimpleTrigger
|
||||
ROTATION = simple("rotation"),
|
||||
OVERSTRESSED = simple("overstressed"),
|
||||
SHIFTING_GEARS = simple("shifting_gears"),
|
||||
CONNECT_BELT = simple("connect_belt"),
|
||||
BONK = simple("bonk"),
|
||||
WATER_WHEEL = simple("water_wheel"),
|
||||
LAVA_WHEEL = simple("lava_wheel"),
|
||||
DEPLOYER_BOOP = simple("deployer"),
|
||||
ABSORBED_LIGHT = simple("light_absorbed"),
|
||||
SPEED_READ = simple("speed_read"),
|
||||
BASIN_THROW = simple("basin"),
|
||||
PRESS_COMPACT = simple("compact"),
|
||||
UPGRADED_ZAPPER = simple("upgraded_zapper"),
|
||||
MIXER_MIX = simple("mixer");
|
||||
|
||||
private static SimpleTrigger simple(String id) {
|
||||
return add(new SimpleTrigger(id));
|
||||
}
|
||||
|
||||
|
||||
private static <T extends CriterionTriggerBase<?>> T add(T instance) {
|
||||
triggers.add(instance);
|
||||
return instance;
|
||||
|
@ -35,19 +46,29 @@ public class AllTriggers {
|
|||
triggers.forEach(CriteriaTriggers::register);
|
||||
}
|
||||
|
||||
public static void triggerForNearbyPlayers(SimpleTrigger trigger, World world, BlockPos pos, int range) {
|
||||
public static void triggerFor(ITriggerable trigger, PlayerEntity player) {
|
||||
if (player instanceof ServerPlayerEntity)
|
||||
trigger.trigger((ServerPlayerEntity) player);
|
||||
}
|
||||
|
||||
public static void triggerForNearbyPlayers(ITriggerable trigger, World world, BlockPos pos, int range) {
|
||||
triggerForNearbyPlayers(trigger, world, pos, range, player -> true);
|
||||
}
|
||||
|
||||
public static void triggerForNearbyPlayers(SimpleTrigger trigger, World world, BlockPos pos, int range,
|
||||
public static void triggerForNearbyPlayers(ITriggerable trigger, World world, BlockPos pos, int range,
|
||||
Predicate<PlayerEntity> playerFilter) {
|
||||
if (world == null)
|
||||
return;
|
||||
if (world.isRemote)
|
||||
return;
|
||||
List<ServerPlayerEntity> players =
|
||||
world.getEntitiesWithinAABB(ServerPlayerEntity.class, new AxisAlignedBB(pos).grow(range));
|
||||
List<ServerPlayerEntity> players = getPlayersInRange(world, pos, range);
|
||||
players.stream().filter(playerFilter).forEach(trigger::trigger);
|
||||
}
|
||||
|
||||
public static List<ServerPlayerEntity> getPlayersInRange(World world, BlockPos pos, int range) {
|
||||
List<ServerPlayerEntity> players =
|
||||
world.getEntitiesWithinAABB(ServerPlayerEntity.class, new AxisAlignedBB(pos).grow(range));
|
||||
return players;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.simibubi.create.foundation.advancement;
|
||||
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
|
||||
public interface ITriggerable {
|
||||
|
||||
public void trigger(ServerPlayerEntity player);
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.simibubi.create.foundation.advancement;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class KineticBlockTrigger extends CriterionTriggerBase<KineticBlockTrigger.Instance> {
|
||||
|
||||
private static final ResourceLocation ID = new ResourceLocation(Create.ID, "kinetic_block");
|
||||
|
||||
public KineticBlockTrigger(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Instance forBlock(Block block) {
|
||||
return new Instance(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) {
|
||||
Block block = null;
|
||||
if (json.has("block")) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(JSONUtils.getString(json, "block"));
|
||||
block = Registry.BLOCK.getValue(resourcelocation).orElseThrow(() -> {
|
||||
return new JsonSyntaxException("Unknown block type '" + resourcelocation + "'");
|
||||
});
|
||||
}
|
||||
|
||||
return new Instance(block);
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player, BlockState state) {
|
||||
trigger(player, Arrays.asList(() -> state.getBlock()));
|
||||
}
|
||||
|
||||
public static class Instance extends CriterionTriggerBase.Instance {
|
||||
private final Block block;
|
||||
|
||||
public Instance(Block block) {
|
||||
super(KineticBlockTrigger.ID);
|
||||
this.block = block;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean test(List<Supplier<Object>> suppliers) {
|
||||
if (suppliers.isEmpty())
|
||||
return false;
|
||||
return block == suppliers.get(0).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public JsonElement serialize() {
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
if (this.block != null)
|
||||
jsonobject.addProperty("block", Registry.BLOCK.getKey(this.block).toString());
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package com.simibubi.create.foundation.advancement;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.minecraft.advancements.criterion.ItemPredicate;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class SandpaperUseTrigger extends CriterionTriggerBase<SandpaperUseTrigger.Instance> {
|
||||
|
||||
public SandpaperUseTrigger(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance deserializeInstance(JsonObject json, JsonDeserializationContext context) {
|
||||
return new SandpaperUseTrigger.Instance(getId(), ItemPredicate.deserialize(json.get("target")),ItemPredicate.deserialize(json.get("result")));
|
||||
}
|
||||
|
||||
public void trigger(ServerPlayerEntity player, ItemStack target, ItemStack result){
|
||||
trigger(player, Arrays.asList(() -> target, () -> result));
|
||||
}
|
||||
|
||||
public static class Instance extends CriterionTriggerBase.Instance {
|
||||
private final ItemPredicate target;
|
||||
private final ItemPredicate result;
|
||||
|
||||
public Instance(ResourceLocation idIn, ItemPredicate target, ItemPredicate result) {
|
||||
super(idIn);
|
||||
this.target = target;
|
||||
this.result = result;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean test(List<Supplier<Object>> suppliers) {
|
||||
return this.target.test((ItemStack) suppliers.get(0).get()) &&
|
||||
this.result.test((ItemStack) suppliers.get(1).get());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ import com.google.gson.JsonObject;
|
|||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class SimpleTrigger extends CriterionTriggerBase<SimpleTrigger.Instance> {
|
||||
public class SimpleTrigger extends CriterionTriggerBase<SimpleTrigger.Instance> implements ITriggerable {
|
||||
|
||||
public SimpleTrigger(String id) {
|
||||
super(id);
|
||||
|
@ -23,6 +23,10 @@ public class SimpleTrigger extends CriterionTriggerBase<SimpleTrigger.Instance>
|
|||
public void trigger(ServerPlayerEntity player){
|
||||
super.trigger(player, null);
|
||||
}
|
||||
|
||||
public Instance instance() {
|
||||
return new Instance(getId());
|
||||
}
|
||||
|
||||
public static class Instance extends CriterionTriggerBase.Instance {
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.foundation.behaviour.filtering;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
|
||||
|
@ -29,6 +30,7 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
|||
private ItemStack filter;
|
||||
public int count;
|
||||
private Consumer<ItemStack> callback;
|
||||
private Supplier<Boolean> isActive;
|
||||
|
||||
int scrollableValue;
|
||||
int ticksUntilScrollPacket;
|
||||
|
@ -40,6 +42,7 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
|||
slotPositioning = slot;
|
||||
showCount = false;
|
||||
callback = stack -> {};
|
||||
isActive = () -> true;
|
||||
textShift = Vec3d.ZERO;
|
||||
count = 0;
|
||||
ticksUntilScrollPacket = -1;
|
||||
|
@ -93,6 +96,11 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
|||
callback = filterCallback;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilteringBehaviour onlyActiveWhen(Supplier<Boolean> condition) {
|
||||
isActive = condition;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilteringBehaviour showCount() {
|
||||
showCount = true;
|
||||
|
@ -161,5 +169,9 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
|||
public boolean anyAmount() {
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return isActive.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ public class FilteringHandler {
|
|||
FilteringBehaviour behaviour = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
if (!behaviour.isActive())
|
||||
return;
|
||||
|
||||
BlockRayTraceResult ray = RaycastHelper.rayTraceRange(world, player, 10);
|
||||
if (ray == null)
|
||||
|
|
|
@ -43,6 +43,8 @@ public class FilteringRenderer {
|
|||
FilteringBehaviour behaviour = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
if (!behaviour.isActive())
|
||||
return;
|
||||
if (Minecraft.getInstance().player.isSneaking())
|
||||
return;
|
||||
|
||||
|
@ -77,6 +79,8 @@ public class FilteringRenderer {
|
|||
FilteringBehaviour behaviour = TileEntityBehaviour.get(tileEntityIn, FilteringBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
if (!behaviour.isActive())
|
||||
return;
|
||||
if (behaviour.getFilter().isEmpty())
|
||||
return;
|
||||
|
||||
|
|
|
@ -95,17 +95,20 @@ public class ScreenElementRenderer {
|
|||
blockRenderer.renderBlock(blockToRender, ms, buffer, 0xF000F0, OverlayTexture.DEFAULT_UV,
|
||||
EmptyModelData.INSTANCE);
|
||||
} else {
|
||||
RenderSystem.rotatef(90, 0, 1, 0);
|
||||
if (color == -1) {
|
||||
blockRenderer.getBlockModelRenderer().renderModel(ms.peek(), vb, blockToRender, modelToRender, 1, 1, 1,
|
||||
0xF000F0, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||
} else {
|
||||
Vec3d rgb = ColorHelper.getRGB(color);
|
||||
blockRenderer.getBlockModelRenderer().renderModel(ms.peek(), vb, blockToRender, modelToRender,
|
||||
(float) rgb.x, (float) rgb.y, (float) rgb.z, 0xF000F0, OverlayTexture.DEFAULT_UV,
|
||||
EmptyModelData.INSTANCE);
|
||||
if (modelToRender != null) {
|
||||
RenderSystem.rotatef(90, 0, 1, 0);
|
||||
if (color == -1) {
|
||||
blockRenderer.getBlockModelRenderer().renderModel(ms.peek(), vb, blockToRender, modelToRender, 1, 1,
|
||||
1, 0xF000F0, OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE);
|
||||
} else {
|
||||
Vec3d rgb = ColorHelper.getRGB(color);
|
||||
blockRenderer.getBlockModelRenderer().renderModel(ms.peek(), vb, blockToRender, modelToRender,
|
||||
(float) rgb.x, (float) rgb.y, (float) rgb.z, 0xF000F0, OverlayTexture.DEFAULT_UV,
|
||||
EmptyModelData.INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderSystem.popMatrix();
|
||||
buffer.draw(renderType);
|
||||
|
||||
|
|
|
@ -127,17 +127,27 @@ public class ItemHelper {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static enum ExtractionCountMode {
|
||||
EXACTLY, UPTO
|
||||
}
|
||||
|
||||
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, boolean simulate) {
|
||||
return extract(inv, test, -1, simulate);
|
||||
return extract(inv, test, ExtractionCountMode.UPTO, AllConfigs.SERVER.logistics.extractorAmount.get(),
|
||||
simulate);
|
||||
}
|
||||
|
||||
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, int exactAmount, boolean simulate) {
|
||||
return extract(inv, test, ExtractionCountMode.EXACTLY, exactAmount, simulate);
|
||||
}
|
||||
|
||||
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, ExtractionCountMode mode, int amount,
|
||||
boolean simulate) {
|
||||
ItemStack extracting = ItemStack.EMPTY;
|
||||
boolean amountRequired = exactAmount != -1;
|
||||
boolean amountRequired = mode == ExtractionCountMode.EXACTLY;
|
||||
boolean checkHasEnoughItems = amountRequired;
|
||||
boolean hasEnoughItems = !checkHasEnoughItems;
|
||||
int maxExtractionCount = hasEnoughItems ? AllConfigs.SERVER.logistics.extractorAmount.get() : exactAmount;
|
||||
boolean potentialOtherMatch = false;
|
||||
int maxExtractionCount = amount;
|
||||
|
||||
Extraction: do {
|
||||
extracting = ItemStack.EMPTY;
|
||||
|
@ -186,7 +196,7 @@ public class ItemHelper {
|
|||
|
||||
} while (true);
|
||||
|
||||
if (amountRequired && extracting.getCount() < exactAmount)
|
||||
if (amountRequired && extracting.getCount() < amount)
|
||||
return ItemStack.EMPTY;
|
||||
|
||||
return extracting;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.utility.data;
|
||||
|
||||
import com.simibubi.create.data.CreateAdvancements;
|
||||
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
@ -11,8 +13,8 @@ public class Generator {
|
|||
@SubscribeEvent
|
||||
public static void gatherData(GatherDataEvent event){
|
||||
DataGenerator gen = event.getGenerator();
|
||||
//gen.addProvider(AllSoundEvents.CUCKOO_PIG);
|
||||
gen.addProvider(new AllItemsTagProvider(gen));
|
||||
gen.addProvider(new CreateAdvancements(gen));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,11 +10,13 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
|
||||
public class CasingBlock extends Block implements IHaveConnectedTextures {
|
||||
public class CasingBlock extends Block implements IHaveConnectedTextures, IWrenchable {
|
||||
|
||||
String textureFrom;
|
||||
|
||||
|
@ -22,6 +24,11 @@ public class CasingBlock extends Block implements IHaveConnectedTextures {
|
|||
super(Properties.from(Blocks.ANDESITE));
|
||||
this.textureFrom = textureFrom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToolType getHarvestTool(BlockState state) {
|
||||
|
|
|
@ -28,6 +28,8 @@ public interface IWrenchable {
|
|||
KineticTileEntity.switchToBlockState(world, context.getPos(), updateAfterWrenched(rotated, context));
|
||||
|
||||
TileEntity te = context.getWorld().getTileEntity(context.getPos());
|
||||
if (te != null)
|
||||
te.updateContainingBlockInfo();
|
||||
if (te instanceof GeneratingKineticTileEntity) {
|
||||
((GeneratingKineticTileEntity) te).updateGeneratedRotation();
|
||||
}
|
||||
|
|
|
@ -248,7 +248,8 @@ public class RotationPropagator {
|
|||
|
||||
// Do not overpower you own network -> cycle
|
||||
if (!currentTE.hasNetwork() || currentTE.network.equals(neighbourTE.network)) {
|
||||
if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour))
|
||||
float epsilon = Math.abs(speedOfNeighbour) / 256f / 256f;
|
||||
if (Math.abs(newSpeed) > Math.abs(speedOfNeighbour) + epsilon)
|
||||
world.destroyBlock(pos, true);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.simibubi.create.foundation.item.ItemDescription.Palette;
|
|||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -64,11 +63,6 @@ public abstract class KineticBlock extends Block implements IRotate {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
|
||||
|
||||
|
|
|
@ -166,9 +166,13 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
public void onSpeedChanged(float previousSpeed) {
|
||||
boolean fromOrToZero = (previousSpeed == 0) != (getSpeed() == 0);
|
||||
boolean directionSwap = !fromOrToZero && Math.signum(previousSpeed) != Math.signum(getSpeed());
|
||||
if (fromOrToZero || directionSwap) {
|
||||
if (fromOrToZero || directionSwap)
|
||||
flickerTally = getFlickerScore() + 5;
|
||||
}
|
||||
|
||||
if (fromOrToZero && previousSpeed == 0 && !world.isRemote)
|
||||
AllTriggers
|
||||
.getPlayersInRange(world, pos, 4)
|
||||
.forEach(p -> AllTriggers.KINETIC_BLOCK.trigger(p, getBlockState()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -355,8 +359,12 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
return;
|
||||
|
||||
TileEntity tileEntityIn = world.getTileEntity(pos);
|
||||
if (!(tileEntityIn instanceof KineticTileEntity))
|
||||
boolean isKinetic = tileEntityIn instanceof KineticTileEntity;
|
||||
|
||||
if (!isKinetic) {
|
||||
world.setBlockState(pos, state, 3);
|
||||
return;
|
||||
}
|
||||
|
||||
KineticTileEntity tileEntity = (KineticTileEntity) tileEntityIn;
|
||||
if (tileEntity.hasNetwork())
|
||||
|
@ -368,8 +376,7 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
}
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {}
|
||||
|
||||
@Override
|
||||
public boolean hasFastRenderer() {
|
||||
|
@ -382,8 +389,9 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
|
||||
if (overStressed && AllConfigs.CLIENT.enableOverstressedTooltip.get()) {
|
||||
tooltip.add(spacing + GOLD + Lang.translate("gui.stress_gauge.overstressed"));
|
||||
String hint = Lang.translate("gui.contraptions.network_overstressed",
|
||||
I18n.format(getBlockState().getBlock().getTranslationKey()));
|
||||
String hint = Lang
|
||||
.translate("gui.contraptions.network_overstressed",
|
||||
I18n.format(getBlockState().getBlock().getTranslationKey()));
|
||||
List<String> cutString = TooltipHelper.cutString(spacing + hint, GRAY, TextFormatting.WHITE);
|
||||
for (int i = 0; i < cutString.size(); i++)
|
||||
tooltip.add((i == 0 ? "" : spacing) + cutString.get(i));
|
||||
|
@ -392,8 +400,9 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
|
||||
if (notFastEnough) {
|
||||
tooltip.add(spacing + GOLD + Lang.translate("tooltip.speedRequirement"));
|
||||
String hint = Lang.translate("gui.contraptions.not_fast_enough",
|
||||
I18n.format(getBlockState().getBlock().getTranslationKey()));
|
||||
String hint = Lang
|
||||
.translate("gui.contraptions.not_fast_enough",
|
||||
I18n.format(getBlockState().getBlock().getTranslationKey()));
|
||||
List<String> cutString = TooltipHelper.cutString(spacing + hint, GRAY, TextFormatting.WHITE);
|
||||
for (int i = 0; i < cutString.size(); i++)
|
||||
tooltip.add((i == 0 ? "" : spacing) + cutString.get(i));
|
||||
|
@ -417,10 +426,14 @@ public abstract class KineticTileEntity extends SmartTileEntity
|
|||
String stressString =
|
||||
spacing + "%s%s" + Lang.translate("generic.unit.stress") + " " + TextFormatting.DARK_GRAY + "%s";
|
||||
|
||||
tooltip.add(String.format(stressString, TextFormatting.AQUA, IHaveGoggleInformation.format(stressAtBase),
|
||||
Lang.translate("gui.goggles.base_value")));
|
||||
tooltip.add(String.format(stressString, TextFormatting.GRAY, IHaveGoggleInformation.format(stressTotal),
|
||||
Lang.translate("gui.goggles.at_current_speed")));
|
||||
tooltip
|
||||
.add(String
|
||||
.format(stressString, TextFormatting.AQUA, IHaveGoggleInformation.format(stressAtBase),
|
||||
Lang.translate("gui.goggles.base_value")));
|
||||
tooltip
|
||||
.add(String
|
||||
.format(stressString, TextFormatting.GRAY, IHaveGoggleInformation.format(stressTotal),
|
||||
Lang.translate("gui.goggles.at_current_speed")));
|
||||
|
||||
added = true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.contraptions.components.actors;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -8,7 +9,9 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
|
@ -16,11 +19,16 @@ import net.minecraft.util.math.shapes.VoxelShape;
|
|||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
|
||||
public abstract class AttachedActorBlock extends HorizontalBlock implements IPortableBlock {
|
||||
public abstract class AttachedActorBlock extends HorizontalBlock implements IPortableBlock, IWrenchable {
|
||||
|
||||
public AttachedActorBlock() {
|
||||
super(Properties.from(Blocks.IRON_BLOCK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.Movement
|
|||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.CocoaBlock;
|
||||
import net.minecraft.block.CropsBlock;
|
||||
import net.minecraft.block.KelpBlock;
|
||||
import net.minecraft.block.SugarCaneBlock;
|
||||
|
@ -81,7 +82,7 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
if (state.getCollisionShape(world, pos).isEmpty()) {
|
||||
if (state.getCollisionShape(world, pos).isEmpty() || state.getBlock() instanceof CocoaBlock) {
|
||||
for (IProperty<?> property : state.getProperties()) {
|
||||
if (!(property instanceof IntegerProperty))
|
||||
continue;
|
||||
|
@ -96,14 +97,14 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean isValidOther(World world, BlockPos pos, BlockState state) {
|
||||
if (state.getBlock() instanceof CropsBlock)
|
||||
return false;
|
||||
if (state.getBlock() instanceof SugarCaneBlock)
|
||||
return true;
|
||||
|
||||
if (state.getCollisionShape(world, pos).isEmpty()) {
|
||||
if (state.getCollisionShape(world, pos).isEmpty() || state.getBlock() instanceof CocoaBlock) {
|
||||
for (IProperty<?> property : state.getProperties()) {
|
||||
if (!(property instanceof IntegerProperty))
|
||||
continue;
|
||||
|
@ -131,7 +132,7 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
|
|||
return Blocks.AIR.getDefaultState();
|
||||
return state.getFluidState().getBlockState();
|
||||
}
|
||||
if (state.getCollisionShape(world, pos).isEmpty()) {
|
||||
if (state.getCollisionShape(world, pos).isEmpty() || state.getBlock() instanceof CocoaBlock) {
|
||||
for (IProperty<?> property : state.getProperties()) {
|
||||
if (!(property instanceof IntegerProperty))
|
||||
continue;
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.simibubi.create.modules.contraptions.components.actors.PloughBlock.Pl
|
|||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FlowingFluidBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.item.Items;
|
||||
|
@ -25,8 +26,8 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
|
||||
@Override
|
||||
public boolean isActive(MovementContext context) {
|
||||
return !VecHelper.isVecPointingTowards(context.relativeMotion,
|
||||
context.state.get(HORIZONTAL_FACING).getOpposite());
|
||||
return !VecHelper
|
||||
.isVecPointingTowards(context.relativeMotion, context.state.get(HORIZONTAL_FACING).getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +67,8 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
|
||||
@Override
|
||||
public boolean canBreak(World world, BlockPos breakingPos, BlockState state) {
|
||||
return state.getCollisionShape(world, breakingPos).isEmpty();
|
||||
return state.getCollisionShape(world, breakingPos).isEmpty()
|
||||
&& !(state.getBlock() instanceof FlowingFluidBlock);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,6 +15,9 @@ import com.simibubi.create.modules.contraptions.components.contraptions.pulley.P
|
|||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.crank.HandCrankBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.fan.NozzleBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.flywheel.engine.EngineBlock;
|
||||
import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock;
|
||||
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
|
||||
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
|
||||
|
@ -26,6 +29,7 @@ import net.minecraft.block.AbstractRailBlock;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.CarpetBlock;
|
||||
import net.minecraft.block.DoorBlock;
|
||||
import net.minecraft.block.FenceGateBlock;
|
||||
import net.minecraft.block.FlowerPotBlock;
|
||||
|
@ -105,6 +109,8 @@ public class BlockMovementTraits {
|
|||
Block block = state.getBlock();
|
||||
if (state.has(BlockStateProperties.HANGING))
|
||||
return true;
|
||||
if (block instanceof HandCrankBlock)
|
||||
return true;
|
||||
if (block instanceof LadderBlock)
|
||||
return true;
|
||||
if (block instanceof ExtractorBlock)
|
||||
|
@ -131,8 +137,14 @@ public class BlockMovementTraits {
|
|||
return true;
|
||||
if (block instanceof RopeBlock)
|
||||
return true;
|
||||
if (block instanceof NozzleBlock)
|
||||
return true;
|
||||
if (block instanceof MagnetBlock)
|
||||
return true;
|
||||
if (block instanceof EngineBlock)
|
||||
return true;
|
||||
if (block instanceof CarpetBlock)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -159,6 +171,8 @@ public class BlockMovementTraits {
|
|||
return direction == Direction.DOWN;
|
||||
if (block instanceof RedstoneWireBlock)
|
||||
return direction == Direction.DOWN;
|
||||
if (block instanceof CarpetBlock)
|
||||
return direction == Direction.DOWN;
|
||||
if (block instanceof RedstoneWallTorchBlock)
|
||||
return state.get(RedstoneWallTorchBlock.FACING) == direction.getOpposite();
|
||||
if (block instanceof TorchBlock)
|
||||
|
@ -178,6 +192,12 @@ public class BlockMovementTraits {
|
|||
return direction == Direction.DOWN;
|
||||
if (block instanceof AttachedActorBlock)
|
||||
return direction == state.get(HarvesterBlock.HORIZONTAL_FACING).getOpposite();
|
||||
if (block instanceof HandCrankBlock)
|
||||
return direction == state.get(HandCrankBlock.FACING).getOpposite();
|
||||
if (block instanceof NozzleBlock)
|
||||
return direction == state.get(NozzleBlock.FACING).getOpposite();
|
||||
if (block instanceof EngineBlock)
|
||||
return direction == state.get(EngineBlock.HORIZONTAL_FACING).getOpposite();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -196,6 +216,8 @@ public class BlockMovementTraits {
|
|||
return state.get(BlockStateProperties.HORIZONTAL_FACING) == facing;
|
||||
if (AllBlocks.ROPE_PULLEY.typeOf(state))
|
||||
return facing == Direction.DOWN;
|
||||
if (state.getBlock() instanceof CarpetBlock)
|
||||
return facing == Direction.UP;
|
||||
return isBrittle(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.modules.contraptions.components.actors.BlockBreakingMovementBehaviour;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.CocoaBlock;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -272,7 +273,8 @@ public class ContraptionCollider {
|
|||
if (AllBlocks.PULLEY_MAGNET.typeOf(collidedState) && pos.equals(BlockPos.ZERO)
|
||||
&& movementDirection == Direction.UP)
|
||||
continue;
|
||||
|
||||
if (collidedState.getBlock() instanceof CocoaBlock)
|
||||
continue;
|
||||
if (!collidedState.getMaterial().isReplaceable()
|
||||
&& !collidedState.getCollisionShape(world, colliderPos).isEmpty()) {
|
||||
return true;
|
||||
|
|
|
@ -593,6 +593,12 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
public void setMotion(Vec3d motionIn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPositionAndUpdate(double x, double y, double z) {
|
||||
if (!stationary)
|
||||
super.setPositionAndUpdate(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction() {
|
||||
return PushReaction.IGNORE;
|
||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.nbt.CompoundNBT;
|
|||
import net.minecraft.state.properties.ChestType;
|
||||
import net.minecraft.tileentity.BarrelTileEntity;
|
||||
import net.minecraft.tileentity.ChestTileEntity;
|
||||
import net.minecraft.tileentity.ShulkerBoxTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
@ -107,6 +108,8 @@ public class MountedStorage {
|
|||
TileEntityType<?> type = te.getType();
|
||||
if (type == AllTileEntities.FLEXCRATE.type)
|
||||
return true;
|
||||
if (te instanceof ShulkerBoxTileEntity)
|
||||
return true;
|
||||
if (te instanceof ChestTileEntity)
|
||||
return true;
|
||||
if (te instanceof BarrelTileEntity)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.simibubi.create.modules.contraptions.components.contraptions;
|
||||
|
||||
import static net.minecraft.block.HorizontalFaceBlock.FACE;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.DirectionHelper;
|
||||
|
@ -11,10 +13,13 @@ import com.simibubi.create.modules.contraptions.components.contraptions.chassis.
|
|||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.HorizontalFaceBlock;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.block.StairsBlock;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.properties.AttachFace;
|
||||
import net.minecraft.state.properties.Half;
|
||||
import net.minecraft.state.properties.SlabType;
|
||||
import net.minecraft.util.Direction;
|
||||
|
@ -74,90 +79,133 @@ public class StructureTransform {
|
|||
* horizontal axes
|
||||
*/
|
||||
public BlockState apply(BlockState state) {
|
||||
|
||||
if (rotationAxis == Axis.Y)
|
||||
state = state.rotate(rotation);
|
||||
else {
|
||||
if (state.getBlock() instanceof AbstractChassisBlock)
|
||||
return rotateChassis(state);
|
||||
return state.rotate(rotation);
|
||||
|
||||
if (state.getBlock() instanceof StairsBlock) {
|
||||
if (state.get(StairsBlock.FACING).getAxis() != rotationAxis) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||
Direction direction = state.get(StairsBlock.FACING);
|
||||
Half half = state.get(StairsBlock.HALF);
|
||||
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ half == Half.BOTTOM
|
||||
^ direction.getAxis() == Axis.Z)
|
||||
state = state.cycle(StairsBlock.HALF);
|
||||
else
|
||||
state = state.with(StairsBlock.FACING, direction.getOpposite());
|
||||
}
|
||||
} else {
|
||||
if (rotation == Rotation.CLOCKWISE_180) {
|
||||
state = state.cycle(StairsBlock.HALF);
|
||||
}
|
||||
}
|
||||
Block block = state.getBlock();
|
||||
|
||||
if (block instanceof AbstractChassisBlock)
|
||||
return rotateChassis(state);
|
||||
|
||||
if (block instanceof HorizontalFaceBlock) {
|
||||
Direction stateFacing = state.get(HorizontalFaceBlock.HORIZONTAL_FACING);
|
||||
AttachFace stateFace = state.get(FACE);
|
||||
Direction forcedAxis = rotationAxis == Axis.Z ? Direction.EAST : Direction.SOUTH;
|
||||
|
||||
if (stateFacing.getAxis() == rotationAxis && stateFace == AttachFace.WALL)
|
||||
return state;
|
||||
|
||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||
stateFace = state.get(FACE);
|
||||
stateFacing = state.get(HorizontalFaceBlock.HORIZONTAL_FACING);
|
||||
|
||||
boolean b = state.get(FACE) == AttachFace.CEILING;
|
||||
state = state.with(HORIZONTAL_FACING, b ? forcedAxis : forcedAxis.getOpposite());
|
||||
|
||||
if (stateFace != AttachFace.WALL) {
|
||||
state = state.with(FACE, AttachFace.WALL);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stateFacing.getAxisDirection() == AxisDirection.POSITIVE) {
|
||||
state = state.with(FACE, AttachFace.FLOOR);
|
||||
continue;
|
||||
}
|
||||
state = state.with(FACE, AttachFace.CEILING);
|
||||
}
|
||||
|
||||
if (AllBlocks.BELT.typeOf(state)) {
|
||||
if (state.get(BeltBlock.HORIZONTAL_FACING).getAxis() != rotationAxis) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||
Slope slope = state.get(BeltBlock.SLOPE);
|
||||
Direction direction = state.get(BeltBlock.HORIZONTAL_FACING);
|
||||
return state;
|
||||
}
|
||||
|
||||
// Rotate diagonal
|
||||
if (slope != Slope.HORIZONTAL && slope != Slope.VERTICAL) {
|
||||
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ slope == Slope.DOWNWARD
|
||||
^ direction.getAxis() == Axis.Z) {
|
||||
state =
|
||||
state.with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD : Slope.UPWARD);
|
||||
} else {
|
||||
state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite());
|
||||
}
|
||||
if (block instanceof StairsBlock) {
|
||||
if (state.get(StairsBlock.FACING).getAxis() != rotationAxis) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||
Direction direction = state.get(StairsBlock.FACING);
|
||||
Half half = state.get(StairsBlock.HALF);
|
||||
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ half == Half.BOTTOM
|
||||
^ direction.getAxis() == Axis.Z)
|
||||
state = state.cycle(StairsBlock.HALF);
|
||||
else
|
||||
state = state.with(StairsBlock.FACING, direction.getOpposite());
|
||||
}
|
||||
} else {
|
||||
if (rotation == Rotation.CLOCKWISE_180) {
|
||||
state = state.cycle(StairsBlock.HALF);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// Rotate horizontal/vertical
|
||||
if (AllBlocks.BELT.typeOf(state)) {
|
||||
if (state.get(BeltBlock.HORIZONTAL_FACING).getAxis() != rotationAxis) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++) {
|
||||
Slope slope = state.get(BeltBlock.SLOPE);
|
||||
Direction direction = state.get(BeltBlock.HORIZONTAL_FACING);
|
||||
|
||||
// Rotate diagonal
|
||||
if (slope != Slope.HORIZONTAL && slope != Slope.VERTICAL) {
|
||||
if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ slope == Slope.DOWNWARD
|
||||
^ direction.getAxis() == Axis.Z) {
|
||||
state = state.with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD : Slope.UPWARD);
|
||||
} else {
|
||||
if (slope == Slope.HORIZONTAL ^ direction.getAxis() == Axis.Z) {
|
||||
state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite());
|
||||
}
|
||||
state = state.with(BeltBlock.SLOPE,
|
||||
slope == Slope.HORIZONTAL ? Slope.VERTICAL : Slope.HORIZONTAL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rotation == Rotation.CLOCKWISE_180) {
|
||||
Slope slope = state.get(BeltBlock.SLOPE);
|
||||
Direction direction = state.get(BeltBlock.HORIZONTAL_FACING);
|
||||
if (slope == Slope.UPWARD || slope == Slope.DOWNWARD) {
|
||||
state = state.with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD
|
||||
: slope == Slope.DOWNWARD ? Slope.UPWARD : slope);
|
||||
} else if (slope == Slope.VERTICAL) {
|
||||
state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite());
|
||||
}
|
||||
|
||||
// Rotate horizontal/vertical
|
||||
} else {
|
||||
if (slope == Slope.HORIZONTAL ^ direction.getAxis() == Axis.Z) {
|
||||
state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite());
|
||||
}
|
||||
state =
|
||||
state.with(BeltBlock.SLOPE, slope == Slope.HORIZONTAL ? Slope.VERTICAL : Slope.HORIZONTAL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rotation == Rotation.CLOCKWISE_180) {
|
||||
Slope slope = state.get(BeltBlock.SLOPE);
|
||||
Direction direction = state.get(BeltBlock.HORIZONTAL_FACING);
|
||||
if (slope == Slope.UPWARD || slope == Slope.DOWNWARD) {
|
||||
state = state
|
||||
.with(BeltBlock.SLOPE, slope == Slope.UPWARD ? Slope.DOWNWARD
|
||||
: slope == Slope.DOWNWARD ? Slope.UPWARD : slope);
|
||||
} else if (slope == Slope.VERTICAL) {
|
||||
state = state.with(BeltBlock.HORIZONTAL_FACING, direction.getOpposite());
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
if (state.has(FACING)) {
|
||||
Direction newFacing = transformFacing(state.get(FACING));
|
||||
if (state.has(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) {
|
||||
if (rotationAxis == newFacing.getAxis() && rotation.ordinal() % 2 == 1)
|
||||
state = state.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
}
|
||||
state = state.with(FACING, newFacing);
|
||||
|
||||
} else if (state.has(AXIS)) {
|
||||
state = state.with(AXIS, transformAxis(state.get(AXIS)));
|
||||
|
||||
} else if (rotation == Rotation.CLOCKWISE_180) {
|
||||
|
||||
if (state.has(FACING)) {
|
||||
Direction newFacing = transformFacing(state.get(FACING));
|
||||
if (state.has(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) {
|
||||
if (rotationAxis == newFacing.getAxis() && rotation.ordinal() % 2 == 1)
|
||||
state = state.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
}
|
||||
state = state.with(FACING, newFacing);
|
||||
|
||||
} else if (state.has(AXIS)) {
|
||||
state = state.with(AXIS, transformAxis(state.get(AXIS)));
|
||||
|
||||
} else if (rotation == Rotation.CLOCKWISE_180) {
|
||||
state = state.rotate(rotation);
|
||||
if (state.has(SlabBlock.TYPE) && state.get(SlabBlock.TYPE) != SlabType.DOUBLE)
|
||||
state = state.with(SlabBlock.TYPE,
|
||||
state.get(SlabBlock.TYPE) == SlabType.BOTTOM ? SlabType.TOP : SlabType.BOTTOM);
|
||||
Direction stateFacing = state.get(FACING);
|
||||
if (stateFacing.getAxis() == rotationAxis)
|
||||
return state;
|
||||
}
|
||||
|
||||
if (state.has(HORIZONTAL_FACING)) {
|
||||
Direction stateFacing = state.get(HORIZONTAL_FACING);
|
||||
if (stateFacing.getAxis() == rotationAxis)
|
||||
return state;
|
||||
}
|
||||
|
||||
state = state.rotate(rotation);
|
||||
if (state.has(SlabBlock.TYPE) && state.get(SlabBlock.TYPE) != SlabType.DOUBLE)
|
||||
state = state
|
||||
.with(SlabBlock.TYPE,
|
||||
state.get(SlabBlock.TYPE) == SlabType.BOTTOM ? SlabType.TOP : SlabType.BOTTOM);
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -24,7 +24,7 @@ public abstract class BearingBlock extends DirectionalKineticBlock {
|
|||
protected boolean hasStaticPart() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return state.get(FACING).getAxis();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
|
||||
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -19,7 +20,7 @@ public class MechanicalBearingBlock extends BearingBlock implements ITE<Mechanic
|
|||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new MechanicalBearingTileEntity();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos,
|
||||
PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
|
||||
|
@ -41,18 +42,21 @@ public class MechanicalBearingBlock extends BearingBlock implements ITE<Mechanic
|
|||
}
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
if (worldIn instanceof WrappedWorld)
|
||||
return;
|
||||
withTileEntityDo(worldIn, pos, MechanicalBearingTileEntity::neighbourChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
if (worldIn instanceof WrappedWorld)
|
||||
return;
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
|
||||
withTileEntityDo(worldIn, pos, MechanicalBearingTileEntity::neighbourChanged);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
|
|||
}
|
||||
|
||||
public void neighbourChanged() {
|
||||
if (!hasWorld())
|
||||
return;
|
||||
|
||||
boolean shouldWindmill = world.isBlockPowered(pos);
|
||||
if (shouldWindmill == isWindmill)
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.simibubi.create.modules.contraptions.components.contraptions.chassis;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.RotatedPillarBlock;
|
||||
|
@ -22,7 +24,7 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.Tags;
|
||||
|
||||
public abstract class AbstractChassisBlock extends RotatedPillarBlock {
|
||||
public abstract class AbstractChassisBlock extends RotatedPillarBlock implements IWrenchable {
|
||||
|
||||
public AbstractChassisBlock(Properties properties) {
|
||||
super(properties);
|
||||
|
@ -45,7 +47,7 @@ public abstract class AbstractChassisBlock extends RotatedPillarBlock {
|
|||
return ActionResultType.PASS;
|
||||
|
||||
ItemStack heldItem = player.getHeldItem(handIn);
|
||||
boolean isSlimeBall = heldItem.getItem().isIn(Tags.Items.SLIMEBALLS);
|
||||
boolean isSlimeBall = heldItem.getItem().isIn(Tags.Items.SLIMEBALLS) || AllItems.SUPER_GLUE.typeOf(heldItem);
|
||||
|
||||
BooleanProperty affectedSide = getGlueableSide(state, hit.getFace());
|
||||
if (affectedSide == null)
|
||||
|
|
|
@ -46,8 +46,9 @@ public class ChassisTileEntity extends SmartTileEntity {
|
|||
te -> ((ChassisTileEntity) te).collectChassisGroup());
|
||||
range.requiresWrench();
|
||||
range.between(1, max);
|
||||
range.withClientCallback(
|
||||
i -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> ChassisRangeDisplay.display(this)));
|
||||
range
|
||||
.withClientCallback(
|
||||
i -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> ChassisRangeDisplay.display(this)));
|
||||
range.value = max / 2;
|
||||
behaviours.add(range);
|
||||
}
|
||||
|
@ -161,7 +162,7 @@ public class ChassisTileEntity extends SmartTileEntity {
|
|||
BlockPos current = pos.offset(facing, i);
|
||||
BlockState currentState = world.getBlockState(current);
|
||||
|
||||
if (forcedMovement != facing && !visualize && !sticky)
|
||||
if (forcedMovement != facing && !sticky)
|
||||
break;
|
||||
|
||||
// Ignore replaceable Blocks and Air-like
|
||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.network.PacketBuffer;
|
|||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
|
||||
|
@ -36,6 +37,7 @@ public class GlueEffectPacket extends SimplePacketBase {
|
|||
buffer.writeBoolean(fullBlock);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
|
|
|
@ -8,6 +8,9 @@ import com.simibubi.create.AllEntities;
|
|||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.modules.schematics.ISpecialEntityItemRequirement;
|
||||
import com.simibubi.create.modules.schematics.ItemRequirement;
|
||||
import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
|
@ -46,7 +49,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
|||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData, ISpecialEntityItemRequirement {
|
||||
|
||||
private int validationTimer;
|
||||
protected BlockPos hangingPosition;
|
||||
|
@ -105,31 +108,32 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
|||
|
||||
protected void updateBoundingBox() {
|
||||
if (this.getFacingDirection() != null) {
|
||||
double x = hangingPosition.getX() + 0.5 - facingDirection.getXOffset() * 0.5;
|
||||
double y = hangingPosition.getY() + 0.5 - facingDirection.getYOffset() * 0.5;
|
||||
double z = hangingPosition.getZ() + 0.5 - facingDirection.getZOffset() * 0.5;
|
||||
double offset = 0.5 - 1 / 256d;
|
||||
double x = hangingPosition.getX() + 0.5 - facingDirection.getXOffset() * offset;
|
||||
double y = hangingPosition.getY() + 0.5 - facingDirection.getYOffset() * offset;
|
||||
double z = hangingPosition.getZ() + 0.5 - facingDirection.getZOffset() * offset;
|
||||
this.setPos(x, y, z);
|
||||
double d1 = (double) this.getWidthPixels();
|
||||
double d2 = (double) this.getHeightPixels();
|
||||
double d3 = (double) this.getWidthPixels();
|
||||
double w = getWidthPixels();
|
||||
double h = getHeightPixels();
|
||||
double l = getWidthPixels();
|
||||
Axis axis = this.getFacingDirection().getAxis();
|
||||
double depth = 2 - 1 / 128f;
|
||||
|
||||
switch (axis) {
|
||||
case X:
|
||||
d1 = depth;
|
||||
w = depth;
|
||||
break;
|
||||
case Y:
|
||||
d2 = depth;
|
||||
h = depth;
|
||||
break;
|
||||
case Z:
|
||||
d3 = depth;
|
||||
l = depth;
|
||||
}
|
||||
|
||||
d1 = d1 / 32.0D;
|
||||
d2 = d2 / 32.0D;
|
||||
d3 = d3 / 32.0D;
|
||||
this.setBoundingBox(new AxisAlignedBB(x - d1, y - d2, z - d3, x + d1, y + d2, z + d3));
|
||||
w = w / 32.0D;
|
||||
h = h / 32.0D;
|
||||
l = l / 32.0D;
|
||||
this.setBoundingBox(new AxisAlignedBB(x - w, y - h, z - l, x + w, y + h, z + l));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,13 +298,13 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
|||
if (this.getFacingDirection().getAxis() != Direction.Axis.Y) {
|
||||
switch (transformRotation) {
|
||||
case CLOCKWISE_180:
|
||||
this.facingDirection = this.getFacingDirection().getOpposite();
|
||||
facingDirection = facingDirection.getOpposite();
|
||||
break;
|
||||
case COUNTERCLOCKWISE_90:
|
||||
this.facingDirection = this.getFacingDirection().rotateYCCW();
|
||||
facingDirection = facingDirection.rotateYCCW();
|
||||
break;
|
||||
case CLOCKWISE_90:
|
||||
this.facingDirection = this.getFacingDirection().rotateY();
|
||||
facingDirection = facingDirection.rotateY();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -366,4 +370,10 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
|||
public Direction getFacingDirection() {
|
||||
return facingDirection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems() {
|
||||
return new ItemRequirement(ItemUseType.DAMAGE, AllItems.SUPER_GLUE.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.block.RenderUtilityBlock;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.mounted.CartAssemblerTileEntity.CartMovementMode;
|
||||
|
||||
|
@ -32,7 +33,7 @@ import net.minecraft.util.math.shapes.VoxelShapes;
|
|||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CartAssemblerBlock extends AbstractRailBlock implements ITE<CartAssemblerTileEntity> {
|
||||
public class CartAssemblerBlock extends AbstractRailBlock implements ITE<CartAssemblerTileEntity>, IWrenchable {
|
||||
|
||||
public static IProperty<RailShape> RAIL_SHAPE =
|
||||
EnumProperty.create("shape", RailShape.class, RailShape.EAST_WEST, RailShape.NORTH_SOUTH);
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.glue.Sup
|
|||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.CarpetBlock;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
|
@ -152,7 +153,7 @@ public class PistonContraption extends Contraption {
|
|||
if (!BlockMovementTraits.movementNecessary(world, currentPos))
|
||||
return true;
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
if (BlockMovementTraits.isBrittle(state))
|
||||
if (BlockMovementTraits.isBrittle(state) && !(state.getBlock() instanceof CarpetBlock))
|
||||
return true;
|
||||
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state) && state.get(FACING) == direction.getOpposite())
|
||||
return true;
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create.modules.contraptions.components.contraptions.piston;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -20,7 +21,7 @@ import net.minecraft.util.math.shapes.VoxelShape;
|
|||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PistonPoleBlock extends ProperDirectionalBlock {
|
||||
public class PistonPoleBlock extends ProperDirectionalBlock implements IWrenchable {
|
||||
|
||||
public PistonPoleBlock() {
|
||||
super(Properties.from(Blocks.PISTON_HEAD));
|
||||
|
|
|
@ -217,10 +217,12 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
});
|
||||
|
||||
groupedItems = new GroupedItems(result);
|
||||
containers.forEach(stack -> {
|
||||
GroupedItems container = new GroupedItems(stack);
|
||||
for (int i = 0; i < containers.size(); i++) {
|
||||
ItemStack stack = containers.get(i);
|
||||
GroupedItems container = new GroupedItems();
|
||||
container.grid.put(Pair.of(i, 0), stack);
|
||||
container.mergeOnto(groupedItems, Pointing.LEFT);
|
||||
});
|
||||
}
|
||||
|
||||
phase = Phase.CRAFTING;
|
||||
countDown = 2000;
|
||||
|
|
|
@ -58,7 +58,8 @@ public class DeployerItemHandler implements IItemHandlerModifiable {
|
|||
return stack;
|
||||
|
||||
int space = held.getMaxStackSize() - held.getCount();
|
||||
ItemStack split = stack.copy().split(space);
|
||||
ItemStack remainder = stack.copy();
|
||||
ItemStack split = remainder.split(space);
|
||||
|
||||
if (space == 0)
|
||||
return stack;
|
||||
|
@ -68,7 +69,7 @@ public class DeployerItemHandler implements IItemHandlerModifiable {
|
|||
set(held);
|
||||
}
|
||||
|
||||
return split;
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -51,8 +51,11 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
|||
|
||||
public class DeployerTileEntity extends KineticTileEntity {
|
||||
|
||||
private static final List<Pair<BlockPos, Direction>> EXTRACTING_LOCATIONS = Arrays.asList(Direction.values())
|
||||
.stream().map(d -> Pair.of(BlockPos.ZERO.offset(d), d.getOpposite())).collect(Collectors.toList());
|
||||
private static final List<Pair<BlockPos, Direction>> EXTRACTING_LOCATIONS = Arrays
|
||||
.asList(Direction.values())
|
||||
.stream()
|
||||
.map(d -> Pair.of(BlockPos.ZERO.offset(d), d.getOpposite()))
|
||||
.collect(Collectors.toList());
|
||||
private FilteringBehaviour filtering;
|
||||
private ExtractingBehaviour extracting;
|
||||
|
||||
|
@ -373,8 +376,9 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
reach = tag.getFloat("Reach");
|
||||
if (tag.contains("Particle")) {
|
||||
ItemStack particleStack = ItemStack.read(tag.getCompound("Particle"));
|
||||
SandPaperItem.spawnParticles(VecHelper.getCenterOf(pos).add(getMovementVector().scale(2f)), particleStack,
|
||||
this.world);
|
||||
SandPaperItem
|
||||
.spawnParticles(VecHelper.getCenterOf(pos).add(getMovementVector().scale(2f)), particleStack,
|
||||
this.world);
|
||||
}
|
||||
|
||||
super.readClientUpdate(tag);
|
||||
|
@ -402,7 +406,8 @@ public class DeployerTileEntity extends KineticTileEntity {
|
|||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
invHandler.invalidate();
|
||||
if (invHandler != null)
|
||||
invHandler.invalidate();
|
||||
}
|
||||
|
||||
public void changeMode() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.contraptions.components.fan;
|
||||
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -49,6 +50,8 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE<Enca
|
|||
}
|
||||
|
||||
protected void blockUpdate(BlockState state, World worldIn, BlockPos pos) {
|
||||
if (worldIn instanceof WrappedWorld)
|
||||
return;
|
||||
notifyFanTile(worldIn, pos);
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
|
|
|
@ -3,11 +3,14 @@ package com.simibubi.create.modules.contraptions.components.fan;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
|
@ -16,7 +19,7 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class NozzleBlock extends ProperDirectionalBlock {
|
||||
public class NozzleBlock extends ProperDirectionalBlock implements IWrenchable {
|
||||
|
||||
public NozzleBlock() {
|
||||
super(Properties.from(AllBlocks.ENCASED_FAN.get()));
|
||||
|
@ -27,6 +30,11 @@ public class NozzleBlock extends ProperDirectionalBlock {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new NozzleTileEntity();
|
||||
|
|
|
@ -3,14 +3,16 @@ package com.simibubi.create.modules.contraptions.components.flywheel.engine;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
|
@ -19,7 +21,7 @@ import net.minecraft.world.World;
|
|||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public abstract class EngineBlock extends HorizontalBlock {
|
||||
public abstract class EngineBlock extends HorizontalBlock implements IWrenchable {
|
||||
|
||||
protected EngineBlock(Properties builder) {
|
||||
super(builder);
|
||||
|
@ -36,10 +38,10 @@ public abstract class EngineBlock extends HorizontalBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.simibubi.create.AllBlockPartials;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||
|
||||
import net.minecraft.block.AbstractFurnaceBlock;
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -53,6 +54,8 @@ public class FurnaceEngineBlock extends EngineBlock implements ITE<FurnaceEngine
|
|||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
super.neighborChanged(state, worldIn, pos, blockIn, fromPos, isMoving);
|
||||
if (worldIn instanceof WrappedWorld)
|
||||
return;
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Optional;
|
|||
import com.simibubi.create.AllRecipes;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.processing.BasinOperatingTileEntity;
|
||||
|
@ -163,8 +164,10 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
pressedItems.add(itemEntity.getItem());
|
||||
sendData();
|
||||
Optional<PressingRecipe> recipe = getRecipe(itemEntity.getItem());
|
||||
if (recipe.isPresent())
|
||||
if (recipe.isPresent()) {
|
||||
InWorldProcessing.applyRecipeOn(itemEntity, recipe.get());
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.BONK, world, pos, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,14 @@ package com.simibubi.create.modules.contraptions.components.waterwheel;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
@ -60,7 +63,7 @@ public class WaterWheelBlock extends HorizontalKineticBlock implements ITE<Water
|
|||
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
|
||||
BlockPos currentPos, BlockPos facingPos) {
|
||||
World world = worldIn.getWorld();
|
||||
if (world == null)
|
||||
if (world == null || worldIn instanceof WrappedWorld)
|
||||
return stateIn;
|
||||
updateFlowAt(stateIn, world, currentPos, facing);
|
||||
updateWheelSpeed(worldIn, currentPos);
|
||||
|
@ -109,6 +112,12 @@ public class WaterWheelBlock extends HorizontalKineticBlock implements ITE<Water
|
|||
flowStrength = flow.y > 0 ^ !clockwise ? -flow.y * clockwiseMultiplier : -flow.y;
|
||||
}
|
||||
|
||||
if (te.getSpeed() == 0 && flowStrength != 0 && !world.isRemote) {
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.WATER_WHEEL, world, pos, 5);
|
||||
if (fluid.getFluid() == Fluids.FLOWING_LAVA || fluid.getFluid() == Fluids.LAVA)
|
||||
AllTriggers.triggerForNearbyPlayers(AllTriggers.LAVA_WHEEL, world, pos, 5);
|
||||
}
|
||||
|
||||
te.setFlow(f, (float) (flowStrength * AllConfigs.SERVER.kinetics.waterWheelSpeed.get() / 2f));
|
||||
});
|
||||
}
|
||||
|
@ -126,7 +135,6 @@ public class WaterWheelBlock extends HorizontalKineticBlock implements ITE<Water
|
|||
if (facing.getAxis().isHorizontal())
|
||||
return getDefaultState().with(HORIZONTAL_FACING,
|
||||
context.getPlayer().isSneaking() ? facing.getOpposite() : facing);
|
||||
|
||||
return super.getStateForPlacement(context);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
package com.simibubi.create.modules.contraptions.processing;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
|
@ -26,7 +28,7 @@ import net.minecraftforge.items.IItemHandlerModifiable;
|
|||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class BasinBlock extends Block implements ITE<BasinTileEntity> {
|
||||
public class BasinBlock extends Block implements ITE<BasinTileEntity>, IWrenchable {
|
||||
|
||||
public BasinBlock() {
|
||||
super(Properties.from(Blocks.ANDESITE));
|
||||
|
@ -41,10 +43,10 @@ public class BasinBlock extends Block implements ITE<BasinTileEntity> {
|
|||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new BasinTileEntity();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,6 +83,11 @@ public class BasinBlock extends Block implements ITE<BasinTileEntity> {
|
|||
|
||||
if (insertItem.isEmpty()) {
|
||||
itemEntity.remove();
|
||||
|
||||
if (!itemEntity.world.isRemote)
|
||||
AllTriggers
|
||||
.triggerForNearbyPlayers(AllTriggers.BASIN_THROW, itemEntity.world,
|
||||
itemEntity.getPosition(), 3);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.advancement.SimpleTrigger;
|
||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.behaviour.simple.DeferralBehaviour;
|
||||
import com.simibubi.create.foundation.utility.recipe.RecipeFinder;
|
||||
|
@ -149,6 +152,13 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
|
|||
// something wasn't found
|
||||
return;
|
||||
}
|
||||
|
||||
if (!world.isRemote) {
|
||||
SimpleTrigger trigger = AllTriggers.MIXER_MIX;
|
||||
if (getType() == AllTileEntities.MECHANICAL_PRESS.type)
|
||||
trigger = AllTriggers.PRESS_COMPACT;
|
||||
AllTriggers.triggerForNearbyPlayers(trigger, world, pos, 4);
|
||||
}
|
||||
|
||||
ItemHandlerHelper.insertItemStacked(outputs, lastRecipe.getRecipeOutput().copy(), false);
|
||||
containers.forEach(stack -> ItemHandlerHelper.insertItemStacked(outputs, stack, false));
|
||||
|
|
|
@ -28,7 +28,13 @@ public class ProcessingRecipeSerializer<T extends ProcessingRecipe<?>>
|
|||
|
||||
List<ProcessingIngredient> ingredients = new ArrayList<>();
|
||||
for (JsonElement e : JSONUtils.getJsonArray(json, "ingredients")) {
|
||||
ingredients.add(ProcessingIngredient.parse(e.getAsJsonObject()));
|
||||
int count = 1;
|
||||
if (JSONUtils.hasField((JsonObject) e, "count")) {
|
||||
count = JSONUtils.getInt(e.getAsJsonObject().get("count"), "count");
|
||||
}
|
||||
for(int i = 0; i < count; i++) {
|
||||
ingredients.add(ProcessingIngredient.parse(e.getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
|
||||
List<ProcessingOutput> results = new ArrayList<>();
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Random;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
|
||||
|
||||
|
@ -21,7 +22,7 @@ import net.minecraft.world.IWorld;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class ContactBlock extends ProperDirectionalBlock implements IPortableBlock {
|
||||
public class ContactBlock extends ProperDirectionalBlock implements IPortableBlock, IWrenchable {
|
||||
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
public static MovementBehaviour MOVEMENT = new ContactMovementBehaviour();
|
||||
|
|
|
@ -59,10 +59,25 @@ public class SpeedControllerTileEntity extends KineticTileEntity {
|
|||
boolean targetingController) {
|
||||
if (!(speedControllerIn instanceof SpeedControllerTileEntity))
|
||||
return 0;
|
||||
SpeedControllerTileEntity speedController = (SpeedControllerTileEntity) speedControllerIn;
|
||||
|
||||
float speed = speedControllerIn.getTheoreticalSpeed();
|
||||
float wheelSpeed = cogWheel.getTheoreticalSpeed();
|
||||
float desiredOutputSpeed = getDesiredOutputSpeed(cogWheel, speedControllerIn, targetingController);
|
||||
|
||||
float compareSpeed = targetingController ? speed : wheelSpeed;
|
||||
if (desiredOutputSpeed >= 0 && compareSpeed >= 0)
|
||||
return Math.max(desiredOutputSpeed, compareSpeed);
|
||||
if (desiredOutputSpeed < 0 && compareSpeed < 0)
|
||||
return Math.min(desiredOutputSpeed, compareSpeed);
|
||||
|
||||
return desiredOutputSpeed;
|
||||
}
|
||||
|
||||
public static float getDesiredOutputSpeed(KineticTileEntity cogWheel, KineticTileEntity speedControllerIn,
|
||||
boolean targetingController) {
|
||||
SpeedControllerTileEntity speedController = (SpeedControllerTileEntity) speedControllerIn;
|
||||
float targetSpeed = speedController.targetSpeed.getValue();
|
||||
float speed = speedControllerIn.getSpeed();
|
||||
float speed = speedControllerIn.getTheoreticalSpeed();
|
||||
float wheelSpeed = cogWheel.getTheoreticalSpeed();
|
||||
|
||||
if (targetSpeed == 0)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -16,6 +17,9 @@ import com.simibubi.create.foundation.utility.Lang;
|
|||
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo;
|
||||
import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||
import com.simibubi.create.modules.schematics.ISpecialBlockItemRequirement;
|
||||
import com.simibubi.create.modules.schematics.ItemRequirement;
|
||||
import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
|
@ -45,12 +49,14 @@ import net.minecraft.util.Direction.Axis;
|
|||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -62,7 +68,7 @@ import net.minecraftforge.common.Tags;
|
|||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEntity>, IHaveColorHandler {
|
||||
public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEntity>, IHaveColorHandler, ISpecialBlockItemRequirement {
|
||||
|
||||
public static final IProperty<Slope> SLOPE = EnumProperty.create("slope", Slope.class);
|
||||
public static final IProperty<Part> PART = EnumProperty.create("part", Part.class);
|
||||
|
@ -338,10 +344,11 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
double d7 = d4 * d1 + x1;
|
||||
double d8 = d5 * d2 + y1;
|
||||
double d9 = d6 * d3 + z1;
|
||||
manager.addEffect(
|
||||
(new DiggingParticle(world, (double) pos.getX() + d7, (double) pos.getY() + d8,
|
||||
(double) pos.getZ() + d9, d4 - 0.5D, d5 - 0.5D, d6 - 0.5D, state))
|
||||
.setBlockPos(pos));
|
||||
manager
|
||||
.addEffect(
|
||||
(new DiggingParticle(world, (double) pos.getX() + d7, (double) pos.getY() + d8,
|
||||
(double) pos.getZ() + d9, d4 - 0.5D, d5 - 0.5D, d6 - 0.5D, state))
|
||||
.setBlockPos(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -358,6 +365,9 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos,
|
||||
ISelectionContext context) {
|
||||
if (state.getBlock() != this)
|
||||
return VoxelShapes.empty();
|
||||
|
||||
VoxelShape shape = getShape(state, worldIn, pos, context);
|
||||
try {
|
||||
if (context.getEntity() == null)
|
||||
|
@ -427,7 +437,9 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
|
||||
for (BlockPos beltPos : beltChain) {
|
||||
TileEntity tileEntity = world.getTileEntity(beltPos);
|
||||
if (tileEntity instanceof BeltTileEntity) {
|
||||
BlockState currentState = world.getBlockState(beltPos);
|
||||
|
||||
if (tileEntity instanceof BeltTileEntity && AllBlocks.BELT.typeOf(currentState)) {
|
||||
BeltTileEntity te = (BeltTileEntity) tileEntity;
|
||||
te.setController(currentPos);
|
||||
te.beltLength = beltChain.size();
|
||||
|
@ -436,7 +448,6 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
te.markDirty();
|
||||
te.sendData();
|
||||
|
||||
BlockState currentState = world.getBlockState(beltPos);
|
||||
boolean isVertical = currentState.get(BeltBlock.SLOPE) == Slope.VERTICAL;
|
||||
|
||||
if (currentState.get(CASING) && isVertical) {
|
||||
|
@ -537,10 +548,10 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
int limit = 1000;
|
||||
BlockPos current = controllerPos;
|
||||
while (limit-- > 0 && current != null) {
|
||||
positions.add(current);
|
||||
BlockState state = world.getBlockState(current);
|
||||
if (!AllBlocks.BELT.typeOf(state))
|
||||
break;
|
||||
positions.add(current);
|
||||
current = nextSegmentPosition(state, current, true);
|
||||
}
|
||||
|
||||
|
@ -605,4 +616,34 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||
return BeltTileEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems(BlockState state) {
|
||||
List<ItemStack> required = new ArrayList<>();
|
||||
if (state.get(PART) != Part.MIDDLE)
|
||||
required.add(new ItemStack(AllBlocksNew.SHAFT.get()));
|
||||
if (state.get(CASING))
|
||||
required.add(new ItemStack(AllBlocks.BRASS_CASING.get()));
|
||||
if (state.get(PART) == Part.START)
|
||||
required.add(AllItems.BELT_CONNECTOR.asStack());
|
||||
if (required.isEmpty())
|
||||
return ItemRequirement.NONE;
|
||||
return new ItemRequirement(ItemUseType.CONSUME, required);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation rot) {
|
||||
BlockState rotate = super.rotate(state, rot);
|
||||
|
||||
if (state.get(SLOPE) != Slope.VERTICAL)
|
||||
return rotate;
|
||||
if (state.get(HORIZONTAL_FACING).getAxisDirection() != rotate.get(HORIZONTAL_FACING).getAxisDirection()) {
|
||||
if (state.get(PART) == Part.START)
|
||||
return rotate.with(PART, Part.END);
|
||||
if (state.get(PART) == Part.END)
|
||||
return rotate.with(PART, Part.START);
|
||||
}
|
||||
|
||||
return rotate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
// Init belt
|
||||
if (beltLength == 0)
|
||||
BeltBlock.initBelt(world, pos);
|
||||
if (!AllBlocks.BELT.typeOf(world.getBlockState(pos)))
|
||||
return;
|
||||
|
||||
// Initialize Belt Attachments
|
||||
if (world != null && trackerUpdateTag != null) {
|
||||
|
@ -131,7 +133,10 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
TileEntity te = world.getTileEntity(controller);
|
||||
if (te == null || !(te instanceof BeltTileEntity))
|
||||
return;
|
||||
IItemHandler handler = ((BeltTileEntity) te).getInventory().createHandlerForSegment(index);
|
||||
BeltInventory inventory = ((BeltTileEntity) te).getInventory();
|
||||
if (inventory == null)
|
||||
return;
|
||||
IItemHandler handler = inventory.createHandlerForSegment(index);
|
||||
itemHandler = LazyOptional.of(() -> handler);
|
||||
}
|
||||
|
||||
|
@ -306,8 +311,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
|
||||
public Direction getMovementFacing() {
|
||||
Axis axis = getBeltFacing().getAxis();
|
||||
return Direction.getFacingFromAxisDirection(axis,
|
||||
getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE);
|
||||
return Direction
|
||||
.getFacingFromAxisDirection(axis, getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE);
|
||||
}
|
||||
|
||||
protected Direction getBeltFacing() {
|
||||
|
@ -344,7 +349,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
if (simulate)
|
||||
return true;
|
||||
|
||||
transportedStack.beltPosition = index + .5f - Math.signum(getSpeed()) / 16f;
|
||||
transportedStack.beltPosition = index + .5f - Math.signum(getDirectionAwareBeltMovementSpeed()) / 16f;
|
||||
|
||||
Direction movementFacing = getMovementFacing();
|
||||
if (!side.getAxis().isVertical()) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.List;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.item.IAddedByOther;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
|
@ -71,9 +72,9 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
|||
if (!canConnect(world, firstPulley, pos))
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
if (firstPulley != null && !firstPulley.equals(pos)) {
|
||||
if (firstPulley != null && !firstPulley.equals(pos) && !world.isRemote) {
|
||||
createBelts(world, firstPulley, pos);
|
||||
|
||||
AllTriggers.triggerFor(AllTriggers.CONNECT_BELT, context.getPlayer());
|
||||
if (!context.getPlayer().isCreative())
|
||||
context.getItem().shrink(1);
|
||||
}
|
||||
|
@ -91,15 +92,16 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
|||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
private void createBelts(World world, BlockPos start, BlockPos end) {
|
||||
public static void createBelts(World world, BlockPos start, BlockPos end) {
|
||||
|
||||
BeltBlock.Slope slope = getSlopeBetween(start, end);
|
||||
Direction facing = getFacingFromTo(start, end);
|
||||
|
||||
BlockPos diff = end.subtract(start);
|
||||
if (diff.getX() == diff.getZ())
|
||||
facing = Direction.getFacingFromAxis(facing.getAxisDirection(),
|
||||
world.getBlockState(start).get(BlockStateProperties.AXIS) == Axis.X ? Axis.Z : Axis.X);
|
||||
facing = Direction
|
||||
.getFacingFromAxis(facing.getAxisDirection(),
|
||||
world.getBlockState(start).get(BlockStateProperties.AXIS) == Axis.X ? Axis.Z : Axis.X);
|
||||
|
||||
List<BlockPos> beltsToCreate = getBeltChainBetween(start, end, slope, facing);
|
||||
BlockState beltBlock = AllBlocks.BELT.get().getDefaultState();
|
||||
|
@ -109,12 +111,17 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
|||
boolean pulley = ShaftBlock.isShaft(world.getBlockState(pos));
|
||||
if (part == Part.MIDDLE && pulley)
|
||||
part = Part.PULLEY;
|
||||
world.setBlockState(pos, beltBlock.with(BeltBlock.SLOPE, slope).with(BeltBlock.PART, part)
|
||||
.with(BeltBlock.HORIZONTAL_FACING, facing), 3);
|
||||
world
|
||||
.setBlockState(pos,
|
||||
beltBlock
|
||||
.with(BeltBlock.SLOPE, slope)
|
||||
.with(BeltBlock.PART, part)
|
||||
.with(BeltBlock.HORIZONTAL_FACING, facing),
|
||||
3);
|
||||
}
|
||||
}
|
||||
|
||||
private Direction getFacingFromTo(BlockPos start, BlockPos end) {
|
||||
private static Direction getFacingFromTo(BlockPos start, BlockPos end) {
|
||||
Axis beltAxis = start.getX() == end.getX() ? Axis.Z : Axis.X;
|
||||
BlockPos diff = end.subtract(start);
|
||||
AxisDirection axisDirection = AxisDirection.POSITIVE;
|
||||
|
@ -128,7 +135,7 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
|||
return Direction.getFacingFromAxis(axisDirection, beltAxis);
|
||||
}
|
||||
|
||||
private Slope getSlopeBetween(BlockPos start, BlockPos end) {
|
||||
private static Slope getSlopeBetween(BlockPos start, BlockPos end) {
|
||||
BlockPos diff = end.subtract(start);
|
||||
|
||||
if (diff.getY() != 0) {
|
||||
|
@ -139,7 +146,7 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
|||
return Slope.HORIZONTAL;
|
||||
}
|
||||
|
||||
private List<BlockPos> getBeltChainBetween(BlockPos start, BlockPos end, Slope slope, Direction direction) {
|
||||
private static List<BlockPos> getBeltChainBetween(BlockPos start, BlockPos end, Slope slope, Direction direction) {
|
||||
List<BlockPos> positions = new LinkedList<>();
|
||||
int limit = 1000;
|
||||
BlockPos current = start;
|
||||
|
|
|
@ -118,18 +118,18 @@ public class BeltInventory {
|
|||
float diffToEnd = beltMovementPositive ? belt.beltLength - currentPos : -currentPos;
|
||||
float limitedMovement =
|
||||
beltMovementPositive ? Math.min(movement, diffToEnd) : Math.max(movement, diffToEnd);
|
||||
|
||||
float nextOffset = current.beltPosition + limitedMovement;
|
||||
if (!onClient) {
|
||||
|
||||
if (!onClient && segmentBefore != -1) {
|
||||
// Don't move if belt attachments want to continue processing
|
||||
if (segmentBefore != -1 && current.locked) {
|
||||
if (current.locked) {
|
||||
BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore);
|
||||
if (beltSegment != null) {
|
||||
|
||||
|
||||
// wait in case belt isnt initialized yet
|
||||
if (current.locked && beltSegment.trackerUpdateTag != null)
|
||||
continue;
|
||||
|
||||
|
||||
current.locked = false;
|
||||
List<BeltAttachmentState> attachments = beltSegment.attachmentTracker.attachments;
|
||||
for (BeltAttachmentState attachmentState : attachments) {
|
||||
|
@ -146,22 +146,24 @@ public class BeltInventory {
|
|||
}
|
||||
|
||||
// See if any new belt processing catches the item
|
||||
int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||
for (int segment = upcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
|
||||
: segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) {
|
||||
BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore);
|
||||
if (beltSegment == null)
|
||||
break;
|
||||
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
|
||||
ItemStack stackBefore = current.stack.copy();
|
||||
if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) {
|
||||
current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
||||
current.locked = true;
|
||||
belt.sendData();
|
||||
continue Items;
|
||||
if (current.beltPosition > .5f || beltMovementPositive) {
|
||||
int firstUpcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||
for (int segment = firstUpcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
|
||||
: segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) {
|
||||
BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segment);
|
||||
if (beltSegment == null)
|
||||
break;
|
||||
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
|
||||
ItemStack stackBefore = current.stack.copy();
|
||||
if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) {
|
||||
current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
||||
current.locked = true;
|
||||
belt.sendData();
|
||||
continue Items;
|
||||
}
|
||||
if (!stackBefore.equals(current.stack, true))
|
||||
belt.sendData();
|
||||
}
|
||||
if (!stackBefore.equals(current.stack, true))
|
||||
belt.sendData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,8 +204,9 @@ public class BeltInventory {
|
|||
if (segment == -1)
|
||||
continue;
|
||||
if (!world.isRemote)
|
||||
world.updateComparatorOutputLevel(BeltHelper.getPositionForOffset(belt, segment),
|
||||
belt.getBlockState().getBlock());
|
||||
world
|
||||
.updateComparatorOutputLevel(BeltHelper.getPositionForOffset(belt, segment),
|
||||
belt.getBlockState().getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,7 +395,8 @@ public class BeltInventory {
|
|||
|
||||
public void read(CompoundNBT nbt) {
|
||||
getItems().clear();
|
||||
nbt.getList("Items", NBT.TAG_COMPOUND)
|
||||
nbt
|
||||
.getList("Items", NBT.TAG_COMPOUND)
|
||||
.forEach(inbt -> getItems().add(TransportedItemStack.read((CompoundNBT) inbt)));
|
||||
beltMovementPositive = nbt.getBoolean("PositiveOrder");
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.elementary;
|
||||
|
||||
import com.simibubi.create.AllBlocksNew;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
|
@ -11,6 +15,7 @@ import net.minecraft.util.Direction.Axis;
|
|||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CogwheelBlockItem extends BlockItem {
|
||||
|
||||
|
@ -52,8 +57,8 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
hitVec = hitVec
|
||||
.mul(new Vec3d(Direction.getFacingFromAxis(AxisDirection.POSITIVE, offsetAxis).getDirectionVec()));
|
||||
|
||||
BlockPos correctPos = context.getPos().add(Math.signum(hitVec.x), Math.signum(hitVec.y),
|
||||
Math.signum(hitVec.z));
|
||||
BlockPos correctPos =
|
||||
context.getPos().add(Math.signum(hitVec.x), Math.signum(hitVec.y), Math.signum(hitVec.z));
|
||||
|
||||
if (context.getWorld().getBlockState(correctPos).getMaterial().isReplaceable())
|
||||
context = BlockItemUseContext.func_221536_a(context, correctPos, largeOnLarge ? face
|
||||
|
@ -65,4 +70,41 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
return super.tryPlace(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
// Trigger cogwheel criterion
|
||||
protected boolean placeBlock(BlockItemUseContext context, BlockState state) {
|
||||
World world = context.getWorld();
|
||||
PlayerEntity player = context.getPlayer();
|
||||
|
||||
if (!world.isRemote && player != null) {
|
||||
Axis axis = state.get(CogWheelBlock.AXIS);
|
||||
for (Axis perpendicular1 : Iterate.axes) {
|
||||
if (perpendicular1 == axis)
|
||||
continue;
|
||||
Direction d1 = Direction.getFacingFromAxis(AxisDirection.POSITIVE, perpendicular1);
|
||||
for (Axis perpendicular2 : Iterate.axes) {
|
||||
if (perpendicular1 == perpendicular2)
|
||||
continue;
|
||||
if (axis == perpendicular2)
|
||||
continue;
|
||||
Direction d2 = Direction.getFacingFromAxis(AxisDirection.POSITIVE, perpendicular2);
|
||||
for (int offset1 : Iterate.positiveAndNegative) {
|
||||
for (int offset2 : Iterate.positiveAndNegative) {
|
||||
BlockPos connectedPos = context.getPos().offset(d1, offset1).offset(d2, offset2);
|
||||
BlockState blockState = world.getBlockState(connectedPos);
|
||||
if (!(blockState.getBlock() instanceof CogWheelBlock))
|
||||
continue;
|
||||
if (blockState.get(CogWheelBlock.AXIS) != axis)
|
||||
continue;
|
||||
if (AllBlocksNew.equals(AllBlocksNew.LARGE_COGWHEEL, blockState) == large)
|
||||
continue;
|
||||
AllTriggers.triggerFor(AllTriggers.SHIFTING_GEARS, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.placeBlock(context, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ public class AdjustablePulleyTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
public void neighborChanged() {
|
||||
if (!hasWorld())
|
||||
return;
|
||||
int power = world.getRedstonePowerFromNeighbors(pos);
|
||||
if (power != signal)
|
||||
signalChanged = true;
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Random;
|
|||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
|
||||
|
@ -79,13 +80,16 @@ public class GaugeBlock extends DirectionalAxisKineticBlock {
|
|||
Direction nearestLookingDirection = context.getNearestLookingDirection();
|
||||
boolean lookPositive = nearestLookingDirection.getAxisDirection() == AxisDirection.POSITIVE;
|
||||
if (face.getAxis() == Axis.X) {
|
||||
toPlace = toPlace.with(FACING, lookPositive ? Direction.NORTH : Direction.SOUTH)
|
||||
toPlace = toPlace
|
||||
.with(FACING, lookPositive ? Direction.NORTH : Direction.SOUTH)
|
||||
.with(AXIS_ALONG_FIRST_COORDINATE, true);
|
||||
} else if (face.getAxis() == Axis.Y) {
|
||||
toPlace = toPlace.with(FACING, horizontalFacing.getOpposite()).with(AXIS_ALONG_FIRST_COORDINATE,
|
||||
horizontalFacing.getAxis() == Axis.X);
|
||||
toPlace = toPlace
|
||||
.with(FACING, horizontalFacing.getOpposite())
|
||||
.with(AXIS_ALONG_FIRST_COORDINATE, horizontalFacing.getAxis() == Axis.X);
|
||||
} else {
|
||||
toPlace = toPlace.with(FACING, lookPositive ? Direction.WEST : Direction.EAST)
|
||||
toPlace = toPlace
|
||||
.with(FACING, lookPositive ? Direction.WEST : Direction.EAST)
|
||||
.with(AXIS_ALONG_FIRST_COORDINATE, false);
|
||||
}
|
||||
|
||||
|
@ -119,8 +123,8 @@ public class GaugeBlock extends DirectionalAxisKineticBlock {
|
|||
if (getRotationAxis(state) == Axis.Y && face != state.get(FACING))
|
||||
return false;
|
||||
BlockState blockState = world.getBlockState(pos.offset(face));
|
||||
if (Block.hasSolidSide(blockState, world, pos, face.getOpposite())
|
||||
&& blockState.getMaterial() != Material.GLASS)
|
||||
if (Block.hasSolidSide(blockState, world, pos, face.getOpposite()) && blockState.getMaterial() != Material.GLASS
|
||||
&& !(world instanceof WrappedWorld))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -149,11 +153,15 @@ public class GaugeBlock extends DirectionalAxisKineticBlock {
|
|||
continue;
|
||||
|
||||
for (int i = 0; i < particleCount; i++) {
|
||||
Vec3d mul = VecHelper.offsetRandomly(Vec3d.ZERO, rand, .25f)
|
||||
.mul(new Vec3d(1, 1, 1).subtract(positiveFaceVec)).normalize().scale(.3f);
|
||||
Vec3d mul = VecHelper
|
||||
.offsetRandomly(Vec3d.ZERO, rand, .25f)
|
||||
.mul(new Vec3d(1, 1, 1).subtract(positiveFaceVec))
|
||||
.normalize()
|
||||
.scale(.3f);
|
||||
Vec3d offset = VecHelper.getCenterOf(pos).add(faceVec.scale(.55)).add(mul);
|
||||
worldIn.addParticle(new RedstoneParticleData((float) rgb.x, (float) rgb.y, (float) rgb.z, 1), offset.x,
|
||||
offset.y, offset.z, mul.x, mul.y, mul.z);
|
||||
worldIn
|
||||
.addParticle(new RedstoneParticleData((float) rgb.x, (float) rgb.y, (float) rgb.z, 1), offset.x,
|
||||
offset.y, offset.z, mul.x, mul.y, mul.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package com.simibubi.create.modules.curiosities.tools;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.IItemTier;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.SwordItem;
|
||||
|
||||
public class BlazingSwordItem extends SwordItem {
|
||||
|
||||
public BlazingSwordItem(IItemTier tier, int attackDamageIn, float attackSpeedIn, Properties builder) {
|
||||
super(tier, attackDamageIn, attackSpeedIn, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
||||
target.setFire(2);
|
||||
return BlazingToolItem.shouldTakeDamage(attacker.world, stack) ? super.hitEntity(stack, target, attacker)
|
||||
: true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBurnTime(ItemStack itemStack) {
|
||||
return itemStack.getMaxDamage() - itemStack.getDamage() + 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -55,7 +55,7 @@ public class BlazingToolItem extends AbstractToolItem {
|
|||
return shouldTakeDamage(attacker.world, stack) ? super.hitEntity(stack, target, attacker) : true;
|
||||
}
|
||||
|
||||
protected boolean shouldTakeDamage(World world, ItemStack stack) {
|
||||
static boolean shouldTakeDamage(World world, ItemStack stack) {
|
||||
return world.getDimension().getType() != DimensionType.THE_NETHER;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package com.simibubi.create.modules.curiosities.tools;
|
||||
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.block.render.CustomRenderedItemModel;
|
||||
import com.simibubi.create.foundation.item.IHaveCustomItemModel;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.components.deployer.DeployerFakePlayer;
|
||||
import com.simibubi.create.modules.curiosities.tools.SandPaperItemRenderer.SandPaperModel;
|
||||
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
|
@ -12,7 +10,6 @@ import net.minecraft.enchantment.Enchantment;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
|
@ -31,6 +28,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
|
||||
public class SandPaperItem extends Item implements IHaveCustomItemModel {
|
||||
|
||||
|
@ -136,11 +134,9 @@ public class SandPaperItem extends Item implements IHaveCustomItemModel {
|
|||
}
|
||||
|
||||
if (!polished.isEmpty()) {
|
||||
if (player instanceof DeployerFakePlayer) {
|
||||
if (player instanceof FakePlayer) {
|
||||
player.dropItem(polished, false, false);
|
||||
} else {
|
||||
AllTriggers.SANDPAPER_USE.trigger((ServerPlayerEntity) player, toPolish, polished);
|
||||
|
||||
player.inventory.placeItemBackInInventory(worldIn, polished);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Set;
|
|||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.block.render.CustomRenderedItemModel;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.item.IHaveCustomItemModel;
|
||||
|
@ -110,8 +111,10 @@ public class BlockzapperItem extends ZapperItem implements IHaveCustomItemModel
|
|||
continue;
|
||||
if (!player.isCreative() && BlockHelper.findAndRemoveInInventory(selectedState, player, 1) == 0) {
|
||||
player.getCooldownTracker().setCooldown(stack.getItem(), 20);
|
||||
player.sendStatusMessage(
|
||||
new StringTextComponent(TextFormatting.RED + Lang.translate("blockzapper.empty")), true);
|
||||
player
|
||||
.sendStatusMessage(
|
||||
new StringTextComponent(TextFormatting.RED + Lang.translate("blockzapper.empty")),
|
||||
true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -119,9 +122,9 @@ public class BlockzapperItem extends ZapperItem implements IHaveCustomItemModel
|
|||
dropBlocks(world, player, stack, face, placed);
|
||||
|
||||
for (Direction updateDirection : Direction.values())
|
||||
selectedState = selectedState.updatePostPlacement(updateDirection,
|
||||
world.getBlockState(placed.offset(updateDirection)), world, placed,
|
||||
placed.offset(updateDirection));
|
||||
selectedState = selectedState
|
||||
.updatePostPlacement(updateDirection, world.getBlockState(placed.offset(updateDirection)),
|
||||
world, placed, placed.offset(updateDirection));
|
||||
|
||||
BlockSnapshot blocksnapshot = BlockSnapshot.getBlockSnapshot(world, placed);
|
||||
IFluidState ifluidstate = world.getFluidState(placed);
|
||||
|
@ -132,9 +135,20 @@ public class BlockzapperItem extends ZapperItem implements IHaveCustomItemModel
|
|||
return false;
|
||||
}
|
||||
|
||||
if (player instanceof ServerPlayerEntity)
|
||||
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, placed,
|
||||
new ItemStack(selectedState.getBlock()));
|
||||
if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) {
|
||||
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
|
||||
CriteriaTriggers.PLACED_BLOCK.trigger(serverPlayer, placed, new ItemStack(selectedState.getBlock()));
|
||||
|
||||
boolean fullyUpgraded = true;
|
||||
for (Components c : Components.values()) {
|
||||
if (getTier(c, stack) != ComponentTier.Chromatic) {
|
||||
fullyUpgraded = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fullyUpgraded)
|
||||
AllTriggers.UPGRADED_ZAPPER.trigger(serverPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -179,8 +193,9 @@ public class BlockzapperItem extends ZapperItem implements IHaveCustomItemModel
|
|||
|
||||
Vec3d start = player.getPositionVec().add(0, player.getEyeHeight(), 0);
|
||||
Vec3d range = player.getLookVec().scale(getRange(stack));
|
||||
BlockRayTraceResult raytrace = player.world.rayTraceBlocks(
|
||||
new RayTraceContext(start, start.add(range), BlockMode.COLLIDER, FluidMode.NONE, player));
|
||||
BlockRayTraceResult raytrace = player.world
|
||||
.rayTraceBlocks(
|
||||
new RayTraceContext(start, start.add(range), BlockMode.COLLIDER, FluidMode.NONE, player));
|
||||
BlockPos pos = raytrace.getPos().toImmutable();
|
||||
|
||||
if (pos == null)
|
||||
|
@ -318,8 +333,8 @@ public class BlockzapperItem extends ZapperItem implements IHaveCustomItemModel
|
|||
Block.spawnDrops(worldIn.getBlockState(placed), worldIn, playerIn.getPosition(), tileentity);
|
||||
|
||||
if (getTier(Components.Retriever, item) == ComponentTier.Chromatic)
|
||||
for (ItemStack stack : Block.getDrops(worldIn.getBlockState(placed), (ServerWorld) worldIn, placed,
|
||||
tileentity))
|
||||
for (ItemStack stack : Block
|
||||
.getDrops(worldIn.getBlockState(placed), (ServerWorld) worldIn, placed, tileentity))
|
||||
if (!playerIn.inventory.addItemStackToInventory(stack))
|
||||
Block.spawnAsEntity(worldIn, placed, stack);
|
||||
}
|
||||
|
|
|
@ -153,6 +153,9 @@ public class InWorldProcessing {
|
|||
return null;
|
||||
|
||||
List<ItemStack> stacks = process(transported.stack, type, belt.getWorld());
|
||||
if (stacks == null)
|
||||
return null;
|
||||
|
||||
List<TransportedItemStack> transportedStacks = new ArrayList<>();
|
||||
for (ItemStack additional : stacks) {
|
||||
TransportedItemStack newTransported = transported.getSimilar();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock;
|
||||
|
||||
|
@ -12,8 +13,10 @@ import net.minecraft.block.material.PushReaction;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -22,7 +25,7 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class AttachedLogisticalBlock extends HorizontalBlock {
|
||||
public abstract class AttachedLogisticalBlock extends HorizontalBlock implements IWrenchable {
|
||||
|
||||
public static final BooleanProperty UPWARD = BooleanProperty.create("upward");
|
||||
|
||||
|
@ -30,6 +33,11 @@ public abstract class AttachedLogisticalBlock extends HorizontalBlock {
|
|||
super(Properties.from(Blocks.ANDESITE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
return ActionResultType.FAIL;
|
||||
}
|
||||
|
||||
protected abstract boolean isVertical();
|
||||
|
||||
protected abstract BlockState getVerticalDefaultState();
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
|
@ -27,7 +28,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
|||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
||||
public class StockswitchBlock extends HorizontalBlock implements ITE<StockswitchTileEntity> {
|
||||
public class StockswitchBlock extends HorizontalBlock implements ITE<StockswitchTileEntity>, IWrenchable {
|
||||
|
||||
public static final IntegerProperty INDICATOR = IntegerProperty.create("indicator", 0, 6);
|
||||
|
||||
|
@ -85,6 +86,8 @@ public class StockswitchBlock extends HorizontalBlock implements ITE<Stockswitch
|
|||
@Override
|
||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
if (player != null && AllItems.WRENCH.typeOf(player.getHeldItem(handIn)))
|
||||
return false;
|
||||
DistExecutor.runWhenOn(Dist.CLIENT,
|
||||
() -> () -> withTileEntityDo(worldIn, pos, te -> this.displayScreen(te, player)));
|
||||
return ActionResultType.SUCCESS;
|
||||
|
@ -136,11 +139,6 @@ public class StockswitchBlock extends HorizontalBlock implements ITE<Stockswitch
|
|||
return new StockswitchTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPushReaction(BlockState state) {
|
||||
return PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<StockswitchTileEntity> getTileEntityClass() {
|
||||
return StockswitchTileEntity.class;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -15,7 +18,7 @@ import net.minecraftforge.common.util.LazyOptional;
|
|||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class StockswitchTileEntity extends SyncedTileEntity {
|
||||
public class StockswitchTileEntity extends SmartTileEntity {
|
||||
|
||||
public float onWhenAbove;
|
||||
public float offWhenBelow;
|
||||
|
@ -34,6 +37,7 @@ public class StockswitchTileEntity extends SyncedTileEntity {
|
|||
currentLevel = -1;
|
||||
powered = false;
|
||||
observedInventory = LazyOptional.empty();
|
||||
setLazyTickRate(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -107,7 +111,17 @@ public class StockswitchTileEntity extends SyncedTileEntity {
|
|||
world.notifyNeighbors(pos, getBlockState().getBlock());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lazyTick() {
|
||||
super.lazyTick();
|
||||
if (world.isRemote)
|
||||
return;
|
||||
findNewInventory();
|
||||
updateCurrentLevel();
|
||||
}
|
||||
|
||||
private boolean findNewInventory() {
|
||||
observedInventory = LazyOptional.empty();
|
||||
BlockPos invPos = getPos().offset(getBlockState().get(BlockStateProperties.HORIZONTAL_FACING));
|
||||
|
||||
if (!world.isBlockPresent(invPos))
|
||||
|
@ -117,14 +131,21 @@ public class StockswitchTileEntity extends SyncedTileEntity {
|
|||
if (!invState.hasTileEntity())
|
||||
return false;
|
||||
TileEntity invTE = world.getTileEntity(invPos);
|
||||
if (invTE == null)
|
||||
return false;
|
||||
|
||||
observedInventory = invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
|
||||
if (observedInventory.isPresent()) {
|
||||
updateCurrentLevel();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.util.List;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
|
@ -104,7 +105,8 @@ public class BeltTunnelBlock extends Block implements ITE<BeltTunnelTileEntity>,
|
|||
@Override
|
||||
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld worldIn,
|
||||
BlockPos currentPos, BlockPos facingPos) {
|
||||
withTileEntityDo(worldIn, currentPos, BeltTunnelTileEntity::initFlaps);
|
||||
if (!(worldIn instanceof WrappedWorld))
|
||||
withTileEntityDo(worldIn, currentPos, BeltTunnelTileEntity::initFlaps);
|
||||
BlockState tunnelState = getTunnelState(worldIn, currentPos);
|
||||
|
||||
if (tunnelState.get(HORIZONTAL_AXIS) == state.get(HORIZONTAL_AXIS)) {
|
||||
|
@ -160,11 +162,11 @@ public class BeltTunnelBlock extends Block implements ITE<BeltTunnelTileEntity>,
|
|||
// T and Cross
|
||||
Direction left = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis).rotateY();
|
||||
BlockState leftState = reader.getBlockState(pos.offset(left).down());
|
||||
boolean onLeft = AllBlocks.BELT.typeOf(leftState)
|
||||
&& leftState.get(BeltBlock.HORIZONTAL_FACING).getAxis() != axis;
|
||||
boolean onLeft =
|
||||
AllBlocks.BELT.typeOf(leftState) && leftState.get(BeltBlock.HORIZONTAL_FACING).getAxis() != axis;
|
||||
BlockState rightState = reader.getBlockState(pos.offset(left.getOpposite()).down());
|
||||
boolean onRight = AllBlocks.BELT.typeOf(rightState)
|
||||
&& rightState.get(BeltBlock.HORIZONTAL_FACING).getAxis() != axis;
|
||||
boolean onRight =
|
||||
AllBlocks.BELT.typeOf(rightState) && rightState.get(BeltBlock.HORIZONTAL_FACING).getAxis() != axis;
|
||||
|
||||
if (onLeft && onRight)
|
||||
state = state.with(SHAPE, Shape.CROSS);
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.simibubi.create.modules.logistics.block.diodes;
|
||||
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
|
||||
import net.minecraft.block.RedstoneDiodeBlock;
|
||||
|
||||
public abstract class AbstractDiodeBlock extends RedstoneDiodeBlock implements IWrenchable {
|
||||
|
||||
public AbstractDiodeBlock(Properties builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,6 @@ import com.simibubi.create.AllBlocks;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.RedstoneDiodeBlock;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
@ -13,7 +12,7 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
|
||||
public class FlexpeaterBlock extends RedstoneDiodeBlock {
|
||||
public class FlexpeaterBlock extends AbstractDiodeBlock {
|
||||
|
||||
public static BooleanProperty POWERING = BooleanProperty.create("powering");
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.util.Random;
|
|||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.RedstoneWireBlock;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
|
@ -30,13 +32,9 @@ public class LatchBlock extends ToggleLatchBlock {
|
|||
@Override
|
||||
protected void updateState(World worldIn, BlockPos pos, BlockState state) {
|
||||
boolean back = state.get(POWERED);
|
||||
boolean shouldBack = this.shouldBePowered(worldIn, pos, state);
|
||||
boolean shouldBack = shouldBePowered(worldIn, pos, state);
|
||||
boolean side = state.get(POWERED_SIDE);
|
||||
|
||||
Direction direction = state.get(HORIZONTAL_FACING);
|
||||
Direction left = direction.rotateY();
|
||||
Direction right = direction.rotateYCCW();
|
||||
boolean shouldSide = worldIn.isBlockPowered(pos.offset(left)) || worldIn.isBlockPowered(pos.offset(right));
|
||||
boolean shouldSide = isPoweredOnSides(worldIn, pos, state);
|
||||
|
||||
TickPriority tickpriority = TickPriority.HIGH;
|
||||
if (this.isFacingTowardsRepeater(worldIn, pos, state))
|
||||
|
@ -50,16 +48,29 @@ public class LatchBlock extends ToggleLatchBlock {
|
|||
worldIn.getPendingBlockTicks().scheduleTick(pos, this, this.getDelay(state), tickpriority);
|
||||
}
|
||||
|
||||
protected boolean isPoweredOnSides(World worldIn, BlockPos pos, BlockState state) {
|
||||
Direction direction = state.get(HORIZONTAL_FACING);
|
||||
Direction left = direction.rotateY();
|
||||
Direction right = direction.rotateYCCW();
|
||||
|
||||
for (Direction d : new Direction[] { left, right }) {
|
||||
BlockPos blockpos = pos.offset(d);
|
||||
int i = worldIn.getRedstonePower(blockpos, d);
|
||||
if (i > 0)
|
||||
return true;
|
||||
BlockState blockstate = worldIn.getBlockState(blockpos);
|
||||
if (blockstate.getBlock() == Blocks.REDSTONE_WIRE && blockstate.get(RedstoneWireBlock.POWER) > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduledTick(BlockState state, ServerWorld worldIn, BlockPos pos, Random random) {
|
||||
boolean back = state.get(POWERED);
|
||||
boolean shouldBack = this.shouldBePowered(worldIn, pos, state);
|
||||
boolean side = state.get(POWERED_SIDE);
|
||||
|
||||
Direction direction = state.get(HORIZONTAL_FACING);
|
||||
Direction left = direction.rotateY();
|
||||
Direction right = direction.rotateYCCW();
|
||||
boolean shouldSide = worldIn.isBlockPowered(pos.offset(left)) || worldIn.isBlockPowered(pos.offset(right));
|
||||
boolean shouldSide = isPoweredOnSides(worldIn, pos, state);
|
||||
BlockState stateIn = state;
|
||||
|
||||
if (back != shouldBack) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import java.util.Random;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.RedstoneDiodeBlock;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.util.Direction;
|
||||
|
@ -14,7 +13,7 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.TickPriority;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class PulseRepeaterBlock extends RedstoneDiodeBlock {
|
||||
public class PulseRepeaterBlock extends AbstractDiodeBlock {
|
||||
|
||||
public static BooleanProperty PULSING = BooleanProperty.create("pulsing");
|
||||
|
||||
|
|
|
@ -2,10 +2,11 @@ package com.simibubi.create.modules.logistics.block.diodes;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.RedstoneDiodeBlock;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
|
@ -18,10 +19,10 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class ToggleLatchBlock extends RedstoneDiodeBlock {
|
||||
public class ToggleLatchBlock extends AbstractDiodeBlock {
|
||||
|
||||
public static BooleanProperty POWERING = BooleanProperty.create("powering");
|
||||
|
||||
|
||||
public ToggleLatchBlock() {
|
||||
super(Properties.from(Blocks.REPEATER));
|
||||
setDefaultState(getDefaultState().with(POWERING, false).with(POWERED, false));
|
||||
|
@ -31,17 +32,17 @@ public class ToggleLatchBlock extends RedstoneDiodeBlock {
|
|||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(POWERED, POWERING, HORIZONTAL_FACING);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) {
|
||||
return blockState.get(HORIZONTAL_FACING) == side ? this.getActiveSignal(blockAccess, pos, blockState) : 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getDelay(BlockState state) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
|
@ -49,6 +50,8 @@ public class ToggleLatchBlock extends RedstoneDiodeBlock {
|
|||
return ActionResultType.PASS;
|
||||
if (player.isSneaking())
|
||||
return ActionResultType.PASS;
|
||||
if (AllItems.WRENCH.typeOf(player.getHeldItem(handIn)))
|
||||
return ActionResultType.PASS;
|
||||
return activated(worldIn, pos, state);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CrateBlock extends ProperDirectionalBlock implements IWrenchable {
|
||||
|
||||
public static final BooleanProperty DOUBLE = BooleanProperty.create("double");
|
||||
|
||||
public CrateBlock(Properties p_i48415_1_) {
|
||||
super(p_i48415_1_);
|
||||
setDefaultState(getDefaultState().with(FACING, Direction.UP).with(DOUBLE, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
return AllShapes.CRATE_BLOCK_SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
|
||||
BlockPos currentPos, BlockPos facingPos) {
|
||||
|
||||
boolean isDouble = stateIn.get(DOUBLE);
|
||||
Direction blockFacing = stateIn.get(FACING);
|
||||
boolean isFacingOther = facingState.getBlock() == this && facingState.get(DOUBLE)
|
||||
&& facingState.get(FACING) == facing.getOpposite();
|
||||
|
||||
if (!isDouble) {
|
||||
if (!isFacingOther)
|
||||
return stateIn;
|
||||
return stateIn.with(DOUBLE, true).with(FACING, facing);
|
||||
}
|
||||
|
||||
if (facing != blockFacing)
|
||||
return stateIn;
|
||||
if (!isFacingOther)
|
||||
return stateIn.with(DOUBLE, false);
|
||||
|
||||
return stateIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
BlockPos pos = context.getPos();
|
||||
World world = context.getWorld();
|
||||
|
||||
if (!context.isPlacerSneaking()) {
|
||||
for (Direction d : Direction.values()) {
|
||||
BlockState state = world.getBlockState(pos.offset(d));
|
||||
if (state.getBlock() == this && !state.get(DOUBLE))
|
||||
return getDefaultState().with(FACING, d).with(DOUBLE, true);
|
||||
}
|
||||
}
|
||||
|
||||
Direction placedOnFace = context.getFace().getOpposite();
|
||||
BlockState state = world.getBlockState(pos.offset(placedOnFace));
|
||||
if (state.getBlock() == this && !state.get(DOUBLE))
|
||||
return getDefaultState().with(FACING, placedOnFace).with(DOUBLE, true);
|
||||
return getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
super.fillStateContainer(builder.add(DOUBLE));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
|
||||
public abstract class CrateTileEntity extends SmartTileEntity {
|
||||
|
||||
public CrateTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {}
|
||||
|
||||
public boolean isDoubleCrate() {
|
||||
return getBlockState().get(FlexcrateBlock.DOUBLE);
|
||||
}
|
||||
|
||||
public boolean isSecondaryCrate() {
|
||||
if (!hasWorld())
|
||||
return false;
|
||||
if (!(getBlockState().getBlock() instanceof CrateBlock))
|
||||
return false;
|
||||
return isDoubleCrate() && getFacing().getAxisDirection() == AxisDirection.NEGATIVE;
|
||||
}
|
||||
|
||||
public Direction getFacing() {
|
||||
return getBlockState().get(FlexcrateBlock.FACING);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class CreativeCrateBlock extends CrateBlock implements ITE<CreativeCrateTileEntity> {
|
||||
|
||||
public CreativeCrateBlock(Properties p_i48415_1_) {
|
||||
super(p_i48415_1_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new CreativeCrateTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
withTileEntityDo(worldIn, pos, CreativeCrateTileEntity::onPlaced);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<CreativeCrateTileEntity> getTileEntityClass() {
|
||||
return CreativeCrateTileEntity.class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class CreativeCrateInventory implements IItemHandler {
|
||||
|
||||
private CreativeCrateTileEntity te;
|
||||
|
||||
public CreativeCrateInventory(CreativeCrateTileEntity te) {
|
||||
this.te = te;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
if (slot == 1)
|
||||
return ItemStack.EMPTY;
|
||||
ItemStack filter = te.filter.getFilter().copy();
|
||||
if (!filter.isEmpty())
|
||||
filter.setCount(filter.getMaxStackSize());
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
ItemStack filter = te.filter.getFilter().copy();
|
||||
if (!filter.isEmpty())
|
||||
filter.setCount(amount);
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
return getStackInSlot(slot).getMaxStackSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
|
||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class CreativeCrateTileEntity extends CrateTileEntity {
|
||||
|
||||
public CreativeCrateTileEntity() {
|
||||
super(AllTileEntities.CREATIVE_CRATE.type);
|
||||
inv = new CreativeCrateInventory(this);
|
||||
itemHandler = LazyOptional.of(() -> inv);
|
||||
}
|
||||
|
||||
FilteringBehaviour filter;
|
||||
LazyOptional<IItemHandler> itemHandler;
|
||||
private CreativeCrateInventory inv;
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
filter = createFilter();
|
||||
filter.onlyActiveWhen(this::filterVisible);
|
||||
filter.withCallback(this::filterChanged);
|
||||
behaviours.add(filter);
|
||||
}
|
||||
|
||||
private boolean filterVisible() {
|
||||
if (!hasWorld() || isDoubleCrate() && !isSecondaryCrate())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void filterChanged(ItemStack filter) {
|
||||
if (!filterVisible())
|
||||
return;
|
||||
CreativeCrateTileEntity otherCrate = getOtherCrate();
|
||||
if (otherCrate == null)
|
||||
return;
|
||||
if (ItemStack.areItemsEqual(filter, otherCrate.filter.getFilter()))
|
||||
return;
|
||||
otherCrate.filter.setFilter(filter);
|
||||
}
|
||||
|
||||
private CreativeCrateTileEntity getOtherCrate() {
|
||||
if (!AllBlocks.CREATIVE_CRATE.typeOf(getBlockState()))
|
||||
return null;
|
||||
TileEntity tileEntity = world.getTileEntity(pos.offset(getFacing()));
|
||||
if (tileEntity instanceof CreativeCrateTileEntity)
|
||||
return (CreativeCrateTileEntity) tileEntity;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onPlaced() {
|
||||
if (!isDoubleCrate())
|
||||
return;
|
||||
CreativeCrateTileEntity otherCrate = getOtherCrate();
|
||||
if (otherCrate == null)
|
||||
return;
|
||||
|
||||
filter.withCallback($ -> {});
|
||||
filter.setFilter(otherCrate.filter.getFilter());
|
||||
filter.withCallback(this::filterChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
return itemHandler.cast();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
public FilteringBehaviour createFilter() {
|
||||
return new FilteringBehaviour(this, new ValueBoxTransform() {
|
||||
|
||||
@Override
|
||||
protected Vec3d getOrientation(BlockState state) {
|
||||
return new Vec3d(0, 0, 90);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vec3d getLocation(BlockState state) {
|
||||
return new Vec3d(0.5, 13 / 16d, 0.5);
|
||||
}
|
||||
|
||||
protected float getScale() {
|
||||
return super.getScale() * 1.5f;
|
||||
};
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +1,27 @@
|
|||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
public class FlexcrateBlock extends ProperDirectionalBlock {
|
||||
|
||||
public static final BooleanProperty DOUBLE = BooleanProperty.create("double");
|
||||
public class FlexcrateBlock extends CrateBlock {
|
||||
|
||||
public FlexcrateBlock() {
|
||||
super(Properties.from(Blocks.ANDESITE));
|
||||
setDefaultState(getDefaultState().with(FACING, Direction.UP).with(DOUBLE, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
return AllShapes.CRATE_BLOCK_SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
super.fillStateContainer(builder.add(DOUBLE));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,23 +30,8 @@ public class FlexcrateBlock extends ProperDirectionalBlock {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
BlockPos pos = context.getPos();
|
||||
World world = context.getWorld();
|
||||
|
||||
if (!context.getPlayer().isSneaking()) {
|
||||
for (Direction d : Direction.values()) {
|
||||
BlockState state = world.getBlockState(pos.offset(d));
|
||||
if (AllBlocks.FLEXCRATE.typeOf(state) && !state.get(DOUBLE))
|
||||
return getDefaultState().with(FACING, d).with(DOUBLE, true);
|
||||
}
|
||||
}
|
||||
|
||||
Direction placedOnFace = context.getFace().getOpposite();
|
||||
BlockState state = world.getBlockState(pos.offset(placedOnFace));
|
||||
if (AllBlocks.FLEXCRATE.typeOf(state) && !state.get(DOUBLE))
|
||||
return getDefaultState().with(FACING, placedOnFace).with(DOUBLE, true);
|
||||
return getDefaultState();
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new FlexcrateTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,7 +46,7 @@ public class FlexcrateBlock extends ProperDirectionalBlock {
|
|||
FlexcrateTileEntity other = te.getOtherCrate();
|
||||
if (other == null)
|
||||
return;
|
||||
|
||||
|
||||
for (int slot = 0; slot < other.inventory.getSlots(); slot++) {
|
||||
te.inventory.setStackInSlot(slot, other.inventory.getStackInSlot(slot));
|
||||
other.inventory.setStackInSlot(slot, ItemStack.EMPTY);
|
||||
|
@ -94,29 +56,6 @@ public class FlexcrateBlock extends ProperDirectionalBlock {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
|
||||
BlockPos currentPos, BlockPos facingPos) {
|
||||
|
||||
boolean isDouble = stateIn.get(DOUBLE);
|
||||
Direction blockFacing = stateIn.get(FACING);
|
||||
boolean isFacingOther = AllBlocks.FLEXCRATE.typeOf(facingState) && facingState.get(DOUBLE)
|
||||
&& facingState.get(FACING) == facing.getOpposite();
|
||||
|
||||
if (!isDouble) {
|
||||
if (!isFacingOther)
|
||||
return stateIn;
|
||||
return stateIn.with(DOUBLE, true).with(FACING, facing);
|
||||
}
|
||||
|
||||
if (facing != blockFacing)
|
||||
return stateIn;
|
||||
if (!isFacingOther)
|
||||
return stateIn.with(DOUBLE, false);
|
||||
|
||||
return stateIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
|
@ -134,11 +73,6 @@ public class FlexcrateBlock extends ProperDirectionalBlock {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new FlexcrateTileEntity();
|
||||
}
|
||||
|
||||
public static void splitCrate(World world, BlockPos pos) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!AllBlocks.FLEXCRATE.typeOf(state))
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.modules.logistics.block.inventories;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
|
@ -15,7 +14,6 @@ import net.minecraft.network.PacketBuffer;
|
|||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
|
@ -24,7 +22,7 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
|||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class FlexcrateTileEntity extends SyncedTileEntity implements INamedContainerProvider {
|
||||
public class FlexcrateTileEntity extends CrateTileEntity implements INamedContainerProvider {
|
||||
|
||||
public class Inv extends ItemStackHandler {
|
||||
public Inv() {
|
||||
|
@ -81,20 +79,6 @@ public class FlexcrateTileEntity extends SyncedTileEntity implements INamedConta
|
|||
return new FlexcrateContainer(id, inventory, this);
|
||||
}
|
||||
|
||||
public boolean isDoubleCrate() {
|
||||
return getBlockState().get(FlexcrateBlock.DOUBLE);
|
||||
}
|
||||
|
||||
public FlexcrateTileEntity getMainCrate() {
|
||||
if (isSecondaryCrate())
|
||||
return getOtherCrate();
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSecondaryCrate() {
|
||||
return isDoubleCrate() && getFacing().getAxisDirection() == AxisDirection.NEGATIVE;
|
||||
}
|
||||
|
||||
public FlexcrateTileEntity getOtherCrate() {
|
||||
if (!AllBlocks.FLEXCRATE.typeOf(getBlockState()))
|
||||
return null;
|
||||
|
@ -104,8 +88,10 @@ public class FlexcrateTileEntity extends SyncedTileEntity implements INamedConta
|
|||
return null;
|
||||
}
|
||||
|
||||
public Direction getFacing() {
|
||||
return getBlockState().get(FlexcrateBlock.FACING);
|
||||
public FlexcrateTileEntity getMainCrate() {
|
||||
if (isSecondaryCrate())
|
||||
return getOtherCrate();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void onSplit() {
|
||||
|
@ -195,7 +181,7 @@ public class FlexcrateTileEntity extends SyncedTileEntity implements INamedConta
|
|||
public <T> LazyOptional<T> getCapability(Capability<T> capability, Direction facing) {
|
||||
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
FlexcrateTileEntity mainCrate = getMainCrate();
|
||||
if (mainCrate != null && mainCrate.invHandler.isPresent())
|
||||
if (mainCrate != null && mainCrate.invHandler != null && mainCrate.invHandler.isPresent())
|
||||
return mainCrate.invHandler.cast();
|
||||
}
|
||||
return super.getCapability(capability, facing);
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.modules.logistics.block.transposer;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
import com.simibubi.create.modules.contraptions.IWrenchable;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltAttachableLogisticalBlock;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -23,7 +22,7 @@ import net.minecraft.world.IBlockReader;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class TransposerBlock extends BeltAttachableLogisticalBlock implements IWrenchable {
|
||||
public class TransposerBlock extends BeltAttachableLogisticalBlock {
|
||||
|
||||
public static BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package com.simibubi.create.modules.schematics;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
||||
public interface ISpecialBlockItemRequirement {
|
||||
|
||||
default ItemRequirement getRequiredItems(BlockState state) {
|
||||
return ItemRequirement.INVALID;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.simibubi.create.modules.schematics;
|
||||
|
||||
public interface ISpecialEntityItemRequirement {
|
||||
|
||||
default ItemRequirement getRequiredItems() {
|
||||
return ItemRequirement.INVALID;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package com.simibubi.create.modules.schematics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.item.ArmorStandEntity;
|
||||
import net.minecraft.entity.item.BoatEntity;
|
||||
import net.minecraft.entity.item.ItemFrameEntity;
|
||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.state.properties.SlabType;
|
||||
|
||||
public class ItemRequirement {
|
||||
|
||||
public enum ItemUseType {
|
||||
CONSUME, DAMAGE
|
||||
}
|
||||
|
||||
ItemUseType usage;
|
||||
List<ItemStack> requiredItems;
|
||||
|
||||
public static ItemRequirement INVALID = new ItemRequirement();
|
||||
public static ItemRequirement NONE = new ItemRequirement();
|
||||
|
||||
private ItemRequirement() {
|
||||
}
|
||||
|
||||
public ItemRequirement(ItemUseType usage, Item item) {
|
||||
this(usage, Arrays.asList(new ItemStack(item)));
|
||||
}
|
||||
|
||||
public ItemRequirement(ItemUseType usage, List<ItemStack> requiredItems) {
|
||||
this.usage = usage;
|
||||
this.requiredItems = requiredItems;
|
||||
}
|
||||
|
||||
public static ItemRequirement of(BlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.AIR)
|
||||
return NONE;
|
||||
if (block instanceof ISpecialBlockItemRequirement)
|
||||
return ((ISpecialBlockItemRequirement) block).getRequiredItems(state);
|
||||
|
||||
Item item = BlockItem.BLOCK_TO_ITEM.getOrDefault(state.getBlock(), Items.AIR);
|
||||
|
||||
// double slab needs two items
|
||||
if (state.has(BlockStateProperties.SLAB_TYPE) && state.get(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE)
|
||||
return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(new ItemStack(item, 2)));
|
||||
|
||||
return item == Items.AIR ? INVALID : new ItemRequirement(ItemUseType.CONSUME, item);
|
||||
}
|
||||
|
||||
public static ItemRequirement of(Entity entity) {
|
||||
EntityType<?> type = entity.getType();
|
||||
|
||||
if (entity instanceof ISpecialEntityItemRequirement)
|
||||
return ((ISpecialEntityItemRequirement) entity).getRequiredItems();
|
||||
|
||||
if (type == EntityType.ITEM_FRAME) {
|
||||
ItemFrameEntity ife = (ItemFrameEntity) entity;
|
||||
ItemStack frame = new ItemStack(Items.ITEM_FRAME);
|
||||
ItemStack displayedItem = ife.getDisplayedItem();
|
||||
if (displayedItem.isEmpty())
|
||||
return new ItemRequirement(ItemUseType.CONSUME, Items.ITEM_FRAME);
|
||||
return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(frame, displayedItem));
|
||||
}
|
||||
|
||||
if (type == EntityType.PAINTING)
|
||||
return new ItemRequirement(ItemUseType.CONSUME, Items.PAINTING);
|
||||
|
||||
if (type == EntityType.ARMOR_STAND) {
|
||||
List<ItemStack> requirements = new ArrayList<>();
|
||||
ArmorStandEntity armorStandEntity = (ArmorStandEntity) entity;
|
||||
armorStandEntity.getEquipmentAndArmor().forEach(requirements::add);
|
||||
requirements.add(new ItemStack(Items.ARMOR_STAND));
|
||||
return new ItemRequirement(ItemUseType.CONSUME, requirements);
|
||||
}
|
||||
|
||||
if (entity instanceof AbstractMinecartEntity) {
|
||||
AbstractMinecartEntity minecartEntity = (AbstractMinecartEntity) entity;
|
||||
return new ItemRequirement(ItemUseType.CONSUME, minecartEntity.getCartItem().getItem());
|
||||
}
|
||||
|
||||
if (entity instanceof BoatEntity) {
|
||||
BoatEntity boatEntity = (BoatEntity) entity;
|
||||
return new ItemRequirement(ItemUseType.CONSUME, boatEntity.getItemBoat().getItem());
|
||||
}
|
||||
|
||||
if (type == EntityType.END_CRYSTAL)
|
||||
return new ItemRequirement(ItemUseType.CONSUME, Items.END_CRYSTAL);
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return NONE == this;
|
||||
}
|
||||
|
||||
public boolean isInvalid() {
|
||||
return INVALID == this;
|
||||
}
|
||||
|
||||
public List<ItemStack> getRequiredItems() {
|
||||
return requiredItems;
|
||||
}
|
||||
|
||||
public ItemUseType getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public static boolean validate(ItemStack required, ItemStack present) {
|
||||
return required.isEmpty() || required.getItem() == present.getItem();
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,9 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
|
@ -21,10 +24,12 @@ public class MaterialChecklist {
|
|||
|
||||
public Map<Item, Integer> gathered;
|
||||
public Map<Item, Integer> required;
|
||||
public Map<Item, Integer> damageRequired;
|
||||
public boolean blocksNotLoaded;
|
||||
|
||||
public MaterialChecklist() {
|
||||
required = new HashMap<>();
|
||||
damageRequired = new HashMap<>();
|
||||
gathered = new HashMap<>();
|
||||
}
|
||||
|
||||
|
@ -32,16 +37,33 @@ public class MaterialChecklist {
|
|||
blocksNotLoaded = true;
|
||||
}
|
||||
|
||||
public void require(Item item) {
|
||||
if (required.containsKey(item))
|
||||
required.put(item, required.get(item) + 1);
|
||||
public void require(ItemRequirement requirement) {
|
||||
if (requirement.isEmpty())
|
||||
return;
|
||||
if (requirement.isInvalid())
|
||||
return;
|
||||
|
||||
for (ItemStack stack : requirement.requiredItems) {
|
||||
if (requirement.getUsage() == ItemUseType.DAMAGE)
|
||||
putOrIncrement(damageRequired, stack);
|
||||
if (requirement.getUsage() == ItemUseType.CONSUME)
|
||||
putOrIncrement(required, stack);
|
||||
}
|
||||
}
|
||||
|
||||
private void putOrIncrement(Map<Item, Integer> map, ItemStack stack) {
|
||||
Item item = stack.getItem();
|
||||
if (item == Items.AIR)
|
||||
return;
|
||||
if (map.containsKey(item))
|
||||
map.put(item, map.get(item) + stack.getCount());
|
||||
else
|
||||
required.put(item, 1);
|
||||
map.put(item, stack.getCount());
|
||||
}
|
||||
|
||||
public void collect(ItemStack stack) {
|
||||
Item item = stack.getItem();
|
||||
if (required.containsKey(item))
|
||||
if (required.containsKey(item) || damageRequired.containsKey(item))
|
||||
if (gathered.containsKey(item))
|
||||
gathered.put(item, gathered.get(item) + stack.getCount());
|
||||
else
|
||||
|
@ -65,19 +87,19 @@ public class MaterialChecklist {
|
|||
string = new StringBuilder("{\"text\":\"");
|
||||
}
|
||||
|
||||
List<Item> keys = new ArrayList<>(required.keySet());
|
||||
List<Item> keys = new ArrayList<>(Sets.union(required.keySet(), damageRequired.keySet()));
|
||||
Collections.sort(keys, (item1, item2) -> {
|
||||
Locale locale = Locale.ENGLISH;
|
||||
String name1 = new TranslationTextComponent(((Item) item1).getTranslationKey()).getFormattedText()
|
||||
.toLowerCase(locale);
|
||||
String name2 = new TranslationTextComponent(((Item) item2).getTranslationKey()).getFormattedText()
|
||||
.toLowerCase(locale);
|
||||
String name1 =
|
||||
new TranslationTextComponent(((Item) item1).getTranslationKey()).getFormattedText().toLowerCase(locale);
|
||||
String name2 =
|
||||
new TranslationTextComponent(((Item) item2).getTranslationKey()).getFormattedText().toLowerCase(locale);
|
||||
return name1.compareTo(name2);
|
||||
});
|
||||
|
||||
List<Item> completed = new ArrayList<>();
|
||||
for (Item item : keys) {
|
||||
int amount = required.get(item);
|
||||
int amount = getRequiredAmount(item);
|
||||
if (gathered.containsKey(item))
|
||||
amount -= gathered.get(item);
|
||||
|
||||
|
@ -106,7 +128,7 @@ public class MaterialChecklist {
|
|||
}
|
||||
|
||||
itemsWritten++;
|
||||
string.append(gatheredEntry(new ItemStack(item), required.get(item)));
|
||||
string.append(gatheredEntry(new ItemStack(item), getRequiredAmount(item)));
|
||||
}
|
||||
|
||||
string.append("\"}");
|
||||
|
@ -120,6 +142,13 @@ public class MaterialChecklist {
|
|||
return book;
|
||||
}
|
||||
|
||||
public Integer getRequiredAmount(Item item) {
|
||||
int amount = required.getOrDefault(item, 0);
|
||||
if (damageRequired.containsKey(item))
|
||||
amount += Math.ceil(damageRequired.get(item) / (float) new ItemStack(item).getMaxDamage());
|
||||
return amount;
|
||||
}
|
||||
|
||||
private String gatheredEntry(ItemStack item, int amount) {
|
||||
int stacks = amount / 64;
|
||||
int remainder = amount % 64;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.modules.schematics;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -14,6 +15,8 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ArmorStandEntity;
|
||||
import net.minecraft.entity.item.ItemFrameEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
|
@ -31,6 +34,7 @@ public class SchematicWorld extends WrappedWorld {
|
|||
|
||||
private Map<BlockPos, BlockState> blocks;
|
||||
private Map<BlockPos, TileEntity> tileEntities;
|
||||
private List<Entity> entities;
|
||||
private Cuboid bounds;
|
||||
public BlockPos anchor;
|
||||
public boolean renderMode;
|
||||
|
@ -41,11 +45,28 @@ public class SchematicWorld extends WrappedWorld {
|
|||
this.tileEntities = new HashMap<>();
|
||||
this.bounds = new Cuboid();
|
||||
this.anchor = anchor;
|
||||
this.entities = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Set<BlockPos> getAllPositions() {
|
||||
return blocks.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addEntity(Entity entityIn) {
|
||||
if (entityIn instanceof ItemFrameEntity)
|
||||
((ItemFrameEntity) entityIn).getDisplayedItem().setTag(null);
|
||||
if (entityIn instanceof ArmorStandEntity) {
|
||||
ArmorStandEntity armorStandEntity = (ArmorStandEntity) entityIn;
|
||||
armorStandEntity.getEquipmentAndArmor().forEach(stack -> stack.setTag(null));
|
||||
}
|
||||
|
||||
return entities.add(entityIn);
|
||||
}
|
||||
|
||||
public List<Entity> getEntities() {
|
||||
return entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity getTileEntity(BlockPos pos) {
|
||||
|
|
|
@ -25,7 +25,6 @@ import com.simibubi.create.modules.schematics.item.SchematicItem;
|
|||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
|
@ -234,7 +233,6 @@ public class ServerSchematicLoader {
|
|||
if (table == null)
|
||||
return;
|
||||
table.finishUpload();
|
||||
table.inventory.setStackInSlot(0, ItemStack.EMPTY);
|
||||
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getName().getFormattedText()));
|
||||
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package com.simibubi.create.modules.schematics.block;
|
||||
|
||||
import com.simibubi.create.foundation.utility.AllShapes;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
|
||||
public class CreativeCrateBlock extends Block {
|
||||
|
||||
public CreativeCrateBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
return AllShapes.CRATE_BLOCK_SHAPE;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package com.simibubi.create.modules.schematics.block;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class LaunchedBlock {
|
||||
|
||||
private final SchematicannonTileEntity te;
|
||||
public int totalTicks;
|
||||
public int ticksRemaining;
|
||||
public BlockPos target;
|
||||
public BlockState state;
|
||||
|
||||
public LaunchedBlock(SchematicannonTileEntity schematicannonTileEntity, BlockPos target, BlockState state) {
|
||||
te = schematicannonTileEntity;
|
||||
this.target = target;
|
||||
this.state = state;
|
||||
totalTicks = (int) (Math.max(10, MathHelper.sqrt(MathHelper.sqrt(target.distanceSq(te.getPos()))) * 4f));
|
||||
ticksRemaining = totalTicks;
|
||||
}
|
||||
|
||||
public LaunchedBlock(SchematicannonTileEntity schematicannonTileEntity, BlockPos target, BlockState state,
|
||||
int ticksLeft, int total) {
|
||||
te = schematicannonTileEntity;
|
||||
this.target = target;
|
||||
this.state = state;
|
||||
this.totalTicks = total;
|
||||
this.ticksRemaining = ticksLeft;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (ticksRemaining > 0)
|
||||
ticksRemaining--;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
package com.simibubi.create.modules.schematics.block;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem;
|
||||
import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class LaunchedItem {
|
||||
|
||||
public int totalTicks;
|
||||
public int ticksRemaining;
|
||||
public BlockPos target;
|
||||
public ItemStack stack;
|
||||
|
||||
private LaunchedItem(BlockPos start, BlockPos target, ItemStack stack) {
|
||||
this(target, stack, ticksForDistance(start, target), ticksForDistance(start, target));
|
||||
}
|
||||
|
||||
private static int ticksForDistance(BlockPos start, BlockPos target) {
|
||||
return (int) (Math.max(10, MathHelper.sqrt(MathHelper.sqrt(target.distanceSq(start))) * 4f));
|
||||
}
|
||||
|
||||
LaunchedItem() {}
|
||||
|
||||
private LaunchedItem(BlockPos target, ItemStack stack, int ticksLeft, int total) {
|
||||
this.target = target;
|
||||
this.stack = stack;
|
||||
this.totalTicks = total;
|
||||
this.ticksRemaining = ticksLeft;
|
||||
}
|
||||
|
||||
public boolean update(World world) {
|
||||
if (ticksRemaining > 0) {
|
||||
ticksRemaining--;
|
||||
return false;
|
||||
}
|
||||
if (world.isRemote)
|
||||
return false;
|
||||
|
||||
place(world);
|
||||
return true;
|
||||
}
|
||||
|
||||
public CompoundNBT serializeNBT() {
|
||||
CompoundNBT c = new CompoundNBT();
|
||||
c.putInt("TotalTicks", totalTicks);
|
||||
c.putInt("TicksLeft", ticksRemaining);
|
||||
c.put("Stack", stack.serializeNBT());
|
||||
c.put("Target", NBTUtil.writeBlockPos(target));
|
||||
return c;
|
||||
}
|
||||
|
||||
public static LaunchedItem fromNBT(CompoundNBT c) {
|
||||
LaunchedItem launched = c.contains("Length") ? new LaunchedItem.ForBelt()
|
||||
: c.contains("BlockState") ? new LaunchedItem.ForBlockState() : new LaunchedItem.ForEntity();
|
||||
launched.readNBT(c);
|
||||
return launched;
|
||||
}
|
||||
|
||||
abstract void place(World world);
|
||||
|
||||
void readNBT(CompoundNBT c) {
|
||||
target = NBTUtil.readBlockPos(c.getCompound("Target"));
|
||||
ticksRemaining = c.getInt("TicksLeft");
|
||||
totalTicks = c.getInt("TotalTicks");
|
||||
stack = ItemStack.read(c.getCompound("Stack"));
|
||||
}
|
||||
|
||||
public static class ForBlockState extends LaunchedItem {
|
||||
public BlockState state;
|
||||
|
||||
ForBlockState() {}
|
||||
|
||||
public ForBlockState(BlockPos start, BlockPos target, ItemStack stack, BlockState state) {
|
||||
super(start, target, stack);
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serializeNBT() {
|
||||
CompoundNBT serializeNBT = super.serializeNBT();
|
||||
serializeNBT.put("BlockState", NBTUtil.writeBlockState(state));
|
||||
return serializeNBT;
|
||||
}
|
||||
|
||||
@Override
|
||||
void readNBT(CompoundNBT nbt) {
|
||||
super.readNBT(nbt);
|
||||
state = NBTUtil.readBlockState(nbt.getCompound("BlockState"));
|
||||
}
|
||||
|
||||
@Override
|
||||
void place(World world) {
|
||||
// Piston
|
||||
if (state.has(BlockStateProperties.EXTENDED))
|
||||
state = state.with(BlockStateProperties.EXTENDED, false);
|
||||
|
||||
if (AllBlocks.BELT.typeOf(state)) {
|
||||
world.setBlockState(target, state, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
world.setBlockState(target, state, 18);
|
||||
state.getBlock().onBlockPlacedBy(world, target, state, null, stack);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ForBelt extends ForBlockState {
|
||||
public int length;
|
||||
|
||||
public ForBelt() {}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serializeNBT() {
|
||||
CompoundNBT serializeNBT = super.serializeNBT();
|
||||
serializeNBT.putInt("Length", length);
|
||||
return serializeNBT;
|
||||
}
|
||||
|
||||
@Override
|
||||
void readNBT(CompoundNBT nbt) {
|
||||
length = nbt.getInt("Length");
|
||||
super.readNBT(nbt);
|
||||
}
|
||||
|
||||
public ForBelt(BlockPos start, BlockPos target, ItemStack stack, BlockState state, int length) {
|
||||
super(start, target, stack, state);
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@Override
|
||||
void place(World world) {
|
||||
// todo place belt
|
||||
boolean isStart = state.get(BeltBlock.PART) == Part.START;
|
||||
BlockPos offset = BeltBlock.nextSegmentPosition(state, BlockPos.ZERO, isStart);
|
||||
int i = length - 1;
|
||||
Axis axis = state.get(BeltBlock.HORIZONTAL_FACING).rotateY().getAxis();
|
||||
world.setBlockState(target, AllBlocks.SHAFT.getDefault().with(ShaftBlock.AXIS, axis));
|
||||
BeltConnectorItem
|
||||
.createBelts(world, target, target.add(offset.getX() * i, offset.getY() * i, offset.getZ() * i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ForEntity extends LaunchedItem {
|
||||
public Entity entity;
|
||||
private CompoundNBT deferredTag;
|
||||
|
||||
ForEntity() {}
|
||||
|
||||
public ForEntity(BlockPos start, BlockPos target, ItemStack stack, Entity entity) {
|
||||
super(start, target, stack);
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(World world) {
|
||||
if (deferredTag != null && entity == null) {
|
||||
try {
|
||||
Optional<Entity> loadEntityUnchecked = EntityType.loadEntityUnchecked(deferredTag, world);
|
||||
if (!loadEntityUnchecked.isPresent())
|
||||
return true;
|
||||
entity = loadEntityUnchecked.get();
|
||||
} catch (Exception var3) {
|
||||
return true;
|
||||
}
|
||||
deferredTag = null;
|
||||
}
|
||||
return super.update(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serializeNBT() {
|
||||
CompoundNBT serializeNBT = super.serializeNBT();
|
||||
if (entity != null)
|
||||
serializeNBT.put("Entity", entity.serializeNBT());
|
||||
return serializeNBT;
|
||||
}
|
||||
|
||||
@Override
|
||||
void readNBT(CompoundNBT nbt) {
|
||||
super.readNBT(nbt);
|
||||
if (nbt.contains("Entity"))
|
||||
deferredTag = nbt.getCompound("Entity");
|
||||
}
|
||||
|
||||
@Override
|
||||
void place(World world) {
|
||||
world.addEntity(entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
|
@ -102,6 +103,7 @@ public class SchematicTableTileEntity extends SyncedTileEntity implements ITicka
|
|||
uploadingProgress = 0;
|
||||
uploadingSchematic = schematic;
|
||||
sendUpdate = true;
|
||||
inventory.setStackInSlot(0, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
public void finishUpload() {
|
||||
|
|
|
@ -17,7 +17,6 @@ import net.minecraft.util.math.BlockRayTraceResult;
|
|||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
|
@ -47,17 +46,11 @@ public class SchematicannonBlock extends Block implements ITE<SchematicannonTile
|
|||
return AllShapes.SCHEMATICANNON_SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
||||
withTileEntityDo(world, pos, SchematicannonTileEntity::findInventories);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
if (worldIn.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
withTileEntityDo(worldIn, pos,
|
||||
te -> NetworkHooks.openGui((ServerPlayerEntity) player, te, te::sendToContainer));
|
||||
return ActionResultType.SUCCESS;
|
||||
|
|
|
@ -3,10 +3,13 @@ package com.simibubi.create.modules.schematics.block;
|
|||
import java.util.Random;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||
import com.simibubi.create.modules.schematics.block.LaunchedItem.ForBlockState;
|
||||
import com.simibubi.create.modules.schematics.block.LaunchedItem.ForEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -14,6 +17,7 @@ import net.minecraft.client.renderer.IRenderTypeBuffer;
|
|||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
|
@ -23,6 +27,7 @@ import net.minecraft.util.math.MathHelper;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SchematicannonRenderer extends SafeTileEntityRenderer<SchematicannonTileEntity> {
|
||||
|
||||
public SchematicannonRenderer(TileEntityRendererDispatcher dispatcher) {
|
||||
|
@ -30,8 +35,8 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void renderSafe(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
protected void renderSafe(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
|
||||
IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
|
||||
|
@ -63,14 +68,14 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
}
|
||||
|
||||
if (!tileEntityIn.flyingBlocks.isEmpty()) {
|
||||
for (LaunchedBlock block : tileEntityIn.flyingBlocks) {
|
||||
for (LaunchedItem launched : tileEntityIn.flyingBlocks) {
|
||||
|
||||
if (block.ticksRemaining == 0)
|
||||
if (launched.ticksRemaining == 0)
|
||||
continue;
|
||||
|
||||
// Calculate position of flying block
|
||||
Vec3d start = new Vec3d(tileEntityIn.getPos().add(.5f, 1, .5f));
|
||||
Vec3d target = new Vec3d(block.target).add(-.5, 0, 1);
|
||||
Vec3d target = new Vec3d(launched.target).add(-.5, 0, 1);
|
||||
Vec3d distance = target.subtract(start);
|
||||
|
||||
double targetY = target.y - start.y;
|
||||
|
@ -78,10 +83,9 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
Vec3d cannonOffset = distance.add(0, throwHeight, 0).normalize().scale(2);
|
||||
start = start.add(cannonOffset);
|
||||
|
||||
float progress = ((float) block.totalTicks - (block.ticksRemaining + 1 - partialTicks))
|
||||
/ block.totalTicks;
|
||||
Vec3d blockLocationXZ = new Vec3d(.5, .5, .5)
|
||||
.add(target.subtract(start).scale(progress).mul(1, 0, 1));
|
||||
float progress =
|
||||
((float) launched.totalTicks - (launched.ticksRemaining + 1 - partialTicks)) / launched.totalTicks;
|
||||
Vec3d blockLocationXZ = new Vec3d(.5, .5, .5).add(target.subtract(start).scale(progress).mul(1, 0, 1));
|
||||
|
||||
// Height is determined through a bezier curve
|
||||
float t = progress;
|
||||
|
@ -93,21 +97,33 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
ms.translate(blockLocation.x, blockLocation.y, blockLocation.z);
|
||||
|
||||
// Rotation and Scaling effects
|
||||
float scale = .3f;
|
||||
ms.multiply(new Vector3f(1, 1, 0).getDegreesQuaternion(360 * t * 2));
|
||||
ms.scale(scale, scale, scale);
|
||||
|
||||
// Render the Block
|
||||
Minecraft.getInstance().getBlockRendererDispatcher().renderBlock(block.state, ms, buffer, light, overlay, EmptyModelData.INSTANCE);
|
||||
if (launched instanceof ForBlockState) {
|
||||
float scale = .3f;
|
||||
ms.scale(scale, scale, scale);
|
||||
Minecraft.getInstance().getBlockRendererDispatcher().renderBlock(((ForBlockState) launched).state,
|
||||
ms, buffer, light, overlay, EmptyModelData.INSTANCE);
|
||||
}
|
||||
|
||||
// Render the item
|
||||
if (launched instanceof ForEntity) {
|
||||
double scale = 1.2f;
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
Minecraft.getInstance().getItemRenderer().renderItem(launched.stack, TransformType.GROUND, light,
|
||||
overlay, ms, buffer);
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
|
||||
// Apply Recoil if block was just launched
|
||||
if ((block.ticksRemaining + 1 - partialTicks) > block.totalTicks - 10) {
|
||||
recoil = Math.max(recoil, (block.ticksRemaining + 1 - partialTicks) - block.totalTicks + 10);
|
||||
if ((launched.ticksRemaining + 1 - partialTicks) > launched.totalTicks - 10) {
|
||||
recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10);
|
||||
}
|
||||
|
||||
// Render particles for launch
|
||||
if (block.ticksRemaining == block.totalTicks && tileEntityIn.firstRenderTick) {
|
||||
if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) {
|
||||
tileEntityIn.firstRenderTick = false;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Random r = tileEntityIn.getWorld().getRandom();
|
||||
|
@ -128,7 +144,7 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
ms.push();
|
||||
BlockState state = tileEntityIn.getBlockState();
|
||||
int lightCoords = WorldRenderer.getLightmapCoordinates(tileEntityIn.getWorld(), pos);
|
||||
|
||||
|
||||
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
|
||||
|
||||
SuperByteBuffer connector = AllBlockPartials.SCHEMATICANNON_CONNECTOR.renderOn(state);
|
||||
|
|
|
@ -26,7 +26,6 @@ import net.minecraft.client.gui.widget.Widget;
|
|||
import net.minecraft.client.renderer.Rectangle2d;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
@ -83,19 +82,20 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
resetButton = new IconButton(x + 106, y + 55, ScreenResources.I_STOP);
|
||||
resetIndicator = new Indicator(x + 106, y + 50, "");
|
||||
resetIndicator.state = State.RED;
|
||||
Collections.addAll(widgets, playButton, playIndicator, pauseButton, pauseIndicator, resetButton,
|
||||
resetIndicator);
|
||||
Collections
|
||||
.addAll(widgets, playButton, playIndicator, pauseButton, pauseIndicator, resetButton, resetIndicator);
|
||||
|
||||
// Replace settings
|
||||
replaceLevelButtons = new Vector<>(4);
|
||||
replaceLevelIndicators = new Vector<>(4);
|
||||
List<ScreenResources> icons = ImmutableList.of(ScreenResources.I_DONT_REPLACE,
|
||||
ScreenResources.I_REPLACE_SOLID, ScreenResources.I_REPLACE_ANY,
|
||||
ScreenResources.I_REPLACE_EMPTY);
|
||||
List<String> toolTips = ImmutableList.of(Lang.translate("gui.schematicannon.option.dontReplaceSolid"),
|
||||
Lang.translate("gui.schematicannon.option.replaceWithSolid"),
|
||||
Lang.translate("gui.schematicannon.option.replaceWithAny"),
|
||||
Lang.translate("gui.schematicannon.option.replaceWithEmpty"));
|
||||
List<ScreenResources> icons = ImmutableList
|
||||
.of(ScreenResources.I_DONT_REPLACE, ScreenResources.I_REPLACE_SOLID, ScreenResources.I_REPLACE_ANY,
|
||||
ScreenResources.I_REPLACE_EMPTY);
|
||||
List<String> toolTips = ImmutableList
|
||||
.of(Lang.translate("gui.schematicannon.option.dontReplaceSolid"),
|
||||
Lang.translate("gui.schematicannon.option.replaceWithSolid"),
|
||||
Lang.translate("gui.schematicannon.option.replaceWithAny"),
|
||||
Lang.translate("gui.schematicannon.option.replaceWithEmpty"));
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
replaceLevelIndicators.add(new Indicator(x + 16 + i * 18, y + 96, ""));
|
||||
|
@ -191,8 +191,10 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
boolean enabled = indicator.state == State.ON;
|
||||
List<String> tip = button.getToolTip();
|
||||
tip.add(TextFormatting.BLUE + (enabled ? optionEnabled : optionDisabled));
|
||||
tip.addAll(TooltipHelper.cutString(Lang.translate("gui.schematicannon.option." + tooltipKey + ".description"),
|
||||
GRAY, GRAY));
|
||||
tip
|
||||
.addAll(TooltipHelper
|
||||
.cutString(Lang.translate("gui.schematicannon.option." + tooltipKey + ".description"), GRAY,
|
||||
GRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -215,21 +217,22 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
String msg = Lang.translate("schematicannon.status." + te.statusMsg);
|
||||
int stringWidth = font.getStringWidth(msg);
|
||||
|
||||
if (te.missingBlock != null) {
|
||||
if (te.missingItem != null) {
|
||||
stringWidth += 15;
|
||||
itemRenderer.renderItemIntoGUI(new ItemStack(BlockItem.BLOCK_TO_ITEM.get(te.missingBlock.getBlock())),
|
||||
guiLeft + 145, guiTop + 25);
|
||||
itemRenderer.renderItemIntoGUI(te.missingItem, guiLeft + 145, guiTop + 25);
|
||||
}
|
||||
|
||||
font.drawStringWithShadow(msg, guiLeft + 20 + 96 - stringWidth / 2, guiTop + 30, 0xCCDDFF);
|
||||
|
||||
font.drawString(settingsTitle, guiLeft + 20 + 13, guiTop + 84, ScreenResources.FONT_COLOR);
|
||||
font.drawString(playerInventory.getDisplayName().getFormattedText(), guiLeft - 10 + 7, guiTop + 145 + 6,
|
||||
0x666666);
|
||||
font
|
||||
.drawString(playerInventory.getDisplayName().getFormattedText(), guiLeft - 10 + 7, guiTop + 145 + 6,
|
||||
0x666666);
|
||||
|
||||
//to see or debug the bounds of the extra area uncomment the following lines
|
||||
//Rectangle2d r = extraAreas.get(0);
|
||||
//fill(r.getX() + r.getWidth(), r.getY() + r.getHeight(), r.getX(), r.getY(), 0xd3d3d3d3);
|
||||
// to see or debug the bounds of the extra area uncomment the following lines
|
||||
// Rectangle2d r = extraAreas.get(0);
|
||||
// fill(r.getX() + r.getWidth(), r.getY() + r.getHeight(), r.getX(), r.getY(),
|
||||
// 0xd3d3d3d3);
|
||||
}
|
||||
|
||||
protected void renderCannon() {
|
||||
|
@ -270,6 +273,10 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
|
||||
protected void renderFuelBar(float amount) {
|
||||
ScreenResources sprite = ScreenResources.SCHEMATICANNON_FUEL;
|
||||
if (container.getTileEntity().hasCreativeCrate) {
|
||||
ScreenResources.SCHEMATICANNON_FUEL_CREATIVE.draw(this, guiLeft + 20 + 73, guiTop + 135);
|
||||
return;
|
||||
}
|
||||
minecraft.getTextureManager().bindTexture(sprite.location);
|
||||
blit(guiLeft + 20 + 73, guiTop + 135, sprite.startX, sprite.startY, (int) (sprite.width * amount),
|
||||
sprite.height);
|
||||
|
@ -282,21 +289,30 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
if (mouseX >= fuelX && mouseY >= fuelY && mouseX <= fuelX + ScreenResources.SCHEMATICANNON_FUEL.width
|
||||
&& mouseY <= fuelY + ScreenResources.SCHEMATICANNON_FUEL.height) {
|
||||
container.getTileEntity();
|
||||
|
||||
double fuelUsageRate = te.getFuelUsageRate();
|
||||
int shotsLeft = (int) (te.fuelLevel / fuelUsageRate);
|
||||
int shotsLeftWithItems = (int) (shotsLeft
|
||||
+ te.inventory.getStackInSlot(4).getCount() * (te.getFuelAddedByGunPowder() / fuelUsageRate));
|
||||
renderTooltip(ImmutableList.of(Lang.translate(_gunpowderLevel, "" + (int) (te.fuelLevel * 100)),
|
||||
GRAY + Lang.translate(_shotsRemaining, "" + TextFormatting.BLUE + shotsLeft),
|
||||
GRAY + Lang.translate(_shotsRemainingWithBackup, "" + TextFormatting.BLUE + shotsLeftWithItems)),
|
||||
mouseX, mouseY);
|
||||
|
||||
List<String> tooltip = new ArrayList<>();
|
||||
float f = te.hasCreativeCrate ? 100 : te.fuelLevel * 100;
|
||||
tooltip.add(Lang.translate(_gunpowderLevel, "" + (int) f));
|
||||
if (!te.hasCreativeCrate)
|
||||
tooltip.add(GRAY + Lang.translate(_shotsRemaining, "" + TextFormatting.BLUE + shotsLeft));
|
||||
if (shotsLeftWithItems != shotsLeft)
|
||||
tooltip
|
||||
.add(GRAY + Lang
|
||||
.translate(_shotsRemainingWithBackup, "" + TextFormatting.BLUE + shotsLeftWithItems));
|
||||
|
||||
renderTooltip(tooltip, mouseX, mouseY);
|
||||
}
|
||||
|
||||
if (te.missingBlock != null) {
|
||||
if (te.missingItem != null) {
|
||||
int missingBlockX = guiLeft + 145, missingBlockY = guiTop + 25;
|
||||
if (mouseX >= missingBlockX && mouseY >= missingBlockY && mouseX <= missingBlockX + 16
|
||||
&& mouseY <= missingBlockY + 16) {
|
||||
renderTooltip(new ItemStack(BlockItem.BLOCK_TO_ITEM.get(te.missingBlock.getBlock())), mouseX, mouseY);
|
||||
renderTooltip(te.missingItem, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue