Lazy Logisticians
- Added a new Villager type for delivering packages - Added the Logisticians Table - Added Package Funnels - Added a generic colorable indicator tileentityrenderer
|
@ -20,7 +20,7 @@ archivesBaseName = 'create'
|
|||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||
|
||||
minecraft {
|
||||
mappings channel: 'snapshot', version: '20190927-1.14.3'
|
||||
mappings channel: 'snapshot', version: '20191008-1.14.3'
|
||||
|
||||
runs {
|
||||
client {
|
||||
|
@ -71,7 +71,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.1.22'
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.1.40'
|
||||
|
||||
// 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")
|
||||
|
|
|
@ -50,6 +50,8 @@ import com.simibubi.create.modules.logistics.management.base.LogisticalCasingBlo
|
|||
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.logistics.transport.villager.LogisticiansTableBlock;
|
||||
import com.simibubi.create.modules.logistics.transport.villager.PackageFunnelBlock;
|
||||
import com.simibubi.create.modules.palettes.GlassPaneBlock;
|
||||
import com.simibubi.create.modules.schematics.block.CreativeCrateBlock;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableBlock;
|
||||
|
@ -133,6 +135,9 @@ public enum AllBlocks {
|
|||
LOGISTICAL_CONTROLLER(new LogisticalControllerBlock()),
|
||||
LOGISTICAL_CONTROLLER_INDICATOR(new LogisticalControllerIndicatorBlock()),
|
||||
LOGISTICAL_INDEX(new LogisticalIndexBlock()),
|
||||
PACKAGE_FUNNEL(new PackageFunnelBlock()),
|
||||
LOGISTICIANS_TABLE(new LogisticiansTableBlock()),
|
||||
LOGISTICIANS_TABLE_INDICATOR(new RenderUtilityBlock()),
|
||||
|
||||
__CURIOSITIES__(),
|
||||
SYMMETRY_PLANE(new PlaneSymmetryBlock()),
|
||||
|
|
|
@ -2,8 +2,8 @@ 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 com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntityRenderer;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
|
|
|
@ -52,6 +52,9 @@ import com.simibubi.create.modules.logistics.management.controller.StorageTileEn
|
|||
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.logistics.transport.villager.LogisticiansTableTileEntity;
|
||||
import com.simibubi.create.modules.logistics.transport.villager.LogisticiansTableTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.transport.villager.PackageFunnelTileEntity;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonRenderer;
|
||||
import com.simibubi.create.modules.schematics.block.SchematicannonTileEntity;
|
||||
|
@ -111,7 +114,9 @@ public enum AllTileEntities {
|
|||
LOGISTICAL_CALCULATION_CONTROLLER(CalculationTileEntity::new, AllBlocks.LOGISTICAL_CONTROLLER),
|
||||
LOGISTICAL_TRANSATIONS_CONTROLLER(TransactionsTileEntity::new, AllBlocks.LOGISTICAL_CONTROLLER),
|
||||
LOGISTICAL_INDEX(LogisticalIndexTileEntity::new, AllBlocks.LOGISTICAL_INDEX),
|
||||
|
||||
LOGISTICIANS_TABLE(LogisticiansTableTileEntity::new, AllBlocks.LOGISTICIANS_TABLE),
|
||||
PACKAGE_FUNNEL(PackageFunnelTileEntity::new, AllBlocks.PACKAGE_FUNNEL),
|
||||
|
||||
// Curiosities
|
||||
WINDOW_IN_A_BLOCK(WindowInABlockTileEntity::new, AllBlocks.WINDOW_IN_A_BLOCK),
|
||||
|
||||
|
@ -125,6 +130,10 @@ public enum AllTileEntities {
|
|||
this.supplier = supplier;
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public boolean typeOf(TileEntity te) {
|
||||
return te.getType().equals(type);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onTileEntityRegistry(final RegistryEvent.Register<TileEntityType<?>> event) {
|
||||
|
@ -165,6 +174,7 @@ public enum AllTileEntities {
|
|||
bind(MechanicalPressTileEntity.class, new MechanicalPressTileEntityRenderer());
|
||||
bind(FlexpeaterTileEntity.class, new FlexpeaterTileEntityRenderer());
|
||||
bind(LogisticalControllerTileEntity.class, new LogisticalControllerTileEntityRenderer());
|
||||
bind(LogisticiansTableTileEntity.class, new LogisticiansTableTileEntityRenderer());
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
|
|
|
@ -7,13 +7,16 @@ 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.logistics.transport.villager.LogisticianHandler;
|
||||
import com.simibubi.create.modules.schematics.ServerSchematicLoader;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.merchant.villager.VillagerProfession;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.crafting.IRecipeSerializer;
|
||||
import net.minecraft.village.PointOfInterestType;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
@ -38,6 +41,7 @@ public class Create {
|
|||
public static FrequencyHandler frequencyHandler;
|
||||
public static MovingConstructHandler constructHandler;
|
||||
public static LogisticalNetworkHandler logisticalNetworkHandler;
|
||||
public static LogisticianHandler logisticianHandler;
|
||||
|
||||
public static ModConfig config;
|
||||
|
||||
|
@ -52,7 +56,7 @@ public class Create {
|
|||
frequencyHandler = new FrequencyHandler();
|
||||
constructHandler = new MovingConstructHandler();
|
||||
logisticalNetworkHandler = new LogisticalNetworkHandler();
|
||||
|
||||
|
||||
CraftingHelper.register(new ModuleLoadedCondition.Serializer());
|
||||
AllPackets.registerPackets();
|
||||
}
|
||||
|
@ -72,12 +76,22 @@ 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 registerVillagerProfessions(RegistryEvent.Register<VillagerProfession> event) {
|
||||
LogisticianHandler.registerVillagerProfessions(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerPointsOfInterest(RegistryEvent.Register<PointOfInterestType> event) {
|
||||
LogisticianHandler.registerPointsOfInterest(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void createConfigs(ModConfig.ModConfigEvent event) {
|
||||
if (event.getConfig().getSpec() == CreateClientConfig.specification)
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
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.data.EmptyModelData;
|
||||
|
||||
public class ColoredIndicatorRenderer extends BufferManipulator {
|
||||
|
||||
protected static Map<BlockState, ColoredIndicatorRenderer> cachedBuffers = new HashMap<>();
|
||||
|
||||
public ColoredIndicatorRenderer(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;
|
||||
}
|
||||
|
||||
public static <R extends ColoredIndicatorRenderer> void cacheIfMissing(BlockState renderedState,
|
||||
Function<ByteBuffer, R> factory) {
|
||||
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(Minecraft.getInstance().world, originalModel, renderedState,
|
||||
BlockPos.ZERO.down(), builder, true, random, 42, EmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
|
||||
cachedBuffers.put(renderedState, factory.apply(builder.getByteBuffer()));
|
||||
}
|
||||
}
|
||||
|
||||
public static ColoredIndicatorRenderer get(BlockState state) {
|
||||
cacheIfMissing(state, ColoredIndicatorRenderer::new);
|
||||
return cachedBuffers.get(state);
|
||||
}
|
||||
|
||||
|
||||
public static void invalidateCache() {
|
||||
cachedBuffers.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
package com.simibubi.create.modules.contraptions;
|
||||
|
||||
import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
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,8 +21,7 @@ public class CachedBufferReloader extends ReloadListener<String> {
|
|||
KineticTileEntityRenderer.invalidateCache();
|
||||
MechanicalPistonTileEntityRenderer.invalidateCache();
|
||||
MechanicalBearingTileEntityRenderer.invalidateCache();
|
||||
FlexpeaterTileEntityRenderer.invalidateCache();
|
||||
LogisticalControllerTileEntityRenderer.invalidateCache();
|
||||
ColoredIndicatorRenderer.invalidateCache();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FAC
|
|||
|
||||
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 com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
|
|
|
@ -12,7 +12,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.Slope;
|
||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
||||
import com.simibubi.create.modules.logistics.entity.CardboardBoxEntity;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
@ -141,7 +141,6 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
boolean slope = te.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL;
|
||||
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(entity);
|
||||
|
|
|
@ -3,7 +3,7 @@ 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 com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
|
@ -19,6 +19,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableTileEntity, IInventoryManipulator {
|
||||
|
||||
|
@ -99,21 +100,20 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
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);
|
||||
if (stack.isEmpty()) {
|
||||
if (!world.isRemote) {
|
||||
entity.remove();
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EAT, SoundCategory.BLOCKS, .125f, 1f);
|
||||
} 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, stack), entity.posX,
|
||||
entity.posY, entity.posZ, xSpeed, 1 / 6f, zSpeed);
|
||||
}
|
||||
return;
|
||||
stack = ItemHandlerHelper.insertItemStacked(inv, stack, false);
|
||||
|
||||
if (stack.isEmpty()) {
|
||||
if (!world.isRemote) {
|
||||
entity.remove();
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EAT, SoundCategory.BLOCKS, .125f, 1f);
|
||||
} 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, stack), entity.posX,
|
||||
entity.posY, entity.posZ, xSpeed, 1 / 6f, zSpeed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
waitingForInventorySpace = true;
|
||||
|
|
|
@ -1,87 +1,28 @@
|
|||
package com.simibubi.create.modules.logistics.block.diodes;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Random;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
|
||||
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 FlexpeaterTileEntityRenderer extends TileEntityRendererFast<FlexpeaterTileEntity> {
|
||||
|
||||
protected class FlexpeaterIndicatorRenderer extends BufferManipulator {
|
||||
|
||||
public FlexpeaterIndicatorRenderer(ByteBuffer original) {
|
||||
super(original);
|
||||
}
|
||||
|
||||
public ByteBuffer getTransformed(float xIn, float yIn, float zIn, float colorModifier, int packedLightCoords) {
|
||||
original.rewind();
|
||||
mutable.rewind();
|
||||
|
||||
int color = ColorHelper.mixColors(0x2C0300, 0xCD0000, colorModifier);
|
||||
|
||||
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 FlexpeaterIndicatorRenderer cachedIndicator;
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(FlexpeaterTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
BlockPos pos = te.getPos();
|
||||
|
||||
if (cachedIndicator == null) {
|
||||
BlockState renderedState = AllBlocks.FLEXPEATER_INDICATOR.get().getDefaultState();
|
||||
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();
|
||||
|
||||
cachedIndicator = new FlexpeaterIndicatorRenderer(builder.getByteBuffer());
|
||||
}
|
||||
|
||||
BlockState renderedState = AllBlocks.FLEXPEATER_INDICATOR.get().getDefaultState();
|
||||
BlockState blockState = te.getBlockState();
|
||||
int color = ColorHelper.mixColors(0x2C0300, 0xCD0000, te.state / (float) te.maxState);
|
||||
int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), pos);
|
||||
buffer.putBulkData(cachedIndicator.getTransformed((float) x, (float) y, (float) z,
|
||||
te.state / (float) te.maxState, packedLightmapCoords));
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
cachedIndicator = null;
|
||||
buffer.putBulkData(ColoredIndicatorRenderer.get(renderedState).getTransformed((float) x, (float) y, (float) z,
|
||||
color, packedLightmapCoords));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
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 com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity;
|
||||
|
||||
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.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
|
@ -30,7 +27,7 @@ public class LogisticalDialItem extends Item implements IItemWithColorHandler {
|
|||
public IItemColor getColorHandler() {
|
||||
return (stack, layer) -> {
|
||||
if (layer == 1 && stack.getOrCreateTag().contains("NetworkIDLeast"))
|
||||
return LogisticalControllerTileEntity.colorFromUUID(stack.getTag().getUniqueId("NetworkID"));
|
||||
return LogisticalActorTileEntity.colorFromUUID(stack.getTag().getUniqueId("NetworkID"));
|
||||
return 0xFFFFFF;
|
||||
};
|
||||
}
|
||||
|
@ -48,8 +45,9 @@ public class LogisticalDialItem extends Item implements IItemWithColorHandler {
|
|||
|
||||
if (!context.getPlayer().isAllowEdit())
|
||||
return super.onItemUse(context);
|
||||
BlockState blockState = context.getWorld().getBlockState(context.getPos());
|
||||
if (!LOGISTICAL_CONTROLLER.typeOf(blockState) && !LOGISTICAL_INDEX.typeOf(blockState)) {
|
||||
|
||||
TileEntity te = context.getWorld().getTileEntity(context.getPos());
|
||||
if (!(te instanceof LogisticalActorTileEntity)) {
|
||||
if (context.isPlacerSneaking()) {
|
||||
if (!isRemote)
|
||||
heldItem.getTag().putUniqueId("NetworkID", UUID.randomUUID());
|
||||
|
@ -59,8 +57,7 @@ public class LogisticalDialItem extends Item implements IItemWithColorHandler {
|
|||
return super.onItemUse(context);
|
||||
}
|
||||
|
||||
LogisticalControllerTileEntity tileEntity = (LogisticalControllerTileEntity) context.getWorld()
|
||||
.getTileEntity(context.getPos());
|
||||
LogisticalActorTileEntity tileEntity = (LogisticalActorTileEntity) te;
|
||||
if (context.isPlacerSneaking()) {
|
||||
if (!isRemote)
|
||||
heldItem.getTag().putUniqueId("NetworkID", tileEntity.getNetworkId());
|
||||
|
|
|
@ -2,29 +2,36 @@ package com.simibubi.create.modules.logistics.management;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity;
|
||||
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.StorageTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.TransactionsTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.index.LogisticalIndexTileEntity;
|
||||
import com.simibubi.create.modules.logistics.transport.villager.PackageFunnelTileEntity;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class LogisticalNetwork {
|
||||
|
||||
public List<TransactionsTileEntity> taskQueues = new ArrayList<>();
|
||||
public List<LogisticalIndexTileEntity> indexers = new ArrayList<>();
|
||||
public Set<PackageFunnelTileEntity> packageTargets = new HashSet<>();
|
||||
public PriorityQueue<LogisticalTask> internalTaskQueue = new PriorityQueue<>();
|
||||
public PriorityQueue<LogisticalControllerTileEntity> suppliers = new PriorityQueue<>();
|
||||
public PriorityQueue<LogisticalControllerTileEntity> receivers = new PriorityQueue<>();
|
||||
public PriorityQueue<LogisticalActorTileEntity> suppliers = new PriorityQueue<>();
|
||||
public PriorityQueue<LogisticalActorTileEntity> receivers = new PriorityQueue<>();
|
||||
public int participants = 0;
|
||||
public boolean tasksUpdated;
|
||||
|
||||
public void addController(LogisticalControllerTileEntity te) {
|
||||
public void addController(LogisticalActorTileEntity te) {
|
||||
if (te instanceof TransactionsTileEntity) {
|
||||
if (taskQueues.contains(te))
|
||||
return;
|
||||
|
@ -49,11 +56,19 @@ public class LogisticalNetwork {
|
|||
participants++;
|
||||
}
|
||||
|
||||
public void addPackageTarget(PackageFunnelTileEntity te) {
|
||||
packageTargets.add(te);
|
||||
}
|
||||
|
||||
public void removePackageTarget(PackageFunnelTileEntity te) {
|
||||
packageTargets.remove(te);
|
||||
}
|
||||
|
||||
public void reAdvertiseReceivers() {
|
||||
indexers.forEach(LogisticalIndexTileEntity::syncReceivers);
|
||||
}
|
||||
|
||||
public void removeController(LogisticalControllerTileEntity te) {
|
||||
public void removeController(LogisticalActorTileEntity te) {
|
||||
if (te instanceof TransactionsTileEntity)
|
||||
if (!taskQueues.remove((TransactionsTileEntity) te))
|
||||
return;
|
||||
|
@ -77,56 +92,63 @@ public class LogisticalNetwork {
|
|||
|
||||
public void enqueueTask(LogisticalTask task) {
|
||||
internalTaskQueue.add(task);
|
||||
|
||||
Minecraft.getInstance().player.sendMessage(new StringTextComponent(internalTaskQueue.toString()));
|
||||
|
||||
if (task instanceof SupplyTask)
|
||||
suppliers.forEach(LogisticalControllerTileEntity::notifyTaskUpdate);
|
||||
suppliers.forEach(LogisticalActorTileEntity::notifyTaskUpdate);
|
||||
if (task instanceof DepositTask)
|
||||
receivers.forEach(LogisticalControllerTileEntity::notifyTaskUpdate);
|
||||
receivers.forEach(LogisticalActorTileEntity::notifyTaskUpdate);
|
||||
}
|
||||
|
||||
public String getNextAvailableAddress(LogisticalControllerTileEntity te) {
|
||||
public String getNextAvailableAddress(LogisticalActorTileEntity te) {
|
||||
Predicate<String> isTaken = s -> false;
|
||||
String prefix = "";
|
||||
|
||||
if (te instanceof TransactionsTileEntity) {
|
||||
prefix = "Task Manager ";
|
||||
prefix = "Task Manager";
|
||||
isTaken = s -> isNameTaken(taskQueues, s);
|
||||
}
|
||||
|
||||
else if (te instanceof LogisticalIndexTileEntity) {
|
||||
prefix = "Index ";
|
||||
prefix = "Index";
|
||||
isTaken = s -> isNameTaken(indexers, s);
|
||||
}
|
||||
|
||||
else if (te instanceof StorageTileEntity) {
|
||||
prefix = "Storage ";
|
||||
prefix = "Storage";
|
||||
isTaken = s -> isNameTaken(suppliers, s);
|
||||
}
|
||||
|
||||
|
||||
else if (te.isSupplier()) {
|
||||
prefix = "Supply ";
|
||||
prefix = "Supply";
|
||||
isTaken = s -> isNameTaken(suppliers, s);
|
||||
}
|
||||
|
||||
else if (te.isReceiver()) {
|
||||
prefix = "Request ";
|
||||
prefix = "Request";
|
||||
isTaken = s -> isNameTaken(receivers, s);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
String name;
|
||||
do {
|
||||
name = prefix + (i == 0 ? "" : i);
|
||||
name = prefix + (i == 0 ? "" : " " + i);
|
||||
i++;
|
||||
} while (isTaken.test(name));
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private static <T extends LogisticalControllerTileEntity> boolean isNameTaken(Collection<T> list, String name) {
|
||||
private static <T extends LogisticalActorTileEntity> boolean isNameTaken(Collection<T> list, String name) {
|
||||
for (T controller : list)
|
||||
if (controller.address.equals(name))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean matchAddresses(String addr1, String addr2) {
|
||||
return addr1.toLowerCase().equals(addr2.toLowerCase());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity;
|
||||
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class LogisticalNetworkHandler {
|
|||
Create.logger.debug("Removed Logistical Network Map for " + world.getDimension().getType().getRegistryName());
|
||||
}
|
||||
|
||||
public LogisticalNetwork handleAdded(LogisticalControllerTileEntity te) {
|
||||
public LogisticalNetwork handleAdded(LogisticalActorTileEntity te) {
|
||||
LogisticalNetwork networkByID = getNetworkByID(te.getWorld(), te.getNetworkId());
|
||||
if (te.address == null || te.address.isEmpty()) {
|
||||
te.address = networkByID.getNextAvailableAddress(te);
|
||||
|
@ -33,7 +33,7 @@ public class LogisticalNetworkHandler {
|
|||
return networkByID;
|
||||
}
|
||||
|
||||
public void handleRemoved(LogisticalControllerTileEntity te) {
|
||||
public void handleRemoved(LogisticalActorTileEntity te) {
|
||||
getNetworkByID(te.getWorld(), te.getNetworkId()).removeController(te);
|
||||
removeIfEmpty(te.getWorld(), te.getNetworkId());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
public interface ILogisticalCasingAttachment {
|
||||
|
||||
public void onCasingUpdated(IWorld world, BlockPos pos, @Nullable LogisticalCasingTileEntity te);
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
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,150 @@
|
|||
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 LogisticalActorTileEntity extends SyncedTileEntity
|
||||
implements Comparable<LogisticalActorTileEntity>, ITickableTileEntity {
|
||||
|
||||
public static final int COOLDOWN = 20;
|
||||
|
||||
public Priority priority = Priority.LOW;
|
||||
public String address = "";
|
||||
|
||||
protected LogisticalNetwork network;
|
||||
protected UUID networkId;
|
||||
protected boolean initialize;
|
||||
protected boolean checkTasks;
|
||||
protected int taskCooldown;
|
||||
|
||||
public LogisticalActorTileEntity(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 notifyTaskUpdate() {
|
||||
checkTasks = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
if (networkId != null)
|
||||
compound.putUniqueId("NetworkID", networkId);
|
||||
compound.putString("Address", address);
|
||||
compound.putInt("Priority", priority.ordinal());
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
public UUID getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
if (compound.contains("NetworkIDLeast"))
|
||||
networkId = compound.getUniqueId("NetworkID");
|
||||
address = compound.getString("Address");
|
||||
priority = Priority.values()[compound.getInt("Priority")];
|
||||
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(LogisticalActorTileEntity o) {
|
||||
return this.priority.compareTo(o.priority);
|
||||
}
|
||||
|
||||
public LogisticalNetwork getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public Priority getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public static enum Priority {
|
||||
HIGHEST, HIGH, LOWEST, LOW;
|
||||
}
|
||||
|
||||
}
|
|
@ -11,6 +11,7 @@ import com.simibubi.create.AllTileEntities;
|
|||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
|
@ -60,7 +61,7 @@ public class LogisticalCasingTileEntity extends SyncedTileEntity {
|
|||
public void neighbourChanged(BlockPos neighbour) {
|
||||
if (!controllerPresent())
|
||||
return;
|
||||
for (LogisticalControllerTileEntity controller : getControllers()) {
|
||||
for (LogisticalActorTileEntity controller : getControllers()) {
|
||||
if (!(controller instanceof LogisticalInventoryControllerTileEntity))
|
||||
continue;
|
||||
((LogisticalInventoryControllerTileEntity) controller).inventoryChanged(neighbour);
|
||||
|
@ -86,18 +87,29 @@ public class LogisticalCasingTileEntity extends SyncedTileEntity {
|
|||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (!(tileEntity instanceof LogisticalInventoryControllerTileEntity))
|
||||
return;
|
||||
for (Direction facing : Direction.values())
|
||||
for (Direction facing : Direction.values()) {
|
||||
((LogisticalInventoryControllerTileEntity) tileEntity).detachInventory(getPos().offset(facing));
|
||||
notifyAttachments(facing);
|
||||
}
|
||||
}
|
||||
|
||||
public void attachController(BlockPos pos) {
|
||||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (!(tileEntity instanceof LogisticalControllerTileEntity))
|
||||
if (!(tileEntity instanceof LogisticalInventoryControllerTileEntity))
|
||||
return;
|
||||
for (Direction facing : Direction.values())
|
||||
for (Direction facing : Direction.values()) {
|
||||
((LogisticalInventoryControllerTileEntity) tileEntity).inventoryChanged(getPos().offset(facing));
|
||||
notifyAttachments(facing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void notifyAttachments(Direction d) {
|
||||
BlockPos offset = pos.offset(d);
|
||||
Block block = world.getBlockState(offset).getBlock();
|
||||
if (block instanceof ILogisticalCasingAttachment)
|
||||
((ILogisticalCasingAttachment) block).onCasingUpdated(world, offset, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
controllers.forEach(this::detachController);
|
||||
|
@ -108,7 +120,7 @@ public class LogisticalCasingTileEntity extends SyncedTileEntity {
|
|||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (!controllerPresent())
|
||||
return LazyOptional.empty();
|
||||
List<LogisticalControllerTileEntity> TEs = getControllers();
|
||||
List<LogisticalActorTileEntity> TEs = getControllers();
|
||||
if (controllers.isEmpty())
|
||||
return LazyOptional.empty();
|
||||
List<T> invs = TEs.stream().map(te -> te.getCasingCapability(cap, side).orElse(null))
|
||||
|
@ -119,12 +131,12 @@ public class LogisticalCasingTileEntity extends SyncedTileEntity {
|
|||
return LazyOptional.of(() -> new CombinedInvWrapper(params)).cast();
|
||||
}
|
||||
|
||||
public List<LogisticalControllerTileEntity> getControllers() {
|
||||
List<LogisticalControllerTileEntity> TEs = new ArrayList<>(controllers.size());
|
||||
public List<LogisticalActorTileEntity> getControllers() {
|
||||
List<LogisticalActorTileEntity> TEs = new ArrayList<>(controllers.size());
|
||||
for (BlockPos controllerPos : controllers) {
|
||||
TileEntity tileEntity = world.getTileEntity(controllerPos);
|
||||
if (tileEntity instanceof LogisticalControllerTileEntity)
|
||||
TEs.add((LogisticalControllerTileEntity) tileEntity);
|
||||
if (tileEntity instanceof LogisticalActorTileEntity)
|
||||
TEs.add((LogisticalActorTileEntity) tileEntity);
|
||||
}
|
||||
return TEs;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package com.simibubi.create.modules.logistics.management.base;
|
||||
|
||||
import static com.simibubi.create.AllItems.LOGISTICAL_CONTROLLER_CALCULATION;
|
||||
import static com.simibubi.create.AllItems.LOGISTICAL_CONTROLLER_REQUEST;
|
||||
import static com.simibubi.create.AllItems.LOGISTICAL_CONTROLLER_STORAGE;
|
||||
import static com.simibubi.create.AllItems.LOGISTICAL_CONTROLLER_SUPPLY;
|
||||
import static com.simibubi.create.AllItems.LOGISTICAL_CONTROLLER_TRANSACTIONS;
|
||||
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.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -43,6 +49,7 @@ 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.RayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
@ -52,7 +59,7 @@ import net.minecraft.world.World;
|
|||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
public class LogisticalControllerBlock extends DirectionalBlock
|
||||
implements IWithoutBlockItem, IWithTileEntity<LogisticalControllerTileEntity> {
|
||||
implements IWithoutBlockItem, IWithTileEntity<LogisticalActorTileEntity> {
|
||||
|
||||
public static final IProperty<Type> TYPE = EnumProperty.create("type", Type.class);
|
||||
|
||||
|
@ -121,6 +128,27 @@ public class LogisticalControllerBlock extends DirectionalBlock
|
|||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
|
||||
PlayerEntity player) {
|
||||
return getItem(world, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getDrops(BlockState state, net.minecraft.world.storage.loot.LootContext.Builder builder) {
|
||||
return Arrays.asList(getItem(builder.getWorld(), BlockPos.ZERO, state));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem(IBlockReader worldIn, BlockPos pos, BlockState state) {
|
||||
for (AllItems item : Arrays.asList(LOGISTICAL_CONTROLLER_CALCULATION, LOGISTICAL_CONTROLLER_REQUEST,
|
||||
LOGISTICAL_CONTROLLER_STORAGE, LOGISTICAL_CONTROLLER_SUPPLY, LOGISTICAL_CONTROLLER_TRANSACTIONS)) {
|
||||
if (((LogisticalControllerItem) item.get()).getType() == state.get(TYPE))
|
||||
return item.asStack();
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) {
|
||||
Direction facing = state.get(FACING);
|
||||
|
|
|
@ -1,155 +1,16 @@
|
|||
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;
|
||||
|
||||
public Priority priority = Priority.LOW;
|
||||
public String address = "";
|
||||
|
||||
protected LogisticalNetwork network;
|
||||
protected UUID networkId;
|
||||
protected boolean initialize;
|
||||
protected boolean checkTasks;
|
||||
protected int taskCooldown;
|
||||
public abstract class LogisticalControllerTileEntity extends LogisticalActorTileEntity {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@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", address);
|
||||
compound.putInt("Priority", priority.ordinal());
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
public UUID getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
if (compound.contains("NetworkIDLeast"))
|
||||
networkId = compound.getUniqueId("NetworkID");
|
||||
address = compound.getString("Address");
|
||||
priority = Priority.values()[compound.getInt("Priority")];
|
||||
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 Priority getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public static enum Priority {
|
||||
HIGHEST, HIGH, LOWEST, LOW;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,92 +3,26 @@ 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 com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
|
||||
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<>();
|
||||
public class LogisticalControllerTileEntityRenderer extends TileEntityRendererFast<LogisticalActorTileEntity> {
|
||||
|
||||
@Override
|
||||
public void renderTileEntityFast(LogisticalControllerTileEntity te, double x, double y, double z,
|
||||
public void renderTileEntityFast(LogisticalActorTileEntity 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,
|
||||
buffer.putBulkData(ColoredIndicatorRenderer.get(renderedState).getTransformed((float) x, (float) y, (float) z,
|
||||
te.getColor(), packedLightmapCoords));
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
cachedBuffers.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,12 +26,19 @@ public abstract class LogisticalTask implements Comparable<LogisticalTask> {
|
|||
|
||||
public static class SupplyTask extends LogisticalTask {
|
||||
public List<Pair<Ingredient, Integer>> items;
|
||||
private String display;
|
||||
|
||||
public SupplyTask(ItemStackEntry requested, String address) {
|
||||
items = Arrays.asList(Pair.of(Ingredient.fromStacks(requested.stack), requested.amount));
|
||||
targetAddress = address;
|
||||
display = "Supply " + requested.amount + "x " + requested.stack.getItem().getName().getFormattedText()
|
||||
+ " -> " + address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return display;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DepositTask extends LogisticalTask {
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
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;
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.simibubi.create.modules.logistics.management.controller;
|
||||
|
||||
import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity.Priority;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity.Priority;
|
||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity.ShippingInventory;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
|
|
|
@ -31,7 +31,7 @@ import com.simibubi.create.foundation.utility.ColorHelper;
|
|||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock.Type;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity.Priority;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity.Priority;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
|
|
|
@ -18,6 +18,7 @@ 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.LogisticalNetwork;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalCasingTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerBlock;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
|
@ -349,9 +350,9 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical
|
|||
|
||||
public class ShippingInventory extends ItemStackHandler {
|
||||
|
||||
static final int SHIPPING = 0;
|
||||
static final int RECEIVING = 1;
|
||||
static final int FILTER = 2;
|
||||
public static final int SHIPPING = 0;
|
||||
public static final int RECEIVING = 1;
|
||||
public static final int FILTER = 2;
|
||||
int filterAmount = 0;
|
||||
|
||||
boolean ships;
|
||||
|
@ -402,10 +403,22 @@ public abstract class LogisticalInventoryControllerTileEntity extends Logistical
|
|||
protected void onContentsChanged(int slot) {
|
||||
super.onContentsChanged(slot);
|
||||
markDirty();
|
||||
boolean empty = getStackInSlot(slot).isEmpty();
|
||||
|
||||
if (slot == RECEIVING && !getStackInSlot(slot).isEmpty())
|
||||
if (slot == RECEIVING && !empty)
|
||||
tryInsertBox = true;
|
||||
if (slot == SHIPPING && getStackInSlot(slot).isEmpty())
|
||||
|
||||
if (slot == RECEIVING && empty) {
|
||||
if (getNetwork() != null) {
|
||||
getNetwork().packageTargets.forEach(target -> {
|
||||
if (target.getAddressList().stream()
|
||||
.anyMatch(e -> LogisticalNetwork.matchAddresses(e, address)))
|
||||
target.slotOpened();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (slot == SHIPPING && empty)
|
||||
checkTasks = true;
|
||||
|
||||
BlockPos start = pos.offset(getBlockState().get(FACING).getOpposite());
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.simibubi.create.modules.logistics.management.controller;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity;
|
||||
|
||||
public class TransactionsTileEntity extends LogisticalControllerTileEntity {
|
||||
public class TransactionsTileEntity extends LogisticalActorTileEntity {
|
||||
|
||||
public TransactionsTileEntity() {
|
||||
super(AllTileEntities.LOGISTICAL_TRANSATIONS_CONTROLLER.type);
|
||||
|
|
|
@ -49,6 +49,7 @@ import net.minecraft.entity.player.PlayerInventory;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class LogisticalIndexScreen extends AbstractSimiContainerScreen<LogisticalIndexContainer> {
|
||||
|
||||
|
@ -201,6 +202,8 @@ public class LogisticalIndexScreen extends AbstractSimiContainerScreen<Logistica
|
|||
}
|
||||
|
||||
private void onReceiverScrollInputChanged(int index) {
|
||||
if (receivers.isEmpty())
|
||||
return;
|
||||
String address = receivers.get(index);
|
||||
receiverTextField.func_212954_a(null);
|
||||
receiverTextField.setSuggestion(null);
|
||||
|
@ -239,7 +242,7 @@ public class LogisticalIndexScreen extends AbstractSimiContainerScreen<Logistica
|
|||
|
||||
@Override
|
||||
public void mouseMoved(double xPos, double yPos) {
|
||||
|
||||
cursorActive = false;
|
||||
super.mouseMoved(xPos, yPos);
|
||||
}
|
||||
|
||||
|
@ -469,7 +472,7 @@ public class LogisticalIndexScreen extends AbstractSimiContainerScreen<Logistica
|
|||
int slot = 0;
|
||||
for (ItemStackEntry entry : displayedItems) {
|
||||
resetColor();
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
|
||||
renderSlot(slot, entry.stack, entry.amount);
|
||||
slot++;
|
||||
}
|
||||
|
@ -481,6 +484,7 @@ public class LogisticalIndexScreen extends AbstractSimiContainerScreen<Logistica
|
|||
|
||||
// boolean ordered = order.contains(stack);
|
||||
boolean orderedFully = order.getItemCount(stack) == count;
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
|
||||
if (orderedFully) {
|
||||
DISABLED_SLOT_FRAME.draw(this, slotX, slotY);
|
||||
|
@ -497,6 +501,7 @@ public class LogisticalIndexScreen extends AbstractSimiContainerScreen<Logistica
|
|||
slotX++;
|
||||
slotY++;
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translatef(0.0F, 0.0F, 32.0F);
|
||||
this.blitOffset = 200;
|
||||
|
@ -509,8 +514,8 @@ public class LogisticalIndexScreen extends AbstractSimiContainerScreen<Logistica
|
|||
String text = count > 1 ? String.valueOf(count) : null;
|
||||
int color = 0xFFFFFF;
|
||||
if (orderedFully) {
|
||||
color = ColorHelper.mixColors(container.te.getColor(), 0, 0.5f);
|
||||
text = "\\u2714";
|
||||
color = ColorHelper.mixColors(container.te.getColor(), 0xFFFFFF, 0.5f);
|
||||
text = new StringTextComponent("\u2714").getFormattedText();
|
||||
}
|
||||
|
||||
this.renderItemOverlayIntoGUI(font, stack, slotX, slotY, text, color);
|
||||
|
|
|
@ -15,7 +15,7 @@ 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.LogisticalActorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.index.IndexContainerUpdatePacket.Type;
|
||||
|
||||
|
@ -34,7 +34,7 @@ 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 {
|
||||
public class LogisticalIndexTileEntity extends LogisticalActorTileEntity implements INamedContainerProvider {
|
||||
|
||||
// Server
|
||||
public int nextPush;
|
||||
|
@ -90,7 +90,7 @@ public class LogisticalIndexTileEntity extends LogisticalControllerTileEntity im
|
|||
if (network == null)
|
||||
return;
|
||||
availableReceivers.clear();
|
||||
for (LogisticalControllerTileEntity logisticalControllerTileEntity : network.receivers)
|
||||
for (LogisticalActorTileEntity logisticalControllerTileEntity : network.receivers)
|
||||
availableReceivers.add(logisticalControllerTileEntity.address);
|
||||
sendData();
|
||||
}
|
||||
|
@ -112,12 +112,6 @@ public class LogisticalIndexTileEntity extends LogisticalControllerTileEntity im
|
|||
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);
|
||||
|
@ -161,7 +155,7 @@ public class LogisticalIndexTileEntity extends LogisticalControllerTileEntity im
|
|||
// First player to open
|
||||
if (!playersEntered.isEmpty() && playersUsing.size() == playersEntered.size()) {
|
||||
controllers.clear();
|
||||
for (LogisticalControllerTileEntity te : network.suppliers) {
|
||||
for (LogisticalActorTileEntity te : network.suppliers) {
|
||||
if (!(te instanceof LogisticalInventoryControllerTileEntity))
|
||||
continue;
|
||||
CountedItemsList allItems = ((LogisticalInventoryControllerTileEntity) te).getAllItems();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.entity;
|
||||
package com.simibubi.create.modules.logistics.transport;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
|
@ -10,6 +10,8 @@ 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.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntitySize;
|
||||
import net.minecraft.entity.EntityType;
|
||||
|
@ -17,6 +19,7 @@ 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.item.minecart.MinecartEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.AbstractArrowEntity;
|
||||
import net.minecraft.inventory.EquipmentSlotType;
|
||||
|
@ -26,8 +29,11 @@ import net.minecraft.network.IPacket;
|
|||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.HandSide;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
|
@ -79,8 +85,15 @@ public class CardboardBoxEntity extends LivingEntity implements IEntityAdditiona
|
|||
extractorAnimationProgress = 20;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return box.getTag().getString("Address");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (extractorAnimationProgress == 0) {
|
||||
setMotion(new Vec3d(extractorSide.getDirectionVec()).scale(1 / 16f).add(0, 1 / 32f, 0));
|
||||
}
|
||||
if (extractorAnimationProgress > -1) {
|
||||
extractorAnimationProgress--;
|
||||
return;
|
||||
|
@ -117,10 +130,137 @@ public class CardboardBoxEntity extends LivingEntity implements IEntityAdditiona
|
|||
recalculateSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getCollisionBoundingBox() {
|
||||
return this.getBoundingBox();
|
||||
return getBoundingBox(getPose()).grow(-.1f, 0, -.1f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBePushed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getCollisionBox(Entity entityIn) {
|
||||
if (entityIn instanceof CardboardBoxEntity)
|
||||
return getBoundingBox();
|
||||
if (entityIn instanceof MinecartEntity)
|
||||
return null;
|
||||
return super.getCollisionBox(entityIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeCollidedWith() {
|
||||
return isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyEntityCollision(Entity entityIn) {
|
||||
if (entityIn instanceof CardboardBoxEntity) {
|
||||
if (entityIn.getBoundingBox().minY < this.getBoundingBox().maxY) {
|
||||
super.applyEntityCollision(entityIn);
|
||||
}
|
||||
} else if (entityIn.getBoundingBox().minY <= this.getBoundingBox().minY) {
|
||||
super.applyEntityCollision(entityIn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType applyPlayerInteraction(PlayerEntity player, Vec3d vec, Hand hand) {
|
||||
return super.applyPlayerInteraction(player, vec, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processInitialInteract(PlayerEntity player, Hand hand) {
|
||||
if (player.getPassengers().isEmpty()) {
|
||||
startRiding(player);
|
||||
return true;
|
||||
} else {
|
||||
for (Entity e : player.getPassengers()) {
|
||||
while (e instanceof CardboardBoxEntity) {
|
||||
if (e == this)
|
||||
return false;
|
||||
if (e.getPassengers().isEmpty()) {
|
||||
startRiding(e);
|
||||
return false;
|
||||
}
|
||||
e = e.getPassengers().get(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super.processInitialInteract(player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRidden() {
|
||||
super.updateRidden();
|
||||
Entity ridingEntity = getRidingEntity();
|
||||
if (ridingEntity instanceof LivingEntity) {
|
||||
|
||||
if (!(ridingEntity instanceof CardboardBoxEntity)) {
|
||||
Vec3d front = VecHelper.rotate(new Vec3d(1, 0, 0), -90 - ridingEntity.getRotationYawHead(), Axis.Y);
|
||||
double x = ridingEntity.posX + front.x;
|
||||
double y = ridingEntity.posY + ridingEntity.getMountedYOffset() / 2 + this.getYOffset();
|
||||
double z = ridingEntity.posZ + front.z;
|
||||
|
||||
prevRotationYaw = rotationYaw;
|
||||
setRotation(-ridingEntity.rotationYaw, 0);
|
||||
|
||||
if (world.isRemote)
|
||||
setPosition(x, y, z);
|
||||
setPositionAndUpdate(x, y, z);
|
||||
|
||||
if (ridingEntity.isSneaking()) {
|
||||
stopRiding();
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
prevRotationYaw = rotationYaw;
|
||||
setRotation(rotationYaw + ridingEntity.rotationYaw - ridingEntity.prevRotationYaw, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMountedYOffset() {
|
||||
return this.getSize(getPose()).height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismountEntity(Entity ridingEntity) {
|
||||
boolean ridingBox = ridingEntity instanceof CardboardBoxEntity;
|
||||
|
||||
if (ridingBox) {
|
||||
super.dismountEntity(ridingEntity);
|
||||
}
|
||||
|
||||
if (ridingEntity instanceof LivingEntity && !ridingBox) {
|
||||
Vec3d front = VecHelper.rotate(new Vec3d(1, 0, 0), -90 - ridingEntity.rotationYaw, Axis.Y);
|
||||
double x = ridingEntity.posX + front.x;
|
||||
double y = ridingEntity.posY + ridingEntity.getMountedYOffset() / 2 + this.getYOffset();
|
||||
double z = ridingEntity.posZ + front.z;
|
||||
setRotation(-ridingEntity.rotationYaw, 0);
|
||||
if (world.isRemote)
|
||||
setPosition(x, y, z);
|
||||
setPositionAndUpdate(x, y, z);
|
||||
}
|
||||
|
||||
getPassengers().forEach(x -> x.stopRiding());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInsideBlock(BlockState state) {
|
||||
if (state.getBlock() == Blocks.WATER) {
|
||||
destroy(DamageSource.DROWN);
|
||||
remove();
|
||||
}
|
||||
super.onInsideBlock(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||
if (world.isRemote || !this.isAlive())
|
||||
return false;
|
||||
|
@ -130,6 +270,9 @@ public class CardboardBoxEntity extends LivingEntity implements IEntityAdditiona
|
|||
return false;
|
||||
}
|
||||
|
||||
if (DamageSource.IN_WALL.equals(source) && isPassenger())
|
||||
return false;
|
||||
|
||||
if (DamageSource.FALL.equals(source))
|
||||
return false;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.simibubi.create.modules.logistics.entity;
|
||||
package com.simibubi.create.modules.logistics.transport;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
|
@ -11,6 +11,7 @@ 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;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
public class CardboardBoxEntityRenderer extends EntityRenderer<CardboardBoxEntity> {
|
||||
|
||||
|
@ -44,22 +45,32 @@ public class CardboardBoxEntityRenderer extends EntityRenderer<CardboardBoxEntit
|
|||
bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(x, y, z);
|
||||
|
||||
|
||||
if (entity.extractorSide != null && entity.extractorAnimationProgress > 0) {
|
||||
float offset = 0;
|
||||
float yOffset = 0.55f;
|
||||
float time = entity.extractorAnimationProgress - partialTicks;
|
||||
float scale = 1;
|
||||
if (time > 5) {
|
||||
scale = MathHelper.lerp(((time - 10) / 10), .3f, .25f);
|
||||
float step = (time - 10) / 10;
|
||||
offset = MathHelper.lerp(step, -.5f, -1.5f);
|
||||
scale = MathHelper.lerp(step, .3f, .3f);
|
||||
} else {
|
||||
float step = time / 5;
|
||||
scale = MathHelper.lerp(step * step * step, 1, .3f);
|
||||
float cubicStep = step * step * step;
|
||||
offset = -cubicStep * .5f;
|
||||
yOffset = step * .55f;
|
||||
scale = MathHelper.lerp(cubicStep, 1, .3f);
|
||||
}
|
||||
|
||||
GlStateManager.scaled(scale, scale, scale);
|
||||
Vec3i vec = entity.extractorSide.getDirectionVec();
|
||||
GlStateManager.translated(offset * vec.getX(), offset * vec.getY() + yOffset, offset * vec.getZ());
|
||||
}
|
||||
|
||||
|
||||
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();
|
|
@ -0,0 +1,40 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleStatus;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.task.Task;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class CollectPackageTask extends Task<VillagerEntity> {
|
||||
private List<CardboardBoxEntity> foundPackages = new ArrayList<>();
|
||||
|
||||
public CollectPackageTask() {
|
||||
super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryModuleStatus.VALUE_ABSENT,
|
||||
MemoryModuleType.WALK_TARGET, MemoryModuleStatus.VALUE_ABSENT), 1);
|
||||
}
|
||||
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
this.foundPackages = worldIn.getEntitiesWithinAABB(CardboardBoxEntity.class,
|
||||
owner.getBoundingBox().grow(1.0D, 0.5D, 1.0D),
|
||||
e -> !e.isPassenger() && !e.getPersistentData().getBoolean("Delivered"));
|
||||
return !this.foundPackages.isEmpty();
|
||||
}
|
||||
|
||||
protected void startExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
LogisticianHandler.ponder(entityIn, "Yoink!");
|
||||
CardboardBoxEntity box = this.foundPackages.get(worldIn.rand.nextInt(this.foundPackages.size()));
|
||||
Entity e = entityIn;
|
||||
while (!e.getPassengers().isEmpty())
|
||||
e = e.getPassengers().get(0);
|
||||
box.startRiding(e);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.memory.WalkTarget;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockPosWrapper;
|
||||
import net.minecraft.util.math.GlobalPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class DeliverPackageToDestinationTask extends PackageDeliveryTask {
|
||||
|
||||
private GlobalPos rememberedAddress;
|
||||
|
||||
public DeliverPackageToDestinationTask() {
|
||||
super(60);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
if (!super.shouldExecute(worldIn, owner))
|
||||
return false;
|
||||
rememberedAddress = LogisticianHandler.getRememberedAddress(owner, getBox(owner).getAddress());
|
||||
return rememberedAddress != null && !rememberedAddress.getPos().withinDistance(owner.getPosition(), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
LogisticianHandler.ponder(entityIn, "I know where this is!");
|
||||
BlockPos pos = rememberedAddress.getPos();
|
||||
Vec3d vec3d = new Vec3d(pos);
|
||||
entityIn.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, new BlockPosWrapper(new BlockPos(vec3d)));
|
||||
entityIn.getBrain().setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(vec3d, 0.5F, 2));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.util.math.GlobalPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class DropPackageAtDestinationTask extends PackageDeliveryTask {
|
||||
|
||||
private GlobalPos rememberedAddress;
|
||||
|
||||
public DropPackageAtDestinationTask() {
|
||||
super(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
if (!super.shouldExecute(worldIn, owner))
|
||||
return false;
|
||||
rememberedAddress = LogisticianHandler.getRememberedAddress(owner, getBox(owner).getAddress());
|
||||
return rememberedAddress != null && rememberedAddress.getPos().withinDistance(owner.getPosition(), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
LogisticianHandler.ponder(entityIn, "You're welcome.");
|
||||
CardboardBoxEntity box = getBox(entityIn);
|
||||
box.stopRiding();
|
||||
Vec3d pos = VecHelper.getCenterOf(rememberedAddress.getPos());
|
||||
box.setPosition(pos.x, pos.y, pos.z);
|
||||
box.getPersistentData().putBoolean("Delivered", true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.ai.brain.task.Task;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.entity.merchant.villager.VillagerProfession;
|
||||
import net.minecraft.util.math.GlobalPos;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class ExpireWorkstationTask extends Task<VillagerEntity> {
|
||||
|
||||
private GlobalPos workstationPos;
|
||||
|
||||
public ExpireWorkstationTask() {
|
||||
super(ImmutableMap.of(), 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
workstationPos = LogisticianHandler.getJobSite(owner);
|
||||
return workstationPos.getPos().withinDistance(owner.getPosition(), 5);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
ServerWorld serverworld = worldIn.getServer().getWorld(workstationPos.getDimension());
|
||||
if (!AllBlocks.LOGISTICIANS_TABLE.typeOf(serverworld.getBlockState(workstationPos.getPos()))) {
|
||||
LogisticianHandler.ponder(entityIn, "Oh no! My workstation!");
|
||||
entityIn.setVillagerData(entityIn.getVillagerData().withProfession(VillagerProfession.NONE).withLevel(1));
|
||||
entityIn.resetBrain(serverworld);
|
||||
entityIn.getPassengers().forEach(Entity::stopRiding);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.mojang.datafixers.Dynamic;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.task.DummyTask;
|
||||
import net.minecraft.entity.ai.brain.task.FindInteractionAndLookTargetTask;
|
||||
import net.minecraft.entity.ai.brain.task.FirstShuffledTask;
|
||||
import net.minecraft.entity.ai.brain.task.LookAtEntityTask;
|
||||
import net.minecraft.entity.ai.brain.task.StayNearPointTask;
|
||||
import net.minecraft.entity.ai.brain.task.Task;
|
||||
import net.minecraft.entity.ai.brain.task.UpdateActivityTask;
|
||||
import net.minecraft.entity.ai.brain.task.WalkTowardsPosTask;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.entity.merchant.villager.VillagerProfession;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.INBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTDynamicOps;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.GlobalPos;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.village.PointOfInterestType;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
|
||||
public class LogisticianHandler {
|
||||
|
||||
public static VillagerProfession LOGISTICIAN;
|
||||
public static PointOfInterestType LOGISTICIANS_TABLE;
|
||||
|
||||
public static void registerPointsOfInterest(RegistryEvent.Register<PointOfInterestType> event) {
|
||||
ImmutableList<BlockState> validStates = AllBlocks.LOGISTICIANS_TABLE.get().getStateContainer().getValidStates();
|
||||
LOGISTICIANS_TABLE = new PointOfInterestType("logistician_table", ImmutableSet.copyOf(validStates), 1,
|
||||
SoundEvents.ENTITY_VILLAGER_WORK_LIBRARIAN, 1)
|
||||
.setRegistryName(new ResourceLocation(Create.ID, "logistician_table"));
|
||||
event.getRegistry().register(LOGISTICIANS_TABLE);
|
||||
}
|
||||
|
||||
public static void registerVillagerProfessions(RegistryEvent.Register<VillagerProfession> event) {
|
||||
LOGISTICIAN = new VillagerProfession("logistician", LOGISTICIANS_TABLE, ImmutableSet.of(), ImmutableSet.of())
|
||||
.setRegistryName(new ResourceLocation(Create.ID, "logistician"));
|
||||
event.getRegistry().register(LOGISTICIAN);
|
||||
}
|
||||
|
||||
public static ImmutableList<Pair<Integer, ? extends Task<? super VillagerEntity>>> work(float p_220639_1_) {
|
||||
return ImmutableList.of(uselessTasks(), actualWorkTasks(),
|
||||
Pair.of(10, new FindInteractionAndLookTargetTask(EntityType.PLAYER, 4)),
|
||||
Pair.of(2, new StayNearPointTask(MemoryModuleType.JOB_SITE, p_220639_1_, 9, 100, 1200)),
|
||||
Pair.of(3, new ExpireWorkstationTask()), Pair.of(99, new UpdateActivityTask()));
|
||||
}
|
||||
|
||||
public static Pair<Integer, Task<VillagerEntity>> actualWorkTasks() {
|
||||
return Pair.of(5,
|
||||
new FirstShuffledTask<>(ImmutableList.of(
|
||||
Pair.of(new WalkToPackageTask(), 1),
|
||||
Pair.of(new CollectPackageTask(), 1),
|
||||
Pair.of(new WalkToWorkstationTask(), 1),
|
||||
Pair.of(new LookupAddressTask(), 1),
|
||||
Pair.of(new DeliverPackageToDestinationTask(), 1),
|
||||
Pair.of(new DropPackageAtDestinationTask(), 1),
|
||||
Pair.of(new WalkTowardsPosTask(MemoryModuleType.JOB_SITE, 1, 10), 5))));
|
||||
}
|
||||
|
||||
private static Pair<Integer, Task<LivingEntity>> uselessTasks() {
|
||||
return Pair.of(6,
|
||||
new FirstShuffledTask<>(ImmutableList.of(Pair.of(new LookAtEntityTask(EntityType.VILLAGER, 8.0F), 2),
|
||||
Pair.of(new LookAtEntityTask(EntityType.PLAYER, 8.0F), 2), Pair.of(new DummyTask(30, 60), 8))));
|
||||
}
|
||||
|
||||
public static GlobalPos getJobSite(VillagerEntity villager) {
|
||||
CompoundNBT nbt = villager.getPersistentData();
|
||||
String jobSiteKey = "JobSite";
|
||||
if (!nbt.contains(jobSiteKey))
|
||||
return null;
|
||||
return GlobalPos.deserialize(new Dynamic<>(NBTDynamicOps.INSTANCE, nbt.getCompound(jobSiteKey)));
|
||||
}
|
||||
|
||||
public static void setJobSite(VillagerEntity villager, GlobalPos pos) {
|
||||
CompoundNBT nbt = villager.getPersistentData();
|
||||
String jobSiteKey = "JobSite";
|
||||
nbt.put(jobSiteKey, pos.serialize(NBTDynamicOps.INSTANCE));
|
||||
}
|
||||
|
||||
public static void rememberAddress(VillagerEntity villager, String address, GlobalPos pos) {
|
||||
ListNBT list = getAddressList(villager);
|
||||
|
||||
for (Iterator<INBT> iterator = list.iterator(); iterator.hasNext();) {
|
||||
INBT inbt = iterator.next();
|
||||
if (((CompoundNBT) inbt).getString("Address").equals(address)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (list.size() > 5)
|
||||
list.remove(0);
|
||||
|
||||
CompoundNBT addedNBT = new CompoundNBT();
|
||||
addedNBT.putString("Address", address);
|
||||
addedNBT.put("Pos", pos.serialize(NBTDynamicOps.INSTANCE));
|
||||
list.add(addedNBT);
|
||||
}
|
||||
|
||||
public static ListNBT getAddressList(VillagerEntity villager) {
|
||||
CompoundNBT nbt = villager.getPersistentData();
|
||||
String listKey = "MemorizedAddresses";
|
||||
if (!nbt.contains(listKey))
|
||||
nbt.put(listKey, new ListNBT());
|
||||
ListNBT list = nbt.getList(listKey, NBT.TAG_COMPOUND);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GlobalPos getRememberedAddress(VillagerEntity villager, String address) {
|
||||
ListNBT list = getAddressList(villager);
|
||||
|
||||
for (INBT inbt : list) {
|
||||
if (((CompoundNBT) inbt).getString("Address").equals(address)) {
|
||||
Dynamic<INBT> dynamic = new Dynamic<>(NBTDynamicOps.INSTANCE, ((CompoundNBT) inbt).getCompound("Pos"));
|
||||
return GlobalPos.deserialize(dynamic);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ponder(VillagerEntity entityIn, String thought) {
|
||||
Minecraft.getInstance().player.sendMessage(
|
||||
new StringTextComponent("<" + entityIn.getDisplayName().getFormattedText() + "> " + thought));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
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.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.schedule.Activity;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.entity.merchant.villager.VillagerProfession;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
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.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.GlobalPos;
|
||||
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.World;
|
||||
|
||||
public class LogisticiansTableBlock extends HorizontalBlock implements IWithTileEntity<LogisticiansTableTileEntity> {
|
||||
|
||||
private static final VoxelShape BASE_SHAPE = Block.makeCuboidShape(4.0D, 0.0D, 4.0D, 12.0D, 2.0D, 12.0D);
|
||||
private static final VoxelShape POLE_SHAPE = Block.makeCuboidShape(5.0D, 2.0D, 5.0D, 11.0D, 14.0D, 11.0D);
|
||||
private static final VoxelShape RENDER_SHAPE = VoxelShapes.or(BASE_SHAPE, POLE_SHAPE);
|
||||
private static final VoxelShape TOP_COLLISION_SHAPE = Block.makeCuboidShape(0.0D, 15.0D, 0.0D, 16.0D, 15.0D, 16.0D);
|
||||
private static final VoxelShape COLLISION_SHAPE = VoxelShapes.or(RENDER_SHAPE, TOP_COLLISION_SHAPE);
|
||||
|
||||
private static final VoxelShape WEST_SHAPE = VoxelShapes.or(
|
||||
Block.makeCuboidShape(1.0D, 10.0D, 0.0D, 5.333333D, 14.0D, 16.0D),
|
||||
Block.makeCuboidShape(5.333333D, 12.0D, 0.0D, 9.666667D, 16.0D, 16.0D),
|
||||
Block.makeCuboidShape(9.666667D, 14.0D, 0.0D, 14.0D, 18.0D, 16.0D), RENDER_SHAPE);
|
||||
private static final VoxelShape NORTH_SHAPE = VoxelShapes.or(
|
||||
Block.makeCuboidShape(0.0D, 10.0D, 1.0D, 16.0D, 14.0D, 5.333333D),
|
||||
Block.makeCuboidShape(0.0D, 12.0D, 5.333333D, 16.0D, 16.0D, 9.666667D),
|
||||
Block.makeCuboidShape(0.0D, 14.0D, 9.666667D, 16.0D, 18.0D, 14.0D), RENDER_SHAPE);
|
||||
private static final VoxelShape EAST_SHAPE = VoxelShapes.or(
|
||||
Block.makeCuboidShape(15.0D, 10.0D, 0.0D, 10.666667D, 14.0D, 16.0D),
|
||||
Block.makeCuboidShape(10.666667D, 12.0D, 0.0D, 6.333333D, 16.0D, 16.0D),
|
||||
Block.makeCuboidShape(6.333333D, 14.0D, 0.0D, 2.0D, 18.0D, 16.0D), RENDER_SHAPE);
|
||||
private static final VoxelShape SOUTH_SHAPE = VoxelShapes.or(
|
||||
Block.makeCuboidShape(0.0D, 10.0D, 15.0D, 16.0D, 14.0D, 10.666667D),
|
||||
Block.makeCuboidShape(0.0D, 12.0D, 10.666667D, 16.0D, 16.0D, 6.333333D),
|
||||
Block.makeCuboidShape(0.0D, 14.0D, 6.333333D, 16.0D, 18.0D, 2.0D), RENDER_SHAPE);
|
||||
|
||||
public LogisticiansTableBlock() {
|
||||
super(Properties.from(Blocks.SPRUCE_LOG));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new LogisticiansTableTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ticksRandomly(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, World worldIn, BlockPos pos, Random random) {
|
||||
for (Entity entity : worldIn.getEntitiesWithinAABB(EntityType.VILLAGER, new AxisAlignedBB(pos).grow(10),
|
||||
e -> ((VillagerEntity) e).getVillagerData().getProfession() == VillagerProfession.NONE)) {
|
||||
|
||||
VillagerEntity e = (VillagerEntity) entity;
|
||||
float f = (float) e.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).getValue();
|
||||
e.setVillagerData(e.getVillagerData().withProfession(LogisticianHandler.LOGISTICIAN).withLevel(2));
|
||||
e.getBrain().registerActivity(Activity.WORK, LogisticianHandler.work(f));
|
||||
e.getBrain().setMemory(MemoryModuleType.JOB_SITE, GlobalPos.of(worldIn.getDimension().getType(), pos));
|
||||
LogisticianHandler.setJobSite(e, GlobalPos.of(worldIn.getDimension().getType(), pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(HORIZONTAL_FACING);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
|
||||
public VoxelShape getRenderShape(BlockState state, IBlockReader worldIn, BlockPos pos) {
|
||||
return RENDER_SHAPE;
|
||||
}
|
||||
|
||||
public boolean func_220074_n(BlockState state) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
return this.getDefaultState().with(HORIZONTAL_FACING, context.getPlacementHorizontalFacing().getOpposite());
|
||||
}
|
||||
|
||||
public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos,
|
||||
ISelectionContext context) {
|
||||
return COLLISION_SHAPE;
|
||||
}
|
||||
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
switch (state.get(HORIZONTAL_FACING)) {
|
||||
case NORTH:
|
||||
return NORTH_SHAPE;
|
||||
case SOUTH:
|
||||
return SOUTH_SHAPE;
|
||||
case EAST:
|
||||
return EAST_SHAPE;
|
||||
case WEST:
|
||||
return WEST_SHAPE;
|
||||
default:
|
||||
return RENDER_SHAPE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity;
|
||||
|
||||
public class LogisticiansTableTileEntity extends LogisticalActorTileEntity {
|
||||
|
||||
public LogisticiansTableTileEntity() {
|
||||
super(AllTileEntities.LOGISTICIANS_TABLE.type);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.ColoredIndicatorRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.model.BookModel;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class LogisticiansTableTileEntityRenderer extends TileEntityRenderer<LogisticiansTableTileEntity> {
|
||||
private static final ResourceLocation bookLocation = new ResourceLocation(
|
||||
"textures/entity/enchanting_table_book.png");
|
||||
private final BookModel bookModel = new BookModel();
|
||||
|
||||
public void render(LogisticiansTableTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
Minecraft.getInstance().textureManager
|
||||
.bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.disableCull();
|
||||
|
||||
if (net.minecraft.client.Minecraft.isAmbientOcclusionEnabled())
|
||||
GlStateManager.shadeModel(GL11.GL_SMOOTH);
|
||||
else
|
||||
GlStateManager.shadeModel(GL11.GL_FLAT);
|
||||
|
||||
GlStateManager.color3f(1, 1, 1);
|
||||
BlockPos pos = tileEntityIn.getPos();
|
||||
BlockState blockState = tileEntityIn.getBlockState();
|
||||
BlockState renderedState = AllBlocks.LOGISTICIANS_TABLE_INDICATOR.get().getDefaultState();
|
||||
int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), pos);
|
||||
Tessellator.getInstance().getBuffer().begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
int color = tileEntityIn.getColor();
|
||||
Tessellator.getInstance().getBuffer().putBulkData(ColoredIndicatorRenderer.get(renderedState)
|
||||
.getTransformed((float) x, (float) y, (float) z, color, packedLightmapCoords));
|
||||
Tessellator.getInstance().draw();
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
BlockState blockstate = tileEntityIn.getBlockState();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translatef((float) x + 0.5F, (float) y + 1.0F + 0.0625F, (float) z + 0.5F);
|
||||
float f = blockstate.get(BlockStateProperties.HORIZONTAL_FACING).rotateY().getHorizontalAngle();
|
||||
GlStateManager.rotatef(-f, 0.0F, 1.0F, 0.0F);
|
||||
GlStateManager.rotatef(67.5F, 0.0F, 0.0F, 1.0F);
|
||||
GlStateManager.translatef(0.0F, -0.125F, 0.0F);
|
||||
this.bindTexture(bookLocation);
|
||||
GlStateManager.enableCull();
|
||||
this.bookModel.render(0.0F, 0.1F, 0.9F, 1.2F, 0.0F, 0.0625F);
|
||||
GlStateManager.disableCull();
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.GlobalPos;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class LookupAddressTask extends PackageDeliveryTask {
|
||||
|
||||
public LookupAddressTask() {
|
||||
super(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
if (!super.shouldExecute(worldIn, owner))
|
||||
return false;
|
||||
CardboardBoxEntity box = getBox(owner);
|
||||
GlobalPos rememberedAddress = LogisticianHandler.getRememberedAddress(owner, box.getAddress());
|
||||
if (rememberedAddress != null)
|
||||
return false;
|
||||
return LogisticianHandler.getJobSite(owner).getPos().withinDistance(owner.getPosition(), 1.5);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
LogisticianHandler.ponder(entityIn, "Let's have a look...");
|
||||
BlockPos tablePos = LogisticianHandler.getJobSite(entityIn).getPos();
|
||||
if (!AllBlocks.LOGISTICIANS_TABLE.typeOf(worldIn.getBlockState(tablePos)))
|
||||
return;
|
||||
TileEntity te = worldIn.getTileEntity(tablePos);
|
||||
if (te == null || !(te instanceof LogisticiansTableTileEntity))
|
||||
return;
|
||||
LogisticiansTableTileEntity lte = (LogisticiansTableTileEntity) te;
|
||||
String address = getBox(entityIn).getAddress();
|
||||
if (lte.getNetwork() == null)
|
||||
return;
|
||||
for (PackageFunnelTileEntity packageFunnelTileEntity : lte.getNetwork().packageTargets) {
|
||||
for (String string : packageFunnelTileEntity.addresses) {
|
||||
if (string.toLowerCase().equals(address.toLowerCase())) {
|
||||
GlobalPos globalPos = GlobalPos.of(worldIn.getDimension().getType(), packageFunnelTileEntity.getPos());
|
||||
LogisticianHandler.rememberAddress(entityIn, address, globalPos);
|
||||
LogisticianHandler.ponder(entityIn, "I see!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
LogisticianHandler.ponder(entityIn, "Hmm. Can't find that one");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleStatus;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.task.Task;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class PackageDeliveryTask extends Task<VillagerEntity> {
|
||||
|
||||
public PackageDeliveryTask(int timeout) {
|
||||
super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryModuleStatus.VALUE_ABSENT,
|
||||
MemoryModuleType.WALK_TARGET, MemoryModuleStatus.VALUE_ABSENT), timeout);
|
||||
}
|
||||
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
return getBox(owner) != null;
|
||||
}
|
||||
|
||||
protected CardboardBoxEntity getBox(VillagerEntity owner) {
|
||||
List<Entity> passengers = owner.getPassengers();
|
||||
if (passengers.isEmpty())
|
||||
return null;
|
||||
Entity entity = passengers.get(0);
|
||||
if (!(entity instanceof CardboardBoxEntity))
|
||||
return null;
|
||||
return (CardboardBoxEntity) entity;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.block.ProperDirectionalBlock;
|
||||
import com.simibubi.create.modules.logistics.management.base.ILogisticalCasingAttachment;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalCasingTileEntity;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class PackageFunnelBlock extends ProperDirectionalBlock
|
||||
implements IWithTileEntity<PackageFunnelTileEntity>, ILogisticalCasingAttachment {
|
||||
|
||||
public static final VoxelShape UP_SHAPE = makeCuboidShape(1, -1, 1, 15, 3, 15),
|
||||
DOWN_SHAPE = makeCuboidShape(1, 13, 1, 15, 17, 15), SOUTH_SHAPE = makeCuboidShape(1, 1, -1, 15, 15, 3),
|
||||
NORTH_SHAPE = makeCuboidShape(1, 1, 13, 15, 15, 17), EAST_SHAPE = makeCuboidShape(-1, 1, 1, 3, 15, 15),
|
||||
WEST_SHAPE = makeCuboidShape(13, 1, 1, 17, 15, 15);
|
||||
|
||||
public PackageFunnelBlock() {
|
||||
super(Properties.from(Blocks.PISTON));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new PackageFunnelTileEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
return getDefaultState().with(FACING, context.getFace());
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos,
|
||||
ISelectionContext context) {
|
||||
if (context.getEntity() instanceof CardboardBoxEntity)
|
||||
return VoxelShapes.empty();
|
||||
return getShape(state, worldIn, pos, context);
|
||||
}
|
||||
|
||||
@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 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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCasingUpdated(IWorld world, BlockPos pos, LogisticalCasingTileEntity te) {
|
||||
Direction facing = world.getBlockState(pos).get(FACING).getOpposite();
|
||||
if (!te.getPos().equals(pos.offset(facing)))
|
||||
return;
|
||||
withTileEntityDo(world, pos, PackageFunnelTileEntity::refreshAddressList);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import static com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity.ShippingInventory.RECEIVING;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.LogisticalNetwork;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.base.LogisticalCasingTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity;
|
||||
import com.simibubi.create.modules.logistics.management.controller.LogisticalInventoryControllerTileEntity.ShippingInventory;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class PackageFunnelTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||
|
||||
public static final int INSERTION_DELAY = 10;
|
||||
|
||||
protected int initialize;
|
||||
protected List<String> addresses;
|
||||
protected boolean waitingForSpace;
|
||||
protected int cooldown;
|
||||
protected AxisAlignedBB bb;
|
||||
|
||||
public PackageFunnelTileEntity() {
|
||||
super(AllTileEntities.PACKAGE_FUNNEL.type);
|
||||
addresses = new ArrayList<String>();
|
||||
waitingForSpace = false;
|
||||
cooldown = 10;
|
||||
}
|
||||
|
||||
public void slotOpened() {
|
||||
waitingForSpace = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
initialize = 2;
|
||||
bb = new AxisAlignedBB(getPos());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
|
||||
// Initialize AFTER the actors to get a working network reference
|
||||
if (initialize > -1)
|
||||
initialize--;
|
||||
if (initialize == 0) {
|
||||
initialize();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cooldown > 0) {
|
||||
cooldown--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (waitingForSpace)
|
||||
return;
|
||||
|
||||
tryInsert();
|
||||
cooldown = INSERTION_DELAY;
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
initialize = -1;
|
||||
refreshAddressList();
|
||||
}
|
||||
|
||||
public void refreshAddressList() {
|
||||
addresses.clear();
|
||||
LogisticalCasingTileEntity casingTE = getCasingTE();
|
||||
if (casingTE == null)
|
||||
return;
|
||||
for (LogisticalActorTileEntity actor : casingTE.getControllers()) {
|
||||
addresses.add(actor.address);
|
||||
if (actor.getNetwork() != null)
|
||||
actor.getNetwork().addPackageTarget(this);
|
||||
}
|
||||
}
|
||||
|
||||
public LogisticalCasingTileEntity getCasingTE() {
|
||||
BlockPos casingPos = pos.offset(getBlockState().get(BlockStateProperties.FACING).getOpposite());
|
||||
TileEntity te = world.getTileEntity(casingPos);
|
||||
if (te == null || !AllTileEntities.LOGISTICAL_CASING.typeOf(te))
|
||||
return null;
|
||||
LogisticalCasingTileEntity casingTE = (LogisticalCasingTileEntity) te;
|
||||
return casingTE;
|
||||
}
|
||||
|
||||
private void tryInsert() {
|
||||
for (CardboardBoxEntity e : world.getEntitiesWithinAABB(CardboardBoxEntity.class, bb, e -> {
|
||||
if (e.isPassenger())
|
||||
return false;
|
||||
for (String address : addresses)
|
||||
if (LogisticalNetwork.matchAddresses(address, e.getAddress()))
|
||||
return true;
|
||||
return false;
|
||||
})) {
|
||||
LogisticalCasingTileEntity casingTE = getCasingTE();
|
||||
if (casingTE == null)
|
||||
return;
|
||||
for (LogisticalActorTileEntity actor : casingTE.getControllers()) {
|
||||
if (!(actor instanceof LogisticalInventoryControllerTileEntity))
|
||||
continue;
|
||||
if (LogisticalNetwork.matchAddresses(actor.address, e.getAddress())) {
|
||||
LogisticalInventoryControllerTileEntity invTe = (LogisticalInventoryControllerTileEntity) actor;
|
||||
if (!invTe.isReceiver())
|
||||
continue;
|
||||
ShippingInventory inventory = invTe.getInventory();
|
||||
if (!inventory.getStackInSlot(RECEIVING).isEmpty()) {
|
||||
waitingForSpace = true;
|
||||
return;
|
||||
}
|
||||
inventory.insertItem(RECEIVING, e.getBox(), false);
|
||||
e.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
BlockPos casingPos = pos.offset(getBlockState().get(BlockStateProperties.FACING).getOpposite());
|
||||
TileEntity te = world.getTileEntity(casingPos);
|
||||
if (te == null || !AllTileEntities.LOGISTICAL_CASING.typeOf(te))
|
||||
return;
|
||||
LogisticalCasingTileEntity casingTE = (LogisticalCasingTileEntity) te;
|
||||
for (LogisticalActorTileEntity actor : casingTE.getControllers()) {
|
||||
if (actor.getNetwork() != null)
|
||||
actor.getNetwork().removePackageTarget(this);
|
||||
}
|
||||
super.remove();
|
||||
}
|
||||
|
||||
public List<String> getAddressList() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleStatus;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.memory.WalkTarget;
|
||||
import net.minecraft.entity.ai.brain.task.Task;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockPosWrapper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class WalkToPackageTask extends Task<VillagerEntity> {
|
||||
private List<CardboardBoxEntity> foundPackages = new ArrayList<>();
|
||||
private CardboardBoxEntity targetedPackage;
|
||||
|
||||
public WalkToPackageTask() {
|
||||
super(ImmutableMap.of(MemoryModuleType.LOOK_TARGET, MemoryModuleStatus.VALUE_ABSENT,
|
||||
MemoryModuleType.WALK_TARGET, MemoryModuleStatus.VALUE_ABSENT), 20);
|
||||
}
|
||||
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
if (!worldIn.getEntitiesWithinAABB(CardboardBoxEntity.class, owner.getBoundingBox().grow(1.0D, 0.5D, 1.0D),
|
||||
e -> !e.isPassenger() && !e.getPersistentData().getBoolean("Delivered")).isEmpty())
|
||||
return false;
|
||||
this.foundPackages = worldIn.getEntitiesWithinAABB(CardboardBoxEntity.class,
|
||||
owner.getBoundingBox().grow(50.0D, 10.0D, 50.0D),
|
||||
e -> !e.isPassenger() && !e.getPersistentData().getBoolean("Delivered"));
|
||||
return !this.foundPackages.isEmpty();
|
||||
}
|
||||
|
||||
protected void startExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
LogisticianHandler.ponder(entityIn, "Let's go to that package over there");
|
||||
targetedPackage = this.foundPackages.get(worldIn.rand.nextInt(this.foundPackages.size()));
|
||||
Vec3d vec3d = targetedPackage.getPositionVec();
|
||||
entityIn.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, new BlockPosWrapper(new BlockPos(vec3d)));
|
||||
entityIn.getBrain().setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(vec3d, 0.5F, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldContinueExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
return !entityIn.getPosition().withinDistance(targetedPackage.getPosition(), 2);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.simibubi.create.modules.logistics.transport.villager;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.ai.brain.memory.MemoryModuleType;
|
||||
import net.minecraft.entity.ai.brain.memory.WalkTarget;
|
||||
import net.minecraft.entity.merchant.villager.VillagerEntity;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.GlobalPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
public class WalkToWorkstationTask extends PackageDeliveryTask {
|
||||
|
||||
public WalkToWorkstationTask() {
|
||||
super(60);
|
||||
}
|
||||
|
||||
protected boolean shouldExecute(ServerWorld worldIn, VillagerEntity owner) {
|
||||
if (!super.shouldExecute(worldIn, owner))
|
||||
return false;
|
||||
CardboardBoxEntity box = getBox(owner);
|
||||
GlobalPos rememberedAddress = LogisticianHandler.getRememberedAddress(owner, box.getAddress());
|
||||
return rememberedAddress == null;
|
||||
}
|
||||
|
||||
protected void startExecuting(ServerWorld worldIn, VillagerEntity entityIn, long gameTimeIn) {
|
||||
LogisticianHandler.ponder(entityIn, "I forgot where this address is at");
|
||||
GlobalPos workstation = LogisticianHandler.getJobSite(entityIn);
|
||||
if (workstation != null) {
|
||||
BlockPos pos = workstation.getPos();
|
||||
if (worldIn.isBlockPresent(pos)) {
|
||||
BlockState blockState = worldIn.getBlockState(pos);
|
||||
if (AllBlocks.LOGISTICIANS_TABLE.typeOf(blockState))
|
||||
pos = pos.offset(blockState.get(BlockStateProperties.HORIZONTAL_FACING));
|
||||
}
|
||||
Vec3d vec = new Vec3d(pos);
|
||||
entityIn.getBrain().setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(vec, 0.5F, 0));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "create:block/logisticians_table"
|
||||
},
|
||||
"variants": {
|
||||
"facing": {
|
||||
"north": { "y": 180 },
|
||||
"south": { },
|
||||
"east": { "y": 270 },
|
||||
"west": { "y": 90 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "create:block/logisticians_table_indicator" }
|
||||
}
|
||||
}
|
|
@ -1,12 +1,14 @@
|
|||
{
|
||||
"forgemarker": 1,
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "create:block/motor"
|
||||
},
|
||||
"variants": {
|
||||
"facing=north": { "model": "create:block/motor", "y": 180 },
|
||||
"facing=south": { "model": "create:block/motor" },
|
||||
"facing=east": { "model": "create:block/motor", "y": 270 },
|
||||
"facing=west": { "model": "create:block/motor", "y": 90 }
|
||||
"facing": {
|
||||
"north": { "y": 180 },
|
||||
"south": { },
|
||||
"east": { "y": 270 },
|
||||
"west": { "y": 90 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "create:block/package_funnel"
|
||||
},
|
||||
"variants": {
|
||||
"facing": {
|
||||
"north": { "y": 180 },
|
||||
"south": { },
|
||||
"west": { "y": 90 },
|
||||
"up": { "model": "create:block/package_funnel_vertical", "x": 90 },
|
||||
"down": { "model": "create:block/package_funnel_vertical", "x": 270 },
|
||||
"east": { "y": 270 }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -85,6 +85,8 @@
|
|||
"block.create.logistical_casing": "Logistical Casing",
|
||||
"block.create.logistical_controller": "Logistical Controller",
|
||||
"block.create.logistical_index": "Logistical Index",
|
||||
"block.create.logisticians_table": "Logisticians Table",
|
||||
"block.create.package_funnel": "Package Funnel",
|
||||
|
||||
"block.create.tiled_glass": "Tiled Glass",
|
||||
"block.create.tiled_glass_pane": "Tiled Glass Pane",
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"smooth_stone_slab_side": "minecraft:block/smooth_stone_slab_side",
|
||||
"brass_casing_side": "create:block/brass_casing_side",
|
||||
"brass_casing": "create:block/brass_casing",
|
||||
"spruce_log": "minecraft:block/spruce_log"
|
||||
},
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [ 30, 45, 0 ],
|
||||
"translation": [ 0, -1.5, 0],
|
||||
"scale":[ 0.625, 0.625, 0.625 ]
|
||||
}
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 4, 0, 4 ],
|
||||
"to": [ 12, 2, 12 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#smooth_stone_slab_side", "uv": [ 3, 14, 11, 16 ] },
|
||||
"east": { "texture": "#smooth_stone_slab_side", "uv": [ 8, 0, 16, 2 ] },
|
||||
"south": { "texture": "#smooth_stone_slab_side", "uv": [ 3, 0, 11, 2 ] },
|
||||
"west": { "texture": "#smooth_stone_slab_side", "uv": [ 16, 0, 8, 2 ] },
|
||||
"up": { "texture": "#smooth_stone_slab_side", "uv": [ 4, 0, 12, 8 ], "rotation": 180 },
|
||||
"down": { "texture": "#smooth_stone_slab_side", "uv": [ 4, 0, 12, 8 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 5, 2, 5 ],
|
||||
"to": [ 11, 15, 11 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#spruce_log", "uv": [ 4, 1, 10, 15 ] },
|
||||
"east": { "texture": "#spruce_log", "uv": [ 6, 2, 12, 15 ] },
|
||||
"south": { "texture": "#spruce_log", "uv": [ 7, 1, 14, 14 ] },
|
||||
"west": { "texture": "#spruce_log", "uv": [ 4, 1, 10, 14 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top",
|
||||
"from": [ 0, 12, 0 ],
|
||||
"to": [ 16, 16, 13 ],
|
||||
"rotation": { "origin": [ 8, 8, 8 ], "axis": "x", "angle": 22.5 },
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing_side", "uv": [ 0, 10, 16, 14 ] },
|
||||
"east": { "texture": "#brass_casing_side", "uv": [ 12, 3, 16, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 4 ] },
|
||||
"west": { "texture": "#brass_casing_side", "uv": [ 0, 3, 4, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#brass_casing_side", "uv": [ 0, 3, 16, 16 ] },
|
||||
"down": { "texture": "#brass_casing_side", "uv": [ 0, 3, 16, 16 ], "rotation": 180 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"textures": {
|
||||
"particle": "create:block/brass_casing_side",
|
||||
"smooth_stone_slab_side": "minecraft:block/smooth_stone_slab_side",
|
||||
"logistical_controller": "create:block/logistical_controller"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 4.75, 3, 4.75 ],
|
||||
"to": [ 11.25, 5, 11.25 ],
|
||||
"shade": false,
|
||||
"faces": {
|
||||
"north": { "texture": "#logistical_controller", "uv": [ 13, 3, 15, 10 ], "rotation": 270 },
|
||||
"east": { "texture": "#logistical_controller", "uv": [ 13, 3, 15, 10 ], "rotation": 90 },
|
||||
"south": { "texture": "#logistical_controller", "uv": [ 13, 3, 15, 10 ], "rotation": 90 },
|
||||
"west": { "texture": "#logistical_controller", "uv": [ 13, 3, 15, 10 ], "rotation": 90 },
|
||||
"up": { "texture": "#smooth_stone_slab_side", "uv": [ 4, 9, 10, 15 ], "rotation": 180 },
|
||||
"down": { "texture": "#smooth_stone_slab_side", "uv": [ 4, 1, 10, 7 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"particle": "create:block/package_funnel_horizontal",
|
||||
"brass_casing": "create:block/brass_casing",
|
||||
"belt_funnel": "create:block/belt_funnel",
|
||||
"package_funnel_horizontal": "create:block/package_funnel_horizontal"
|
||||
},
|
||||
"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 ]
|
||||
}
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 1, 1, -1 ],
|
||||
"to": [ 15, 2, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 1, 14, 15, 15 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 13, 12, 14, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#package_funnel_horizontal", "uv": [ 0, 13, 14, 14 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 13, 12, 14, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#belt_funnel", "uv": [ 0, 12, 14, 16 ] },
|
||||
"down": { "texture": "#belt_funnel", "uv": [ 0, 12, 14, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 1, 14, -1 ],
|
||||
"to": [ 15, 15, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 2 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 0, 12, 1, 16 ], "rotation": 90 },
|
||||
"south": { "texture": "#package_funnel_horizontal", "uv": [ 0, 0, 14, 1 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 0, 12, 1, 16 ], "rotation": 270 },
|
||||
"up": { "texture": "#belt_funnel", "uv": [ 0, 12, 14, 16 ] },
|
||||
"down": { "texture": "#belt_funnel", "uv": [ 0, 12, 14, 16 ] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 1, 2, -1 ],
|
||||
"to": [ 2, 14, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 14, 2, 15, 14 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 1, 12, 13, 16 ], "rotation": 270 },
|
||||
"south": { "texture": "#package_funnel_horizontal", "uv": [ 0, 1, 1, 13 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 1, 12, 13, 16 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cube",
|
||||
"from": [ 14, 2, -1 ],
|
||||
"to": [ 15, 14, 3 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 1, 2, 2, 14 ] },
|
||||
"east": { "texture": "#belt_funnel", "uv": [ 1, 12, 13, 16 ], "rotation": 270 },
|
||||
"south": { "texture": "#package_funnel_horizontal", "uv": [ 13, 1, 14, 13 ] },
|
||||
"west": { "texture": "#belt_funnel", "uv": [ 1, 12, 13, 16 ], "rotation": 90 }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Inner",
|
||||
"from": [ 2, 2, -1 ],
|
||||
"to": [ 14, 14, 2 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#brass_casing", "uv": [ 2, 2, 14, 14 ] },
|
||||
"south": { "texture": "#package_funnel_horizontal", "uv": [ 1, 1, 13, 13 ] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"parent": "create:block/package_funnel",
|
||||
"textures": {
|
||||
"particle": "create:block/package_funnel_vertical",
|
||||
"package_funnel_horizontal": "create:block/package_funnel_vertical"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "create:block/logisticians_table"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "create:block/package_funnel"
|
||||
}
|
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 531 B |
After Width: | Height: | Size: 419 B |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"villager": {
|
||||
"hat": "full"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 395 B |
BIN
src/main/resources/assets/create/textures/item/crushed_gold.png
Normal file
After Width: | Height: | Size: 432 B |
BIN
src/main/resources/assets/create/textures/item/crushed_iron.png
Normal file
After Width: | Height: | Size: 409 B |