Advanced Logistics Headstart
- Added Logistical Controllers - Added Logistical Casings - Added the Logistical Index - Added a Logistical Dial - Started laying out logic for Logistical Networks
This commit is contained in:
parent
0a1b85fe39
commit
0f9cb916cd
118 changed files with 5035 additions and 91 deletions
|
@ -20,7 +20,7 @@ archivesBaseName = 'create'
|
|||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||
|
||||
minecraft {
|
||||
mappings channel: 'snapshot', version: '20190917-1.14.3'
|
||||
mappings channel: 'snapshot', version: '20190927-1.14.3'
|
||||
|
||||
runs {
|
||||
client {
|
||||
|
@ -71,12 +71,12 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.1.6'
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.1.22'
|
||||
|
||||
// compile against the JEI API but do not include it at runtime
|
||||
compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10:api")
|
||||
// at runtime, use the full JEI jar
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10")
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.13")
|
||||
}
|
||||
|
||||
jar {
|
||||
|
|
|
@ -37,15 +37,19 @@ import com.simibubi.create.modules.curiosities.symmetry.block.CrossPlaneSymmetry
|
|||
import com.simibubi.create.modules.curiosities.symmetry.block.PlaneSymmetryBlock;
|
||||
import com.simibubi.create.modules.curiosities.symmetry.block.TriplePlaneSymmetryBlock;
|
||||
import com.simibubi.create.modules.gardens.CocoaLogBlock;
|
||||
import com.simibubi.create.modules.logistics.block.BeltFunnelBlock;
|
||||
import com.simibubi.create.modules.logistics.block.EntityDetectorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.ExtractorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.FlexcrateBlock;
|
||||
import com.simibubi.create.modules.logistics.block.LinkedExtractorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.RedstoneBridgeBlock;
|
||||
import com.simibubi.create.modules.logistics.block.StockswitchBlock;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltFunnelBlock;
|
||||
import com.simibubi.create.modules.logistics.block.belts.EntityDetectorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.belts.ExtractorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.belts.LinkedExtractorBlock;
|
||||
import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterBlock;
|
||||
import com.simibubi.create.modules.logistics.block.diodes.PulseRepeaterBlock;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalCasingBlock;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.LogisticalControllerIndicatorBlock;
|
||||
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexBlock;
|
||||
import com.simibubi.create.modules.palettes.GlassPaneBlock;
|
||||
import com.simibubi.create.modules.schematics.block.CreativeCrateBlock;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
|
||||
|
@ -125,6 +129,10 @@ public enum AllBlocks {
|
|||
PULSE_REPEATER(new PulseRepeaterBlock()),
|
||||
FLEXPEATER(new FlexpeaterBlock()),
|
||||
FLEXPEATER_INDICATOR(new RenderUtilityBlock()),
|
||||
LOGISTICAL_CASING(new LogisticalCasingBlock()),
|
||||
LOGISTICAL_CONTROLLER(new LogisticalControllerBlock()),
|
||||
LOGISTICAL_CONTROLLER_INDICATOR(new LogisticalControllerIndicatorBlock()),
|
||||
LOGISTICAL_INDEX(new LogisticalIndexBlock()),
|
||||
|
||||
__CURIOSITIES__(),
|
||||
SYMMETRY_PLANE(new PlaneSymmetryBlock()),
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.modules.logistics.block.FlexcrateContainer;
|
||||
import com.simibubi.create.modules.logistics.block.FlexcrateScreen;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateContainer;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateScreen;
|
||||
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexContainer;
|
||||
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexScreen;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableContainer;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableScreen;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonContainer;
|
||||
|
@ -29,6 +31,7 @@ public enum AllContainers {
|
|||
SCHEMATIC_TABLE(SchematicTableContainer::new),
|
||||
SCHEMATICANNON(SchematicannonContainer::new),
|
||||
FLEXCRATE(FlexcrateContainer::new),
|
||||
LOGISTICAL_INDEX(LogisticalIndexContainer::new),
|
||||
|
||||
;
|
||||
|
||||
|
@ -54,6 +57,7 @@ public enum AllContainers {
|
|||
bind(SCHEMATIC_TABLE, SchematicTableScreen::new);
|
||||
bind(SCHEMATICANNON, SchematicannonScreen::new);
|
||||
bind(FLEXCRATE, FlexcrateScreen::new);
|
||||
bind(LOGISTICAL_INDEX, LogisticalIndexScreen::new);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
|
61
src/main/java/com/simibubi/create/AllEntities.java
Normal file
61
src/main/java/com/simibubi/create/AllEntities.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.simibubi.create.modules.logistics.entity.CardboardBoxEntity;
|
||||
import com.simibubi.create.modules.logistics.entity.CardboardBoxEntityRenderer;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.EntityType.Builder;
|
||||
import net.minecraft.entity.EntityType.IFactory;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||
|
||||
public enum AllEntities {
|
||||
|
||||
CARDBOARD_BOX(CardboardBoxEntity::new, 30, 3, CardboardBoxEntity::build),
|
||||
|
||||
;
|
||||
|
||||
private IFactory<?> factory;
|
||||
private int range;
|
||||
private int updateFrequency;
|
||||
private Function<EntityType.Builder<? extends Entity>, EntityType.Builder<? extends Entity>> propertyBuilder;
|
||||
private EntityClassification group;
|
||||
|
||||
public EntityType<? extends Entity> type;
|
||||
|
||||
private AllEntities(IFactory<?> factory, int range, int updateFrequency,
|
||||
Function<EntityType.Builder<? extends Entity>, EntityType.Builder<? extends Entity>> propertyBuilder) {
|
||||
this.factory = factory;
|
||||
this.range = range;
|
||||
this.updateFrequency = updateFrequency;
|
||||
this.propertyBuilder = propertyBuilder;
|
||||
}
|
||||
|
||||
public static void register(final RegistryEvent.Register<EntityType<?>> event) {
|
||||
for (AllEntities entity : values()) {
|
||||
String id = entity.name().toLowerCase();
|
||||
ResourceLocation resourceLocation = new ResourceLocation(Create.ID, id);
|
||||
Builder<? extends Entity> builder = EntityType.Builder.create(entity.factory, entity.group)
|
||||
.setTrackingRange(entity.range).setUpdateInterval(entity.updateFrequency)
|
||||
.setShouldReceiveVelocityUpdates(true);
|
||||
if (entity.propertyBuilder != null)
|
||||
builder = entity.propertyBuilder.apply(builder);
|
||||
entity.type = builder.build(id).setRegistryName(resourceLocation);
|
||||
event.getRegistry().register(entity.type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
public static void registerRenderers() {
|
||||
RenderingRegistry.registerEntityRenderingHandler(CardboardBoxEntity.class, CardboardBoxEntityRenderer::new);
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,10 @@ import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunItemRe
|
|||
import com.simibubi.create.modules.curiosities.symmetry.SymmetryWandItem;
|
||||
import com.simibubi.create.modules.curiosities.symmetry.client.SymmetryWandItemRenderer;
|
||||
import com.simibubi.create.modules.gardens.TreeFertilizerItem;
|
||||
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
||||
import com.simibubi.create.modules.logistics.management.LogisticalDialItem;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.Type;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerItem;
|
||||
import com.simibubi.create.modules.schematics.item.SchematicAndQuillItem;
|
||||
import com.simibubi.create.modules.schematics.item.SchematicItem;
|
||||
|
||||
|
@ -76,6 +80,19 @@ public enum AllItems {
|
|||
DOUGH(ingredient()),
|
||||
PROPELLER(ingredient()),
|
||||
|
||||
__LOGISTICS__(),
|
||||
CARDBOARD_BOX_1616(new CardboardBoxItem(standardItemProperties())),
|
||||
CARDBOARD_BOX_1612(new CardboardBoxItem(standardItemProperties())),
|
||||
CARDBOARD_BOX_1416(new CardboardBoxItem(standardItemProperties())),
|
||||
CARDBOARD_BOX_1410(new CardboardBoxItem(standardItemProperties())),
|
||||
|
||||
LOGISTICAL_DIAL(new LogisticalDialItem(standardItemProperties())),
|
||||
LOGISTICAL_CONTROLLER_SUPPLY(new LogisticalControllerItem(standardItemProperties(), Type.SUPPLY)),
|
||||
LOGISTICAL_CONTROLLER_REQUEST(new LogisticalControllerItem(standardItemProperties(), Type.REQUEST)),
|
||||
LOGISTICAL_CONTROLLER_STORAGE(new LogisticalControllerItem(standardItemProperties(), Type.STORAGE)),
|
||||
LOGISTICAL_CONTROLLER_CALCULATION(new LogisticalControllerItem(standardItemProperties(), Type.CALCULATION)),
|
||||
LOGISTICAL_CONTROLLER_TRANSACTIONS(new LogisticalControllerItem(standardItemProperties(), Type.TRANSACTIONS)),
|
||||
|
||||
;
|
||||
|
||||
private static class CategoryTracker {
|
||||
|
@ -129,6 +146,10 @@ public enum AllItems {
|
|||
public boolean typeOf(ItemStack stack) {
|
||||
return stack.getItem() == item;
|
||||
}
|
||||
|
||||
public ItemStack asStack() {
|
||||
return new ItemStack(item);
|
||||
}
|
||||
|
||||
// Client
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
|
|||
|
||||
public enum AllKeys {
|
||||
|
||||
TOOL_MENU("toolmenu", GLFW.GLFW_KEY_LEFT_ALT),
|
||||
TOOL_MENU("toolmenu", GLFW.GLFW_KEY_LEFT_ALT),
|
||||
ACTIVATE_TOOL("", GLFW.GLFW_KEY_LEFT_CONTROL),
|
||||
|
||||
;
|
||||
|
@ -30,7 +30,7 @@ public enum AllKeys {
|
|||
key.keybind = new KeyBinding(key.description, key.key, Create.NAME);
|
||||
if (!key.modifiable)
|
||||
continue;
|
||||
|
||||
|
||||
ClientRegistry.registerKeyBinding(key.keybind);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import com.simibubi.create.modules.contraptions.receivers.constructs.ConfigureCh
|
|||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunBeamPacket;
|
||||
import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket;
|
||||
import com.simibubi.create.modules.logistics.block.diodes.ConfigureFlexpeaterPacket;
|
||||
import com.simibubi.create.modules.logistics.management.index.IndexContainerUpdatePacket;
|
||||
import com.simibubi.create.modules.logistics.management.index.IndexOrderRequest;
|
||||
import com.simibubi.create.modules.logistics.packet.ConfigureFlexcratePacket;
|
||||
import com.simibubi.create.modules.logistics.packet.ConfigureStockswitchPacket;
|
||||
import com.simibubi.create.modules.schematics.packet.ConfigureSchematicannonPacket;
|
||||
|
@ -35,10 +37,12 @@ public enum AllPackets {
|
|||
CONFIGURE_FLEXPEATER(ConfigureFlexpeaterPacket.class, ConfigureFlexpeaterPacket::new),
|
||||
PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new),
|
||||
UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new),
|
||||
|
||||
INDEX_ORDER_REQUEST(IndexOrderRequest.class, IndexOrderRequest::new),
|
||||
|
||||
// Server to Client
|
||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new),
|
||||
BEAM_EFFECT(BuilderGunBeamPacket.class, BuilderGunBeamPacket::new),
|
||||
INDEX_CONTAINER_UPDATE(IndexContainerUpdatePacket.class, IndexContainerUpdatePacket::new),
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -30,19 +30,28 @@ import com.simibubi.create.modules.contraptions.relays.SplitShaftTileEntityRende
|
|||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntityRenderer;
|
||||
import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.BeltFunnelTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.EntityDetectorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.EntityDetectorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.ExtractorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.ExtractorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.LinkedExtractorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.LinkedExtractorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.LinkedTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.StockswitchTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltFunnelTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.EntityDetectorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.EntityDetectorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.belts.ExtractorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.ExtractorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.belts.LinkedExtractorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.LinkedExtractorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalCasingTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.management.controller.CalculationTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.RequestTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.StorageTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.SupplyTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.TransactionsTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexTileEntity;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonTileEntity;
|
||||
|
@ -95,6 +104,13 @@ public enum AllTileEntities {
|
|||
BELT_FUNNEL(BeltFunnelTileEntity::new, AllBlocks.BELT_FUNNEL),
|
||||
ENTITY_DETECTOR(EntityDetectorTileEntity::new, AllBlocks.ENTITY_DETECTOR),
|
||||
FLEXPEATER(FlexpeaterTileEntity::new, AllBlocks.FLEXPEATER),
|
||||
LOGISTICAL_CASING(LogisticalCasingTileEntity::new, AllBlocks.LOGISTICAL_CASING),
|
||||
LOGISTICAL_SUPPLY_CONTROLLER(SupplyTileEntity::new, AllBlocks.LOGISTICAL_CONTROLLER),
|
||||
LOGISTICAL_REQUEST_CONTROLLER(RequestTileEntity::new, AllBlocks.LOGISTICAL_CONTROLLER),
|
||||
LOGISTICAL_STORAGE_CONTROLLER(StorageTileEntity::new, AllBlocks.LOGISTICAL_CONTROLLER),
|
||||
LOGISTICAL_CALCULATION_CONTROLLER(CalculationTileEntity::new, AllBlocks.LOGISTICAL_CONTROLLER),
|
||||
LOGISTICAL_TRANSATIONS_CONTROLLER(TransactionsTileEntity::new, AllBlocks.LOGISTICAL_CONTROLLER),
|
||||
LOGISTICAL_INDEX(LogisticalIndexTileEntity::new, AllBlocks.LOGISTICAL_INDEX),
|
||||
|
||||
// Curiosities
|
||||
WINDOW_IN_A_BLOCK(WindowInABlockTileEntity::new, AllBlocks.WINDOW_IN_A_BLOCK),
|
||||
|
@ -148,6 +164,7 @@ public enum AllTileEntities {
|
|||
bind(EntityDetectorTileEntity.class, new EntityDetectorTileEntityRenderer());
|
||||
bind(MechanicalPressTileEntity.class, new MechanicalPressTileEntityRenderer());
|
||||
bind(FlexpeaterTileEntity.class, new FlexpeaterTileEntityRenderer());
|
||||
bind(LogisticalControllerTileEntity.class, new LogisticalControllerTileEntityRenderer());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
|
|
@ -6,9 +6,11 @@ import org.apache.logging.log4j.Logger;
|
|||
import com.simibubi.create.modules.ModuleLoadedCondition;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MovingConstructHandler;
|
||||
import com.simibubi.create.modules.logistics.FrequencyHandler;
|
||||
import com.simibubi.create.modules.logistics.management.LogisticalNetworkHandler;
|
||||
import com.simibubi.create.modules.schematics.ServerSchematicLoader;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.crafting.IRecipeSerializer;
|
||||
|
@ -35,6 +37,7 @@ public class Create {
|
|||
public static ServerSchematicLoader schematicReceiver;
|
||||
public static FrequencyHandler frequencyHandler;
|
||||
public static MovingConstructHandler constructHandler;
|
||||
public static LogisticalNetworkHandler logisticalNetworkHandler;
|
||||
|
||||
public static ModConfig config;
|
||||
|
||||
|
@ -48,6 +51,8 @@ public class Create {
|
|||
schematicReceiver = new ServerSchematicLoader();
|
||||
frequencyHandler = new FrequencyHandler();
|
||||
constructHandler = new MovingConstructHandler();
|
||||
logisticalNetworkHandler = new LogisticalNetworkHandler();
|
||||
|
||||
CraftingHelper.register(new ModuleLoadedCondition.Serializer());
|
||||
AllPackets.registerPackets();
|
||||
}
|
||||
|
@ -67,6 +72,11 @@ public class Create {
|
|||
public static void registerRecipes(RegistryEvent.Register<IRecipeSerializer<?>> event) {
|
||||
AllRecipes.register(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerEntities(final RegistryEvent.Register<EntityType<?>> event) {
|
||||
AllEntities.register(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void createConfigs(ModConfig.ModConfigEvent event) {
|
||||
|
|
|
@ -54,6 +54,7 @@ public class CreateClient {
|
|||
AllTileEntities.registerRenderers();
|
||||
AllItems.registerColorHandlers();
|
||||
AllBlocks.registerColorHandlers();
|
||||
AllEntities.registerRenderers();
|
||||
|
||||
IResourceManager resourceManager = Minecraft.getInstance().getResourceManager();
|
||||
if (resourceManager instanceof IReloadableResourceManager)
|
||||
|
|
|
@ -15,7 +15,7 @@ public final class CreateItemGroup extends ItemGroup {
|
|||
|
||||
@Override
|
||||
public ItemStack createIcon() {
|
||||
return new ItemStack(AllItems.SYMMETRY_WAND.get());
|
||||
return new ItemStack(AllBlocks.COGWHEEL.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,6 +45,7 @@ public class Events {
|
|||
IWorld world = event.getWorld();
|
||||
Create.frequencyHandler.onLoadWorld(world);
|
||||
Create.constructHandler.onLoadWorld(world);
|
||||
Create.logisticalNetworkHandler.onLoadWorld(world);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -52,6 +53,7 @@ public class Events {
|
|||
IWorld world = event.getWorld();
|
||||
Create.frequencyHandler.onUnloadWorld(world);
|
||||
Create.constructHandler.onUnloadWorld(world);
|
||||
Create.logisticalNetworkHandler.onUnloadWorld(world);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -81,7 +83,8 @@ public class Events {
|
|||
if (AllBlocks.WINDOW_IN_A_BLOCK.typeOf(blockState))
|
||||
return;
|
||||
|
||||
world.setBlockState(pos, AllBlocks.WINDOW_IN_A_BLOCK.get().getDefaultState());
|
||||
BlockState defaultState = AllBlocks.WINDOW_IN_A_BLOCK.get().getDefaultState();
|
||||
world.setBlockState(pos, defaultState);
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if (te != null && te instanceof WindowInABlockTileEntity) {
|
||||
WindowInABlockTileEntity wte = (WindowInABlockTileEntity) te;
|
||||
|
|
|
@ -5,16 +5,16 @@ import net.minecraft.client.gui.AbstractGui;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public enum ScreenResources {
|
||||
|
||||
|
||||
// Inventories
|
||||
PLAYER_INVENTORY("player_inventory.png", 176, 108),
|
||||
WAND_SYMMETRY("wand_symmetry.png", 207, 58),
|
||||
PLACEMENT_GUN("placement_handgun.png", 217, 70),
|
||||
|
||||
|
||||
SCHEMATIC_TABLE("schematic_table.png", 207, 89),
|
||||
SCHEMATIC_TABLE_PROGRESS("schematic_table.png", 209, 0, 24, 17),
|
||||
SCHEMATIC("schematic.png", 207, 95),
|
||||
|
||||
|
||||
SCHEMATICANNON("schematicannon.png", 247, 161),
|
||||
SCHEMATICANNON_PROGRESS("schematicannon.png", 0, 161, 121, 16),
|
||||
SCHEMATICANNON_PROGRESS_2("schematicannon.png", 122, 161, 16, 15),
|
||||
|
@ -23,7 +23,7 @@ public enum ScreenResources {
|
|||
|
||||
FLEXCRATE("flex_crate_and_stockpile_switch.png", 125, 129),
|
||||
FLEXCRATE_LOCKED_SLOT("flex_crate_and_stockpile_switch.png", 138, 0, 18, 18),
|
||||
|
||||
|
||||
STOCKSWITCH("flex_crate_and_stockpile_switch.png", 0, 129, 205, 93),
|
||||
STOCKSWITCH_INTERVAL("flex_crate_and_stockpile_switch.png", 0, 222, 198, 17),
|
||||
STOCKSWITCH_INTERVAL_END("flex_crate_and_stockpile_switch.png", 0, 239, 198, 17),
|
||||
|
@ -31,14 +31,36 @@ public enum ScreenResources {
|
|||
STOCKSWITCH_CURSOR_OFF("flex_crate_and_stockpile_switch.png", 226, 129, 8, 21),
|
||||
STOCKSWITCH_BOUND_LEFT("flex_crate_and_stockpile_switch.png", 234, 129, 7, 21),
|
||||
STOCKSWITCH_BOUND_RIGHT("flex_crate_and_stockpile_switch.png", 241, 129, 7, 21),
|
||||
|
||||
|
||||
// Logistical Index
|
||||
INDEX_TOP("index.png", 41, 0, 174, 22),
|
||||
INDEX_TOP_TRIM("index.png", 41, 22, 174, 6),
|
||||
INDEX_MIDDLE("index.png", 41, 28, 183, 178),
|
||||
INDEX_BOTTOM_TRIM("index.png", 41, 206, 174, 6),
|
||||
INDEX_BOTTOM("index.png", 41, 212, 181, 44),
|
||||
INDEX_SCROLLER_TOP("index.png", 224, 31, 10, 6),
|
||||
INDEX_SCROLLER_MIDDLE("index.png", 224, 37, 10, 6),
|
||||
INDEX_SCROLLER_BOTTOM("index.png", 224, 43, 10, 6),
|
||||
INDEX_TAB("index.png", 0, 55, 22, 22),
|
||||
INDEX_TAB_ACTIVE("index.png", 0, 77, 22, 22),
|
||||
INDEX_SEARCH("index.png", 0, 99, 28, 19),
|
||||
INDEX_SEARCH_OVERLAY("widgets.png", 0, 81, 176, 20),
|
||||
|
||||
SLOT_FRAME("index.png", 0, 118, 18, 18),
|
||||
SLOT_INNER("index.png", 18, 118, 18, 18),
|
||||
DISABLED_SLOT_FRAME("index.png", 0, 136, 18, 18),
|
||||
DISABLED_SLOT_INNER("index.png", 18, 136, 18, 18),
|
||||
CRAFTY_SLOT_FRAME("index.png", 0, 154, 18, 18),
|
||||
CRAFTY_SLOT_INNER("index.png", 18, 154, 18, 18),
|
||||
SELECTED_SLOT_INNER("index.png", 18, 172, 18, 18),
|
||||
|
||||
// JEI
|
||||
CRUSHING_RECIPE("recipes1.png", 177, 109),
|
||||
FAN_RECIPE("recipes1.png", 0, 128, 177, 109),
|
||||
BLOCKZAPPER_UPGRADE_RECIPE("recipes2.png", 144, 66),
|
||||
PRESSER_RECIPE("recipes2.png", 0, 108, 177, 109),
|
||||
WASHING_RECIPE("recipes3.png", 177, 109),
|
||||
|
||||
|
||||
// Widgets
|
||||
PALETTE_BUTTON("palette_picker.png", 0, 236, 20, 20),
|
||||
TEXT_INPUT("widgets.png", 0, 28, 194, 47),
|
||||
|
@ -51,9 +73,9 @@ public enum ScreenResources {
|
|||
INDICATOR_YELLOW("widgets.png", 18, 23, 18, 5),
|
||||
INDICATOR_RED("widgets.png", 36, 23, 18, 5),
|
||||
GRAY("background.png", 0, 0, 16, 16),
|
||||
|
||||
|
||||
BLUEPRINT_SLOT("widgets.png", 90, 0, 24, 24),
|
||||
|
||||
|
||||
// Icons
|
||||
ICON_NONE("icons.png", 16, 16, 16, 16),
|
||||
ICON_ADD("icons.png", 16, 16),
|
||||
|
@ -61,28 +83,28 @@ public enum ScreenResources {
|
|||
ICON_3x3("icons.png", 32, 0, 16, 16),
|
||||
ICON_TARGET("icons.png", 48, 0, 16, 16),
|
||||
ICON_CONFIRM("icons.png", 0, 16, 16, 16),
|
||||
|
||||
|
||||
ICON_OPEN_FOLDER("icons.png", 32, 16, 16, 16),
|
||||
ICON_REFRESH("icons.png", 48, 16, 16, 16),
|
||||
|
||||
|
||||
ICON_DONT_REPLACE("icons.png", 0, 32, 16, 16),
|
||||
ICON_REPLACE_SOLID("icons.png", 16, 32, 16, 16),
|
||||
ICON_REPLACE_ANY("icons.png", 32, 32, 16, 16),
|
||||
ICON_REPLACE_EMPTY("icons.png", 48, 32, 16, 16),
|
||||
|
||||
|
||||
ICON_TOOL_DEPLOY("icons.png", 0, 48, 16, 16),
|
||||
ICON_SKIP_MISSING("icons.png", 16, 48, 16, 16),
|
||||
ICON_SKIP_TILES("icons.png", 32, 48, 16, 16),
|
||||
|
||||
|
||||
ICON_TOOL_MOVE_XZ("icons.png", 0, 64, 16, 16),
|
||||
ICON_TOOL_MOVE_Y("icons.png", 16, 64, 16, 16),
|
||||
ICON_TOOL_ROTATE("icons.png", 32, 64, 16, 16),
|
||||
ICON_TOOL_MIRROR("icons.png", 48, 64, 16, 16),
|
||||
|
||||
|
||||
ICON_PLAY("icons.png", 0, 80, 16, 16),
|
||||
ICON_PAUSE("icons.png", 16, 80, 16, 16),
|
||||
ICON_STOP("icons.png", 32, 80, 16, 16),
|
||||
|
||||
|
||||
ICON_PATTERN_SOLID("icons.png", 0, 96, 16, 16),
|
||||
ICON_PATTERN_CHECKERED("icons.png", 16, 96, 16, 16),
|
||||
ICON_PATTERN_CHECKERED_INVERSED("icons.png", 32, 96, 16, 16),
|
||||
|
@ -91,29 +113,31 @@ public enum ScreenResources {
|
|||
ICON_PATTERN_CHANCE_75("icons.png", 16, 112, 16, 16),
|
||||
ICON_FOLLOW_DIAGONAL("icons.png", 32, 112, 16, 16),
|
||||
ICON_FOLLOW_MATERIAL("icons.png", 48, 112, 16, 16),
|
||||
|
||||
|
||||
;
|
||||
|
||||
|
||||
public static final int FONT_COLOR = 0x575F7A;
|
||||
|
||||
|
||||
public final ResourceLocation location;
|
||||
public int width, height;
|
||||
public int startX, startY;
|
||||
|
||||
|
||||
private ScreenResources(String location, int width, int height) {
|
||||
this(location, 0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
private ScreenResources(String location, int startX, int startY, int width, int height) {
|
||||
this.location = new ResourceLocation(Create.ID, "textures/gui/" + location);
|
||||
this.width = width; this.height = height;
|
||||
this.startX = startX; this.startY = startY;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.startX = startX;
|
||||
this.startY = startY;
|
||||
}
|
||||
|
||||
|
||||
public void bind() {
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(location);
|
||||
}
|
||||
|
||||
|
||||
public void draw(AbstractGui screen, int i, int j) {
|
||||
bind();
|
||||
screen.blit(i, j, startX, startY, width, height);
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.block.StairsBlock;
|
|||
public class ProperStairsBlock extends StairsBlock {
|
||||
|
||||
public ProperStairsBlock(Block block) {
|
||||
super(block.getDefaultState(), Properties.from(block));
|
||||
super(() -> block.getDefaultState(), Properties.from(block));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package com.simibubi.create.foundation.block;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public abstract class TileEntityExtension<T extends TileEntity> {
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
public class InterpolatedChasingValue extends InterpolatedValue {
|
||||
|
||||
float speed = 0.5f;
|
||||
float target = 0;
|
||||
float eps = 1 / 4096f;
|
||||
|
||||
public void tick() {
|
||||
float diff = target - value;
|
||||
if (Math.abs(diff) < eps)
|
||||
return;
|
||||
set(value + (diff) * speed);
|
||||
}
|
||||
|
||||
public InterpolatedChasingValue withSpeed(float speed) {
|
||||
this.speed = speed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InterpolatedChasingValue target(float target) {
|
||||
this.target = target;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class InterpolatedValue {
|
||||
|
||||
public float value = 0;
|
||||
public float lastValue = 0;
|
||||
|
||||
public InterpolatedValue set(float value) {
|
||||
lastValue = this.value;
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public float get(float partialTicks) {
|
||||
return MathHelper.lerp(partialTicks, lastValue, value);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.simibubi.create.foundation.type;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CombinedCountedItemsList<T> {
|
||||
|
||||
protected Map<T, CountedItemsList> lists = new HashMap<>();
|
||||
protected CountedItemsList combined = new CountedItemsList();
|
||||
boolean combinedListDirty = true;
|
||||
|
||||
public void add(T key, CountedItemsList list) {
|
||||
lists.put(key, list);
|
||||
combinedListDirty = true;
|
||||
}
|
||||
|
||||
public void remove(T key) {
|
||||
lists.remove(key);
|
||||
combinedListDirty = true;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
lists.clear();
|
||||
combinedListDirty = true;
|
||||
}
|
||||
|
||||
public CountedItemsList get() {
|
||||
if (combinedListDirty) {
|
||||
combined = new CountedItemsList();
|
||||
lists.values().forEach(list -> list.getFlattenedList().forEach(combined::add));
|
||||
combinedListDirty = false;
|
||||
}
|
||||
return combined;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
package com.simibubi.create.foundation.type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class CountedItemsList {
|
||||
|
||||
Map<Item, Set<ItemStackEntry>> items = new HashMap<>();
|
||||
|
||||
Collection<ItemStackEntry> flattenedList = new PriorityQueue<>();
|
||||
boolean flattenedListDirty = true;
|
||||
|
||||
public CountedItemsList() {
|
||||
}
|
||||
|
||||
public CountedItemsList(IItemHandler inventory) {
|
||||
for (int slot = 0; slot < inventory.getSlots(); slot++)
|
||||
add(inventory.extractItem(slot, inventory.getSlotLimit(slot), true));
|
||||
}
|
||||
|
||||
public List<ItemStackEntry> getStacksToUpdate(CountedItemsList newList) {
|
||||
List<ItemStackEntry> changes = new ArrayList<>();
|
||||
for (Item key : Sets.union(items.keySet(), newList.items.keySet())) {
|
||||
Set<ItemStackEntry> currentSet = items.get(key);
|
||||
Set<ItemStackEntry> newSet = newList.items.get(key);
|
||||
|
||||
if (currentSet == null) {
|
||||
changes.addAll(newSet);
|
||||
continue;
|
||||
}
|
||||
if (newSet == null) {
|
||||
currentSet.forEach(entry -> changes.add(new ItemStackEntry(entry.stack, 0)));
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<ItemStackEntry> remainderNew = new HashSet<>(newSet);
|
||||
OuterLoop: for (ItemStackEntry entry : currentSet) {
|
||||
for (ItemStackEntry newEntry : newSet) {
|
||||
if (!entry.matches(newEntry.stack))
|
||||
continue;
|
||||
remainderNew.remove(newEntry);
|
||||
if (entry.amount != newEntry.amount)
|
||||
changes.add(newEntry);
|
||||
continue OuterLoop;
|
||||
}
|
||||
changes.add(new ItemStackEntry(entry.stack, 0));
|
||||
}
|
||||
changes.addAll(remainderNew);
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public void add(ItemStack stack) {
|
||||
add(stack, stack.getCount());
|
||||
}
|
||||
|
||||
public void add(ItemStackEntry entry) {
|
||||
add(entry.stack, entry.amount);
|
||||
}
|
||||
|
||||
public void add(ItemStack stack, int amount) {
|
||||
if (stack.isEmpty())
|
||||
return;
|
||||
|
||||
Set<ItemStackEntry> stackSet = getOrCreateItemSet(stack);
|
||||
for (ItemStackEntry entry : stackSet) {
|
||||
if (!entry.matches(stack))
|
||||
continue;
|
||||
entry.amount += amount;
|
||||
return;
|
||||
}
|
||||
stackSet.add(new ItemStackEntry(stack, amount));
|
||||
flattenedListDirty = true;
|
||||
}
|
||||
|
||||
public boolean contains(ItemStack stack) {
|
||||
return getItemCount(stack) != 0;
|
||||
}
|
||||
|
||||
public int getItemCount(ItemStack stack) {
|
||||
Set<ItemStackEntry> stackSet = getItemSet(stack);
|
||||
if (stackSet == null)
|
||||
return 0;
|
||||
for (ItemStackEntry entry : stackSet) {
|
||||
if (!entry.matches(stack))
|
||||
continue;
|
||||
return entry.amount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setItemCount(ItemStack stack, int amount) {
|
||||
remove(stack);
|
||||
add(stack, amount);
|
||||
}
|
||||
|
||||
public void remove(ItemStack stack) {
|
||||
Set<ItemStackEntry> stackSet = getItemSet(stack);
|
||||
if (stackSet == null)
|
||||
return;
|
||||
|
||||
for (Iterator<ItemStackEntry> iterator = stackSet.iterator(); iterator.hasNext();) {
|
||||
ItemStackEntry entry = iterator.next();
|
||||
if (entry.matches(stack)) {
|
||||
iterator.remove();
|
||||
flattenedListDirty = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<ItemStackEntry> getFlattenedList() {
|
||||
if (flattenedListDirty) {
|
||||
flattenedList.clear();
|
||||
items.values().forEach(set -> flattenedList.addAll(set));
|
||||
flattenedListDirty = false;
|
||||
}
|
||||
return flattenedList;
|
||||
}
|
||||
|
||||
private Set<ItemStackEntry> getItemSet(ItemStack stack) {
|
||||
return items.get(stack.getItem());
|
||||
}
|
||||
|
||||
private Set<ItemStackEntry> getOrCreateItemSet(ItemStack stack) {
|
||||
if (!items.containsKey(stack.getItem()))
|
||||
items.put(stack.getItem(), new HashSet<>());
|
||||
return getItemSet(stack);
|
||||
}
|
||||
|
||||
public class ItemStackEntry implements Comparable<ItemStackEntry> {
|
||||
public ItemStack stack;
|
||||
public int amount;
|
||||
|
||||
public ItemStackEntry(ItemStack stack) {
|
||||
this(stack, stack.getCount());
|
||||
}
|
||||
|
||||
public ItemStackEntry(CompoundNBT nbt) {
|
||||
this(ItemStack.read(nbt.getCompound("Item")), nbt.getInt("Amount"));
|
||||
}
|
||||
|
||||
public ItemStackEntry(ItemStack stack, int amount) {
|
||||
this.stack = stack.copy();
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack other) {
|
||||
return ItemHandlerHelper.canItemStacksStack(other, stack);
|
||||
}
|
||||
|
||||
public CompoundNBT serializeNBT() {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
nbt.put("Item", stack.serializeNBT());
|
||||
nbt.putInt("Amount", amount);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ItemStackEntry o) {
|
||||
return amount - o.amount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
public class ColorHelper {
|
||||
|
||||
public static int rainbowColor(int timeStep) {
|
||||
|
@ -39,4 +41,17 @@ public class ColorHelper {
|
|||
return color;
|
||||
}
|
||||
|
||||
public static void glColor(int color) {
|
||||
color = mixColors(color, 0xFFFFFF, .5f);
|
||||
int r = (color >> 16);
|
||||
int g = (color >> 8) & 0xFF;
|
||||
int b = color & 0xFF;
|
||||
|
||||
GlStateManager.color4f(r / 256f, g / 256f, b / 256f, 1);
|
||||
}
|
||||
|
||||
public static void glResetColor() {
|
||||
GlStateManager.color4f(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class ItemHelper {
|
||||
|
||||
|
@ -11,13 +13,37 @@ public class ItemHelper {
|
|||
List<ItemStack> stacks = new ArrayList<>();
|
||||
ItemStack result = out.copy();
|
||||
result.setCount(in.getCount() * out.getCount());
|
||||
|
||||
|
||||
while (result.getCount() > result.getMaxStackSize()) {
|
||||
stacks.add(result.split(result.getMaxStackSize()));
|
||||
}
|
||||
|
||||
|
||||
stacks.add(result);
|
||||
return stacks;
|
||||
}
|
||||
|
||||
public static void addToList(ItemStack stack, List<ItemStack> stacks) {
|
||||
for (ItemStack s : stacks) {
|
||||
if (!ItemHandlerHelper.canItemStacksStack(stack, s))
|
||||
continue;
|
||||
int transferred = Math.min(s.getMaxStackSize() - s.getCount(), stack.getCount());
|
||||
s.grow(transferred);
|
||||
stack.shrink(transferred);
|
||||
}
|
||||
if (stack.getCount() > 0)
|
||||
stacks.add(stack);
|
||||
}
|
||||
|
||||
public static boolean isSameInventory(IItemHandler h1, IItemHandler h2) {
|
||||
if (h1 == null || h2 == null)
|
||||
return false;
|
||||
if (h1.getSlots() != h2.getSlots())
|
||||
return false;
|
||||
for (int slot = 0; slot < h1.getSlots(); slot++) {
|
||||
if (h1.getStackInSlot(slot) != h2.getStackInSlot(slot))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.client.renderer.ActiveRenderInfo;
|
|||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -30,7 +31,11 @@ public class TessellatorHelper {
|
|||
}
|
||||
|
||||
public static void begin() {
|
||||
Tessellator.getInstance().getBuffer().begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
||||
begin(DefaultVertexFormats.POSITION_TEX);
|
||||
}
|
||||
|
||||
public static void begin(VertexFormat format) {
|
||||
Tessellator.getInstance().getBuffer().begin(GL11.GL_QUADS, format);
|
||||
}
|
||||
|
||||
public static void draw() {
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
|||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalBearingTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.MechanicalPistonTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntityRenderer;
|
||||
|
||||
import net.minecraft.client.resources.ReloadListener;
|
||||
import net.minecraft.profiler.IProfiler;
|
||||
|
@ -22,6 +23,7 @@ public class CachedBufferReloader extends ReloadListener<String> {
|
|||
MechanicalPistonTileEntityRenderer.invalidateCache();
|
||||
MechanicalBearingTileEntityRenderer.invalidateCache();
|
||||
FlexpeaterTileEntityRenderer.invalidateCache();
|
||||
LogisticalControllerTileEntityRenderer.invalidateCache();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public class DrillTileEntity extends KineticTileEntity implements ITickableTileE
|
|||
|
||||
private static final AtomicInteger NEXT_DRILL_ID = new AtomicInteger();
|
||||
|
||||
private static DamageSource damageSourceDrill = new DamageSource("create.drill").setDamageBypassesArmor();
|
||||
public static DamageSource damageSourceDrill = new DamageSource("create.drill").setDamageBypassesArmor();
|
||||
private int ticksUntilNextProgress;
|
||||
private int destroyProgress;
|
||||
private int drillId = -NEXT_DRILL_ID.incrementAndGet();
|
||||
|
|
|
@ -171,7 +171,7 @@ public class WindowInABlockBlock extends PaneBlock
|
|||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
WindowInABlockTileEntity tileEntity = getTileEntity(worldIn, pos);
|
||||
if (tileEntity == null)
|
||||
return VoxelShapes.empty();
|
||||
return makeCuboidShape(7, 0, 7, 9, 16, 9);
|
||||
VoxelShape shape1 = tileEntity.getPartialBlock().getShape(worldIn, pos, context);
|
||||
VoxelShape shape2 = tileEntity.getWindowBlock().getShape(worldIn, pos, context);
|
||||
return VoxelShapes.or(shape1, shape2);
|
||||
|
|
|
@ -12,17 +12,27 @@ import net.minecraft.nbt.CompoundNBT;
|
|||
import net.minecraft.nbt.NBTUtil;
|
||||
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.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class WindowInABlockTileEntity extends SyncedTileEntity {
|
||||
|
||||
private BlockState partialBlock = Blocks.AIR.getDefaultState();
|
||||
private BlockState windowBlock = Blocks.AIR.getDefaultState();
|
||||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
private IModelData modelData;
|
||||
|
||||
public WindowInABlockTileEntity() {
|
||||
super(AllTileEntities.WINDOW_IN_A_BLOCK.type);
|
||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> this::initDataMap);
|
||||
}
|
||||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
private void initDataMap() {
|
||||
modelData = new ModelDataMap.Builder().withInitial(WINDOW_BLOCK, Blocks.AIR.getDefaultState())
|
||||
.withInitial(PARTIAL_BLOCK, Blocks.AIR.getDefaultState())
|
||||
.withInitial(WindowInABlockModel.POSITION, BlockPos.ZERO).build();
|
||||
|
@ -57,6 +67,7 @@ public class WindowInABlockTileEntity extends SyncedTileEntity {
|
|||
markDirty();
|
||||
}
|
||||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
@Override
|
||||
public IModelData getModelData() {
|
||||
modelData.setData(WindowInABlockModel.PARTIAL_BLOCK, partialBlock);
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.logistics.entity.CardboardBoxEntity;
|
||||
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
|
@ -168,10 +174,20 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
|
|||
if (!simulate && hasEnoughItems) {
|
||||
World world = getWorld();
|
||||
Vec3d pos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0);
|
||||
ItemEntity entityIn = new ItemEntity(world, pos.x, pos.y, pos.z, extracting);
|
||||
entityIn.setMotion(Vec3d.ZERO);
|
||||
Entity entityIn = null;
|
||||
|
||||
if (extracting.getItem() instanceof CardboardBoxItem) {
|
||||
Direction face = getWorld().getBlockState(getPos()).get(HORIZONTAL_FACING).getOpposite();
|
||||
entityIn = new CardboardBoxEntity(world, pos, extracting, face);
|
||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .25f, .05f);
|
||||
|
||||
} else {
|
||||
entityIn = new ItemEntity(world, pos.x, pos.y, pos.z, extracting);
|
||||
entityIn.setMotion(Vec3d.ZERO);
|
||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f, .1f);
|
||||
}
|
||||
|
||||
world.addEntity(entityIn);
|
||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f, .1f);
|
||||
}
|
||||
|
||||
return extracting;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -11,6 +11,8 @@ import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.B
|
|||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
||||
import com.simibubi.create.modules.logistics.entity.CardboardBoxEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -35,10 +37,8 @@ import net.minecraft.world.World;
|
|||
|
||||
public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, IWithTileEntity<BeltFunnelTileEntity> {
|
||||
|
||||
public static final VoxelShape
|
||||
SHAPE_NORTH = makeCuboidShape(3, -4, -1, 13, 8, 5),
|
||||
SHAPE_SOUTH = makeCuboidShape(3, -4, 11, 13, 8, 17),
|
||||
SHAPE_WEST = makeCuboidShape(-1, -4, 3, 5, 8, 13),
|
||||
public static final VoxelShape SHAPE_NORTH = makeCuboidShape(3, -4, -1, 13, 8, 5),
|
||||
SHAPE_SOUTH = makeCuboidShape(3, -4, 11, 13, 8, 17), SHAPE_WEST = makeCuboidShape(-1, -4, 3, 5, 8, 13),
|
||||
SHAPE_EAST = makeCuboidShape(11, -4, 3, 17, 8, 13);
|
||||
|
||||
public BeltFunnelBlock() {
|
||||
|
@ -135,15 +135,16 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
|
||||
@Override
|
||||
public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
||||
if (!(entity instanceof ItemEntity))
|
||||
boolean isItem = entity instanceof ItemEntity;
|
||||
if (!isItem && !(entity instanceof CardboardBoxEntity))
|
||||
return false;
|
||||
boolean slope = te.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL;
|
||||
if (entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > (slope ? .6f : .4f))
|
||||
if (isItem && entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > (slope ? .6f : .4f))
|
||||
return false;
|
||||
|
||||
entity.setMotion(Vec3d.ZERO);
|
||||
withTileEntityDo(te.getWorld(), state.attachmentPos, funnelTE -> {
|
||||
funnelTE.tryToInsert((ItemEntity) entity);
|
||||
funnelTE.tryToInsert(entity);
|
||||
});
|
||||
|
||||
return true;
|
|
@ -1,8 +1,11 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
||||
import com.simibubi.create.modules.logistics.entity.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -33,12 +36,12 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
waitingForInventorySpace = compound.getBoolean("Waiting");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
initialize = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void readClientUpdate(CompoundNBT tag) {
|
||||
super.readClientUpdate(tag);
|
||||
|
@ -61,7 +64,7 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
public LazyOptional<IItemHandler> getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (initialize && hasWorld()) {
|
||||
|
@ -69,7 +72,7 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
initialize = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setInventory(LazyOptional<IItemHandler> inventory) {
|
||||
this.inventory = inventory;
|
||||
|
@ -83,13 +86,18 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
sendData();
|
||||
}
|
||||
|
||||
public void tryToInsert(ItemEntity entity) {
|
||||
public void tryToInsert(Entity entity) {
|
||||
if (!inventory.isPresent())
|
||||
return;
|
||||
if (waitingForInventorySpace)
|
||||
return;
|
||||
|
||||
ItemStack stack = entity.getItem().copy();
|
||||
ItemStack stack = null;
|
||||
if (entity instanceof ItemEntity)
|
||||
stack = ((ItemEntity) entity).getItem().copy();
|
||||
if (entity instanceof CardboardBoxEntity)
|
||||
stack = ((CardboardBoxEntity) entity).getBox().copy();
|
||||
|
||||
IItemHandler inv = inventory.orElse(null);
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
stack = inv.insertItem(slot, stack, world.isRemote);
|
||||
|
@ -97,12 +105,12 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
if (!world.isRemote) {
|
||||
entity.remove();
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EAT, SoundCategory.BLOCKS, .125f, 1f);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Vec3i directionVec = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getDirectionVec();
|
||||
float xSpeed = directionVec.getX() * 1/8f;
|
||||
float zSpeed = directionVec.getZ() * 1/8f;
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, entity.getItem()), entity.posX, entity.posY, entity.posZ, xSpeed, 1/6f, zSpeed);
|
||||
float xSpeed = directionVec.getX() * 1 / 8f;
|
||||
float zSpeed = directionVec.getZ() * 1 / 8f;
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), entity.posX,
|
||||
entity.posY, entity.posZ, xSpeed, 1 / 6f, zSpeed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -111,8 +119,9 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
waitingForInventorySpace = true;
|
||||
sendData();
|
||||
|
||||
if (!stack.equals(entity.getItem(), false))
|
||||
entity.setItem(stack);
|
||||
if (entity instanceof ItemEntity)
|
||||
if (!stack.equals(((ItemEntity) entity).getItem(), false))
|
||||
((ItemEntity) entity).setItem(stack);
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -14,6 +14,7 @@ import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.I
|
|||
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.BeltBlock.Slope;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
|
@ -1,7 +1,8 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.IHaveFilter;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.mojang.blaze3d.platform.GLX;
|
||||
import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
|
@ -1,9 +1,11 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
|
||||
import com.simibubi.create.modules.logistics.block.IExtractor;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
|
@ -1,8 +1,10 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.IExtractor;
|
||||
import com.simibubi.create.modules.logistics.block.IHaveFilter;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
|
@ -1,4 +1,6 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFrequency;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
|
@ -1,10 +1,13 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.POWERED;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.modules.logistics.IReceiveWireless;
|
||||
import com.simibubi.create.modules.logistics.block.IExtractor;
|
||||
import com.simibubi.create.modules.logistics.block.IHaveFilter;
|
||||
import com.simibubi.create.modules.logistics.block.LinkedTileEntity;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
|
@ -1,4 +1,7 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.LinkedTileEntityRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import com.simibubi.create.AllContainers;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import static com.simibubi.create.ScreenResources.FLEXCRATE;
|
||||
import static com.simibubi.create.ScreenResources.PLAYER_INVENTORY;
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.block;
|
||||
package com.simibubi.create.modules.logistics.block.inventories;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
|
@ -0,0 +1,291 @@
|
|||
package com.simibubi.create.modules.logistics.entity;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.AllEntities;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.receivers.DrillTileEntity;
|
||||
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntitySize;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.Pose;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.AbstractArrowEntity;
|
||||
import net.minecraft.inventory.EquipmentSlotType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.network.FMLPlayMessages.SpawnEntity;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
public class CardboardBoxEntity extends LivingEntity implements IEntityAdditionalSpawnData {
|
||||
|
||||
public ItemStack box;
|
||||
|
||||
public int extractorAnimationProgress;
|
||||
public Direction extractorSide;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public CardboardBoxEntity(EntityType<? extends Entity> entityTypeIn, World worldIn) {
|
||||
super((EntityType<? extends LivingEntity>) entityTypeIn, worldIn);
|
||||
}
|
||||
|
||||
protected CardboardBoxEntity(World worldIn, double x, double y, double z) {
|
||||
this(AllEntities.CARDBOARD_BOX.type, worldIn);
|
||||
this.setPosition(x, y, z);
|
||||
this.recalculateSize();
|
||||
this.rotationYaw = this.rand.nextFloat() * 360.0F;
|
||||
}
|
||||
|
||||
public CardboardBoxEntity(World worldIn, Vec3d pos, ItemStack stack, Direction extractionDirection) {
|
||||
this(worldIn, pos.x, pos.y, pos.z);
|
||||
this.setBox(stack);
|
||||
this.extractedFrom(extractionDirection);
|
||||
}
|
||||
|
||||
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
||||
@SuppressWarnings("unchecked")
|
||||
EntityType.Builder<CardboardBoxEntity> boxBuilder = (EntityType.Builder<CardboardBoxEntity>) builder;
|
||||
return boxBuilder.setCustomClientFactory(CardboardBoxEntity::spawn).size(1, 1);
|
||||
}
|
||||
|
||||
protected void registerAttributes() {
|
||||
super.registerAttributes();
|
||||
this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(5.0D);
|
||||
}
|
||||
|
||||
private void extractedFrom(Direction side) {
|
||||
extractorSide = side;
|
||||
extractorAnimationProgress = 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (extractorAnimationProgress > -1) {
|
||||
extractorAnimationProgress--;
|
||||
return;
|
||||
}
|
||||
super.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntitySize getSize(Pose poseIn) {
|
||||
if (box == null)
|
||||
return super.getSize(poseIn);
|
||||
if (AllItems.CARDBOARD_BOX_1410.typeOf(box))
|
||||
return new EntitySize(14 / 16f, 10 / 16f, true);
|
||||
if (AllItems.CARDBOARD_BOX_1416.typeOf(box))
|
||||
return new EntitySize(14 / 16f, 1f, true);
|
||||
if (AllItems.CARDBOARD_BOX_1612.typeOf(box))
|
||||
return new EntitySize(1f, 12 / 16f, true);
|
||||
if (AllItems.CARDBOARD_BOX_1616.typeOf(box))
|
||||
return new EntitySize(1f, 1f, true);
|
||||
|
||||
return super.getSize(poseIn);
|
||||
}
|
||||
|
||||
public static CardboardBoxEntity spawn(SpawnEntity spawnEntity, World world) {
|
||||
return new CardboardBoxEntity(world, 0, 0, 0);
|
||||
}
|
||||
|
||||
public ItemStack getBox() {
|
||||
return box;
|
||||
}
|
||||
|
||||
public void setBox(ItemStack box) {
|
||||
this.box = box.copy();
|
||||
recalculateSize();
|
||||
}
|
||||
|
||||
public AxisAlignedBB getCollisionBoundingBox() {
|
||||
return this.getBoundingBox();
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||
if (world.isRemote || !this.isAlive())
|
||||
return false;
|
||||
|
||||
if (DamageSource.OUT_OF_WORLD.equals(source)) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DamageSource.FALL.equals(source))
|
||||
return false;
|
||||
|
||||
if (this.isInvulnerableTo(source))
|
||||
return false;
|
||||
|
||||
if (source.isExplosion()) {
|
||||
this.destroy(source);
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DamageSource.IN_FIRE.equals(source)) {
|
||||
if (this.isBurning()) {
|
||||
this.takeDamage(source, 0.15F);
|
||||
} else {
|
||||
this.setFire(5);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DamageSource.ON_FIRE.equals(source) && this.getHealth() > 0.5F) {
|
||||
this.takeDamage(source, 4.0F);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean wasShot = source.getImmediateSource() instanceof AbstractArrowEntity;
|
||||
boolean shotCanPierce = wasShot && ((AbstractArrowEntity) source.getImmediateSource()).getPierceLevel() > 0;
|
||||
|
||||
if (source.getTrueSource() instanceof PlayerEntity
|
||||
&& !((PlayerEntity) source.getTrueSource()).abilities.allowEdit)
|
||||
return false;
|
||||
|
||||
this.destroy(source);
|
||||
this.remove();
|
||||
return shotCanPierce;
|
||||
}
|
||||
|
||||
private void takeDamage(DamageSource source, float amount) {
|
||||
float hp = this.getHealth();
|
||||
hp = hp - amount;
|
||||
if (hp <= 0.5F) {
|
||||
this.destroy(source);
|
||||
this.remove();
|
||||
} else {
|
||||
this.setHealth(hp);
|
||||
}
|
||||
}
|
||||
|
||||
private void destroy(DamageSource source) {
|
||||
this.world.playSound((PlayerEntity) null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_ARMOR_STAND_BREAK,
|
||||
this.getSoundCategory(), 1.0F, 1.0F);
|
||||
this.spawnDrops(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void spawnDrops(DamageSource source) {
|
||||
super.spawnDrops(source);
|
||||
for (ItemStack stack : CardboardBoxItem.getContents(box)) {
|
||||
ItemEntity entityIn = new ItemEntity(world, posX, posY, posZ, stack);
|
||||
world.addEntity(entityIn);
|
||||
if (DrillTileEntity.damageSourceDrill.equals(source))
|
||||
entityIn.setMotion(Vec3d.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(boolean keepData) {
|
||||
if (world.isRemote) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
Vec3d pos = VecHelper.offsetRandomly(this.getPositionVector(), world.rand, .5f);
|
||||
Vec3d motion = Vec3d.ZERO;
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, box), pos.x, pos.y, pos.z, motion.x,
|
||||
motion.y, motion.z);
|
||||
}
|
||||
}
|
||||
super.remove(keepData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerData() {
|
||||
super.registerData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditional(CompoundNBT compound) {
|
||||
super.readAdditional(compound);
|
||||
box = ItemStack.read(compound.getCompound("Box"));
|
||||
if (compound.contains("Direction"))
|
||||
extractedFrom(Direction.byIndex(compound.getInt("Direction")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeAdditional(CompoundNBT compound) {
|
||||
super.writeAdditional(compound);
|
||||
compound.put("Box", box.serializeNBT());
|
||||
if (extractorSide != null)
|
||||
compound.putInt("Direction", extractorSide.getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPacket<?> createSpawnPacket() {
|
||||
return NetworkHooks.getEntitySpawningPacket(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ItemStack> getArmorInventoryList() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStackFromSlot(EquipmentSlotType slotIn) {
|
||||
if (slotIn == EquipmentSlotType.MAINHAND)
|
||||
return getBox();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItemStackToSlot(EquipmentSlotType slotIn, ItemStack stack) {
|
||||
if (slotIn == EquipmentSlotType.MAINHAND)
|
||||
setBox(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandSide getPrimaryHand() {
|
||||
return HandSide.LEFT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(PacketBuffer buffer) {
|
||||
buffer.writeItemStack(getBox());
|
||||
boolean sidePresent = extractorSide != null;
|
||||
buffer.writeBoolean(sidePresent);
|
||||
if (sidePresent)
|
||||
buffer.writeInt(extractorSide.getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(PacketBuffer additionalData) {
|
||||
setBox(additionalData.readItemStack());
|
||||
if (additionalData.readBoolean())
|
||||
extractedFrom(Direction.byIndex(additionalData.readInt()));
|
||||
}
|
||||
|
||||
protected SoundEvent getFallSound(int heightIn) {
|
||||
return SoundEvents.ENTITY_ARMOR_STAND_FALL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected SoundEvent getHurtSound(DamageSource damageSourceIn) {
|
||||
return SoundEvents.ENTITY_ARMOR_STAND_HIT;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected SoundEvent getDeathSound() {
|
||||
return SoundEvents.ENTITY_ARMOR_STAND_BREAK;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.simibubi.create.modules.logistics.entity;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.culling.ICamera;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class CardboardBoxEntityRenderer extends EntityRenderer<CardboardBoxEntity> {
|
||||
|
||||
public CardboardBoxEntityRenderer(EntityRendererManager renderManager) {
|
||||
super(renderManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(CardboardBoxEntity entity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(CardboardBoxEntity livingEntity, ICamera camera, double camX, double camY,
|
||||
double camZ) {
|
||||
return super.shouldRender(livingEntity, camera, camX, camY, camZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderMultipass(CardboardBoxEntity entityIn, double x, double y, double z, float entityYaw,
|
||||
float partialTicks) {
|
||||
super.renderMultipass(entityIn, x, y, z, entityYaw, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(CardboardBoxEntity entity, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||
IBakedModel model = getModelForBox(entity);
|
||||
if (model == null)
|
||||
return;
|
||||
|
||||
bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(x, y, z);
|
||||
|
||||
if (entity.extractorSide != null && entity.extractorAnimationProgress > 0) {
|
||||
float time = entity.extractorAnimationProgress - partialTicks;
|
||||
float scale = 1;
|
||||
if (time > 5) {
|
||||
scale = MathHelper.lerp(((time - 10) / 10), .3f, .25f);
|
||||
} else {
|
||||
float step = time / 5;
|
||||
scale = MathHelper.lerp(step * step * step, 1, .3f);
|
||||
}
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
}
|
||||
|
||||
GlStateManager.rotated(entity.rotationYaw, 0, 1, 0);
|
||||
GlStateManager.translated(-.5, 0, .5);
|
||||
|
||||
Minecraft.getInstance().getBlockRendererDispatcher().getBlockModelRenderer().renderModelBrightness(model,
|
||||
Blocks.AIR.getDefaultState(), 1, false);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
super.doRender(entity, x, y, z, entityYaw, partialTicks);
|
||||
}
|
||||
|
||||
public IBakedModel getModelForBox(CardboardBoxEntity entity) {
|
||||
if (entity.getBox() == null || entity.getBox().isEmpty())
|
||||
return null;
|
||||
return Minecraft.getInstance().getItemRenderer().getModelWithOverrides(entity.getBox());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package com.simibubi.create.modules.logistics.item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.ItemStackHelper;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
|
||||
public class CardboardBoxItem extends Item {
|
||||
|
||||
static final int SLOTS = 9;
|
||||
static final List<CardboardBoxItem> ALL_BOXES = new ArrayList<>();
|
||||
|
||||
public CardboardBoxItem(Properties properties) {
|
||||
super(properties);
|
||||
ALL_BOXES.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||
if (!playerIn.isSneaking())
|
||||
return super.onItemRightClick(worldIn, playerIn, handIn);
|
||||
|
||||
ItemStack box = playerIn.getHeldItem(handIn);
|
||||
for (ItemStack stack : getContents(box))
|
||||
playerIn.inventory.placeItemBackInInventory(worldIn, stack);
|
||||
|
||||
if (!playerIn.isCreative()) {
|
||||
box.shrink(1);
|
||||
}
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, box);
|
||||
}
|
||||
|
||||
public static ItemStack containing(List<ItemStack> stacks) {
|
||||
ItemStack box = new ItemStack(randomBox());
|
||||
CompoundNBT compound = new CompoundNBT();
|
||||
|
||||
NonNullList<ItemStack> list = NonNullList.create();
|
||||
list.addAll(stacks);
|
||||
ItemStackHelper.saveAllItems(compound, list);
|
||||
|
||||
box.setTag(compound);
|
||||
return box;
|
||||
}
|
||||
|
||||
public static void addAddress(ItemStack box, String address) {
|
||||
box.getOrCreateTag().putString("Address", address);
|
||||
}
|
||||
|
||||
public static boolean matchAddress(ItemStack box, String other) {
|
||||
String address = box.getTag().getString("Address");
|
||||
if (address == null || address.isEmpty())
|
||||
return false;
|
||||
if (address.equals("*"))
|
||||
return true;
|
||||
if (address.equals(other))
|
||||
return true;
|
||||
if (address.endsWith("*") && other.startsWith(address.substring(0, address.length() - 1)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<ItemStack> getContents(ItemStack box) {
|
||||
NonNullList<ItemStack> list = NonNullList.withSize(SLOTS, ItemStack.EMPTY);
|
||||
ItemStackHelper.loadAllItems(box.getOrCreateTag(), list);
|
||||
return list;
|
||||
}
|
||||
|
||||
public static CardboardBoxItem randomBox() {
|
||||
return ALL_BOXES.get(new Random().nextInt(ALL_BOXES.size()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
|
||||
super.addInformation(stack, worldIn, tooltip, flagIn);
|
||||
CompoundNBT compoundnbt = stack.getOrCreateTag();
|
||||
|
||||
if (compoundnbt.contains("Address", Constants.NBT.TAG_STRING)) {
|
||||
tooltip.add(new StringTextComponent("-> " + compoundnbt.getString("Address"))
|
||||
.applyTextStyle(TextFormatting.GOLD));
|
||||
}
|
||||
|
||||
if (!compoundnbt.contains("Items", Constants.NBT.TAG_LIST))
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
for (ItemStack itemstack : getContents(stack)) {
|
||||
if (itemstack.isEmpty())
|
||||
continue;
|
||||
|
||||
++j;
|
||||
if (i <= 4) {
|
||||
++i;
|
||||
ITextComponent itextcomponent = itemstack.getDisplayName().deepCopy();
|
||||
itextcomponent.appendText(" x").appendText(String.valueOf(itemstack.getCount()))
|
||||
.applyTextStyle(TextFormatting.GRAY);
|
||||
tooltip.add(itextcomponent);
|
||||
}
|
||||
}
|
||||
|
||||
if (j - i > 0) {
|
||||
tooltip.add((new TranslationTextComponent("container.shulkerBox.more", j - i))
|
||||
.applyTextStyle(TextFormatting.ITALIC));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package com.simibubi.create.modules.logistics.management;
|
||||
|
||||
import static com.simibubi.create.AllBlocks.LOGISTICAL_CONTROLLER;
|
||||
import static com.simibubi.create.AllBlocks.LOGISTICAL_INDEX;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.foundation.item.IItemWithColorHandler;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.color.IItemColor;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class LogisticalDialItem extends Item implements IItemWithColorHandler {
|
||||
|
||||
public LogisticalDialItem(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemColor getColorHandler() {
|
||||
return (stack, layer) -> {
|
||||
if (layer == 1 && stack.getOrCreateTag().contains("NetworkIDLeast"))
|
||||
return LogisticalControllerTileEntity.colorFromUUID(stack.getTag().getUniqueId("NetworkID"));
|
||||
return 0xFFFFFF;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inventoryTick(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) {
|
||||
if (worldIn.isRemote && !stack.hasTag())
|
||||
stack.getOrCreateTag().putUniqueId("NetworkID", UUID.randomUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onItemUse(ItemUseContext context) {
|
||||
ItemStack heldItem = context.getItem();
|
||||
boolean isRemote = context.getWorld().isRemote;
|
||||
|
||||
if (!context.getPlayer().isAllowEdit())
|
||||
return super.onItemUse(context);
|
||||
BlockState blockState = context.getWorld().getBlockState(context.getPos());
|
||||
if (!LOGISTICAL_CONTROLLER.typeOf(blockState) && !LOGISTICAL_INDEX.typeOf(blockState)) {
|
||||
if (context.isPlacerSneaking()) {
|
||||
if (!isRemote)
|
||||
heldItem.getTag().putUniqueId("NetworkID", UUID.randomUUID());
|
||||
context.getPlayer().getCooldownTracker().setCooldown(heldItem.getItem(), 5);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
return super.onItemUse(context);
|
||||
}
|
||||
|
||||
LogisticalControllerTileEntity tileEntity = (LogisticalControllerTileEntity) context.getWorld()
|
||||
.getTileEntity(context.getPos());
|
||||
if (context.isPlacerSneaking()) {
|
||||
if (!isRemote)
|
||||
heldItem.getTag().putUniqueId("NetworkID", tileEntity.getNetworkId());
|
||||
context.getPlayer().getCooldownTracker().setCooldown(heldItem.getItem(), 5);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
tileEntity.setNetworkId(heldItem.getTag().getUniqueId("NetworkID"));
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||
if (!playerIn.isSneaking())
|
||||
return super.onItemRightClick(worldIn, playerIn, handIn);
|
||||
|
||||
ItemStack heldItem = playerIn.getHeldItem(handIn);
|
||||
if (!worldIn.isRemote) {
|
||||
heldItem.getTag().putUniqueId("NetworkID", UUID.randomUUID());
|
||||
playerIn.inventory.markDirty();
|
||||
}
|
||||
playerIn.getCooldownTracker().setCooldown(heldItem.getItem(), 5);
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, heldItem);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.simibubi.create.modules.logistics.management;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalTask;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalTask.DepositTask;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalTask.SupplyTask;
|
||||
import com.simibubi.create.modules.logistics.management.controller.TransactionsTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexTileEntity;
|
||||
|
||||
public class LogisticalNetwork {
|
||||
|
||||
public List<TransactionsTileEntity> taskQueues = new ArrayList<>();
|
||||
public List<LogisticalIndexTileEntity> indexers = new ArrayList<>();
|
||||
public PriorityQueue<LogisticalTask> internalTaskQueue = new PriorityQueue<>();
|
||||
public PriorityQueue<LogisticalControllerTileEntity> suppliers = new PriorityQueue<>();
|
||||
public PriorityQueue<LogisticalControllerTileEntity> receivers = new PriorityQueue<>();
|
||||
public int participants = 0;
|
||||
public boolean tasksUpdated;
|
||||
|
||||
public void addController(LogisticalControllerTileEntity te) {
|
||||
if (te instanceof TransactionsTileEntity) {
|
||||
if (taskQueues.contains(te))
|
||||
return;
|
||||
taskQueues.add((TransactionsTileEntity) te);
|
||||
}
|
||||
if (te instanceof LogisticalIndexTileEntity) {
|
||||
if (indexers.contains(te))
|
||||
return;
|
||||
indexers.add((LogisticalIndexTileEntity) te);
|
||||
}
|
||||
if (te.isSupplier()) {
|
||||
if (suppliers.contains(te))
|
||||
return;
|
||||
suppliers.add(te);
|
||||
}
|
||||
if (te.isReceiver()) {
|
||||
if (receivers.contains(te))
|
||||
return;
|
||||
receivers.add(te);
|
||||
indexers.forEach(LogisticalIndexTileEntity::syncReceivers);
|
||||
}
|
||||
participants++;
|
||||
}
|
||||
|
||||
public void removeController(LogisticalControllerTileEntity te) {
|
||||
if (te instanceof TransactionsTileEntity)
|
||||
if (!taskQueues.remove((TransactionsTileEntity) te))
|
||||
return;
|
||||
if (te instanceof LogisticalIndexTileEntity)
|
||||
if (!indexers.remove((LogisticalIndexTileEntity) te))
|
||||
return;
|
||||
if (te.isSupplier())
|
||||
if (!suppliers.remove(te))
|
||||
return;
|
||||
if (te.isReceiver()) {
|
||||
if (!receivers.remove(te))
|
||||
return;
|
||||
indexers.forEach(LogisticalIndexTileEntity::syncReceivers);
|
||||
}
|
||||
participants--;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return participants == 0;
|
||||
}
|
||||
|
||||
public void enqueueTask(LogisticalTask task) {
|
||||
internalTaskQueue.add(task);
|
||||
if (task instanceof SupplyTask)
|
||||
suppliers.forEach(LogisticalControllerTileEntity::notifyTaskUpdate);
|
||||
if (task instanceof DepositTask)
|
||||
receivers.forEach(LogisticalControllerTileEntity::notifyTaskUpdate);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.simibubi.create.modules.logistics.management;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
public class LogisticalNetworkHandler {
|
||||
|
||||
static Map<IWorld, Map<UUID, LogisticalNetwork>> networks = new HashMap<>();
|
||||
|
||||
public void onLoadWorld(IWorld world) {
|
||||
networks.put(world, new HashMap<>());
|
||||
Create.logger.debug("Prepared Logistical Network Map for " + world.getDimension().getType().getRegistryName());
|
||||
}
|
||||
|
||||
public void onUnloadWorld(IWorld world) {
|
||||
networks.remove(world);
|
||||
Create.logger.debug("Removed Logistical Network Map for " + world.getDimension().getType().getRegistryName());
|
||||
}
|
||||
|
||||
public LogisticalNetwork handleAdded(LogisticalControllerTileEntity te) {
|
||||
LogisticalNetwork networkByID = getNetworkByID(te.getWorld(), te.getNetworkId());
|
||||
networkByID.addController(te);
|
||||
return networkByID;
|
||||
}
|
||||
|
||||
public void handleRemoved(LogisticalControllerTileEntity te) {
|
||||
getNetworkByID(te.getWorld(), te.getNetworkId()).removeController(te);
|
||||
removeIfEmpty(te.getWorld(), te.getNetworkId());
|
||||
}
|
||||
|
||||
public LogisticalNetwork getNetworkByID(IWorld world, UUID id) {
|
||||
Map<UUID, LogisticalNetwork> worldNets = networks.get(world);
|
||||
if (!worldNets.containsKey(id))
|
||||
worldNets.put(id, new LogisticalNetwork());
|
||||
return worldNets.get(id);
|
||||
}
|
||||
|
||||
private void removeIfEmpty(IWorld world, UUID id) {
|
||||
Map<UUID, LogisticalNetwork> worldNets = networks.get(world);
|
||||
if (worldNets.get(id).isEmpty())
|
||||
worldNets.remove(id);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class IncrementalInventoryUpdate {
|
||||
|
||||
public ItemStack item;
|
||||
public int newAmount;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
public abstract class LogisticalActor {
|
||||
|
||||
public enum Actors {
|
||||
SUPPLY(new Supply()),
|
||||
STORAGE(new Storage()),
|
||||
DEMAND(new Demand()),
|
||||
|
||||
;
|
||||
|
||||
private LogisticalActor actor;
|
||||
|
||||
public LogisticalActor get() {
|
||||
return this.actor;
|
||||
}
|
||||
|
||||
private Actors(LogisticalActor actor) {
|
||||
this.actor = actor;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Supply extends LogisticalActor {
|
||||
|
||||
}
|
||||
|
||||
public static class Storage extends LogisticalActor {
|
||||
|
||||
}
|
||||
|
||||
public static class Demand extends LogisticalActor {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import static net.minecraft.util.Direction.AxisDirection.POSITIVE;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
|
||||
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.BlockItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
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.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class LogisticalCasingBlock extends Block implements IWithTileEntity<LogisticalCasingTileEntity> {
|
||||
|
||||
public static final EnumProperty<Direction.Axis> AXIS = BlockStateProperties.AXIS;
|
||||
public static final IProperty<Part> PART = EnumProperty.create("part", Part.class);
|
||||
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
|
||||
|
||||
public static final VoxelShape SINGLE_SHAPE = VoxelShapes.or(makeCuboidShape(0, 0, 0, 16, 2, 16),
|
||||
makeCuboidShape(1, 1, 1, 15, 15, 15), makeCuboidShape(0, 14, 0, 16, 16, 16));
|
||||
|
||||
public LogisticalCasingBlock() {
|
||||
super(Properties.from(Blocks.DARK_OAK_PLANKS));
|
||||
setDefaultState(getDefaultState().with(PART, Part.NONE).with(AXIS, Axis.Y).with(ACTIVE, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
BlockState state = getDefaultState();
|
||||
for (Direction face : Direction.values()) {
|
||||
BlockState neighbour = context.getWorld().getBlockState(context.getPos().offset(face));
|
||||
if (!AllBlocks.LOGISTICAL_CASING.typeOf(neighbour))
|
||||
continue;
|
||||
if (neighbour.get(PART) != Part.NONE && face.getAxis() != neighbour.get(AXIS))
|
||||
continue;
|
||||
state = state.with(PART, face.getAxisDirection() == AxisDirection.POSITIVE ? Part.START : Part.END);
|
||||
state = state.with(AXIS, face.getAxis());
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
||||
BlockState invState = world.getBlockState(neighbor);
|
||||
|
||||
if (!invState.hasTileEntity())
|
||||
return;
|
||||
TileEntity invTE = world.getTileEntity(neighbor);
|
||||
|
||||
LazyOptional<IItemHandler> inventory = invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
|
||||
if (inventory.isPresent() && world instanceof IWorld) {
|
||||
withTileEntityDo((IWorld) world, pos, te -> te.neighbourChanged(neighbor));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
boolean blockChanged = state.getBlock() != newState.getBlock();
|
||||
if (state.hasTileEntity() && (blockChanged || !newState.hasTileEntity())) {
|
||||
worldIn.removeTileEntity(pos);
|
||||
return;
|
||||
}
|
||||
if (blockChanged) {
|
||||
Part part = state.get(PART);
|
||||
Direction facing = Direction.getFacingFromAxis(POSITIVE, state.get(AXIS));
|
||||
if (part == Part.END || part == Part.MIDDLE)
|
||||
worldIn.getPendingBlockTicks().scheduleTick(pos.offset(facing.getOpposite()), state.getBlock(), 1);
|
||||
if (part == Part.START || part == Part.MIDDLE)
|
||||
worldIn.getPendingBlockTicks().scheduleTick(pos.offset(facing), state.getBlock(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return state.get(ACTIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new LogisticalCasingTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
return state.get(PART) == Part.NONE ? SINGLE_SHAPE : VoxelShapes.fullCube();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updatePostPlacement(BlockState state, Direction face, BlockState facingState, IWorld worldIn,
|
||||
BlockPos currentPos, BlockPos facingPos) {
|
||||
Part part = state.get(PART);
|
||||
boolean neighbourPresent = AllBlocks.LOGISTICAL_CASING.typeOf(facingState);
|
||||
boolean alongAxis = face.getAxis() == state.get(AXIS);
|
||||
boolean positive = face.getAxisDirection() == AxisDirection.POSITIVE;
|
||||
boolean neighbourAlongAxis = neighbourPresent
|
||||
&& (facingState.get(PART) == Part.NONE || facingState.get(AXIS) == face.getAxis());
|
||||
|
||||
if (part == Part.NONE && neighbourPresent && neighbourAlongAxis) {
|
||||
state = state.with(PART, positive ? Part.START : Part.END);
|
||||
return state.with(AXIS, face.getAxis());
|
||||
}
|
||||
|
||||
if (!alongAxis)
|
||||
return state;
|
||||
|
||||
if (part == Part.END) {
|
||||
if (positive && neighbourPresent && neighbourAlongAxis)
|
||||
return state.with(PART, Part.MIDDLE);
|
||||
if (!positive && !neighbourPresent)
|
||||
return state.with(PART, Part.NONE).with(AXIS, Axis.Y);
|
||||
}
|
||||
|
||||
if (part == Part.START) {
|
||||
if (!positive && neighbourPresent && neighbourAlongAxis)
|
||||
return state.with(PART, Part.MIDDLE);
|
||||
if (positive && !neighbourPresent)
|
||||
return state.with(PART, Part.NONE).with(AXIS, Axis.Y);
|
||||
}
|
||||
|
||||
if (part == Part.MIDDLE) {
|
||||
if (!positive && !neighbourPresent)
|
||||
return state.with(PART, Part.START);
|
||||
if (positive && !neighbourPresent)
|
||||
return state.with(PART, Part.END);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
if (!player.getHeldItem(handIn).isEmpty())
|
||||
return false;
|
||||
if (worldIn.isRemote)
|
||||
return true;
|
||||
if (!state.get(ACTIVE))
|
||||
player.sendStatusMessage(new StringTextComponent("Not Active").applyTextStyle(TextFormatting.RED), false);
|
||||
else {
|
||||
LogisticalCasingTileEntity tileEntity = (LogisticalCasingTileEntity) worldIn.getTileEntity(pos);
|
||||
player.sendStatusMessage(new StringTextComponent("Controllers: " + tileEntity.controllers.toString())
|
||||
.applyTextStyle(TextFormatting.GREEN), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
boolean blockChanged = state.getBlock() != oldState.getBlock();
|
||||
if (blockChanged)
|
||||
worldIn.getPendingBlockTicks().scheduleTick(pos, state.getBlock(), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, World worldIn, BlockPos pos, Random random) {
|
||||
synchronizeCasingGroup(worldIn, pos);
|
||||
}
|
||||
|
||||
protected void synchronizeCasingGroup(World world, BlockPos start) {
|
||||
List<BlockPos> chain = LogisticalControllerBlock.collectCasings(world, start);
|
||||
Set<BlockPos> controllers = new HashSet<>();
|
||||
|
||||
// Collect all Controllers
|
||||
for (BlockPos pos : chain) {
|
||||
BlockState casing = world.getBlockState(pos);
|
||||
if (!casing.get(ACTIVE))
|
||||
continue;
|
||||
LogisticalCasingTileEntity te = (LogisticalCasingTileEntity) world.getTileEntity(pos);
|
||||
if (te == null)
|
||||
continue;
|
||||
for (BlockPos controller : te.controllers) {
|
||||
if (controller.withinDistance(te.getPos(), 1 + 1 / 512f))
|
||||
controllers.add(controller);
|
||||
}
|
||||
}
|
||||
|
||||
// Advertise all Controllers
|
||||
for (BlockPos pos : chain) {
|
||||
BlockState state = world.getBlockState(pos);
|
||||
boolean shouldBeActive = !controllers.isEmpty();
|
||||
if (state.get(ACTIVE) != shouldBeActive) {
|
||||
if (!shouldBeActive) {
|
||||
LogisticalCasingTileEntity te = (LogisticalCasingTileEntity) world.getTileEntity(pos);
|
||||
te.controllers.forEach(te::detachController);
|
||||
}
|
||||
world.setBlockState(pos, state.with(ACTIVE, shouldBeActive));
|
||||
}
|
||||
if (!shouldBeActive)
|
||||
continue;
|
||||
|
||||
LogisticalCasingTileEntity te = (LogisticalCasingTileEntity) world.getTileEntity(pos);
|
||||
if (te == null)
|
||||
continue;
|
||||
|
||||
// detach missing
|
||||
for (Iterator<BlockPos> iterator = te.controllers.iterator(); iterator.hasNext();) {
|
||||
BlockPos controller = iterator.next();
|
||||
if (controllers.contains(controller))
|
||||
continue;
|
||||
iterator.remove();
|
||||
te.detachController(controller);
|
||||
}
|
||||
|
||||
// attach new
|
||||
for (BlockPos controller : controllers) {
|
||||
if (!te.controllers.contains(controller))
|
||||
te.addController(controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(AXIS, PART, ACTIVE);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
|
||||
public enum Part implements IStringSerializable {
|
||||
START, MIDDLE, END, NONE;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
||||
public class LogisticalCasingTileEntity extends SyncedTileEntity {
|
||||
|
||||
Set<BlockPos> controllers = new HashSet<>();
|
||||
|
||||
public LogisticalCasingTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_CASING.type);
|
||||
}
|
||||
|
||||
public boolean controllerPresent() {
|
||||
if (controllers.isEmpty())
|
||||
return false;
|
||||
for (BlockPos blockPos : controllers) {
|
||||
if (world.isBlockPresent(blockPos))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
ListNBT contollerNBT = new ListNBT();
|
||||
controllers.forEach(pos -> contollerNBT.add(NBTUtil.writeBlockPos(pos)));
|
||||
compound.put("Controllers", contollerNBT);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
controllers.clear();
|
||||
ListNBT controllerNBT = compound.getList("Controllers", NBT.TAG_COMPOUND);
|
||||
controllerNBT.forEach(tag -> controllers.add(NBTUtil.readBlockPos((CompoundNBT) tag)));
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
public void neighbourChanged(BlockPos neighbour) {
|
||||
if (!controllerPresent())
|
||||
return;
|
||||
for (LogisticalControllerTileEntity controller : getControllers()) {
|
||||
if (!(controller instanceof LogisticalInventoryControllerTileEntity))
|
||||
continue;
|
||||
((LogisticalInventoryControllerTileEntity) controller).inventoryChanged(neighbour);
|
||||
}
|
||||
}
|
||||
|
||||
public void addController(BlockPos pos) {
|
||||
controllers.add(pos);
|
||||
attachController(pos);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void removeController(BlockPos pos) {
|
||||
controllers.remove(pos);
|
||||
detachController(pos);
|
||||
markDirty();
|
||||
|
||||
if (controllers.isEmpty())
|
||||
world.setBlockState(getPos(), getBlockState().with(LogisticalCasingBlock.ACTIVE, false));
|
||||
}
|
||||
|
||||
public void detachController(BlockPos pos) {
|
||||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (!(tileEntity instanceof LogisticalInventoryControllerTileEntity))
|
||||
return;
|
||||
for (Direction facing : Direction.values())
|
||||
((LogisticalInventoryControllerTileEntity) tileEntity).detachInventory(getPos().offset(facing));
|
||||
}
|
||||
|
||||
public void attachController(BlockPos pos) {
|
||||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (!(tileEntity instanceof LogisticalControllerTileEntity))
|
||||
return;
|
||||
for (Direction facing : Direction.values())
|
||||
((LogisticalInventoryControllerTileEntity) tileEntity).inventoryChanged(getPos().offset(facing));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
controllers.forEach(this::detachController);
|
||||
super.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (!controllerPresent())
|
||||
return LazyOptional.empty();
|
||||
List<LogisticalControllerTileEntity> TEs = getControllers();
|
||||
if (controllers.isEmpty())
|
||||
return LazyOptional.empty();
|
||||
List<T> invs = TEs.stream().map(te -> te.getCasingCapability(cap, side).orElse(null))
|
||||
.filter(Predicates.notNull()).filter(inv -> inv instanceof IItemHandlerModifiable)
|
||||
.collect(Collectors.toList());
|
||||
IItemHandlerModifiable[] params = new IItemHandlerModifiable[invs.size()];
|
||||
invs.toArray(params);
|
||||
return LazyOptional.of(() -> new CombinedInvWrapper(params)).cast();
|
||||
}
|
||||
|
||||
public List<LogisticalControllerTileEntity> getControllers() {
|
||||
List<LogisticalControllerTileEntity> TEs = new ArrayList<>(controllers.size());
|
||||
for (BlockPos controllerPos : controllers) {
|
||||
TileEntity tileEntity = world.getTileEntity(controllerPos);
|
||||
if (tileEntity instanceof LogisticalControllerTileEntity)
|
||||
TEs.add((LogisticalControllerTileEntity) tileEntity);
|
||||
}
|
||||
return TEs;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import static com.simibubi.create.modules.logistics.management.base.LogisticalCasingBlock.ACTIVE;
|
||||
import static com.simibubi.create.modules.logistics.management.base.LogisticalCasingBlock.PART;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||
import static net.minecraft.util.Direction.AxisDirection.POSITIVE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.block.IWithoutBlockItem;
|
||||
import com.simibubi.create.foundation.block.RenderUtilityBlock;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalCasingBlock.Part;
|
||||
import com.simibubi.create.modules.logistics.management.controller.CalculationTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.RequestTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.StorageTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.SupplyTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.TransactionsTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.DirectionalBlock;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
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.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class LogisticalControllerBlock extends DirectionalBlock
|
||||
implements IWithoutBlockItem, IWithTileEntity<LogisticalControllerTileEntity> {
|
||||
|
||||
public static final IProperty<Type> TYPE = EnumProperty.create("type", Type.class);
|
||||
|
||||
public static final VoxelShape UP_SHAPE = makeCuboidShape(2, -1, 2, 14, 3, 14),
|
||||
DOWN_SHAPE = makeCuboidShape(2, 13, 2, 14, 17, 14), SOUTH_SHAPE = makeCuboidShape(2, 2, -1, 14, 14, 3),
|
||||
NORTH_SHAPE = makeCuboidShape(2, 2, 13, 14, 14, 17), EAST_SHAPE = makeCuboidShape(-1, 2, 2, 3, 14, 14),
|
||||
WEST_SHAPE = makeCuboidShape(13, 2, 2, 17, 14, 14);
|
||||
|
||||
public LogisticalControllerBlock() {
|
||||
super(Properties.from(Blocks.PISTON));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(TYPE, FACING);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
Type type = state.get(TYPE);
|
||||
|
||||
if (type == Type.SUPPLY)
|
||||
return new SupplyTileEntity();
|
||||
if (type == Type.REQUEST)
|
||||
return new RequestTileEntity();
|
||||
if (type == Type.STORAGE)
|
||||
return new StorageTileEntity();
|
||||
if (type == Type.CALCULATION)
|
||||
return new CalculationTileEntity();
|
||||
if (type == Type.TRANSACTIONS)
|
||||
return new TransactionsTileEntity();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
|
||||
if (!(placer instanceof PlayerEntity))
|
||||
return;
|
||||
PlayerEntity player = (PlayerEntity) placer;
|
||||
for (int slot = 0; slot < player.inventory.getSizeInventory(); slot++) {
|
||||
ItemStack itemStack = player.inventory.getStackInSlot(slot);
|
||||
if (!AllItems.LOGISTICAL_DIAL.typeOf(itemStack))
|
||||
continue;
|
||||
if (!itemStack.hasTag())
|
||||
continue;
|
||||
withTileEntityDo(worldIn, pos, te -> te.setNetworkId(itemStack.getTag().getUniqueId("NetworkID")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
BlockState state = getDefaultState().with(FACING, context.getFace());
|
||||
|
||||
Item item = context.getItem().getItem();
|
||||
if (item instanceof LogisticalControllerItem)
|
||||
state = state.with(TYPE, ((LogisticalControllerItem) item).getType());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
|
||||
Direction facing = state.get(FACING);
|
||||
BlockPos offset = pos.offset(facing.getOpposite());
|
||||
BlockState blockState = worldIn.getBlockState(offset);
|
||||
boolean isCasing = AllBlocks.LOGISTICAL_CASING.typeOf(blockState);
|
||||
|
||||
return isCasing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
if (player.isSneaking() || !player.isAllowEdit())
|
||||
return false;
|
||||
ItemStack held = player.getHeldItem(handIn);
|
||||
if (held.getItem() != Items.NAME_TAG)
|
||||
return false;
|
||||
if (!held.hasDisplayName())
|
||||
return false;
|
||||
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
te.setName(held.getDisplayName().getUnformattedComponentText());
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
BlockPos start = pos.offset(state.get(FACING).getOpposite());
|
||||
List<BlockPos> toUpdate = collectCasings(worldIn, start);
|
||||
|
||||
for (BlockPos blockPos : toUpdate) {
|
||||
worldIn.setBlockState(blockPos, worldIn.getBlockState(blockPos).with(ACTIVE, true));
|
||||
LogisticalCasingTileEntity tileEntity = (LogisticalCasingTileEntity) worldIn.getTileEntity(blockPos);
|
||||
tileEntity.addController(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
boolean blockChanged = state.getBlock() != newState.getBlock() || state.get(TYPE) != newState.get(TYPE);
|
||||
|
||||
if (blockChanged) {
|
||||
BlockPos start = pos.offset(state.get(FACING).getOpposite());
|
||||
List<BlockPos> toUpdate = collectCasings(worldIn, start);
|
||||
|
||||
for (BlockPos blockPos : toUpdate) {
|
||||
if (!worldIn.getBlockState(blockPos).get(ACTIVE))
|
||||
continue;
|
||||
LogisticalCasingTileEntity tileEntity = (LogisticalCasingTileEntity) worldIn.getTileEntity(blockPos);
|
||||
tileEntity.removeController(pos);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.hasTileEntity() && blockChanged) {
|
||||
worldIn.removeTileEntity(pos);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<BlockPos> collectCasings(World worldIn, BlockPos start) {
|
||||
BlockState casing = worldIn.getBlockState(start);
|
||||
if (!AllBlocks.LOGISTICAL_CASING.typeOf(casing))
|
||||
return Collections.emptyList();
|
||||
List<BlockPos> casings = new ArrayList<>();
|
||||
casings.add(start);
|
||||
if (casing.get(PART) != Part.NONE) {
|
||||
Direction casingDirection = Direction.getFacingFromAxis(POSITIVE, casing.get(AXIS));
|
||||
BlockPos search = start;
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (worldIn.getBlockState(search).get(PART) == Part.START)
|
||||
break;
|
||||
search = search.offset(casingDirection.getOpposite());
|
||||
if (!AllBlocks.LOGISTICAL_CASING.typeOf(worldIn.getBlockState(search)))
|
||||
break;
|
||||
casings.add(search);
|
||||
}
|
||||
search = start;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (worldIn.getBlockState(search).get(PART) == Part.END)
|
||||
break;
|
||||
search = search.offset(casingDirection);
|
||||
if (!AllBlocks.LOGISTICAL_CASING.typeOf(worldIn.getBlockState(search)))
|
||||
break;
|
||||
casings.add(search);
|
||||
}
|
||||
}
|
||||
return casings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
if (state.isValidPosition(worldIn, pos))
|
||||
return;
|
||||
|
||||
TileEntity tileentity = state.hasTileEntity() ? worldIn.getTileEntity(pos) : null;
|
||||
spawnDrops(state, worldIn, pos, tileentity);
|
||||
worldIn.removeBlock(pos, false);
|
||||
|
||||
for (Direction direction : Direction.values())
|
||||
worldIn.notifyNeighborsOfStateChange(pos.offset(direction), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
Direction facing = state.get(FACING);
|
||||
|
||||
if (facing == Direction.UP)
|
||||
return UP_SHAPE;
|
||||
if (facing == Direction.DOWN)
|
||||
return DOWN_SHAPE;
|
||||
if (facing == Direction.EAST)
|
||||
return EAST_SHAPE;
|
||||
if (facing == Direction.WEST)
|
||||
return WEST_SHAPE;
|
||||
if (facing == Direction.NORTH)
|
||||
return NORTH_SHAPE;
|
||||
if (facing == Direction.SOUTH)
|
||||
return SOUTH_SHAPE;
|
||||
|
||||
return VoxelShapes.empty();
|
||||
}
|
||||
|
||||
public static class LogisticalControllerIndicatorBlock extends RenderUtilityBlock {
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(TYPE, FACING);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Type implements IStringSerializable {
|
||||
SUPPLY, REQUEST, STORAGE, CALCULATION, TRANSACTIONS;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.Type;
|
||||
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
public class LogisticalControllerItem extends BlockItem {
|
||||
|
||||
private Type type;
|
||||
|
||||
public LogisticalControllerItem(Properties builder, Type type) {
|
||||
super(AllBlocks.LOGISTICAL_CONTROLLER.get(), builder);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillItemGroup(ItemGroup group, NonNullList<ItemStack> items) {
|
||||
if (this.isInGroup(group)) {
|
||||
items.add(new ItemStack(this));
|
||||
}
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.modules.logistics.management.LogisticalNetwork;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
public abstract class LogisticalControllerTileEntity extends SyncedTileEntity
|
||||
implements Comparable<LogisticalControllerTileEntity>, ITickableTileEntity {
|
||||
|
||||
public static final int COOLDOWN = 20;
|
||||
|
||||
protected Priority priority = Priority.LOW;
|
||||
protected LogisticalNetwork network;
|
||||
protected String name = "";
|
||||
protected UUID networkId;
|
||||
protected boolean initialize;
|
||||
protected boolean checkTasks;
|
||||
protected int taskCooldown;
|
||||
|
||||
public LogisticalControllerTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
initialize = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (initialize) {
|
||||
initialize = false;
|
||||
initialize();
|
||||
return;
|
||||
}
|
||||
|
||||
if (taskCooldown > 0)
|
||||
taskCooldown--;
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
if (networkId != null)
|
||||
handleAdded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (networkId != null)
|
||||
handleRemoved();
|
||||
super.remove();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFastRenderer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void notifyTaskUpdate() {
|
||||
checkTasks = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
if (networkId != null)
|
||||
compound.putUniqueId("NetworkID", networkId);
|
||||
compound.putString("Address", name);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
public UUID getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
if (compound.contains("NetworkIDLeast"))
|
||||
networkId = compound.getUniqueId("NetworkID");
|
||||
name = compound.getString("Address");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return colorFromUUID(networkId);
|
||||
}
|
||||
|
||||
public static int colorFromUUID(UUID uuid) {
|
||||
if (uuid == null)
|
||||
return 0x333333;
|
||||
int rainbowColor = ColorHelper.rainbowColor((int) uuid.getLeastSignificantBits());
|
||||
return ColorHelper.mixColors(rainbowColor, 0xFFFFFF, .5f);
|
||||
}
|
||||
|
||||
public <T> LazyOptional<T> getCasingCapability(Capability<T> cap, Direction side) {
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
public void setNetworkId(UUID uniqueId) {
|
||||
if (getNetwork() != null)
|
||||
handleRemoved();
|
||||
networkId = uniqueId;
|
||||
handleAdded();
|
||||
markDirty();
|
||||
sendData();
|
||||
}
|
||||
|
||||
public void handleAdded() {
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (getNetwork() != null)
|
||||
return;
|
||||
network = Create.logisticalNetworkHandler.handleAdded(this);
|
||||
}
|
||||
|
||||
public void handleRemoved() {
|
||||
if (world.isRemote)
|
||||
return;
|
||||
Create.logisticalNetworkHandler.handleRemoved(this);
|
||||
network = null;
|
||||
}
|
||||
|
||||
public boolean isSupplier() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isReceiver() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(LogisticalControllerTileEntity o) {
|
||||
return this.priority.compareTo(o.priority);
|
||||
}
|
||||
|
||||
public LogisticalNetwork getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public static enum Priority {
|
||||
LOWEST, LOW, MEDIUM, HIGH, HIGHEST;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import static com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.TYPE;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.client.model.animation.TileEntityRendererFast;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class LogisticalControllerTileEntityRenderer extends TileEntityRendererFast<LogisticalControllerTileEntity> {
|
||||
|
||||
protected class LogisticalControllerIndicatorRenderer extends BufferManipulator {
|
||||
|
||||
public LogisticalControllerIndicatorRenderer(ByteBuffer original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, int color, int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
byte r = (byte) (color >> 16);
|
||||
byte g = (byte) ((color >> 8) & 0xFF);
|
||||
byte b = (byte) (color & 0xFF);
|
||||
byte a = (byte) 255;
|
||||
|
||||
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||
putColor(mutable, vertex, r, g, b, a);
|
||||
putPos(mutable, vertex, getX(original, vertex) + xIn, getY(original, vertex) + yIn,
|
||||
getZ(original, vertex) + zIn);
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
|
||||
return mutable;
|
||||
}
|
||||
}
|
||||
|
||||
protected static Map<BlockState, LogisticalControllerIndicatorRenderer> cachedBuffers = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(LogisticalControllerTileEntity te, double x, double y, double z,
|
||||
float partialTicks, int destroyStage, BufferBuilder buffer) {
|
||||
BlockPos pos = te.getPos();
|
||||
BlockState blockState = te.getBlockState();
|
||||
|
||||
if (AllBlocks.LOGISTICAL_INDEX.typeOf(blockState))
|
||||
return;
|
||||
|
||||
BlockState renderedState = AllBlocks.LOGISTICAL_CONTROLLER_INDICATOR.get().getDefaultState()
|
||||
.with(FACING, blockState.get(FACING)).with(TYPE, blockState.get(TYPE));
|
||||
|
||||
if (!cachedBuffers.containsKey(renderedState)) {
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
IBakedModel originalModel = dispatcher.getModelForState(renderedState);
|
||||
BufferBuilder builder = new BufferBuilder(0);
|
||||
Random random = new Random();
|
||||
|
||||
builder.setTranslation(0, 1, 0);
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModelFlat(getWorld(), originalModel, renderedState, BlockPos.ZERO.down(), builder, true,
|
||||
random, 42, EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
cachedBuffers.put(renderedState, new LogisticalControllerIndicatorRenderer(builder.getByteBuffer()));
|
||||
}
|
||||
|
||||
int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), pos);
|
||||
buffer.putBulkData(cachedBuffers.get(renderedState).getTransformed((float) x, (float) y, (float) z,
|
||||
te.getColor(), packedLightmapCoords));
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
cachedBuffers.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,402 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.foundation.type.CombinedCountedItemsList;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry;
|
||||
import com.simibubi.create.foundation.utility.ItemHelper;
|
||||
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalTask.DepositTask;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalTask.SupplyTask;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public abstract class LogisticalInventoryControllerTileEntity extends LogisticalControllerTileEntity {
|
||||
|
||||
protected Map<BlockPos, ConnectedInventory> observedInventories = new HashMap<>();
|
||||
protected Map<IItemHandler, ConnectedInventory> inventoryByHandler = new HashMap<>();
|
||||
protected CombinedCountedItemsList<IItemHandler> allItems = new CombinedCountedItemsList<>();
|
||||
protected boolean inventorySetDirty;
|
||||
|
||||
protected LazyOptional<IItemHandler> shippingInventory;
|
||||
protected boolean tryInsertBox;
|
||||
|
||||
public LogisticalInventoryControllerTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
this.shippingInventory = LazyOptional.of(this::createInventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
super.read(compound);
|
||||
if (compound.contains("ShippingInventory")) {
|
||||
ShippingInventory inv = (ShippingInventory) shippingInventory.orElse(null);
|
||||
inv.deserializeNBT(compound.getCompound("ShippingInventory"));
|
||||
}
|
||||
}
|
||||
|
||||
public void inventoryChanged(BlockPos pos) {
|
||||
removeInvalidatedInventories();
|
||||
TileEntity invTE = world.getTileEntity(pos);
|
||||
if (invTE == null)
|
||||
return;
|
||||
if (invTE instanceof LogisticalCasingTileEntity)
|
||||
return;
|
||||
|
||||
LazyOptional<IItemHandler> inventory = invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
|
||||
if (!observedInventories.containsKey(pos)) {
|
||||
addInventory(pos, inventory);
|
||||
notifyIndexers(observedInventories.get(pos).countedItems);
|
||||
} else {
|
||||
if (inventoryByHandler.containsKey(inventory.orElse(null))) {
|
||||
List<ItemStackEntry> localChanges = observedInventories.get(pos).refresh();
|
||||
CountedItemsList changes = new CountedItemsList();
|
||||
for (ItemStackEntry entry : localChanges)
|
||||
changes.add(entry.stack, allItems.get().getItemCount(entry.stack));
|
||||
notifyIndexers(changes);
|
||||
}
|
||||
}
|
||||
checkTasks = true;
|
||||
tryInsertBox = true;
|
||||
}
|
||||
|
||||
public void detachInventory(BlockPos pos) {
|
||||
observedInventories.remove(pos);
|
||||
inventorySetDirty = true;
|
||||
}
|
||||
|
||||
public void addInventory(BlockPos pos, LazyOptional<IItemHandler> inventory) {
|
||||
observedInventories.put(pos, new ConnectedInventory(inventory));
|
||||
inventorySetDirty = true;
|
||||
}
|
||||
|
||||
protected void notifyIndexers(CountedItemsList updates) {
|
||||
if (network == null)
|
||||
return;
|
||||
network.indexers.forEach(indexer -> indexer.handleUpdatedController(getName(), updates));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (taskCooldown > 0 || world.isRemote)
|
||||
return;
|
||||
|
||||
if (tryInsertBox) {
|
||||
tryInsertBox = false;
|
||||
tryInsertBox();
|
||||
}
|
||||
|
||||
if (checkTasks) {
|
||||
checkTasks = false;
|
||||
if (getNetwork() == null)
|
||||
return;
|
||||
checkTasks();
|
||||
}
|
||||
|
||||
taskCooldown = COOLDOWN;
|
||||
}
|
||||
|
||||
private void tryInsertBox() {
|
||||
if (!canReceive())
|
||||
return;
|
||||
|
||||
ShippingInventory inventory = getInventory();
|
||||
ItemStack box = inventory.getStackInSlot(ShippingInventory.RECEIVING);
|
||||
if (box.isEmpty())
|
||||
return;
|
||||
List<ItemStack> contents = CardboardBoxItem.getContents(box);
|
||||
if (InsertAll(contents, true)) {
|
||||
ItemStack copy = box.copy();
|
||||
copy.shrink(1);
|
||||
inventory.setStackInSlot(ShippingInventory.RECEIVING, copy);
|
||||
InsertAll(contents, false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean InsertAll(List<ItemStack> stacks, boolean simulate) {
|
||||
removeInvalidatedInventories();
|
||||
for (ItemStack stack : stacks) {
|
||||
ItemStack toInsert = stack.copy();
|
||||
|
||||
InventoryScan: for (IItemHandler inv : getObservedInventories()) {
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
toInsert = inv.insertItem(slot, stack, simulate);
|
||||
if (toInsert.isEmpty())
|
||||
break InventoryScan;
|
||||
}
|
||||
}
|
||||
if (!toInsert.isEmpty())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void removeInvalidatedInventories() {
|
||||
observedInventories.keySet().stream().filter(key -> !observedInventories.get(key).itemHandler.isPresent())
|
||||
.collect(Collectors.toList()).forEach(this::detachInventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
super.initialize();
|
||||
BlockPos start = pos.offset(getBlockState().get(FACING).getOpposite());
|
||||
List<BlockPos> toUpdate = LogisticalControllerBlock.collectCasings(world, start);
|
||||
for (BlockPos blockPos : toUpdate) {
|
||||
world.updateComparatorOutputLevel(blockPos, world.getBlockState(blockPos).getBlock());
|
||||
|
||||
for (Direction face : Direction.values()) {
|
||||
BlockPos neighbour = blockPos.offset(face);
|
||||
BlockState invState = world.getBlockState(neighbour);
|
||||
if (!invState.hasTileEntity())
|
||||
continue;
|
||||
TileEntity invTE = world.getTileEntity(neighbour);
|
||||
if (invTE instanceof LogisticalCasingTileEntity)
|
||||
continue;
|
||||
|
||||
LazyOptional<IItemHandler> inventory = invTE
|
||||
.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
|
||||
if (!inventory.isPresent())
|
||||
continue;
|
||||
addInventory(neighbour, inventory);
|
||||
taskCooldown = COOLDOWN;
|
||||
checkTasks = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTasks() {
|
||||
for (Iterator<LogisticalTask> iterator = getNetwork().internalTaskQueue.iterator(); iterator.hasNext();) {
|
||||
LogisticalTask task = iterator.next();
|
||||
|
||||
if (canSupply() && task instanceof SupplyTask) {
|
||||
List<Pair<Ingredient, Integer>> items = ((SupplyTask) task).items;
|
||||
if (findItems(items, true) == null)
|
||||
continue;
|
||||
|
||||
List<ItemStack> collectedStacks = findItems(items, false);
|
||||
getInventory().createPackage(collectedStacks, task.targetAddress);
|
||||
iterator.remove();
|
||||
checkTasks = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (canReceive() && task instanceof DepositTask) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<ItemStack> findItems(List<Pair<Ingredient, Integer>> items, boolean simulate) {
|
||||
removeInvalidatedInventories();
|
||||
List<ItemStack> foundItems = new ArrayList<>();
|
||||
|
||||
// Over Requested Ingredients
|
||||
for (Pair<Ingredient, Integer> pair : items) {
|
||||
int amountLeft = pair.getValue();
|
||||
|
||||
// Over Attached inventories
|
||||
InventoryScan: for (IItemHandler inv : getObservedInventories()) {
|
||||
|
||||
// Over Slots
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
if (!pair.getKey().test(stackInSlot))
|
||||
continue;
|
||||
|
||||
ItemStack extracted = inv.extractItem(slot, amountLeft, simulate);
|
||||
amountLeft -= extracted.getCount();
|
||||
ItemHelper.addToList(extracted, foundItems);
|
||||
|
||||
if (amountLeft == 0)
|
||||
break InventoryScan;
|
||||
}
|
||||
}
|
||||
if (amountLeft > 0)
|
||||
return null;
|
||||
}
|
||||
return foundItems;
|
||||
}
|
||||
|
||||
public CountedItemsList getAllItems() {
|
||||
if (inventorySetDirty)
|
||||
refreshItemHandlerSet();
|
||||
return allItems.get();
|
||||
}
|
||||
|
||||
public Collection<IItemHandler> getObservedInventories() {
|
||||
if (inventorySetDirty)
|
||||
refreshItemHandlerSet();
|
||||
return inventoryByHandler.keySet();
|
||||
}
|
||||
|
||||
public void refreshItemHandlerSet() {
|
||||
inventorySetDirty = false;
|
||||
inventoryByHandler.clear();
|
||||
allItems.clear();
|
||||
observedInventories.forEach((pos, connectedInventory) -> {
|
||||
if (connectedInventory.itemHandler.isPresent()) {
|
||||
IItemHandler inv = connectedInventory.itemHandler.orElse(null);
|
||||
for (IItemHandler iItemHandler : inventoryByHandler.keySet()) {
|
||||
if (ItemHelper.isSameInventory(iItemHandler, inv))
|
||||
return;
|
||||
}
|
||||
inventoryByHandler.put(inv, connectedInventory);
|
||||
allItems.add(inv, connectedInventory.countedItems);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
shippingInventory.ifPresent(inv -> compound.put("ShippingInventory", ((ShippingInventory) inv).serializeNBT()));
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
shippingInventory.invalidate();
|
||||
super.remove();
|
||||
}
|
||||
|
||||
public <T> LazyOptional<T> getCasingCapability(Capability<T> cap, Direction side) {
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
return shippingInventory.cast();
|
||||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
protected boolean canSupply() {
|
||||
return isSupplier() && getInventory().canCreatePackage();
|
||||
}
|
||||
|
||||
protected boolean canReceive() {
|
||||
return isReceiver();
|
||||
}
|
||||
|
||||
public ShippingInventory getInventory() {
|
||||
return (ShippingInventory) shippingInventory.orElse(null);
|
||||
}
|
||||
|
||||
public class ConnectedInventory {
|
||||
LazyOptional<IItemHandler> itemHandler;
|
||||
CountedItemsList countedItems;
|
||||
|
||||
public ConnectedInventory(LazyOptional<IItemHandler> inv) {
|
||||
itemHandler = inv;
|
||||
countedItems = makeList(inv);
|
||||
}
|
||||
|
||||
public CountedItemsList makeList(LazyOptional<IItemHandler> inv) {
|
||||
return inv.isPresent() ? new CountedItemsList(inv.orElse(null)) : new CountedItemsList();
|
||||
}
|
||||
|
||||
public List<ItemStackEntry> refresh() {
|
||||
CountedItemsList newList = makeList(itemHandler);
|
||||
List<ItemStackEntry> stacksToUpdate = countedItems.getStacksToUpdate(newList);
|
||||
countedItems = newList;
|
||||
allItems.add(itemHandler.orElse(null), countedItems);
|
||||
return stacksToUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ShippingInventory createInventory();
|
||||
|
||||
public class ShippingInventory extends ItemStackHandler {
|
||||
|
||||
static final int SHIPPING = 0;
|
||||
static final int RECEIVING = 1;
|
||||
boolean ships;
|
||||
boolean receives;
|
||||
|
||||
public ShippingInventory(boolean ships, boolean receives) {
|
||||
super(2);
|
||||
this.ships = ships;
|
||||
this.receives = receives;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
if (slot == RECEIVING && receives)
|
||||
return stack.getItem() instanceof CardboardBoxItem && CardboardBoxItem.matchAddress(stack, name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canCreatePackage() {
|
||||
return getStackInSlot(SHIPPING).isEmpty() && ships;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
if (slot == RECEIVING)
|
||||
return ItemStack.EMPTY;
|
||||
return super.extractItem(slot, amount, simulate);
|
||||
}
|
||||
|
||||
public void createPackage(List<ItemStack> contents, String address) {
|
||||
ItemStack box = CardboardBoxItem.containing(contents);
|
||||
CardboardBoxItem.addAddress(box, address);
|
||||
setStackInSlot(SHIPPING, box);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
super.onContentsChanged(slot);
|
||||
markDirty();
|
||||
|
||||
if (slot == RECEIVING && !getStackInSlot(slot).isEmpty())
|
||||
tryInsertBox = true;
|
||||
if (slot == SHIPPING && getStackInSlot(slot).isEmpty())
|
||||
checkTasks = true;
|
||||
|
||||
BlockPos start = pos.offset(getBlockState().get(FACING).getOpposite());
|
||||
List<BlockPos> toUpdate = LogisticalControllerBlock.collectCasings(world, start);
|
||||
for (BlockPos blockPos : toUpdate) {
|
||||
TileEntity tileEntity = world.getTileEntity(blockPos);
|
||||
if (tileEntity == null)
|
||||
continue;
|
||||
tileEntity.getWorld().updateComparatorOutputLevel(blockPos, tileEntity.getBlockState().getBlock());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT serializeNBT() {
|
||||
CompoundNBT tag = super.serializeNBT();
|
||||
tag.putBoolean("Ships", ships);
|
||||
tag.putBoolean("Receives", receives);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundNBT nbt) {
|
||||
ships = nbt.getBoolean("Ships");
|
||||
receives = nbt.getBoolean("Receives");
|
||||
super.deserializeNBT(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
|
||||
public abstract class LogisticalTask implements Comparable<LogisticalTask> {
|
||||
|
||||
public enum Priority {
|
||||
HIGH, MEDIUM, LOW
|
||||
}
|
||||
|
||||
Priority priority = Priority.LOW;
|
||||
public String targetAddress;
|
||||
|
||||
@Override
|
||||
public int compareTo(LogisticalTask o) {
|
||||
return priority.compareTo(o.priority);
|
||||
}
|
||||
|
||||
public static class SupplyTask extends LogisticalTask {
|
||||
public List<Pair<Ingredient, Integer>> items;
|
||||
|
||||
public SupplyTask(ItemStackEntry requested, String address) {
|
||||
items = Arrays.asList(Pair.of(Ingredient.fromStacks(requested.stack), requested.amount));
|
||||
targetAddress = address;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DepositTask extends LogisticalTask {
|
||||
public ItemStack stack;
|
||||
|
||||
public DepositTask(ItemStack stack) {
|
||||
this.stack = stack.copy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LogisticalTileEntityExtension {
|
||||
|
||||
List<String> tags = new ArrayList<>();
|
||||
UUID networkId;
|
||||
LogisticalActor actor;
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.simibubi.create.modules.logistics.management.controller;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity;
|
||||
|
||||
public class CalculationTileEntity extends LogisticalInventoryControllerTileEntity {
|
||||
|
||||
public CalculationTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_CALCULATION_CONTROLLER.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShippingInventory createInventory() {
|
||||
return new ShippingInventory(false, false);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.simibubi.create.modules.logistics.management.controller;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity;
|
||||
|
||||
public class RequestTileEntity extends LogisticalInventoryControllerTileEntity {
|
||||
|
||||
public RequestTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_REQUEST_CONTROLLER.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShippingInventory createInventory() {
|
||||
return new ShippingInventory(false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAdded() {
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (getNetwork() != null)
|
||||
return;
|
||||
super.handleAdded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReceiver() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.simibubi.create.modules.logistics.management.controller;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity;
|
||||
|
||||
public class StorageTileEntity extends LogisticalInventoryControllerTileEntity {
|
||||
|
||||
public StorageTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_STORAGE_CONTROLLER.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShippingInventory createInventory() {
|
||||
return new ShippingInventory(true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupplier() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReceiver() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.simibubi.create.modules.logistics.management.controller;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity;
|
||||
|
||||
public class SupplyTileEntity extends LogisticalInventoryControllerTileEntity {
|
||||
|
||||
public SupplyTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_SUPPLY_CONTROLLER.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShippingInventory createInventory() {
|
||||
return new ShippingInventory(true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupplier() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.simibubi.create.modules.logistics.management.controller;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
|
||||
public class TransactionsTileEntity extends LogisticalControllerTileEntity {
|
||||
|
||||
public TransactionsTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_TRANSATIONS_CONTROLLER.type);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package com.simibubi.create.modules.logistics.management.index;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
|
||||
public class IndexContainerUpdatePacket extends SimplePacketBase {
|
||||
|
||||
public enum Type {
|
||||
INITIAL, UPDATE
|
||||
}
|
||||
|
||||
Type type;
|
||||
List<Pair<String, CountedItemsList>> items;
|
||||
BlockPos pos;
|
||||
|
||||
public IndexContainerUpdatePacket(Type type, String address, CountedItemsList items, BlockPos pos) {
|
||||
this(type, Arrays.asList(Pair.of(address, items)), pos);
|
||||
}
|
||||
|
||||
public IndexContainerUpdatePacket(Type type, List<Pair<String, CountedItemsList>> items, BlockPos pos) {
|
||||
this.type = type;
|
||||
this.items = items;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public IndexContainerUpdatePacket(PacketBuffer buffer) {
|
||||
type = Type.values()[buffer.readInt()];
|
||||
int numControllers = buffer.readInt();
|
||||
items = new ArrayList<>(numControllers);
|
||||
for (int i = 0; i < numControllers; i++) {
|
||||
String address = buffer.readString(4096);
|
||||
CountedItemsList itemList = new CountedItemsList();
|
||||
int numEntries = buffer.readInt();
|
||||
for (int j = 0; j < numEntries; j++)
|
||||
itemList.add(buffer.readItemStack(), buffer.readInt());
|
||||
items.add(Pair.of(address, itemList));
|
||||
}
|
||||
pos = buffer.readBlockPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeInt(type.ordinal());
|
||||
buffer.writeInt(items.size());
|
||||
for (Pair<String, CountedItemsList> pair : items) {
|
||||
buffer.writeString(pair.getKey(), 4096);
|
||||
Collection<ItemStackEntry> entries = pair.getValue().getFlattenedList();
|
||||
buffer.writeInt(entries.size());
|
||||
for (ItemStackEntry entry : entries) {
|
||||
buffer.writeItemStack(entry.stack);
|
||||
buffer.writeInt(entry.amount);
|
||||
}
|
||||
}
|
||||
buffer.writeBlockPos(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get().enqueueWork(() -> {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
Container openContainer = mc.player.openContainer;
|
||||
if (openContainer == null)
|
||||
return;
|
||||
if (!(openContainer instanceof LogisticalIndexContainer))
|
||||
return;
|
||||
LogisticalIndexTileEntity te = (LogisticalIndexTileEntity) mc.world.getTileEntity(pos);
|
||||
if (te == null)
|
||||
return;
|
||||
|
||||
if (type == Type.INITIAL)
|
||||
te.index(items);
|
||||
if (type == Type.UPDATE)
|
||||
te.update(items);
|
||||
|
||||
((LogisticalIndexContainer) openContainer).refresh();
|
||||
});
|
||||
context.get().setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.simibubi.create.modules.logistics.management.index;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry;
|
||||
import com.simibubi.create.modules.logistics.management.LogisticalNetwork;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalTask.SupplyTask;
|
||||
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
|
||||
public class IndexOrderRequest extends SimplePacketBase {
|
||||
|
||||
String targetAddress;
|
||||
UUID networkID;
|
||||
CountedItemsList items;
|
||||
BlockPos indexPos;
|
||||
|
||||
public IndexOrderRequest(BlockPos indexPos, String targetAddress, CountedItemsList list, UUID networkID) {
|
||||
this.targetAddress = targetAddress;
|
||||
items = list;
|
||||
this.networkID = networkID;
|
||||
this.indexPos = indexPos;
|
||||
}
|
||||
|
||||
public IndexOrderRequest(PacketBuffer buffer) {
|
||||
indexPos = buffer.readBlockPos();
|
||||
networkID = new UUID(buffer.readLong(), buffer.readLong());
|
||||
targetAddress = buffer.readString(4096);
|
||||
items = new CountedItemsList();
|
||||
int numEntries = buffer.readInt();
|
||||
for (int j = 0; j < numEntries; j++)
|
||||
items.add(buffer.readItemStack(), buffer.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeBlockPos(indexPos);
|
||||
buffer.writeLong(networkID.getMostSignificantBits());
|
||||
buffer.writeLong(networkID.getLeastSignificantBits());
|
||||
buffer.writeString(targetAddress, 4096);
|
||||
Collection<ItemStackEntry> entries = items.getFlattenedList();
|
||||
buffer.writeInt(entries.size());
|
||||
for (ItemStackEntry entry : entries) {
|
||||
buffer.writeItemStack(entry.stack);
|
||||
buffer.writeInt(entry.amount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get().enqueueWork(() -> {
|
||||
ServerPlayerEntity player = context.get().getSender();
|
||||
TileEntity tileEntity = player.getEntityWorld().getTileEntity(indexPos);
|
||||
if (tileEntity != null && tileEntity instanceof LogisticalIndexTileEntity)
|
||||
((LogisticalIndexTileEntity) tileEntity).lastOrderAddress = targetAddress;
|
||||
LogisticalNetwork networkByID = Create.logisticalNetworkHandler.getNetworkByID(player.getEntityWorld(),
|
||||
networkID);
|
||||
items.getFlattenedList().forEach(entry -> networkByID.enqueueTask(new SupplyTask(entry, targetAddress)));
|
||||
});
|
||||
context.get().setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
package com.simibubi.create.modules.logistics.management.index;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.foundation.block.IBlockWithColorHandler;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.client.renderer.color.IBlockColor;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
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.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.Direction;
|
||||
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.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
public class LogisticalIndexBlock extends HorizontalBlock
|
||||
implements IBlockWithColorHandler, IWithTileEntity<LogisticalIndexTileEntity> {
|
||||
|
||||
public static final VoxelShape SOUTH_SHAPE = makeCuboidShape(3, 1, -1, 13, 15, 3),
|
||||
NORTH_SHAPE = makeCuboidShape(3, 1, 13, 13, 15, 17), EAST_SHAPE = makeCuboidShape(-1, 1, 3, 3, 15, 13),
|
||||
WEST_SHAPE = makeCuboidShape(13, 1, 3, 17, 15, 13);
|
||||
|
||||
public LogisticalIndexBlock() {
|
||||
super(Properties.from(Blocks.GRANITE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
|
||||
Direction facing = state.get(HORIZONTAL_FACING);
|
||||
BlockPos offset = pos.offset(facing.getOpposite());
|
||||
BlockState blockState = worldIn.getBlockState(offset);
|
||||
return !blockState.getMaterial().isReplaceable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(HORIZONTAL_FACING);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.CUTOUT_MIPPED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
BlockState defaultState = getDefaultState();
|
||||
if (context.getFace().getAxis().isHorizontal())
|
||||
return defaultState.with(HORIZONTAL_FACING, context.getFace());
|
||||
return defaultState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
if (state.isValidPosition(worldIn, pos))
|
||||
return;
|
||||
|
||||
TileEntity tileentity = state.hasTileEntity() ? worldIn.getTileEntity(pos) : null;
|
||||
spawnDrops(state, worldIn, pos, tileentity);
|
||||
worldIn.removeBlock(pos, false);
|
||||
|
||||
for (Direction direction : Direction.values())
|
||||
worldIn.notifyNeighborsOfStateChange(pos.offset(direction), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new LogisticalIndexTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
if (AllItems.LOGISTICAL_DIAL.typeOf(player.getHeldItem(handIn))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (worldIn.isRemote) {
|
||||
return true;
|
||||
} else {
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
NetworkHooks.openGui((ServerPlayerEntity) player, te, te::sendToContainer);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
|
||||
if (!(placer instanceof PlayerEntity))
|
||||
return;
|
||||
PlayerEntity player = (PlayerEntity) placer;
|
||||
for (int slot = 0; slot < player.inventory.getSizeInventory(); slot++) {
|
||||
ItemStack itemStack = player.inventory.getStackInSlot(slot);
|
||||
if (!AllItems.LOGISTICAL_DIAL.typeOf(itemStack))
|
||||
continue;
|
||||
if (!itemStack.hasTag())
|
||||
continue;
|
||||
withTileEntityDo(worldIn, pos, te -> te.setNetworkId(itemStack.getTag().getUniqueId("NetworkID")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
Direction facing = state.get(HORIZONTAL_FACING);
|
||||
|
||||
if (facing == Direction.EAST)
|
||||
return EAST_SHAPE;
|
||||
if (facing == Direction.WEST)
|
||||
return WEST_SHAPE;
|
||||
if (facing == Direction.NORTH)
|
||||
return NORTH_SHAPE;
|
||||
if (facing == Direction.SOUTH)
|
||||
return SOUTH_SHAPE;
|
||||
|
||||
return VoxelShapes.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockColor getColorHandler() {
|
||||
return (state, world, pos, layer) -> {
|
||||
if (layer == 0) {
|
||||
LogisticalIndexTileEntity tileEntity = getTileEntity(world, pos);
|
||||
if (tileEntity == null)
|
||||
return 0;
|
||||
return tileEntity.getColor();
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.simibubi.create.modules.logistics.management.index;
|
||||
|
||||
import com.simibubi.create.AllContainers;
|
||||
import com.simibubi.create.foundation.type.CombinedCountedItemsList;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
||||
public class LogisticalIndexContainer extends Container {
|
||||
|
||||
public LogisticalIndexTileEntity te;
|
||||
public CombinedCountedItemsList<String> allItems = new CombinedCountedItemsList<>();
|
||||
|
||||
public LogisticalIndexContainer(int id, PlayerInventory inv, PacketBuffer extraData) {
|
||||
super(AllContainers.LOGISTICAL_INDEX.type, id);
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
this.te = (LogisticalIndexTileEntity) world.getTileEntity(extraData.readBlockPos());
|
||||
this.te.handleUpdateTag(extraData.readCompoundTag());
|
||||
init();
|
||||
}
|
||||
|
||||
public LogisticalIndexContainer(int id, PlayerInventory inv, LogisticalIndexTileEntity te) {
|
||||
super(AllContainers.LOGISTICAL_INDEX.type, id);
|
||||
this.te = te;
|
||||
init();
|
||||
te.addPlayer((ServerPlayerEntity) inv.player);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
detectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContainerClosed(PlayerEntity playerIn) {
|
||||
if (!te.getWorld().isRemote)
|
||||
te.removePlayer((ServerPlayerEntity) playerIn);
|
||||
else
|
||||
te.controllers.clear();
|
||||
super.onContainerClosed(playerIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(PlayerEntity playerIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
allItems.clear();
|
||||
te.controllers.forEach(allItems::add);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,645 @@
|
|||
package com.simibubi.create.modules.logistics.management.index;
|
||||
|
||||
import static com.simibubi.create.ScreenResources.DISABLED_SLOT_FRAME;
|
||||
import static com.simibubi.create.ScreenResources.DISABLED_SLOT_INNER;
|
||||
import static com.simibubi.create.ScreenResources.ICON_CONFIRM;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_BOTTOM;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_BOTTOM_TRIM;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_MIDDLE;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_SCROLLER_BOTTOM;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_SCROLLER_MIDDLE;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_SCROLLER_TOP;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_SEARCH;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_SEARCH_OVERLAY;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_TAB;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_TAB_ACTIVE;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_TOP;
|
||||
import static com.simibubi.create.ScreenResources.INDEX_TOP_TRIM;
|
||||
import static com.simibubi.create.ScreenResources.SLOT_FRAME;
|
||||
import static com.simibubi.create.ScreenResources.SLOT_INNER;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.ScreenResources;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen;
|
||||
import com.simibubi.create.foundation.gui.ScreenElementRenderer;
|
||||
import com.simibubi.create.foundation.gui.widgets.IconButton;
|
||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
|
||||
import com.simibubi.create.foundation.gui.widgets.ScrollInput;
|
||||
import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.GameSettings;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.util.InputMappings;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
public class LogisticalIndexScreen extends AbstractSimiContainerScreen<LogisticalIndexContainer> {
|
||||
|
||||
protected LogisticalIndexContainer container;
|
||||
protected IconButton orderButton;
|
||||
|
||||
boolean searchActive = false;
|
||||
boolean searchHovered = false;
|
||||
InterpolatedChasingValue searchButtonOffset;
|
||||
TextFieldWidget searchTextField;
|
||||
String searchKey = "";
|
||||
|
||||
TextFieldWidget receiverTextField;
|
||||
ScrollInput receiverScrollInput;
|
||||
List<String> receivers = new ArrayList<>();
|
||||
|
||||
int cursorPos = 0;
|
||||
boolean cursorActive = false;
|
||||
InterpolatedChasingValue cursorLight;
|
||||
|
||||
List<ItemStackEntry> displayedItems = new ArrayList<>();
|
||||
CountedItemsList order = new CountedItemsList();
|
||||
String initialTargetAddress;
|
||||
|
||||
String title = Lang.translate("gui.index.title");
|
||||
String receiverScrollInputTitle = Lang.translate("gui.index.targetAddressSelect");
|
||||
String orderButtonTooltip = Lang.translate("gui.index.confirmOrder");
|
||||
String keyNumberInventories = "gui.index.numberIndexedInventories";
|
||||
ItemStack chestIcon = new ItemStack(Blocks.CHEST);
|
||||
|
||||
public LogisticalIndexScreen(LogisticalIndexContainer container, PlayerInventory inv, ITextComponent title) {
|
||||
super(container, inv, title);
|
||||
this.container = container;
|
||||
cursorLight = new InterpolatedChasingValue().withSpeed(.25f);
|
||||
searchButtonOffset = new InterpolatedChasingValue().withSpeed(.5f);
|
||||
receivers = container.te.availableReceivers;
|
||||
initialTargetAddress = container.te.lastOrderAddress;
|
||||
buildDisplayedItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int height = INDEX_TOP.height + INDEX_TOP_TRIM.height + INDEX_MIDDLE.height + INDEX_BOTTOM_TRIM.height
|
||||
+ INDEX_BOTTOM.height;
|
||||
int width = INDEX_MIDDLE.width;
|
||||
setWindowSize(width, height);
|
||||
super.init();
|
||||
widgets.clear();
|
||||
|
||||
searchTextField = new TextFieldWidget(font, guiLeft + 23, guiTop + 8, 128, 8, "");
|
||||
searchTextField.setTextColor(0xFFFFFF);
|
||||
searchTextField.setDisabledTextColour(-1);
|
||||
searchTextField.setEnableBackgroundDrawing(false);
|
||||
searchTextField.setMaxStringLength(256);
|
||||
searchTextField.func_212954_a(this::onSearchKeyChanged);
|
||||
searchTextField.setFocused2(false);
|
||||
|
||||
receiverTextField = new TextFieldWidget(font, guiLeft + 29, guiTop + 240, 116, 8, "");
|
||||
receiverTextField.setTextColor(0xFFFFFF);
|
||||
receiverTextField.setDisabledTextColour(-1);
|
||||
receiverTextField.setEnableBackgroundDrawing(false);
|
||||
receiverTextField.setMaxStringLength(256);
|
||||
receiverTextField.func_212954_a(this::onReceiverTextChanged);
|
||||
if (initialTargetAddress != null)
|
||||
receiverTextField.setText(initialTargetAddress);
|
||||
receiverTextField.setFocused2(false);
|
||||
|
||||
receiverScrollInput = new SelectionScrollInput(guiLeft + 24, guiTop + 235, 126, 18).forOptions(receivers)
|
||||
.titled(receiverScrollInputTitle).calling(this::onReceiverScrollInputChanged);
|
||||
|
||||
orderButton = new IconButton(guiLeft + 152, guiTop + 235, ICON_CONFIRM);
|
||||
orderButton.active = false;
|
||||
orderButton.setToolTip(orderButtonTooltip);
|
||||
|
||||
widgets.add(receiverTextField);
|
||||
widgets.add(receiverScrollInput);
|
||||
widgets.add(orderButton);
|
||||
|
||||
if (searchActive)
|
||||
widgets.add(searchTextField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
float targetOffset = 0.75f;
|
||||
if (searchTextField.isFocused())
|
||||
targetOffset = 1.5f;
|
||||
else if (searchHovered || searchActive)
|
||||
targetOffset = 1f;
|
||||
searchButtonOffset.target(targetOffset);
|
||||
searchButtonOffset.tick();
|
||||
|
||||
if (cursorActive) {
|
||||
cursorLight.target(1);
|
||||
cursorLight.tick();
|
||||
} else {
|
||||
cursorLight.set(0);
|
||||
}
|
||||
|
||||
if (!searchActive && searchTextField.isFocused())
|
||||
searchTextField.changeFocus(false);
|
||||
|
||||
if (container.te.update) {
|
||||
buildDisplayedItems();
|
||||
container.te.update = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateSubmitButton() {
|
||||
orderButton.active = canSubmit();
|
||||
}
|
||||
|
||||
public boolean canSubmit() {
|
||||
return !order.getFlattenedList().isEmpty()
|
||||
&& container.te.availableReceivers.contains(receiverTextField.getText());
|
||||
}
|
||||
|
||||
private void onSearchKeyChanged(String newSearch) {
|
||||
if (searchKey.equals(newSearch))
|
||||
return;
|
||||
searchKey = new String(newSearch);
|
||||
buildDisplayedItems();
|
||||
}
|
||||
|
||||
private void sendRequest() {
|
||||
String address = receiverTextField.getText();
|
||||
UUID id = container.te.getNetworkId();
|
||||
AllPackets.channel.sendToServer(new IndexOrderRequest(container.te.getPos(), address, order, id));
|
||||
order = new CountedItemsList();
|
||||
updateSubmitButton();
|
||||
}
|
||||
|
||||
private void onReceiverTextChanged(String newSearch) {
|
||||
if (!receiverTextField.isFocused())
|
||||
return;
|
||||
receiverScrollInput.setState(0);
|
||||
receivers = container.te.availableReceivers.stream()
|
||||
.filter(str -> str.toLowerCase().startsWith(newSearch.toLowerCase())).collect(Collectors.toList());
|
||||
((SelectionScrollInput) receiverScrollInput).forOptions(receivers);
|
||||
receiverScrollInput.active = !receivers.isEmpty();
|
||||
if (receivers.isEmpty() || newSearch.isEmpty())
|
||||
receiverTextField.setSuggestion(null);
|
||||
else
|
||||
receiverTextField.setSuggestion(receivers.get(0).substring(newSearch.length()));
|
||||
updateSubmitButton();
|
||||
}
|
||||
|
||||
private void onReceiverScrollInputChanged(int index) {
|
||||
String address = receivers.get(index);
|
||||
receiverTextField.func_212954_a(null);
|
||||
receiverTextField.setSuggestion(null);
|
||||
receiverTextField.setText(address);
|
||||
receiverTextField.func_212954_a(this::onReceiverTextChanged);
|
||||
updateSubmitButton();
|
||||
}
|
||||
|
||||
public void buildDisplayedItems() {
|
||||
if (searchKey.isEmpty()) {
|
||||
displayedItems = container.allItems.get().getFlattenedList().stream().collect(Collectors.toList());
|
||||
} else {
|
||||
displayedItems = container.allItems
|
||||
.get().getFlattenedList().parallelStream().filter(entry -> entry.stack.getDisplayName()
|
||||
.getUnformattedComponentText().toLowerCase().startsWith(searchKey.toLowerCase()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (cursorActive)
|
||||
moveCursor(cursorPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
if (searchHovered && button == 0) {
|
||||
setSearchActive(!searchActive);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (orderButton.isHovered() && orderButton.active) {
|
||||
sendRequest();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.mouseClicked(x, y, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(double xPos, double yPos) {
|
||||
|
||||
super.mouseMoved(xPos, yPos);
|
||||
}
|
||||
|
||||
private void setSearchActive(boolean searchActive) {
|
||||
this.searchActive = searchActive;
|
||||
if (searchActive) {
|
||||
cursorActive = false;
|
||||
searchTextField.setSelectionPos(0);
|
||||
searchTextField.changeFocus(true);
|
||||
widgets.add(searchTextField);
|
||||
} else {
|
||||
widgets.remove(searchTextField);
|
||||
onSearchKeyChanged("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int code, int p_keyPressed_2_, int p_keyPressed_3_) {
|
||||
InputMappings.Input mouseKey = InputMappings.getInputByCode(code, p_keyPressed_2_);
|
||||
boolean receiverFocused = receiverTextField.isFocused();
|
||||
boolean searchFocused = searchTextField.isFocused();
|
||||
boolean space = code == GLFW.GLFW_KEY_SPACE;
|
||||
boolean enter = code == GLFW.GLFW_KEY_ENTER;
|
||||
boolean writingText = receiverFocused || searchFocused;
|
||||
boolean closingScreen = this.minecraft.gameSettings.keyBindInventory.isActiveAndMatches(mouseKey);
|
||||
|
||||
if (closingScreen && writingText) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (canSubmit() && hasShiftDown() && enter) {
|
||||
sendRequest();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (enter && searchActive && searchFocused) {
|
||||
searchTextField.changeFocus(false);
|
||||
searchTextField.setCursorPositionEnd();
|
||||
searchTextField.setSelectionPos(searchTextField.getCursorPosition());
|
||||
|
||||
cursorActive = true;
|
||||
cursorPos = 0;
|
||||
|
||||
if (searchTextField.getText().isEmpty())
|
||||
setSearchActive(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (enter && !writingText && cursorActive) {
|
||||
ItemStackEntry entry = displayedItems.get(cursorPos);
|
||||
if (!order.contains(entry.stack)) {
|
||||
if (order.getFlattenedList().size() > 4)
|
||||
return true;
|
||||
order.add(entry);
|
||||
} else
|
||||
order.remove(entry.stack);
|
||||
updateSubmitButton();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (space && !writingText) {
|
||||
setSearchActive(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean up = code == GLFW.GLFW_KEY_UP;
|
||||
boolean left = code == GLFW.GLFW_KEY_LEFT;
|
||||
boolean down = code == GLFW.GLFW_KEY_DOWN;
|
||||
boolean right = code == GLFW.GLFW_KEY_RIGHT;
|
||||
boolean tab = code == GLFW.GLFW_KEY_TAB;
|
||||
|
||||
if (!writingText && tab) {
|
||||
receiverTextField.setCursorPositionEnd();
|
||||
receiverTextField.setSelectionPos(0);
|
||||
receiverTextField.changeFocus(true);
|
||||
}
|
||||
|
||||
if (receiverFocused) {
|
||||
if (enter) {
|
||||
receiverTextField.changeFocus(false);
|
||||
}
|
||||
if (tab) {
|
||||
if (receivers.isEmpty())
|
||||
return false;
|
||||
receiverTextField.setText(receivers.get(0));
|
||||
return true;
|
||||
}
|
||||
if (up || down) {
|
||||
receiverScrollInput.setState(receiverScrollInput.getState() + (up ? -1 : 1));
|
||||
receiverScrollInput.onChanged();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!writingText) {
|
||||
GameSettings keys = minecraft.gameSettings;
|
||||
boolean w = keys.keyBindForward.getKey().getKeyCode() == code || up;
|
||||
boolean a = keys.keyBindLeft.getKey().getKeyCode() == code || left;
|
||||
boolean s = keys.keyBindBack.getKey().getKeyCode() == code || down;
|
||||
boolean d = keys.keyBindRight.getKey().getKeyCode() == code || right;
|
||||
boolean any = w || a || s || d;
|
||||
|
||||
if (any && !cursorActive) {
|
||||
cursorActive = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (any) {
|
||||
int offset = w ? -8 : a ? -1 : s ? 8 : d ? 1 : 0;
|
||||
if (hasShiftDown()) {
|
||||
offset *= 4;
|
||||
if (a || d) {
|
||||
int col = cursorPos % 8;
|
||||
offset = MathHelper.clamp(offset, -col, 7 - col);
|
||||
}
|
||||
}
|
||||
moveCursor(cursorPos + offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_);
|
||||
}
|
||||
|
||||
protected void moveCursor(int slot) {
|
||||
int clamp = MathHelper.clamp(slot, 0, slotsVisible() - 1);
|
||||
if (cursorPos != clamp)
|
||||
cursorLight.set(0).set(0);
|
||||
cursorPos = clamp;
|
||||
}
|
||||
|
||||
protected int slotsVisible() {
|
||||
return displayedItems.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(int mouseX, int mouseY, float partialTicks) {
|
||||
applyNetworkColor();
|
||||
|
||||
// Search bar
|
||||
searchHovered = (mouseX > guiLeft - 25 && mouseX < guiLeft && mouseY > guiTop + 6 && mouseY < guiTop + 31);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translatef(searchButtonOffset.get(partialTicks) * -14, 0, 0);
|
||||
INDEX_SEARCH.draw(this, guiLeft - 5, guiTop + 8);
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
INDEX_MIDDLE.draw(this, guiLeft, guiTop + INDEX_TOP.height + 6);
|
||||
renderScrollbar();
|
||||
renderTabs();
|
||||
resetColor();
|
||||
renderSlots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char character, int code) {
|
||||
if (!searchActive && !receiverTextField.isFocused())
|
||||
return false;
|
||||
if (character == ' ' && (searchTextField.getText().isEmpty()
|
||||
|| searchTextField.getSelectedText().equals(searchTextField.getText())))
|
||||
return false;
|
||||
return super.charTyped(character, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) {
|
||||
resetColor();
|
||||
INDEX_TOP_TRIM.draw(this, guiLeft, guiTop + INDEX_TOP.height);
|
||||
INDEX_BOTTOM_TRIM.draw(this, guiLeft, guiTop + INDEX_TOP.height + INDEX_MIDDLE.height + 6);
|
||||
applyNetworkColor();
|
||||
INDEX_TOP.draw(this, guiLeft, guiTop);
|
||||
INDEX_BOTTOM.draw(this, guiLeft, guiTop + INDEX_TOP.height + INDEX_MIDDLE.height + 12);
|
||||
|
||||
if (searchActive) {
|
||||
INDEX_SEARCH_OVERLAY.draw(this, guiLeft - 1, guiTop + 2);
|
||||
resetColor();
|
||||
|
||||
} else {
|
||||
resetColor();
|
||||
int offset = (INDEX_TOP.width - font.getStringWidth(title)) / 2;
|
||||
font.drawStringWithShadow(title, guiLeft + offset, guiTop + 8,
|
||||
ColorHelper.mixColors(0xFFFFFF, container.te.getColor(), .25f));
|
||||
}
|
||||
|
||||
orderButton.render(mouseX, mouseY, partialTicks);
|
||||
if (searchActive)
|
||||
searchTextField.render(mouseX, mouseY, partialTicks);
|
||||
receiverTextField.render(mouseX, mouseY, partialTicks);
|
||||
|
||||
renderOrderedItems();
|
||||
ScreenElementRenderer.render3DItem(() -> {
|
||||
GlStateManager.translated(guiLeft + 6.5, guiTop + 235, 0);
|
||||
return chestIcon;
|
||||
});
|
||||
|
||||
super.renderWindowForeground(mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
private void renderOrderedItems() {
|
||||
Collection<ItemStackEntry> flattenedList = order.getFlattenedList();
|
||||
|
||||
int slotX = guiLeft + (getXSize() - flattenedList.size() * 18) / 2;
|
||||
int slotY = guiTop + 215;
|
||||
|
||||
for (ItemStackEntry entry : flattenedList) {
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.enableDepthTest();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translatef(0.0F, 0.0F, 32.0F);
|
||||
this.blitOffset = 200;
|
||||
this.itemRenderer.zLevel = 200.0F;
|
||||
net.minecraft.client.gui.FontRenderer font = entry.stack.getItem().getFontRenderer(entry.stack);
|
||||
if (font == null)
|
||||
font = this.font;
|
||||
this.itemRenderer.renderItemAndEffectIntoGUI(entry.stack, slotX, slotY);
|
||||
this.renderItemOverlayIntoGUI(font, entry.stack, slotX, slotY,
|
||||
entry.amount > 1 ? String.valueOf(entry.amount) : null, 0xFFFFFF);
|
||||
this.blitOffset = 0;
|
||||
this.itemRenderer.zLevel = 0.0F;
|
||||
GlStateManager.popMatrix();
|
||||
slotX += 18;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderSlots() {
|
||||
int slot = 0;
|
||||
for (ItemStackEntry entry : displayedItems) {
|
||||
resetColor();
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
renderSlot(slot, entry.stack, entry.amount);
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
|
||||
private void renderSlot(int slot, ItemStack stack, int count) {
|
||||
int slotX = getSlotX(slot);
|
||||
int slotY = getSlotY(slot);
|
||||
|
||||
// boolean ordered = order.contains(stack);
|
||||
boolean orderedFully = order.getItemCount(stack) == count;
|
||||
|
||||
if (orderedFully) {
|
||||
DISABLED_SLOT_FRAME.draw(this, slotX, slotY);
|
||||
DISABLED_SLOT_INNER.draw(this, slotX, slotY);
|
||||
} else {
|
||||
SLOT_FRAME.draw(this, slotX, slotY);
|
||||
SLOT_INNER.draw(this, slotX, slotY);
|
||||
}
|
||||
|
||||
if (cursorActive && slot == cursorPos) {
|
||||
renderCursor();
|
||||
}
|
||||
|
||||
slotX++;
|
||||
slotY++;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translatef(0.0F, 0.0F, 32.0F);
|
||||
this.blitOffset = 200;
|
||||
this.itemRenderer.zLevel = 200.0F;
|
||||
net.minecraft.client.gui.FontRenderer font = stack.getItem().getFontRenderer(stack);
|
||||
if (font == null)
|
||||
font = this.font;
|
||||
this.itemRenderer.renderItemAndEffectIntoGUI(stack, slotX, slotY);
|
||||
|
||||
String text = count > 1 ? String.valueOf(count) : null;
|
||||
int color = 0xFFFFFF;
|
||||
if (orderedFully) {
|
||||
color = ColorHelper.mixColors(container.te.getColor(), 0, 0.5f);
|
||||
text = "0";
|
||||
}
|
||||
|
||||
this.renderItemOverlayIntoGUI(font, stack, slotX, slotY, text, color);
|
||||
this.blitOffset = 0;
|
||||
this.itemRenderer.zLevel = 0.0F;
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
public int getSlotY(int slot) {
|
||||
return guiTop + 28 + 18 * (slot / 8);
|
||||
}
|
||||
|
||||
public int getSlotX(int slot) {
|
||||
return guiLeft + 15 + 18 * (slot % 8);
|
||||
}
|
||||
|
||||
private void renderScrollbar() {
|
||||
INDEX_SCROLLER_TOP.draw(this, guiLeft + 173, guiTop + 31);
|
||||
INDEX_SCROLLER_MIDDLE.draw(this, guiLeft + 173, guiTop + 37);
|
||||
INDEX_SCROLLER_BOTTOM.draw(this, guiLeft + 173, guiTop + 43);
|
||||
}
|
||||
|
||||
private void renderTabs() {
|
||||
INDEX_TAB.draw(this, guiLeft - 19, guiTop + 40);
|
||||
INDEX_TAB_ACTIVE.draw(this, guiLeft - 19, guiTop + 61);
|
||||
INDEX_TAB.draw(this, guiLeft - 19, guiTop + 82);
|
||||
INDEX_TAB.draw(this, guiLeft - 19, guiTop + 103);
|
||||
}
|
||||
|
||||
public void resetColor() {
|
||||
ColorHelper.glResetColor();
|
||||
}
|
||||
|
||||
public void applyNetworkColor() {
|
||||
ColorHelper.glColor(container.te.getColor());
|
||||
}
|
||||
|
||||
private void renderCursor() {
|
||||
if (!cursorActive)
|
||||
return;
|
||||
int x = getSlotX(cursorPos);
|
||||
int y = getSlotY(cursorPos);
|
||||
|
||||
float pt = minecraft.getRenderPartialTicks();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.color4f(1, 1, 1, cursorLight.get(pt));
|
||||
ScreenResources.SELECTED_SLOT_INNER.draw(this, x, y);
|
||||
resetColor();
|
||||
}
|
||||
|
||||
public void renderItemOverlayIntoGUI(FontRenderer fr, ItemStack stack, int xPosition, int yPosition,
|
||||
@Nullable String text, int textColor) {
|
||||
if (!stack.isEmpty()) {
|
||||
if (stack.getItem().showDurabilityBar(stack)) {
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.disableDepthTest();
|
||||
GlStateManager.disableTexture();
|
||||
GlStateManager.disableAlphaTest();
|
||||
GlStateManager.disableBlend();
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||
double health = stack.getItem().getDurabilityForDisplay(stack);
|
||||
int i = Math.round(13.0F - (float) health * 13.0F);
|
||||
int j = stack.getItem().getRGBDurabilityForDisplay(stack);
|
||||
this.draw(bufferbuilder, xPosition + 2, yPosition + 13, 13, 2, 0, 0, 0, 255);
|
||||
this.draw(bufferbuilder, xPosition + 2, yPosition + 13, i, 1, j >> 16 & 255, j >> 8 & 255, j & 255,
|
||||
255);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.enableAlphaTest();
|
||||
GlStateManager.enableTexture();
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.enableDepthTest();
|
||||
}
|
||||
|
||||
if (stack.getCount() != 1 || text != null) {
|
||||
String s = text == null ? String.valueOf(stack.getCount()) : text;
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.disableDepthTest();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
int guiScaleFactor = (int) minecraft.mainWindow.getGuiScaleFactor();
|
||||
GlStateManager.translated((float) (xPosition + 16.5f), (float) (yPosition + 16.5f), 0);
|
||||
|
||||
double scale = 1;
|
||||
switch (guiScaleFactor) {
|
||||
case 1:
|
||||
scale = 2060 / 2048d;
|
||||
break;
|
||||
case 2:
|
||||
scale = .5;
|
||||
break;
|
||||
case 3:
|
||||
scale = .675;
|
||||
break;
|
||||
case 4:
|
||||
scale = .75;
|
||||
break;
|
||||
default:
|
||||
scale = ((float) guiScaleFactor - 1) / guiScaleFactor;
|
||||
}
|
||||
|
||||
GlStateManager.scaled(scale, scale, 0);
|
||||
GlStateManager.translated(-fr.getStringWidth(s) - (guiScaleFactor > 1 ? 0 : -.5f),
|
||||
-font.FONT_HEIGHT + (guiScaleFactor > 1 ? 1 : 1.75f), 0);
|
||||
fr.drawStringWithShadow(s, 0, 0, textColor);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.enableDepthTest();
|
||||
GlStateManager.enableBlend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void draw(BufferBuilder renderer, int x, int y, int width, int height, int red, int green, int blue,
|
||||
int alpha) {
|
||||
renderer.begin(7, DefaultVertexFormats.POSITION_COLOR);
|
||||
renderer.pos((double) (x + 0), (double) (y + 0), 0.0D).color(red, green, blue, alpha).endVertex();
|
||||
renderer.pos((double) (x + 0), (double) (y + height), 0.0D).color(red, green, blue, alpha).endVertex();
|
||||
renderer.pos((double) (x + width), (double) (y + height), 0.0D).color(red, green, blue, alpha).endVertex();
|
||||
renderer.pos((double) (x + width), (double) (y + 0), 0.0D).color(red, green, blue, alpha).endVertex();
|
||||
Tessellator.getInstance().draw();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
package com.simibubi.create.modules.logistics.management.index;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.AllPackets;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList;
|
||||
import com.simibubi.create.foundation.type.CountedItemsList.ItemStackEntry;
|
||||
import com.simibubi.create.modules.logistics.management.LogisticalNetwork;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalInventoryControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.index.IndexContainerUpdatePacket.Type;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.INBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.StringNBT;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class LogisticalIndexTileEntity extends LogisticalControllerTileEntity implements INamedContainerProvider {
|
||||
|
||||
// Server
|
||||
public int nextPush;
|
||||
public Set<ServerPlayerEntity> playersEntered = new HashSet<>();
|
||||
protected Set<ServerPlayerEntity> playersUsing = new HashSet<>();
|
||||
protected List<Pair<String, CountedItemsList>> controllersToUpdate = new LinkedList<>();
|
||||
|
||||
// Both
|
||||
public String lastOrderAddress = null;
|
||||
protected Map<String, CountedItemsList> controllers = new HashMap<>();
|
||||
|
||||
// Client
|
||||
public boolean update = false;
|
||||
public List<String> availableReceivers = new ArrayList<>();
|
||||
|
||||
public LogisticalIndexTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_INDEX.type);
|
||||
nextPush = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
if (lastOrderAddress != null)
|
||||
compound.putString("LastAdress", lastOrderAddress);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
if (compound.contains("LastAdress"))
|
||||
lastOrderAddress = compound.getString("LastAdress");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT writeToClient(CompoundNBT tag) {
|
||||
ListNBT receivers = new ListNBT();
|
||||
availableReceivers.forEach(s -> receivers.add(new StringNBT(s)));
|
||||
tag.put("Receivers", receivers);
|
||||
return super.writeToClient(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readClientUpdate(CompoundNBT tag) {
|
||||
availableReceivers.clear();
|
||||
for (INBT inbt : tag.getList("Receivers", NBT.TAG_STRING))
|
||||
availableReceivers.add(((StringNBT) inbt).getString());
|
||||
update = true;
|
||||
super.readClientUpdate(tag);
|
||||
}
|
||||
|
||||
public void syncReceivers() {
|
||||
if (network == null)
|
||||
return;
|
||||
availableReceivers.clear();
|
||||
for (LogisticalControllerTileEntity logisticalControllerTileEntity : network.receivers)
|
||||
availableReceivers.add(logisticalControllerTileEntity.getName());
|
||||
sendData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
super.initialize();
|
||||
syncReceivers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (nextPush == 1)
|
||||
pushItems();
|
||||
|
||||
if (nextPush > 0)
|
||||
nextPush--;
|
||||
}
|
||||
|
||||
@Override
|
||||
// Prevents the inherited TESR
|
||||
public double getMaxRenderDistanceSquared() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container createMenu(int id, PlayerInventory inv, PlayerEntity player) {
|
||||
return new LogisticalIndexContainer(id, inv, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName() {
|
||||
return new StringTextComponent(getType().getRegistryName().toString());
|
||||
}
|
||||
|
||||
public void sendToContainer(PacketBuffer buffer) {
|
||||
buffer.writeBlockPos(getPos());
|
||||
buffer.writeCompoundTag(getUpdateTag());
|
||||
}
|
||||
|
||||
public void addPlayer(ServerPlayerEntity player) {
|
||||
nextPush = 5;
|
||||
playersEntered.add(player);
|
||||
playersUsing.add(player);
|
||||
}
|
||||
|
||||
public void removePlayer(ServerPlayerEntity player) {
|
||||
playersUsing.remove(player);
|
||||
if (playersUsing.isEmpty())
|
||||
controllers.clear();
|
||||
}
|
||||
|
||||
public void handleUpdatedController(String address, CountedItemsList updates) {
|
||||
if (playersUsing.isEmpty())
|
||||
return;
|
||||
controllersToUpdate.add(Pair.of(address, updates));
|
||||
if (nextPush == 0)
|
||||
nextPush = 5;
|
||||
}
|
||||
|
||||
private void pushItems() {
|
||||
LogisticalNetwork network = this.getNetwork();
|
||||
if (network == null)
|
||||
return;
|
||||
|
||||
// First player to open
|
||||
if (!playersEntered.isEmpty() && playersUsing.size() == playersEntered.size()) {
|
||||
controllers.clear();
|
||||
for (LogisticalControllerTileEntity te : network.suppliers) {
|
||||
if (!(te instanceof LogisticalInventoryControllerTileEntity))
|
||||
continue;
|
||||
CountedItemsList allItems = ((LogisticalInventoryControllerTileEntity) te).getAllItems();
|
||||
controllers.put(te.getName(), allItems);
|
||||
}
|
||||
}
|
||||
|
||||
// Initial Packets
|
||||
if (!playersEntered.isEmpty()) {
|
||||
controllers.forEach((address, items) -> {
|
||||
for (ServerPlayerEntity player : playersUsing)
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new IndexContainerUpdatePacket(Type.INITIAL, address, items, pos));
|
||||
});
|
||||
playersEntered.clear();
|
||||
}
|
||||
|
||||
// pending Incremental Updates
|
||||
if (!playersUsing.isEmpty() && !controllersToUpdate.isEmpty()) {
|
||||
for (Pair<String, CountedItemsList> pair : controllersToUpdate) {
|
||||
CountedItemsList list = controllers.getOrDefault(pair.getKey(), new CountedItemsList());
|
||||
pair.getValue().getFlattenedList().forEach(list::add);
|
||||
}
|
||||
for (ServerPlayerEntity player : playersUsing)
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new IndexContainerUpdatePacket(Type.UPDATE, controllersToUpdate, pos));
|
||||
controllersToUpdate.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void index(List<Pair<String, CountedItemsList>> items) {
|
||||
items.forEach(pair -> {
|
||||
controllers.put(pair.getKey(), pair.getValue());
|
||||
});
|
||||
update = true;
|
||||
}
|
||||
|
||||
public void update(List<Pair<String, CountedItemsList>> items) {
|
||||
for (Pair<String, CountedItemsList> pair : items) {
|
||||
if (!controllers.containsKey(pair.getKey()))
|
||||
return;
|
||||
CountedItemsList list = controllers.get(pair.getKey());
|
||||
for (ItemStackEntry entry : pair.getValue().getFlattenedList()) {
|
||||
list.setItemCount(entry.stack, entry.amount);
|
||||
}
|
||||
}
|
||||
update = true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.simibubi.create.modules.logistics.packet;
|
||||
|
||||
import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket;
|
||||
import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateTileEntity;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"variants": {
|
||||
"active": {
|
||||
"true": {},
|
||||
"false": {}
|
||||
},
|
||||
"part": {
|
||||
"none": { "model": "create:block/logistical_casing" },
|
||||
"start": { "model": "create:block/logistical_casing_start" },
|
||||
"middle": { "model": "create:block/logistical_casing_middle" },
|
||||
"end": { "model": "create:block/logistical_casing_end" }
|
||||
},
|
||||
"axis": {
|
||||
"y": {},
|
||||
"x": { "x": 90, "y": 90 },
|
||||
"z": { "x": 270 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "create:block/logistical_controller"
|
||||
},
|
||||
"variants": {
|
||||
"type": {
|
||||
"storage": { },
|
||||
"calculation": { },
|
||||
"supply": { },
|
||||
"transactions": { },
|
||||
"request": { }
|
||||
},
|
||||
"facing": {
|
||||
"north": { "y": 180 },
|
||||
"south": { },
|
||||
"west": { "y": 90 },
|
||||
"up": { "x": 90 },
|
||||
"down": { "x": 270 },
|
||||
"east": { "y": 270 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"variants": {
|
||||
"type": {
|
||||
"storage": { "model": "create:block/logistical_controller_icon_storage" },
|
||||
"calculation": { "model": "create:block/logistical_controller_icon_calculation" },
|
||||
"supply": { "model": "create:block/logistical_controller_icon_supply" },
|
||||
"transactions": { "model": "create:block/logistical_controller_icon_transactions" },
|
||||
"request": { "model": "create:block/logistical_controller_icon_request" }
|
||||
},
|
||||
"facing": {
|
||||
"north": { "y": 180 },
|
||||
"south": { },
|
||||
"west": { "y": 90 },
|
||||
"up": { "x": 90 },
|
||||
"down": { "x": 270 },
|
||||
"east": { "y": 270 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "create:block/logistical_index"
|
||||
},
|
||||
"variants": {
|
||||
"facing": {
|
||||
"north": { "y": 180 },
|
||||
"south": { },
|
||||
"east": { "y": 270 },
|
||||
"west": { "y": 90 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -340,6 +340,10 @@
|
|||
"create.schematicannon.status.schematicNotPlaced": "Schematic not Deployed",
|
||||
"create.schematicannon.status.schematicExpired": "Schematic File Expired",
|
||||
|
||||
"create.gui.index.title": "Logistical Index",
|
||||
"create.gui.index.targetAddressSelect": "Destination Address",
|
||||
"create.gui.index.confirmOrder": "Confirm Order",
|
||||
|
||||
"create.tooltip.holdKey": "Hold [%1$s]",
|
||||
"create.tooltip.holdKeyOrKey": "Hold [%1$s] or [%2$s]",
|
||||
"create.tooltip.keyShift": "Shift",
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"brass_casing_side": "create:block/brass_casing_side",
|
||||
"brass_casing": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 1, 2, 1 ],
|
||||
"to": [ 15, 14, 15 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 2, 1, 14, 15 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 2, 1, 14, 15 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 2, 1, 14, 15 ], "rotation": 90 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 2, 1, 14, 15 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 0, 0 ],
|
||||
"to": [ 16, 2, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ] },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ] },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ] },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ] },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 14, 0 ],
|
||||
"to": [ 16, 16, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ] },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ] },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ] },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ] },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"brass_casing_side": "create:block/brass_casing_side",
|
||||
"brass_casing": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 1, 0, 1 ],
|
||||
"to": [ 15, 14, 15 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 2, 1, 16, 15 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 2, 1, 16, 15 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 2, 1, 16, 15 ], "rotation": 90 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 1, 14, 15 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 0, 0 ],
|
||||
"to": [ 2, 14, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 2, 0, 16, 2 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 2, 0, 16, 2 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 2, 0, 16, 2 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 2, 2 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 14, 2, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 14, 0, 0 ],
|
||||
"to": [ 16, 14, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 14, 0, 16, 2 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 14, 14, 16, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 14, 0, 14 ],
|
||||
"to": [ 16, 14, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 14, 14, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 14, 0, 16, 2 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 0, 14 ],
|
||||
"to": [ 2, 14, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 14, 2, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 2, 2 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 14, 0 ],
|
||||
"to": [ 16, 16, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
|
||||
"east": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
|
||||
"south": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
|
||||
"west": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"brass_casing_side": "create:block/brass_casing_side",
|
||||
"brass_casing": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 1, 0, 1 ],
|
||||
"to": [ 15, 16, 15 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 1, 16, 15 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 1, 16, 15 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 1, 16, 15 ], "rotation": 90 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 1, 16, 15 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 0, 0 ],
|
||||
"to": [ 2, 16, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 2, 2 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 14, 2, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 14, 0, 0 ],
|
||||
"to": [ 16, 16, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 14, 0, 16, 2 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 14, 14, 16, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 14, 0, 14 ],
|
||||
"to": [ 16, 16, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 14, 14, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 14, 0, 16, 2 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 0, 14 ],
|
||||
"to": [ 2, 16, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 0, 16, 2 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 14, 16, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 14, 2, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 2, 2 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"brass_casing_side": "create:block/brass_casing_side",
|
||||
"brass_casing": "create:block/brass_casing"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Center",
|
||||
"from": [ 1, 2, 1 ],
|
||||
"to": [ 15, 16, 15 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 1, 14, 15 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 1, 14, 15 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 1, 14, 15 ], "rotation": 90 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 2, 1, 16, 15 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 2, 0 ],
|
||||
"to": [ 2, 16, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 2, 0, 16, 2 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 2, 0, 16, 2 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 2, 0, 16, 2 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 2, 2 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 14, 2, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 14, 2, 0 ],
|
||||
"to": [ 16, 16, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 14, 0, 16, 2 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 14, 14, 16, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 14, 2, 14 ],
|
||||
"to": [ 16, 16, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 14, 14, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 14, 0, 16, 2 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 2, 14 ],
|
||||
"to": [ 2, 16, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 90 },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing_side", "uv": [ 0, 0, 14, 2 ], "rotation": 270 },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 14, 14, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 14, 2, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 2, 2 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 0, 0, 0 ],
|
||||
"to": [ 16, 2, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
|
||||
"east": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
|
||||
"south": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
|
||||
"west": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
|
||||
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"textures": {
|
||||
"particle": "create:block/logistical_controller",
|
||||
"logistical_controller": "create:block/logistical_controller"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Body",
|
||||
"from": [ 2, 2, -1 ],
|
||||
"to": [ 14, 14, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ] },
|
||||
"south": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ], "rotation": 180 },
|
||||
"up": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ], "rotation": 180 },
|
||||
"down": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"textures": {
|
||||
"logistical_controller": "create:block/logistical_controller",
|
||||
"logistical_icons_1": "create:block/logistical_icons_1"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 9, 2, 14, 7 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"textures": {
|
||||
"logistical_controller": "create:block/logistical_controller",
|
||||
"logistical_icons_1": "create:block/logistical_icons_1"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 9, 9, 14, 14 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"textures": {
|
||||
"logistical_controller": "create:block/logistical_controller",
|
||||
"logistical_icons_1": "create:block/logistical_icons_1"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 2, 2, 7, 7 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"textures": {
|
||||
"logistical_controller": "create:block/logistical_controller",
|
||||
"logistical_icons_1": "create:block/logistical_icons_1"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 2, 9, 7, 14 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:block/logistical_controller_icon_storage",
|
||||
"textures": {
|
||||
"logistical_icons_1": "create:block/logistical_icons_2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"redstone_antenna": "create:block/redstone_antenna_powered",
|
||||
"logistical_index_side_overlay": "create:block/logistical_index_side_overlay",
|
||||
"logistical_index_side": "create:block/logistical_index_side",
|
||||
"particle": "create:block/logistical_index_side"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Inner",
|
||||
"from": [ 3, 1, -1 ],
|
||||
"to": [ 13, 15, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#logistical_index_side", "uv": [ 0, 0, 10, 14 ] },
|
||||
"east": { "texture": "#logistical_index_side", "uv": [ 10, 0, 14, 14 ] },
|
||||
"south": { "texture": "#logistical_index_side", "uv": [ 0, 0, 10, 14 ] },
|
||||
"west": { "texture": "#logistical_index_side", "uv": [ 10, 0, 14, 14 ], "rotation": 180 },
|
||||
"up": { "texture": "#logistical_index_side", "uv": [ 12, 2, 16, 12 ], "rotation": 270 },
|
||||
"down": { "texture": "#logistical_index_side", "uv": [ 12, 2, 16, 12 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Overlay",
|
||||
"from": [ 2.99, 1, -1 ],
|
||||
"to": [ 13.01, 15, 3.01 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_index_side_overlay", "uv": [ 10, 0, 14.01, 14 ], "tintindex": 0 },
|
||||
"south": { "texture": "#logistical_index_side_overlay", "uv": [ 0, 0, 10.02, 14 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_index_side_overlay", "uv": [ 10, 0, 14.01, 14 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antenna stick",
|
||||
"from": [ 2, 11, 1 ],
|
||||
"to": [ 3, 18, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#redstone_antenna", "uv": [ 11, 3, 12, 10 ] },
|
||||
"east": { "texture": "#redstone_antenna", "uv": [ 11, 3, 12, 10 ] },
|
||||
"south": { "texture": "#redstone_antenna", "uv": [ 11, 3, 12, 10 ] },
|
||||
"west": { "texture": "#redstone_antenna", "uv": [ 11, 3, 12, 10 ] },
|
||||
"down": { "texture": "#redstone_antenna", "uv": [ 11, 9, 12, 10 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antenna Top",
|
||||
"from": [ 1, 18, 1 ],
|
||||
"to": [ 4, 21, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": { "texture": "#redstone_antenna", "uv": [ 10, 0, 13, 3 ], "tintindex": 0 },
|
||||
"south": { "texture": "#redstone_antenna", "uv": [ 10, 0, 13, 3 ], "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antenna Top2",
|
||||
"from": [ 2, 18, 0 ],
|
||||
"to": [ 3, 21, 3 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#redstone_antenna", "uv": [ 10, 0, 13, 3 ], "tintindex": 0 },
|
||||
"west": { "texture": "#redstone_antenna", "uv": [ 10, 0, 13, 3 ], "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Antenna TopFace",
|
||||
"from": [ 2, 19, 1 ],
|
||||
"to": [ 3, 20, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"up": { "texture": "#redstone_antenna", "uv": [ 11, 1, 12, 2 ], "tintindex": 0 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:item/cardboard_box_particle",
|
||||
"cardboard_box_1410": "create:item/cardboard_box_1410"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Box",
|
||||
"from": [ 1, 0, 1 ],
|
||||
"to": [ 15, 10, 15 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#cardboard_box_1410", "uv": [ 8, 8, 15, 13 ] },
|
||||
"east": { "texture": "#cardboard_box_1410", "uv": [ 1, 3, 8, 8 ] },
|
||||
"south": { "texture": "#cardboard_box_1410", "uv": [ 8, 8, 15, 13 ] },
|
||||
"west": { "texture": "#cardboard_box_1410", "uv": [ 1, 3, 8, 8 ] },
|
||||
"up": { "texture": "#cardboard_box_1410", "uv": [ 8, 1, 15, 8 ] },
|
||||
"down": { "texture": "#cardboard_box_1410", "uv": [ 1, 8, 8, 15 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:item/cardboard_box_particle",
|
||||
"cardboard_box_1416": "create:item/cardboard_box_1416"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Box",
|
||||
"from": [ 1, 0, 1 ],
|
||||
"to": [ 15, 16, 15 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#cardboard_box_1416", "uv": [ 8, 8, 15, 16 ] },
|
||||
"east": { "texture": "#cardboard_box_1416", "uv": [ 1, 0, 8, 8 ] },
|
||||
"south": { "texture": "#cardboard_box_1416", "uv": [ 8, 8, 15, 16 ] },
|
||||
"west": { "texture": "#cardboard_box_1416", "uv": [ 1, 0, 8, 8 ] },
|
||||
"up": { "texture": "#cardboard_box_1416", "uv": [ 8, 1, 15, 8 ] },
|
||||
"down": { "texture": "#cardboard_box_1416", "uv": [ 1, 8, 8, 15 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:item/cardboard_box_particle",
|
||||
"cardboard_box_1612": "create:item/cardboard_box_1612"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Box",
|
||||
"from": [ 0, 0, 0 ],
|
||||
"to": [ 16, 12, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#cardboard_box_1612", "uv": [ 8, 8, 16, 14 ] },
|
||||
"east": { "texture": "#cardboard_box_1612", "uv": [ 0, 2, 8, 8 ] },
|
||||
"south": { "texture": "#cardboard_box_1612", "uv": [ 8, 8, 16, 14 ] },
|
||||
"west": { "texture": "#cardboard_box_1612", "uv": [ 0, 2, 8, 8 ] },
|
||||
"up": { "texture": "#cardboard_box_1612", "uv": [ 8, 0, 16, 8 ] },
|
||||
"down": { "texture": "#cardboard_box_1612", "uv": [ 0, 8, 8, 16 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:item/cardboard_box_particle",
|
||||
"cardboard_box_1616": "create:item/cardboard_box_1616"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Box",
|
||||
"from": [ 0, 0, 0 ],
|
||||
"to": [ 16, 16, 16 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#cardboard_box_1616", "uv": [ 8, 8, 16, 16 ] },
|
||||
"east": { "texture": "#cardboard_box_1616", "uv": [ 0, 0, 8, 8 ] },
|
||||
"south": { "texture": "#cardboard_box_1616", "uv": [ 8, 8, 16, 16 ] },
|
||||
"west": { "texture": "#cardboard_box_1616", "uv": [ 0, 0, 8, 8 ] },
|
||||
"up": { "texture": "#cardboard_box_1616", "uv": [ 8, 0, 16, 8 ] },
|
||||
"down": { "texture": "#cardboard_box_1616", "uv": [ 0, 8, 8, 16 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "create:block/logistical_casing"
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/logistical_controller",
|
||||
"logistical_controller": "create:block/logistical_controller",
|
||||
"logistical_icons_1": "create:block/logistical_icons_1"
|
||||
},
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [ 30, 45, 0 ],
|
||||
"translation": [ 2.6, -1, 0 ],
|
||||
"scale": [ 0.625, 0.625, 0.625 ]
|
||||
},
|
||||
"ground": {
|
||||
"rotation": [ 0, 0, 0 ],
|
||||
"translation": [ 0, 3, 2 ],
|
||||
"scale": [ 0.25, 0.25, 0.25 ]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [ 0, 180, 0 ],
|
||||
"translation": [ 0, 0, -7 ],
|
||||
"scale": [ 0.625, 0.625, 0.625 ]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "create:item/logistical_controller",
|
||||
"elements": [
|
||||
{
|
||||
"name": "Body",
|
||||
"from": [ 2, 2, -1 ],
|
||||
"to": [ 14, 14, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ] },
|
||||
"south": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ], "rotation": 180 },
|
||||
"up": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ], "rotation": 180 },
|
||||
"down": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 9, 2, 14, 7 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "create:item/logistical_controller",
|
||||
"elements": [
|
||||
{
|
||||
"name": "Body",
|
||||
"from": [ 2, 2, -1 ],
|
||||
"to": [ 14, 14, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ] },
|
||||
"south": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ], "rotation": 180 },
|
||||
"up": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ], "rotation": 180 },
|
||||
"down": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 9, 9, 14, 14 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "create:item/logistical_controller",
|
||||
"elements": [
|
||||
{
|
||||
"name": "Body",
|
||||
"from": [ 2, 2, -1 ],
|
||||
"to": [ 14, 14, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ] },
|
||||
"south": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ], "rotation": 180 },
|
||||
"up": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ], "rotation": 180 },
|
||||
"down": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 2, 2, 7, 7 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "create:item/logistical_controller",
|
||||
"elements": [
|
||||
{
|
||||
"name": "Body",
|
||||
"from": [ 2, 2, -1 ],
|
||||
"to": [ 14, 14, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ] },
|
||||
"south": { "texture": "#logistical_controller", "uv": [ 0, 0, 12, 12 ] },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 12, 0, 16, 12 ], "rotation": 180 },
|
||||
"up": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ], "rotation": 180 },
|
||||
"down": { "texture": "#logistical_controller", "uv": [ 0, 12, 12, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Indicator",
|
||||
"from": [ 1.99, 3, 0 ],
|
||||
"to": [ 14.01, 13, 2 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "tintindex": 0 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 1, 15, 11 ], "rotation": 180, "tintindex": 0 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Icon",
|
||||
"from": [ 5, 5, 2.5 ],
|
||||
"to": [ 11, 11, 3.5 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"south": { "texture": "#logistical_icons_1", "uv": [ 2, 9, 7, 14 ], "tintindex": 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "create:item/logistical_controller_storage",
|
||||
"textures": {
|
||||
"logistical_icons_1": "create:block/logistical_icons_2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "create:item/logistical_dial",
|
||||
"layer1": "create:item/logistical_dial_overlay"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"parent": "create:block/logistical_index",
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [ 30, 45, 0 ],
|
||||
"translation": [ 2.6, -1, 0 ],
|
||||
"scale": [ 0.625, 0.625, 0.625 ]
|
||||
},
|
||||
"ground": {
|
||||
"rotation": [ 0, 0, 0 ],
|
||||
"translation": [ 0, 3, 2 ],
|
||||
"scale": [ 0.25, 0.25, 0.25 ]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [ 0, 180, 0 ],
|
||||
"translation": [ 0, 0, -7 ],
|
||||
"scale": [ 0.625, 0.625, 0.625 ]
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue