More moves and compilation fixes
This commit is contained in:
@@ -37,7 +37,6 @@ import appeng.api.util.IOrientable;
|
||||
import appeng.api.util.IOrientableBlock;
|
||||
import appeng.block.misc.LightDetectorBlock;
|
||||
import appeng.block.misc.SkyCompassBlock;
|
||||
import appeng.block.networking.WirelessBlock;
|
||||
import appeng.me.helpers.IGridProxyable;
|
||||
import appeng.tile.AEBaseBlockEntity;
|
||||
|
||||
@@ -85,7 +84,7 @@ public class AEBaseBlockItem extends BlockItem {
|
||||
} else {
|
||||
forward = Direction.UP;
|
||||
}
|
||||
} else if (this.blockType instanceof WirelessBlock || this.blockType instanceof SkyCompassBlock) {
|
||||
} else if (/* FIXME FABRIC this.blockType instanceof WirelessBlock || */ this.blockType instanceof SkyCompassBlock) {
|
||||
forward = side;
|
||||
if (forward == Direction.UP || forward == Direction.DOWN) {
|
||||
up = Direction.SOUTH;
|
||||
@@ -141,7 +140,7 @@ public class AEBaseBlockItem extends BlockItem {
|
||||
}
|
||||
|
||||
if (tile instanceof IGridProxyable) {
|
||||
((IGridProxyable) tile).getProxy().setOwner(player);
|
||||
// FIXME FABRIC ((IGridProxyable) tile).getProxy().setOwner(player);
|
||||
}
|
||||
|
||||
tile.onPlacement(context);
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.function.Supplier;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import alexiil.mc.lib.attributes.AttributeList;
|
||||
import alexiil.mc.lib.attributes.AttributeProvider;
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -49,15 +51,13 @@ import net.minecraft.world.World;
|
||||
import appeng.api.implementations.items.IMemoryCard;
|
||||
import appeng.api.implementations.items.MemoryCardMessages;
|
||||
import appeng.api.util.IOrientable;
|
||||
import appeng.block.networking.CableBusBlock;
|
||||
import appeng.tile.AEBaseInvBlockEntity;
|
||||
import appeng.tile.AEBaseBlockEntity;
|
||||
import appeng.tile.networking.CableBusBlockEntity;
|
||||
import appeng.tile.storage.SkyChestBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.SettingsFrom;
|
||||
|
||||
public abstract class AEBaseTileBlock<T extends AEBaseBlockEntity> extends AEBaseBlock implements BlockEntityProvider {
|
||||
public abstract class AEBaseTileBlock<T extends AEBaseBlockEntity> extends AEBaseBlock implements BlockEntityProvider, AttributeProvider {
|
||||
|
||||
@Nonnull
|
||||
private Class<T> blockEntityClass;
|
||||
@@ -205,7 +205,7 @@ public abstract class AEBaseTileBlock<T extends AEBaseBlockEntity> extends AEBas
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
|
||||
if (tile instanceof CableBusBlockEntity || tile instanceof SkyChestBlockEntity) {
|
||||
if (/* FIXME FABRIC tile instanceof CableBusBlockEntity || */ tile instanceof SkyChestBlockEntity) {
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ public abstract class AEBaseTileBlock<T extends AEBaseBlockEntity> extends AEBas
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
|
||||
if (heldItem.getItem() instanceof IMemoryCard && !(this instanceof CableBusBlock)) {
|
||||
if (heldItem.getItem() instanceof IMemoryCard /* FIXME FABRIC && !(this instanceof CableBusBlock)*/) {
|
||||
final IMemoryCard memoryCard = (IMemoryCard) heldItem.getItem();
|
||||
final AEBaseBlockEntity tileEntity = this.getBlockEntity(world, pos);
|
||||
|
||||
@@ -299,4 +299,13 @@ public abstract class AEBaseTileBlock<T extends AEBaseBlockEntity> extends AEBas
|
||||
return currentState;
|
||||
}
|
||||
|
||||
// Gives our tile entity a chance to provide it's attributes
|
||||
@Override
|
||||
public void addAllAttributes(World world, BlockPos pos, BlockState state, AttributeList<?> to) {
|
||||
T te = getBlockEntity(world, pos);
|
||||
if (te != null) {
|
||||
te.addAllAttributes(world, pos, state, to);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.block.storage;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.tile.storage.SkyChestBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class SkyChestBlock extends AEBaseTileBlock<SkyChestBlockEntity> {
|
||||
|
||||
private static final double AABB_OFFSET_BOTTOM = 0.00;
|
||||
private static final double AABB_OFFSET_SIDES = 0.06;
|
||||
private static final double AABB_OFFSET_TOP = 0.125;
|
||||
|
||||
public enum SkyChestType {
|
||||
STONE, BLOCK
|
||||
};
|
||||
|
||||
public final SkyChestType type;
|
||||
|
||||
public SkyChestBlock(final SkyChestType type, Settings props) {
|
||||
super(props);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderType getRenderType(BlockState state) {
|
||||
return BlockRenderType.ENTITYBLOCK_ANIMATED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTranslucent(BlockState state, BlockView reader, BlockPos pos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onActivated(final World w, final BlockPos pos, final PlayerEntity player, final Hand hand,
|
||||
final @Nullable ItemStack heldItem, final BlockHitResult hit) {
|
||||
if (Platform.isServer()) {
|
||||
SkyChestBlockEntity tile = getBlockEntity(w, pos);
|
||||
if (tile == null) {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
throw new IllegalStateException();
|
||||
// FIXME FABRIC ContainerOpener.openContainer(SkyChestContainer.TYPE, player, ContainerLocator.forTileEntity(tile));
|
||||
}
|
||||
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView worldIn, BlockPos pos, ShapeContext context) {
|
||||
// TODO Cache this! It can't be that hard!
|
||||
Box aabb = computeAABB(worldIn, pos);
|
||||
return VoxelShapes.cuboid(aabb);
|
||||
}
|
||||
|
||||
private Box computeAABB(final BlockView w, final BlockPos pos) {
|
||||
final SkyChestBlockEntity sk = this.getBlockEntity(w, pos);
|
||||
Direction o = Direction.UP;
|
||||
|
||||
if (sk != null) {
|
||||
o = sk.getUp();
|
||||
}
|
||||
|
||||
final double offsetX = o.getOffsetX() == 0 ? AABB_OFFSET_SIDES : 0.0;
|
||||
final double offsetY = o.getOffsetY() == 0 ? AABB_OFFSET_SIDES : 0.0;
|
||||
final double offsetZ = o.getOffsetZ() == 0 ? AABB_OFFSET_SIDES : 0.0;
|
||||
|
||||
// for x/z top and bottom is swapped
|
||||
final double minX = Math.max(0.0,
|
||||
offsetX + (o.getOffsetX() < 0 ? AABB_OFFSET_BOTTOM : (o.getOffsetX() * AABB_OFFSET_TOP)));
|
||||
final double minY = Math.max(0.0,
|
||||
offsetY + (o.getOffsetY() < 0 ? AABB_OFFSET_TOP : (o.getOffsetY() * AABB_OFFSET_BOTTOM)));
|
||||
final double minZ = Math.max(0.0,
|
||||
offsetZ + (o.getOffsetZ() < 0 ? AABB_OFFSET_BOTTOM : (o.getOffsetZ() * AABB_OFFSET_TOP)));
|
||||
|
||||
final double maxX = Math.min(1.0,
|
||||
1.0 - offsetX - (o.getOffsetX() < 0 ? AABB_OFFSET_TOP : (o.getOffsetX() * AABB_OFFSET_BOTTOM)));
|
||||
final double maxY = Math.min(1.0,
|
||||
1.0 - offsetY - (o.getOffsetY() < 0 ? AABB_OFFSET_BOTTOM : (o.getOffsetY() * AABB_OFFSET_TOP)));
|
||||
final double maxZ = Math.min(1.0,
|
||||
1.0 - offsetZ - (o.getOffsetZ() < 0 ? AABB_OFFSET_TOP : (o.getOffsetZ() * AABB_OFFSET_BOTTOM)));
|
||||
|
||||
return new Box(minX, minY, minZ, maxX, maxY, maxZ);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import appeng.block.AEBaseBlock;
|
||||
import appeng.block.AEBaseBlockItem;
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.bootstrap.definitions.TileEntityDefinition;
|
||||
import appeng.core.AEItemGroup;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.CreativeTab;
|
||||
import appeng.core.features.BlockDefinition;
|
||||
@@ -171,8 +170,8 @@ class BlockDefinitionBuilder implements IBlockBuilder {
|
||||
definition = (T) new BlockDefinition(this.id.getPath(), block, item, features);
|
||||
}
|
||||
|
||||
if (itemGroup instanceof AEItemGroup) {
|
||||
((AEItemGroup) itemGroup).add(definition);
|
||||
if (itemGroup == CreativeTab.INSTANCE) {
|
||||
CreativeTab.add(definition);
|
||||
}
|
||||
|
||||
return definition;
|
||||
|
||||
@@ -26,14 +26,11 @@ import net.minecraft.block.Block;
|
||||
import net.minecraft.client.color.block.BlockColorProvider;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.bootstrap.components.BlockColorComponent;
|
||||
import appeng.bootstrap.components.RenderTypeComponent;
|
||||
import appeng.client.render.model.AutoRotatingBakedModel;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
class BlockRendering implements IBlockRendering {
|
||||
|
||||
@@ -79,7 +76,7 @@ class BlockRendering implements IBlockRendering {
|
||||
// This is a default rotating model if the base-block uses an AE block entity
|
||||
// which exposes UP/FRONT as
|
||||
// extended props
|
||||
factory.addModelOverride(id.getPath(), (l, m) -> new AutoRotatingBakedModel(m));
|
||||
// FIXME FABRIC factory.addModelOverride(id.getPath(), (l, m) -> new AutoRotatingBakedModel(m));
|
||||
}
|
||||
|
||||
if (this.blockColor != null) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package appeng.bootstrap;
|
||||
|
||||
import appeng.api.features.AEFeature;
|
||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
|
||||
import net.fabricmc.fabric.impl.object.builder.FabricEntityType;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
@@ -19,7 +21,7 @@ public class EntityBuilder<T extends Entity> {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final EntityType.Builder<T> builder;
|
||||
private final FabricEntityTypeBuilder<T> builder;
|
||||
|
||||
private final EnumSet<AEFeature> features = EnumSet.noneOf(AEFeature.class);
|
||||
|
||||
@@ -27,7 +29,7 @@ public class EntityBuilder<T extends Entity> {
|
||||
SpawnGroup classification) {
|
||||
this.factory = factory;
|
||||
this.id = id;
|
||||
this.builder = EntityType.Builder.create(entityFactory, classification);
|
||||
this.builder = FabricEntityTypeBuilder.create(classification, entityFactory);
|
||||
}
|
||||
|
||||
public EntityBuilder<T> features(AEFeature... features) {
|
||||
@@ -41,14 +43,14 @@ public class EntityBuilder<T extends Entity> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityBuilder<T> customize(Consumer<EntityType.Builder<T>> function) {
|
||||
public EntityBuilder<T> customize(Consumer<FabricEntityTypeBuilder<T>> function) {
|
||||
function.accept(builder);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityType<T> build() {
|
||||
EntityType<T> entityType = builder.build();
|
||||
String fullId = "appliedenergistics2:" + this.id;
|
||||
EntityType<T> entityType = builder.build(fullId);
|
||||
Registry.register(Registry.ENTITY_TYPE, fullId, entityType);
|
||||
return entityType;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.bootstrap.components.IInitComponent;
|
||||
import appeng.core.AEItemGroup;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.CreativeTab;
|
||||
import appeng.core.features.ItemDefinition;
|
||||
@@ -149,8 +148,8 @@ class ItemDefinitionBuilder implements IItemBuilder {
|
||||
this.itemRendering.apply(this.factory, item);
|
||||
}
|
||||
|
||||
if (itemGroup instanceof AEItemGroup) {
|
||||
((AEItemGroup) itemGroup).add(definition);
|
||||
if (itemGroup == CreativeTab.INSTANCE) {
|
||||
CreativeTab.add(definition);
|
||||
}
|
||||
|
||||
return definition;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
package appeng.client;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
public enum ActionKey {
|
||||
TOGGLE_FOCUS(GLFW.GLFW_KEY_TAB);
|
||||
|
||||
private final int defaultKey;
|
||||
|
||||
private ActionKey(int defaultKey) {
|
||||
this.defaultKey = defaultKey;
|
||||
}
|
||||
|
||||
public String getTranslationKey() {
|
||||
return "key." + this.name().toLowerCase() + ".desc";
|
||||
}
|
||||
|
||||
public int getDefaultKey() {
|
||||
return this.defaultKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.client;
|
||||
|
||||
public enum EffectType {
|
||||
Energy, Vibrant, LightningArc
|
||||
}
|
||||
@@ -19,28 +19,28 @@
|
||||
package appeng.client.render.effects;
|
||||
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.ParticleFactory;
|
||||
import net.minecraft.client.particle.SpriteProvider;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.RedstoneParticle;
|
||||
import net.minecraft.client.particle.RedDustParticle;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.particle.DefaultParticleType;
|
||||
import net.minecraft.particles.RedstoneParticleData;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.particle.DustParticleEffect;
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ChargedOreFX extends RedstoneParticle {
|
||||
public class ChargedOreFX extends RedDustParticle {
|
||||
|
||||
private static final RedstoneParticleData PARTICLE_DATA = new RedstoneParticleData(0.21f, 0.61f, 1.0f, 1.0f);
|
||||
private static final DustParticleEffect PARTICLE_DATA = new DustParticleEffect(0.21f, 0.61f, 1.0f, 1.0f);
|
||||
|
||||
private ChargedOreFX(World worldIn, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed,
|
||||
IAnimatedSprite spriteSet) {
|
||||
super(worldIn, x, y, z, xSpeed, ySpeed, zSpeed, PARTICLE_DATA, spriteSet);
|
||||
private ChargedOreFX(ClientWorld world, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed,
|
||||
SpriteProvider spriteSet) {
|
||||
super(world, x, y, z, xSpeed, ySpeed, zSpeed, PARTICLE_DATA, spriteSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightnessForRender(final float par1) {
|
||||
int j1 = super.getBrightnessForRender(par1);
|
||||
public int getColorMultiplier(final float par1) {
|
||||
int j1 = super.getColorMultiplier(par1);
|
||||
j1 = Math.max(j1 >> 20, j1 >> 4);
|
||||
j1 += 3;
|
||||
if (j1 > 15) {
|
||||
@@ -50,17 +50,17 @@ public class ChargedOreFX extends RedstoneParticle {
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Factory implements IParticleFactory<DefaultParticleType> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||
private final SpriteProvider spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite p_i50477_1_) {
|
||||
public Factory(SpriteProvider p_i50477_1_) {
|
||||
this.spriteSet = p_i50477_1_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(DefaultParticleType typeIn, World worldIn, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
return new ChargedOreFX(worldIn, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet);
|
||||
public Particle createParticle(DefaultParticleType effect, ClientWorld world, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
return new ChargedOreFX(world, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,20 +18,17 @@
|
||||
|
||||
package appeng.client.render.effects;
|
||||
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.IParticleRenderType;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.particle.DefaultParticleType;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@@ -43,42 +40,44 @@ public class CraftingFx extends SpriteBillboardParticle {
|
||||
private final float offsetY;
|
||||
private final float offsetZ;
|
||||
|
||||
public CraftingFx(final World par1World, final double x, final double y, final double z,
|
||||
final IAnimatedSprite sprite) {
|
||||
super(par1World, x, y, z);
|
||||
public CraftingFx(ClientWorld world, final double x, final double y, final double z,
|
||||
final SpriteProvider sprite) {
|
||||
super(world, x, y, z);
|
||||
|
||||
// Pick a random normal, offset it by 0.35 and use that as the particle origin
|
||||
Vector3f off = new Vector3f(rand.nextFloat() - 0.5f, rand.nextFloat() - 0.5f, rand.nextFloat() - 0.5f);
|
||||
Vector3f off = new Vector3f(random.nextFloat() - 0.5f, random.nextFloat() - 0.5f, random.nextFloat() - 0.5f);
|
||||
off.normalize();
|
||||
off.mul(0.35f);
|
||||
off.scale(0.35f);
|
||||
offsetX = off.getX();
|
||||
offsetY = off.getY();
|
||||
offsetZ = off.getZ();
|
||||
|
||||
this.particleGravity = 0;
|
||||
this.particleBlue = 1;
|
||||
this.particleGreen = 0.9f;
|
||||
this.particleRed = 1;
|
||||
this.selectSpriteRandomly(sprite);
|
||||
this.gravityStrength = 0;
|
||||
this.colorBlue = 1;
|
||||
this.colorGreen = 0.9f;
|
||||
this.colorRed = 1;
|
||||
this.setSprite(sprite);
|
||||
this.maxAge /= 1.2;
|
||||
this.canCollide = false; // we're INSIDE the block anyway
|
||||
this.collidesWithWorld = false; // we're INSIDE the block anyway
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void renderParticle(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) {
|
||||
public void buildGeometry(VertexConsumer buffer, Camera camera, float partialTicks) {
|
||||
|
||||
float f = (this.age + partialTicks) / this.maxAge;
|
||||
|
||||
float offX = (float) posX + MathHelper.lerp(f, offsetX, 0);
|
||||
float offY = (float) posY + MathHelper.lerp(f, offsetY, 0);
|
||||
float offZ = (float) posZ + MathHelper.lerp(f, offsetZ, 0);
|
||||
float offX = (float) x + MathHelper.lerp(f, offsetX, 0);
|
||||
float offY = (float) y + MathHelper.lerp(f, offsetY, 0);
|
||||
float offZ = (float) z + MathHelper.lerp(f, offsetZ, 0);
|
||||
float alpha = MathHelper.lerp(easeOutCirc(f), 1.3f, 0.1f);
|
||||
float scale = MathHelper.lerp(easeOutCirc(f), 0.13f, 0.0f);
|
||||
|
||||
// I believe this particle is same as breaking particle, but should not exit the
|
||||
// original block it was
|
||||
// spawned in (which is encased in glass)
|
||||
Vec3d vec3d = renderInfo.getProjectedView();
|
||||
Vec3d vec3d = camera.getPos();
|
||||
offX -= vec3d.x;
|
||||
offY -= vec3d.y;
|
||||
offZ -= vec3d.z;
|
||||
@@ -88,8 +87,8 @@ public class CraftingFx extends SpriteBillboardParticle {
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Vector3f vector3f = avector3f[i];
|
||||
vector3f.transform(renderInfo.getRotation());
|
||||
vector3f.mul(scale);
|
||||
vector3f.rotate(camera.getRotation());
|
||||
vector3f.scale(scale);
|
||||
vector3f.add(offX, offY, offZ);
|
||||
}
|
||||
|
||||
@@ -98,14 +97,14 @@ public class CraftingFx extends SpriteBillboardParticle {
|
||||
float minV = this.getMinV();
|
||||
float maxV = this.getMaxV();
|
||||
int j = 15728880; // full brightness
|
||||
buffer.pos(avector3f[0].getX(), avector3f[0].getY(), avector3f[0].getZ()).tex(maxU, maxV)
|
||||
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j).endVertex();
|
||||
buffer.pos(avector3f[1].getX(), avector3f[1].getY(), avector3f[1].getZ()).tex(maxU, minV)
|
||||
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j).endVertex();
|
||||
buffer.pos(avector3f[2].getX(), avector3f[2].getY(), avector3f[2].getZ()).tex(minU, minV)
|
||||
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j).endVertex();
|
||||
buffer.pos(avector3f[3].getX(), avector3f[3].getY(), avector3f[3].getZ()).tex(minU, maxV)
|
||||
.color(this.particleRed, this.particleGreen, this.particleBlue, alpha).lightmap(j).endVertex();
|
||||
buffer.vertex(avector3f[0].getX(), avector3f[0].getY(), avector3f[0].getZ()).texture(maxU, maxV)
|
||||
.color(this.colorRed, this.colorGreen, this.colorBlue, alpha).light(j).next();
|
||||
buffer.vertex(avector3f[1].getX(), avector3f[1].getY(), avector3f[1].getZ()).texture(maxU, minV)
|
||||
.color(this.colorRed, this.colorGreen, this.colorBlue, alpha).light(j).next();
|
||||
buffer.vertex(avector3f[2].getX(), avector3f[2].getY(), avector3f[2].getZ()).texture(minU, minV)
|
||||
.color(this.colorRed, this.colorGreen, this.colorBlue, alpha).light(j).next();
|
||||
buffer.vertex(avector3f[3].getX(), avector3f[3].getY(), avector3f[3].getZ()).texture(minU, maxV)
|
||||
.color(this.colorRed, this.colorGreen, this.colorBlue, alpha).light(j).next();
|
||||
}
|
||||
|
||||
// https://easings.net/#easeOutCirc
|
||||
@@ -114,29 +113,29 @@ public class CraftingFx extends SpriteBillboardParticle {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParticleRenderType getRenderType() {
|
||||
return IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
public ParticleTextureSheet getType() {
|
||||
return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (this.age++ >= this.maxAge) {
|
||||
this.setExpired();
|
||||
this.markDead();
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Factory implements IParticleFactory<DefaultParticleType> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||
private final SpriteProvider spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite p_i50477_1_) {
|
||||
public Factory(SpriteProvider p_i50477_1_) {
|
||||
this.spriteSet = p_i50477_1_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(DefaultParticleType data, World worldIn, double x, double y, double z, double xSpeed,
|
||||
double ySpeed, double zSpeed) {
|
||||
return new CraftingFx(worldIn, x, y, z, spriteSet);
|
||||
public Particle createParticle(DefaultParticleType effect, ClientWorld world, double x, double y, double z, double xSpeed,
|
||||
double ySpeed, double zSpeed) {
|
||||
return new CraftingFx(world, x, y, z, spriteSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
package appeng.client.render.effects;
|
||||
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class EnergyFx extends SpriteBillboardParticle {
|
||||
@@ -34,44 +34,44 @@ public class EnergyFx extends SpriteBillboardParticle {
|
||||
private final int startBlkY;
|
||||
private final int startBlkZ;
|
||||
|
||||
public EnergyFx(final World par1World, final double par2, final double par4, final double par6,
|
||||
final IAnimatedSprite sprite) {
|
||||
super(par1World, par2, par4, par6);
|
||||
this.particleGravity = 0;
|
||||
this.particleBlue = 1;
|
||||
this.particleGreen = 1;
|
||||
this.particleRed = 1;
|
||||
this.particleAlpha = 1.4f;
|
||||
this.particleScale = 3.5f;
|
||||
this.selectSpriteRandomly(sprite);
|
||||
public EnergyFx(ClientWorld world, final double par2, final double par4, final double par6,
|
||||
final SpriteProvider sprite) {
|
||||
super(world, par2, par4, par6);
|
||||
this.gravityStrength = 0;
|
||||
this.colorBlue = 1;
|
||||
this.colorGreen = 1;
|
||||
this.colorRed = 1;
|
||||
this.colorAlpha = 1.4f;
|
||||
this.scale = 3.5f;
|
||||
this.setSprite(sprite);
|
||||
|
||||
this.startBlkX = MathHelper.floor(this.posX);
|
||||
this.startBlkY = MathHelper.floor(this.posY);
|
||||
this.startBlkZ = MathHelper.floor(this.posZ);
|
||||
this.startBlkX = MathHelper.floor(this.x);
|
||||
this.startBlkY = MathHelper.floor(this.y);
|
||||
this.startBlkZ = MathHelper.floor(this.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParticleRenderType getRenderType() {
|
||||
return IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
public ParticleTextureSheet getType() {
|
||||
return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getScale(float scaleFactor) {
|
||||
return 0.1f * this.particleScale;
|
||||
public float getSize(float tickDelta) {
|
||||
return 0.1f * this.scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderParticle(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) {
|
||||
float x = (float) (this.prevX + (this.posX - this.prevX) * partialTicks);
|
||||
float y = (float) (this.prevY + (this.posY - this.prevY) * partialTicks);
|
||||
float z = (float) (this.prevZ + (this.posZ - this.prevZ) * partialTicks);
|
||||
public void buildGeometry(VertexConsumer buffer, Camera camera, float partialTicks) {
|
||||
float x = (float) (this.prevPosX + (this.x - this.prevPosX) * partialTicks);
|
||||
float y = (float) (this.prevPosY + (this.y - this.prevPosY) * partialTicks);
|
||||
float z = (float) (this.prevPosZ + (this.z - this.prevPosZ) * partialTicks);
|
||||
|
||||
final int blkX = MathHelper.floor(x);
|
||||
final int blkY = MathHelper.floor(y);
|
||||
final int blkZ = MathHelper.floor(z);
|
||||
|
||||
if (blkX == this.startBlkX && blkY == this.startBlkY && blkZ == this.startBlkZ) {
|
||||
super.renderParticle(buffer, renderInfo, partialTicks);
|
||||
super.buildGeometry(buffer, camera, partialTicks);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,42 +80,42 @@ public class EnergyFx extends SpriteBillboardParticle {
|
||||
super.tick();
|
||||
this.onGround = false;
|
||||
|
||||
this.particleScale *= 0.89f;
|
||||
this.particleAlpha *= 0.89f;
|
||||
this.scale *= 0.89f;
|
||||
this.colorAlpha *= 0.89f;
|
||||
}
|
||||
|
||||
public void setMotionX(float motionX) {
|
||||
this.motionX = motionX;
|
||||
public void setVelocityX(float velocityX) {
|
||||
this.velocityX = velocityX;
|
||||
}
|
||||
|
||||
public void setMotionY(float motionY) {
|
||||
this.motionY = motionY;
|
||||
public void setVelocityY(float velocityY) {
|
||||
this.velocityY = velocityY;
|
||||
}
|
||||
|
||||
public void setMotionZ(float motionZ) {
|
||||
this.motionZ = motionZ;
|
||||
public void setVelocityZ(float velocityZ) {
|
||||
this.velocityZ = velocityZ;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Factory implements IParticleFactory<EnergyParticleData> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
public static class Factory implements ParticleFactory<EnergyParticleData> {
|
||||
private final SpriteProvider spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite spriteSet) {
|
||||
public Factory(SpriteProvider spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(EnergyParticleData data, World worldIn, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
EnergyFx result = new EnergyFx(worldIn, x, y, z, spriteSet);
|
||||
result.setMotionX((float) xSpeed);
|
||||
result.setMotionY((float) ySpeed);
|
||||
result.setMotionZ((float) zSpeed);
|
||||
if (data.forItem) {
|
||||
result.posX += -0.2 * data.direction.xOffset;
|
||||
result.posY += -0.2 * data.direction.yOffset;
|
||||
result.posZ += -0.2 * data.direction.zOffset;
|
||||
result.particleScale *= 0.8f;
|
||||
public Particle createParticle(EnergyParticleData effect, ClientWorld world, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
EnergyFx result = new EnergyFx(world, x, y, z, spriteSet);
|
||||
result.setVelocityX((float) xSpeed);
|
||||
result.setVelocityY((float) ySpeed);
|
||||
result.setVelocityZ((float) zSpeed);
|
||||
if (effect.forItem) {
|
||||
result.x += -0.2 * effect.direction.xOffset;
|
||||
result.y += -0.2 * effect.direction.yOffset;
|
||||
result.z += -0.2 * effect.direction.zOffset;
|
||||
result.scale *= 0.8f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -21,10 +21,11 @@ package appeng.client.render.effects;
|
||||
import java.util.Random;
|
||||
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.SpriteProvider;
|
||||
import net.minecraft.client.particle.ParticleFactory;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
||||
@@ -37,9 +38,9 @@ public class LightningArcFX extends LightningFX {
|
||||
private final double ry;
|
||||
private final double rz;
|
||||
|
||||
public LightningArcFX(final World w, final double x, final double y, final double z, final double ex,
|
||||
public LightningArcFX(ClientWorld world, final double x, final double y, final double z, final double ex,
|
||||
final double ey, final double ez, final double r, final double g, final double b) {
|
||||
super(w, x, y, z, r, g, b, 6);
|
||||
super(world, x, y, z, r, g, b, 6);
|
||||
|
||||
this.rx = ex - x;
|
||||
this.ry = ey - y;
|
||||
@@ -67,19 +68,19 @@ public class LightningArcFX extends LightningFX {
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Factory implements IParticleFactory<LightningArcParticleData> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
public static class Factory implements ParticleFactory<LightningArcParticleData> {
|
||||
private final SpriteProvider spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite spriteSet) {
|
||||
public Factory(SpriteProvider spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(LightningArcParticleData data, World worldIn, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
SpriteBillboardParticle lightningFX = new LightningArcFX(worldIn, x, y, z, data.target.x, data.target.y,
|
||||
data.target.z, 0, 0, 0);
|
||||
lightningFX.selectSpriteRandomly(this.spriteSet);
|
||||
public Particle createParticle(LightningArcParticleData effect, ClientWorld world, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
SpriteBillboardParticle lightningFX = new LightningArcFX(world, x, y, z, effect.target.x, effect.target.y,
|
||||
effect.target.z, 0, 0, 0);
|
||||
lightningFX.setSprite(this.spriteSet);
|
||||
return lightningFX;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,22 +20,19 @@ package appeng.client.render.effects;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.IParticleRenderType;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.particle.DefaultParticleType;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class LightningFX extends SpriteBillboardParticle {
|
||||
@@ -49,19 +46,19 @@ public class LightningFX extends SpriteBillboardParticle {
|
||||
private final double[] verticesWithUV = new double[3];
|
||||
private boolean hasData = false;
|
||||
|
||||
private LightningFX(final World w, final double x, final double y, final double z, final double r, final double g,
|
||||
private LightningFX(ClientWorld world, final double x, final double y, final double z, final double r, final double g,
|
||||
final double b) {
|
||||
this(w, x, y, z, r, g, b, 6);
|
||||
this(world, x, y, z, r, g, b, 6);
|
||||
this.regen();
|
||||
}
|
||||
|
||||
protected LightningFX(final World w, final double x, final double y, final double z, final double r, final double g,
|
||||
protected LightningFX(ClientWorld world, final double x, final double y, final double z, final double r, final double g,
|
||||
final double b, final int maxAge) {
|
||||
super(w, x, y, z, r, g, b);
|
||||
super(world, x, y, z, r, g, b);
|
||||
this.precomputedSteps = new double[LightningFX.STEPS][3];
|
||||
this.motionX = 0;
|
||||
this.motionY = 0;
|
||||
this.motionZ = 0;
|
||||
this.velocityX = 0;
|
||||
this.velocityY = 0;
|
||||
this.velocityZ = 0;
|
||||
this.maxAge = maxAge;
|
||||
}
|
||||
|
||||
@@ -84,40 +81,40 @@ public class LightningFX extends SpriteBillboardParticle {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParticleRenderType getRenderType() {
|
||||
public ParticleTextureSheet getType() {
|
||||
// TODO: FIXME
|
||||
return IParticleRenderType.PARTICLE_SHEET_OPAQUE;
|
||||
return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.prevPosX = this.x;
|
||||
this.prevPosY = this.y;
|
||||
this.prevPosZ = this.z;
|
||||
|
||||
if (this.age++ >= this.maxAge) {
|
||||
this.setExpired();
|
||||
this.markDead();
|
||||
}
|
||||
|
||||
this.motionY -= 0.04D * this.particleGravity;
|
||||
this.move(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.9800000190734863D;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= 0.9800000190734863D;
|
||||
this.velocityY -= 0.04D * this.gravityStrength;
|
||||
this.move(this.velocityX, this.velocityY, this.velocityZ);
|
||||
this.velocityX *= 0.9800000190734863D;
|
||||
this.velocityY *= 0.9800000190734863D;
|
||||
this.velocityZ *= 0.9800000190734863D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderParticle(IVertexBuilder buffer, ActiveRenderInfo renderInfo, float partialTicks) {
|
||||
Vec3d vec3d = renderInfo.getProjectedView();
|
||||
float centerX = (float) (MathHelper.lerp(partialTicks, this.prevX, this.posX) - vec3d.getX());
|
||||
float centerY = (float) (MathHelper.lerp(partialTicks, this.prevY, this.posY) - vec3d.getY());
|
||||
float centerZ = (float) (MathHelper.lerp(partialTicks, this.prevZ, this.posZ) - vec3d.getZ());
|
||||
public void buildGeometry(VertexConsumer buffer, Camera camera, float partialTicks) {
|
||||
Vec3d vec3d = camera.getPos();
|
||||
float centerX = (float) (MathHelper.lerp(partialTicks, this.prevPosX, this.x) - vec3d.getX());
|
||||
float centerY = (float) (MathHelper.lerp(partialTicks, this.prevPosY, this.y) - vec3d.getY());
|
||||
float centerZ = (float) (MathHelper.lerp(partialTicks, this.prevPosZ, this.z) - vec3d.getZ());
|
||||
|
||||
final float j = 1.0f;
|
||||
float red = this.particleRed * j * 0.9f;
|
||||
float green = this.particleGreen * j * 0.95f;
|
||||
float blue = this.particleBlue * j;
|
||||
final float alpha = this.particleAlpha;
|
||||
float red = this.colorRed * j * 0.9f;
|
||||
float green = this.colorGreen * j * 0.95f;
|
||||
float blue = this.colorBlue * j;
|
||||
final float alpha = this.colorAlpha;
|
||||
|
||||
if (this.age == 3) {
|
||||
this.regen();
|
||||
@@ -126,7 +123,7 @@ public class LightningFX extends SpriteBillboardParticle {
|
||||
float u = this.getMinU() + (this.getMaxU() - this.getMinU()) / 2;
|
||||
float v = this.getMinV() + (this.getMaxV() - this.getMinV()) / 2;
|
||||
|
||||
double scale = 0.02;// 0.02F * this.particleScale;
|
||||
double scale = 0.02;// 0.02F * this.scale;
|
||||
|
||||
final double[] a = new double[3];
|
||||
final double[] b = new double[3];
|
||||
@@ -147,17 +144,17 @@ public class LightningFX extends SpriteBillboardParticle {
|
||||
// FIXME offX *= 0.001;
|
||||
// FIXME offY *= 0.001;
|
||||
// FIXME offZ *= 0.001;
|
||||
red = this.particleRed * j * 0.4f;
|
||||
green = this.particleGreen * j * 0.25f;
|
||||
blue = this.particleBlue * j * 0.45f;
|
||||
red = this.colorRed * j * 0.4f;
|
||||
green = this.colorGreen * j * 0.25f;
|
||||
blue = this.colorBlue * j * 0.45f;
|
||||
} else {
|
||||
// FIXME offX = 0;
|
||||
// FIXME offY = 0;
|
||||
// FIXME offZ = 0;
|
||||
scale = 0.02;
|
||||
red = this.particleRed * j * 0.9f;
|
||||
green = this.particleGreen * j * 0.65f;
|
||||
blue = this.particleBlue * j * 0.85f;
|
||||
red = this.colorRed * j * 0.9f;
|
||||
green = this.colorGreen * j * 0.65f;
|
||||
blue = this.colorBlue * j * 0.85f;
|
||||
}
|
||||
|
||||
for (int cycle = 0; cycle < 3; cycle++) {
|
||||
@@ -221,17 +218,17 @@ public class LightningFX extends SpriteBillboardParticle {
|
||||
this.hasData = false;
|
||||
}
|
||||
|
||||
private void draw(float red, float green, float blue, final IVertexBuilder tess, final double[] a, final double[] b,
|
||||
final float u, final float v) {
|
||||
private void draw(float red, float green, float blue, final VertexConsumer tess, final double[] a, final double[] b,
|
||||
final float u, final float v) {
|
||||
if (this.hasData) {
|
||||
tess.pos(a[0], a[1], a[2]).tex(u, v).color(red, green, blue, this.particleAlpha)
|
||||
.lightmap(BRIGHTNESS, BRIGHTNESS).endVertex();
|
||||
tess.pos(this.vertices[0], this.vertices[1], this.vertices[2]).tex(u, v)
|
||||
.color(red, green, blue, this.particleAlpha).lightmap(BRIGHTNESS, BRIGHTNESS).endVertex();
|
||||
tess.pos(this.verticesWithUV[0], this.verticesWithUV[1], this.verticesWithUV[2]).tex(u, v)
|
||||
.color(red, green, blue, this.particleAlpha).lightmap(BRIGHTNESS, BRIGHTNESS).endVertex();
|
||||
tess.pos(b[0], b[1], b[2]).tex(u, v).color(red, green, blue, this.particleAlpha)
|
||||
.lightmap(BRIGHTNESS, BRIGHTNESS).endVertex();
|
||||
tess.vertex(a[0], a[1], a[2]).texture(u, v).color(red, green, blue, this.colorAlpha)
|
||||
.light(BRIGHTNESS, BRIGHTNESS).next();
|
||||
tess.vertex(this.vertices[0], this.vertices[1], this.vertices[2]).texture(u, v)
|
||||
.color(red, green, blue, this.colorAlpha).light(BRIGHTNESS, BRIGHTNESS).next();
|
||||
tess.vertex(this.verticesWithUV[0], this.verticesWithUV[1], this.verticesWithUV[2]).texture(u, v)
|
||||
.color(red, green, blue, this.colorAlpha).light(BRIGHTNESS, BRIGHTNESS).next();
|
||||
tess.vertex(b[0], b[1], b[2]).texture(u, v).color(red, green, blue, this.colorAlpha)
|
||||
.light(BRIGHTNESS, BRIGHTNESS).next();
|
||||
}
|
||||
this.hasData = true;
|
||||
for (int x = 0; x < 3; x++) {
|
||||
@@ -245,18 +242,18 @@ public class LightningFX extends SpriteBillboardParticle {
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Factory implements IParticleFactory<DefaultParticleType> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||
private final SpriteProvider spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite spriteSet) {
|
||||
public Factory(SpriteProvider spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(DefaultParticleType typeIn, World worldIn, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
LightningFX lightningFX = new LightningFX(worldIn, x, y, z, xSpeed, ySpeed, zSpeed);
|
||||
lightningFX.selectSpriteRandomly(this.spriteSet);
|
||||
public Particle createParticle(DefaultParticleType type, ClientWorld world, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
LightningFX lightningFX = new LightningFX(world, x, y, z, xSpeed, ySpeed, zSpeed);
|
||||
lightningFX.setSprite(this.spriteSet);
|
||||
return lightningFX;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,69 +20,69 @@ package appeng.client.render.effects;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.particle.DefaultParticleType;
|
||||
import net.minecraft.world.World;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.api.util.AEPartLocation;
|
||||
|
||||
public class MatterCannonFX extends SpriteBillboardParticle {
|
||||
|
||||
public MatterCannonFX(final World par1World, final double x, final double y, final double z,
|
||||
IAnimatedSprite sprite) {
|
||||
super(par1World, x, y, z);
|
||||
this.particleGravity = 0;
|
||||
this.particleBlue = 1;
|
||||
this.particleGreen = 1;
|
||||
this.particleRed = 1;
|
||||
this.particleAlpha = 1.4f;
|
||||
this.particleScale = 1.1f;
|
||||
this.motionX = 0.0f;
|
||||
this.motionY = 0.0f;
|
||||
this.motionZ = 0.0f;
|
||||
this.selectSpriteRandomly(sprite);
|
||||
public MatterCannonFX(ClientWorld world, final double x, final double y, final double z,
|
||||
SpriteProvider sprite) {
|
||||
super(world, x, y, z);
|
||||
this.gravityStrength = 0;
|
||||
this.colorBlue = 1;
|
||||
this.colorGreen = 1;
|
||||
this.colorRed = 1;
|
||||
this.colorAlpha = 1.4f;
|
||||
this.scale = 1.1f;
|
||||
this.velocityX = 0.0f;
|
||||
this.velocityY = 0.0f;
|
||||
this.velocityZ = 0.0f;
|
||||
this.setSprite(sprite);
|
||||
}
|
||||
|
||||
public void fromItem(final AEPartLocation d) {
|
||||
this.particleScale *= 1.2f;
|
||||
this.scale *= 1.2f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParticleRenderType getRenderType() {
|
||||
return IParticleRenderType.PARTICLE_SHEET_OPAQUE;
|
||||
public ParticleTextureSheet getType() {
|
||||
return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
this.prevPosX = this.x;
|
||||
this.prevPosY = this.y;
|
||||
this.prevPosZ = this.z;
|
||||
|
||||
if (this.age++ >= this.maxAge) {
|
||||
this.setExpired();
|
||||
this.markDead();
|
||||
}
|
||||
|
||||
this.motionY -= 0.04D * this.particleGravity;
|
||||
this.move(this.motionX, this.motionY, this.motionZ);
|
||||
this.motionX *= 0.9800000190734863D;
|
||||
this.motionY *= 0.9800000190734863D;
|
||||
this.motionZ *= 0.9800000190734863D;
|
||||
this.velocityY -= 0.04D * this.gravityStrength;
|
||||
this.move(this.velocityX, this.velocityY, this.velocityZ);
|
||||
this.velocityX *= 0.9800000190734863D;
|
||||
this.velocityY *= 0.9800000190734863D;
|
||||
this.velocityZ *= 0.9800000190734863D;
|
||||
|
||||
this.particleScale *= 1.19f;
|
||||
this.particleAlpha *= 0.59f;
|
||||
this.scale *= 1.19f;
|
||||
this.colorAlpha *= 0.59f;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Factory implements IParticleFactory<DefaultParticleType> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||
private final SpriteProvider spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite spriteSet) {
|
||||
public Factory(SpriteProvider spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(DefaultParticleType data, World world, double x, double y, double z, double xSpeed,
|
||||
double ySpeed, double zSpeed) {
|
||||
public Particle createParticle(DefaultParticleType effect, ClientWorld world, double x, double y, double z, double xSpeed,
|
||||
double ySpeed, double zSpeed) {
|
||||
return new MatterCannonFX(world, x, y, z, spriteSet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.particle.DefaultParticleType;
|
||||
import net.minecraft.particle.ParticleType;
|
||||
|
||||
import appeng.core.AppEng;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public final class ParticleTypes {
|
||||
|
||||
@@ -21,14 +22,14 @@ public final class ParticleTypes {
|
||||
public static final DefaultParticleType MATTER_CANNON = FabricParticleTypes.simple(false);
|
||||
public static final DefaultParticleType VIBRANT = FabricParticleTypes.simple(false);
|
||||
|
||||
static {
|
||||
CHARGED_ORE.setRegistryName(AppEng.MOD_ID, "charged_ore_fx");
|
||||
CRAFTING.setRegistryName(AppEng.MOD_ID, "crafting_fx");
|
||||
ENERGY.setRegistryName(AppEng.MOD_ID, "energy_fx");
|
||||
LIGHTNING_ARC.setRegistryName(AppEng.MOD_ID, "lightning_arc_fx");
|
||||
LIGHTNING.setRegistryName(AppEng.MOD_ID, "lightning_fx");
|
||||
MATTER_CANNON.setRegistryName(AppEng.MOD_ID, "matter_cannon_fx");
|
||||
VIBRANT.setRegistryName(AppEng.MOD_ID, "vibrant_fx");
|
||||
public static void register() {
|
||||
Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("charged_ore_fx"), CHARGED_ORE);
|
||||
Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("crafting_fx"), CRAFTING);
|
||||
Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("energy_fx"), ENERGY);
|
||||
Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("lightning_arc_fx"), LIGHTNING_ARC);
|
||||
Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("lightning_fx"), LIGHTNING);
|
||||
Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("matter_cannon_fx"), MATTER_CANNON);
|
||||
Registry.register(Registry.PARTICLE_TYPE, AppEng.makeId("vibrant_fx"), VIBRANT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,44 +20,43 @@ package appeng.client.render.effects;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.IParticleRenderType;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SpriteBillboardParticle;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.client.particle.ParticleFactory;
|
||||
import net.minecraft.client.particle.ParticleTextureSheet;
|
||||
import net.minecraft.client.particle.SpriteProvider;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.particle.DefaultParticleType;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class VibrantFX extends SpriteBillboardParticle {
|
||||
|
||||
public VibrantFX(final World par1World, final double x, final double y, final double z, final double par8,
|
||||
final double par10, final double par12, IAnimatedSprite sprite) {
|
||||
super(par1World, x, y, z, par8, par10, par12);
|
||||
final float f = this.rand.nextFloat() * 0.1F + 0.8F;
|
||||
this.particleRed = f * 0.7f;
|
||||
this.particleGreen = f * 0.89f;
|
||||
this.particleBlue = f * 0.9f;
|
||||
this.selectSpriteRandomly(sprite);
|
||||
this.setSize(0.04F, 0.04F);
|
||||
this.particleScale *= this.rand.nextFloat() * 0.6F + 1.9F;
|
||||
this.motionX = 0.0D;
|
||||
this.motionY = 0.0D;
|
||||
this.motionZ = 0.0D;
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
public VibrantFX(ClientWorld world, final double x, final double y, final double z, final double par8,
|
||||
final double par10, final double par12, SpriteProvider sprite) {
|
||||
super(world, x, y, z, par8, par10, par12);
|
||||
final float f = this.random.nextFloat() * 0.1F + 0.8F;
|
||||
this.colorRed = f * 0.7f;
|
||||
this.colorGreen = f * 0.89f;
|
||||
this.colorBlue = f * 0.9f;
|
||||
this.setSprite(sprite);
|
||||
this.setBoundingBoxSpacing(0.04F, 0.04F);
|
||||
this.scale *= this.random.nextFloat() * 0.6F + 1.9F;
|
||||
this.velocityX = 0.0D;
|
||||
this.velocityY = 0.0D;
|
||||
this.velocityZ = 0.0D;
|
||||
this.prevPosX = this.x;
|
||||
this.prevPosY = this.y;
|
||||
this.prevPosZ = this.z;
|
||||
this.maxAge = (int) (20.0D / (Math.random() * 0.8D + 0.1D));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IParticleRenderType getRenderType() {
|
||||
public ParticleTextureSheet getType() {
|
||||
// FIXME Might be PARTICLE_SHEET_LIT
|
||||
return IParticleRenderType.PARTICLE_SHEET_OPAQUE;
|
||||
return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightnessForRender(final float par1) {
|
||||
public int getColorMultiplier(final float par1) {
|
||||
// This just means full brightness
|
||||
return 15 << 20 | 15 << 4;
|
||||
}
|
||||
@@ -67,30 +66,30 @@ public class VibrantFX extends SpriteBillboardParticle {
|
||||
*/
|
||||
@Override
|
||||
public void tick() {
|
||||
this.prevX = this.posX;
|
||||
this.prevY = this.posY;
|
||||
this.prevZ = this.posZ;
|
||||
// this.moveEntity(this.motionX, this.motionY, this.motionZ);
|
||||
this.particleScale *= 0.95;
|
||||
this.prevPosX = this.x;
|
||||
this.prevPosY = this.y;
|
||||
this.prevPosZ = this.z;
|
||||
// this.moveEntity(this.velocityX, this.velocityY, this.velocityZ);
|
||||
this.scale *= 0.95;
|
||||
|
||||
if (this.maxAge <= 0 || this.particleScale < 0.1) {
|
||||
this.setExpired();
|
||||
if (this.maxAge <= 0 || this.scale < 0.1) {
|
||||
this.markDead();
|
||||
}
|
||||
this.maxAge--;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static class Factory implements IParticleFactory<DefaultParticleType> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
public static class Factory implements ParticleFactory<DefaultParticleType> {
|
||||
private final SpriteProvider spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite spriteSet) {
|
||||
public Factory(SpriteProvider spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Particle makeParticle(DefaultParticleType typeIn, World worldIn, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
return new VibrantFX(worldIn, x, y, z, xSpeed, ySpeed, zSpeed, spriteSet);
|
||||
public Particle createParticle(DefaultParticleType effect, ClientWorld world, double x, double y, double z,
|
||||
double xSpeed, double ySpeed, double zSpeed) {
|
||||
return new VibrantFX(world, x, y, z, xSpeed, ySpeed, zSpeed, spriteSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
/**
|
||||
* This implementation of IModelData allows us to know precisely which data is
|
||||
* part of the model data. This is relevant for {@link AutoRotatingBakedModel}
|
||||
* and {@link AutoRotatingCacheKey}.
|
||||
*/
|
||||
public class AEModelData {
|
||||
|
||||
private final Direction up;
|
||||
private final Direction forward;
|
||||
|
||||
public AEModelData(Direction up, Direction forward) {
|
||||
this.up = Preconditions.checkNotNull(up);
|
||||
this.forward = Preconditions.checkNotNull(forward);
|
||||
}
|
||||
|
||||
public Direction getUp() {
|
||||
return up;
|
||||
}
|
||||
|
||||
public Direction getForward() {
|
||||
return forward;
|
||||
}
|
||||
|
||||
public boolean isCacheable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
AEModelData that = (AEModelData) o;
|
||||
return up == that.up && forward == that.forward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(up, forward);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,57 +18,44 @@
|
||||
|
||||
package appeng.core;
|
||||
|
||||
import appeng.api.config.*;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.config.*;
|
||||
import appeng.core.settings.TickRates;
|
||||
import appeng.util.EnumCycler;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.function.DoubleSupplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.EnumValue;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
import appeng.api.config.*;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.settings.TickRates;
|
||||
import appeng.util.EnumCycler;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = AppEng.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public final class AEConfig {
|
||||
|
||||
public static final ClientConfig CLIENT;
|
||||
public static final ForgeConfigSpec CLIENT_SPEC;
|
||||
public static final CommonConfig COMMON;
|
||||
public static final ForgeConfigSpec COMMON_SPEC;
|
||||
public final ClientConfig clientConfig;
|
||||
public final CommonConfig commonConfig;
|
||||
|
||||
public AEConfig(File configDir) {
|
||||
ConfigSection clientRoot = ConfigSection.createRoot();
|
||||
clientConfig = new ClientConfig(clientRoot);
|
||||
syncClientConfig();
|
||||
|
||||
ConfigSection commonRoot = ConfigSection.createRoot();
|
||||
commonConfig = new CommonConfig(commonRoot);
|
||||
syncCommonConfig();
|
||||
|
||||
// FIXME config loading/saving
|
||||
}
|
||||
|
||||
// Default Energy Conversion Rates
|
||||
private static final double DEFAULT_IC2_EXCHANGE = 2.0;
|
||||
private static final double DEFAULT_RF_EXCHANGE = 0.5;
|
||||
|
||||
static {
|
||||
final Pair<ClientConfig, ForgeConfigSpec> specPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new);
|
||||
CLIENT_SPEC = specPair.getRight();
|
||||
CLIENT = specPair.getLeft();
|
||||
|
||||
final Pair<CommonConfig, ForgeConfigSpec> commonPair = new ForgeConfigSpec.Builder()
|
||||
.configure(CommonConfig::new);
|
||||
COMMON_SPEC = commonPair.getRight();
|
||||
COMMON = commonPair.getLeft();
|
||||
}
|
||||
|
||||
public static final String VERSION = "@version@";
|
||||
public static final String CHANNEL = "@aechannel@";
|
||||
|
||||
// Config instance
|
||||
private static final AEConfig instance = new AEConfig();
|
||||
private static AEConfig instance;
|
||||
|
||||
private final EnumSet<AEFeature> featureFlags = EnumSet.noneOf(AEFeature.class);
|
||||
|
||||
@@ -86,7 +73,7 @@ public final class AEConfig {
|
||||
private final int[] craftByStacks = new int[4];
|
||||
private final int[] priorityByStacks = new int[4];
|
||||
private final int[] levelByStacks = new int[4];
|
||||
private final int[] levelByMillibuckets = { 10, 100, 1000, 10000 };
|
||||
private final int[] levelByMillibuckets = {10, 100, 1000, 10000};
|
||||
|
||||
// Spatial IO/Dimension
|
||||
private double spatialPowerExponent;
|
||||
@@ -119,65 +106,55 @@ public final class AEConfig {
|
||||
// Tunnels
|
||||
public static final double TUNNEL_POWER_LOSS = 0.05;
|
||||
|
||||
// FIXME: this is shit, move this concern out of the config class
|
||||
@SubscribeEvent
|
||||
public static void onModConfigEvent(final ModConfig.ModConfigEvent configEvent) {
|
||||
if (configEvent.getConfig().getSpec() == CLIENT_SPEC) {
|
||||
instance.syncClientConfig();
|
||||
} else if (configEvent.getConfig().getSpec() == COMMON_SPEC) {
|
||||
instance.syncCommonConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private void syncClientConfig() {
|
||||
this.disableColoredCableRecipesInJEI = CLIENT.disableColoredCableRecipesInJEI.get();
|
||||
this.enableEffects = CLIENT.enableEffects.get();
|
||||
this.useLargeFonts = CLIENT.useLargeFonts.get();
|
||||
this.useColoredCraftingStatus = CLIENT.useColoredCraftingStatus.get();
|
||||
this.selectedPowerUnit = CLIENT.selectedPowerUnit.get();
|
||||
this.disableColoredCableRecipesInJEI = clientConfig.disableColoredCableRecipesInJEI.get();
|
||||
this.enableEffects = clientConfig.enableEffects.get();
|
||||
this.useLargeFonts = clientConfig.useLargeFonts.get();
|
||||
this.useColoredCraftingStatus = clientConfig.useColoredCraftingStatus.get();
|
||||
this.selectedPowerUnit = clientConfig.selectedPowerUnit.get();
|
||||
|
||||
// load buttons..
|
||||
for (int btnNum = 0; btnNum < 4; btnNum++) {
|
||||
this.craftByStacks[btnNum] = CLIENT.craftByStacks.get(btnNum).get();
|
||||
this.priorityByStacks[btnNum] = CLIENT.priorityByStacks.get(btnNum).get();
|
||||
this.levelByStacks[btnNum] = CLIENT.levelByStacks.get(btnNum).get();
|
||||
this.craftByStacks[btnNum] = clientConfig.craftByStacks.get(btnNum).get();
|
||||
this.priorityByStacks[btnNum] = clientConfig.priorityByStacks.get(btnNum).get();
|
||||
this.levelByStacks[btnNum] = clientConfig.levelByStacks.get(btnNum).get();
|
||||
}
|
||||
}
|
||||
|
||||
private void syncCommonConfig() {
|
||||
PowerUnits.EU.conversionRatio = COMMON.powerRatioIc2.get();
|
||||
PowerUnits.RF.conversionRatio = COMMON.powerRatioForgeEnergy.get();
|
||||
PowerMultiplier.CONFIG.multiplier = COMMON.powerUsageMultiplier.get();
|
||||
PowerUnits.EU.conversionRatio = commonConfig.powerRatioIc2.get();
|
||||
PowerUnits.RF.conversionRatio = commonConfig.powerRatioForgeEnergy.get();
|
||||
PowerMultiplier.CONFIG.multiplier = commonConfig.powerUsageMultiplier.get();
|
||||
|
||||
CondenserOutput.MATTER_BALLS.requiredPower = COMMON.condenserMatterBallsPower.get();
|
||||
CondenserOutput.SINGULARITY.requiredPower = COMMON.condenserSingularityPower.get();
|
||||
CondenserOutput.MATTER_BALLS.requiredPower = commonConfig.condenserMatterBallsPower.get();
|
||||
CondenserOutput.SINGULARITY.requiredPower = commonConfig.condenserSingularityPower.get();
|
||||
|
||||
this.oreDoublePercentage = COMMON.oreDoublePercentage.get().floatValue();
|
||||
this.oreDoublePercentage = (float) commonConfig.oreDoublePercentage.get();
|
||||
|
||||
this.meteoriteMaximumSpawnHeight = COMMON.meteoriteMaximumSpawnHeight.get();
|
||||
this.meteoriteDimensionWhitelist = new HashSet<>(COMMON.meteoriteDimensionWhitelist.get());
|
||||
this.meteoriteMaximumSpawnHeight = commonConfig.meteoriteMaximumSpawnHeight.get();
|
||||
this.meteoriteDimensionWhitelist = new HashSet<>(commonConfig.meteoriteDimensionWhitelist.get());
|
||||
|
||||
this.wirelessBaseCost = COMMON.wirelessBaseCost.get();
|
||||
this.wirelessCostMultiplier = COMMON.wirelessCostMultiplier.get();
|
||||
this.wirelessBaseRange = COMMON.wirelessBaseRange.get();
|
||||
this.wirelessBoosterRangeMultiplier = COMMON.wirelessBoosterRangeMultiplier.get();
|
||||
this.wirelessBoosterExp = COMMON.wirelessBoosterExp.get();
|
||||
this.wirelessHighWirelessCount = COMMON.wirelessHighWirelessCount.get();
|
||||
this.wirelessTerminalDrainMultiplier = COMMON.wirelessTerminalDrainMultiplier.get();
|
||||
this.wirelessBaseCost = commonConfig.wirelessBaseCost.get();
|
||||
this.wirelessCostMultiplier = commonConfig.wirelessCostMultiplier.get();
|
||||
this.wirelessBaseRange = commonConfig.wirelessBaseRange.get();
|
||||
this.wirelessBoosterRangeMultiplier = commonConfig.wirelessBoosterRangeMultiplier.get();
|
||||
this.wirelessBoosterExp = commonConfig.wirelessBoosterExp.get();
|
||||
this.wirelessHighWirelessCount = commonConfig.wirelessHighWirelessCount.get();
|
||||
this.wirelessTerminalDrainMultiplier = commonConfig.wirelessTerminalDrainMultiplier.get();
|
||||
|
||||
this.formationPlaneEntityLimit = COMMON.formationPlaneEntityLimit.get();
|
||||
this.formationPlaneEntityLimit = commonConfig.formationPlaneEntityLimit.get();
|
||||
|
||||
this.wirelessTerminalBattery = COMMON.wirelessTerminalBattery.get();
|
||||
this.chargedStaffBattery = COMMON.chargedStaffBattery.get();
|
||||
this.entropyManipulatorBattery = COMMON.entropyManipulatorBattery.get();
|
||||
this.portableCellBattery = COMMON.portableCellBattery.get();
|
||||
this.colorApplicatorBattery = COMMON.colorApplicatorBattery.get();
|
||||
this.matterCannonBattery = COMMON.matterCannonBattery.get();
|
||||
this.wirelessTerminalBattery = commonConfig.wirelessTerminalBattery.get();
|
||||
this.chargedStaffBattery = commonConfig.chargedStaffBattery.get();
|
||||
this.entropyManipulatorBattery = commonConfig.entropyManipulatorBattery.get();
|
||||
this.portableCellBattery = commonConfig.portableCellBattery.get();
|
||||
this.colorApplicatorBattery = commonConfig.colorApplicatorBattery.get();
|
||||
this.matterCannonBattery = commonConfig.matterCannonBattery.get();
|
||||
|
||||
this.featureFlags.clear();
|
||||
for (final AEFeature feature : AEFeature.values()) {
|
||||
if (feature.isVisible()) {
|
||||
if (COMMON.enabledFeatures.containsKey(feature)) {
|
||||
if (commonConfig.enabledFeatures.containsKey(feature)) {
|
||||
this.featureFlags.add(feature);
|
||||
}
|
||||
} else {
|
||||
@@ -186,16 +163,16 @@ public final class AEConfig {
|
||||
}
|
||||
|
||||
for (final TickRates tr : TickRates.values()) {
|
||||
tr.setMin(COMMON.tickRateMin.get(tr).get());
|
||||
tr.setMax(COMMON.tickRateMin.get(tr).get());
|
||||
tr.setMin(commonConfig.tickRateMin.get(tr).get());
|
||||
tr.setMax(commonConfig.tickRateMin.get(tr).get());
|
||||
}
|
||||
|
||||
this.spatialPowerMultiplier = COMMON.spatialPowerMultiplier.get();
|
||||
this.spatialPowerExponent = COMMON.spatialPowerExponent.get();
|
||||
this.spatialPowerMultiplier = commonConfig.spatialPowerMultiplier.get();
|
||||
this.spatialPowerExponent = commonConfig.spatialPowerExponent.get();
|
||||
|
||||
this.craftingCalculationTimePerTick = COMMON.craftingCalculationTimePerTick.get();
|
||||
this.craftingCalculationTimePerTick = commonConfig.craftingCalculationTimePerTick.get();
|
||||
|
||||
this.removeCrashingItemsOnLoad = COMMON.removeCrashingItemsOnLoad.get();
|
||||
this.removeCrashingItemsOnLoad = commonConfig.removeCrashingItemsOnLoad.get();
|
||||
}
|
||||
|
||||
public static AEConfig instance() {
|
||||
@@ -225,34 +202,27 @@ public final class AEConfig {
|
||||
}
|
||||
|
||||
public YesNo getSearchTooltips() {
|
||||
return CLIENT.searchTooltips.get();
|
||||
return clientConfig.searchTooltips.get();
|
||||
}
|
||||
|
||||
public TerminalStyle getTerminalStyle() {
|
||||
return CLIENT.terminalStyle.get();
|
||||
return clientConfig.terminalStyle.get();
|
||||
}
|
||||
|
||||
public void setTerminalStyle(TerminalStyle setting) {
|
||||
CLIENT.terminalStyle.set(setting);
|
||||
clientConfig.terminalStyle.set(setting);
|
||||
}
|
||||
|
||||
public SearchBoxMode getTerminalSearchMode() {
|
||||
return CLIENT.terminalSearchMode.get();
|
||||
return clientConfig.terminalSearchMode.get();
|
||||
}
|
||||
|
||||
public void setTerminalSearchMode(SearchBoxMode setting) {
|
||||
CLIENT.terminalSearchMode.set(setting);
|
||||
clientConfig.terminalSearchMode.set(setting);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
if (CLIENT_SPEC.isLoaded()) {
|
||||
CLIENT.selectedPowerUnit.set(this.selectedPowerUnit);
|
||||
CLIENT_SPEC.save();
|
||||
}
|
||||
|
||||
if (COMMON_SPEC.isLoaded()) {
|
||||
COMMON_SPEC.save();
|
||||
}
|
||||
clientConfig.selectedPowerUnit.set(this.selectedPowerUnit);
|
||||
}
|
||||
|
||||
public int craftItemsByStackAmounts(final int i) {
|
||||
@@ -272,14 +242,14 @@ public final class AEConfig {
|
||||
}
|
||||
|
||||
public PowerUnits getSelectedPowerUnit() {
|
||||
return this.selectedPowerUnit;
|
||||
return this.clientConfig.selectedPowerUnit.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void nextPowerUnit(final boolean backwards) {
|
||||
this.selectedPowerUnit = EnumCycler.rotateEnum(this.selectedPowerUnit, backwards,
|
||||
PowerUnits selectedPowerUnit = EnumCycler.rotateEnum(this.selectedPowerUnit, backwards,
|
||||
(EnumSet<PowerUnits>) Settings.POWER_UNITS.getPossibleValues());
|
||||
this.save();
|
||||
clientConfig.selectedPowerUnit.set(selectedPowerUnit);
|
||||
}
|
||||
|
||||
// Getters
|
||||
@@ -348,15 +318,15 @@ public final class AEConfig {
|
||||
}
|
||||
|
||||
public float getSpawnChargedChance() {
|
||||
return COMMON.spawnChargedChance.get().floatValue();
|
||||
return (float) commonConfig.spawnChargedChance.get();
|
||||
}
|
||||
|
||||
public int getQuartzOresPerCluster() {
|
||||
return COMMON.quartzOresPerCluster.get();
|
||||
return commonConfig.quartzOresPerCluster.get();
|
||||
}
|
||||
|
||||
public int getQuartzOresClusterAmount() {
|
||||
return COMMON.quartzOresClusterAmount.get();
|
||||
return commonConfig.quartzOresClusterAmount.get();
|
||||
}
|
||||
|
||||
public int getMeteoriteMaximumSpawnHeight() {
|
||||
@@ -372,32 +342,31 @@ public final class AEConfig {
|
||||
private static class ClientConfig {
|
||||
|
||||
// Misc
|
||||
public final BooleanValue enableEffects;
|
||||
public final BooleanValue useLargeFonts;
|
||||
public final BooleanValue useColoredCraftingStatus;
|
||||
public final BooleanValue disableColoredCableRecipesInJEI;
|
||||
public final EnumValue<PowerUnits> selectedPowerUnit;
|
||||
public final BooleanOption enableEffects;
|
||||
public final BooleanOption useLargeFonts;
|
||||
public final BooleanOption useColoredCraftingStatus;
|
||||
public final BooleanOption disableColoredCableRecipesInJEI;
|
||||
public final EnumOption<PowerUnits> selectedPowerUnit;
|
||||
|
||||
// GUI Buttons
|
||||
private static final int[] BTN_BY_STACK_DEFAULTS = { 1, 10, 100, 1000 };
|
||||
public final List<ConfigValue<Integer>> craftByStacks;
|
||||
public final List<ConfigValue<Integer>> priorityByStacks;
|
||||
public final List<ConfigValue<Integer>> levelByStacks;
|
||||
private static final int[] BTN_BY_STACK_DEFAULTS = {1, 10, 100, 1000};
|
||||
public final List<IntegerOption> craftByStacks;
|
||||
public final List<IntegerOption> priorityByStacks;
|
||||
public final List<IntegerOption> levelByStacks;
|
||||
|
||||
// Terminal Settings
|
||||
public final EnumValue<YesNo> searchTooltips;
|
||||
public final EnumValue<TerminalStyle> terminalStyle;
|
||||
public final EnumValue<SearchBoxMode> terminalSearchMode;
|
||||
public final EnumOption<YesNo> searchTooltips;
|
||||
public final EnumOption<TerminalStyle> terminalStyle;
|
||||
public final EnumOption<SearchBoxMode> terminalSearchMode;
|
||||
|
||||
public ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||
builder.push("client");
|
||||
this.disableColoredCableRecipesInJEI = builder.comment("TODO").define("disableColoredCableRecipesInJEI",
|
||||
public ClientConfig(ConfigSection root) {
|
||||
ConfigSection client = root.subsection("client");
|
||||
this.disableColoredCableRecipesInJEI = client.addBoolean("disableColoredCableRecipesInJEI",
|
||||
true);
|
||||
this.enableEffects = builder.comment("TODO").define("enableEffects", true);
|
||||
this.useLargeFonts = builder.comment("TODO").define("useTerminalUseLargeFont", false);
|
||||
this.useColoredCraftingStatus = builder.comment("TODO").define("useColoredCraftingStatus", true);
|
||||
this.selectedPowerUnit = builder.comment("Power unit shown in AE UIs").defineEnum("PowerUnit",
|
||||
PowerUnits.AE, PowerUnits.values());
|
||||
this.enableEffects = client.addBoolean("enableEffects", true);
|
||||
this.useLargeFonts = client.addBoolean("useTerminalUseLargeFont", false);
|
||||
this.useColoredCraftingStatus = client.addBoolean("useColoredCraftingStatus", true);
|
||||
this.selectedPowerUnit = client.addEnum("PowerUnit", PowerUnits.AE, "Power unit shown in AE UIs");
|
||||
|
||||
this.craftByStacks = new ArrayList<>(4);
|
||||
this.priorityByStacks = new ArrayList<>(4);
|
||||
@@ -407,23 +376,19 @@ public final class AEConfig {
|
||||
int defaultValue = BTN_BY_STACK_DEFAULTS[btnNum];
|
||||
final int buttonCap = (int) (Math.pow(10, btnNum + 1) - 1);
|
||||
|
||||
this.craftByStacks.add(builder.comment("Controls buttons on Crafting Screen")
|
||||
.defineInRange("craftByStacks" + btnNum, defaultValue, 1, buttonCap));
|
||||
this.priorityByStacks.add(builder.comment("Controls buttons on Priority Screen")
|
||||
.defineInRange("priorityByStacks" + btnNum, defaultValue, 1, buttonCap));
|
||||
this.levelByStacks.add(builder.comment("Controls buttons on Level Emitter Screen")
|
||||
.defineInRange("levelByStacks" + btnNum, defaultValue, 1, buttonCap));
|
||||
this.craftByStacks.add(client
|
||||
.addInt("craftByStacks" + btnNum, defaultValue, 1, buttonCap, "Controls buttons on Crafting Screen"));
|
||||
this.priorityByStacks.add(client
|
||||
.addInt("priorityByStacks" + btnNum, defaultValue, 1, buttonCap, "Controls buttons on Priority Screen"));
|
||||
this.levelByStacks.add(client
|
||||
.addInt("levelByStacks" + btnNum, defaultValue, 1, buttonCap, "Controls buttons on Level Emitter Screen"));
|
||||
}
|
||||
|
||||
builder.pop();
|
||||
|
||||
builder.push("terminals");
|
||||
this.searchTooltips = builder.comment("Should tooltips be searched. Performance impact")
|
||||
.defineEnum("searchTooltips", YesNo.YES, YesNo.values());
|
||||
this.terminalStyle = builder.defineEnum("terminalStyle", TerminalStyle.TALL, TerminalStyle.values());
|
||||
this.terminalSearchMode = builder.defineEnum("terminalSearchMode", SearchBoxMode.AUTOSEARCH,
|
||||
SearchBoxMode.values());
|
||||
builder.pop();
|
||||
ConfigSection terminals = root.subsection("terminals");
|
||||
this.searchTooltips = terminals
|
||||
.addEnum("searchTooltips", YesNo.YES, "Should tooltips be searched. Performance impact");
|
||||
this.terminalStyle = terminals.addEnum("terminalStyle", TerminalStyle.TALL);
|
||||
this.terminalSearchMode = terminals.addEnum("terminalSearchMode", SearchBoxMode.AUTOSEARCH);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -431,63 +396,62 @@ public final class AEConfig {
|
||||
private static class CommonConfig {
|
||||
|
||||
// Feature toggles
|
||||
public final Map<AEFeature, BooleanValue> enabledFeatures = new EnumMap<>(AEFeature.class);
|
||||
public final Map<AEFeature, BooleanOption> enabledFeatures = new EnumMap<>(AEFeature.class);
|
||||
|
||||
// Misc
|
||||
public final BooleanValue removeCrashingItemsOnLoad;
|
||||
public final ConfigValue<Integer> formationPlaneEntityLimit;
|
||||
public final ConfigValue<Integer> craftingCalculationTimePerTick;
|
||||
public final BooleanOption removeCrashingItemsOnLoad;
|
||||
public final IntegerOption formationPlaneEntityLimit;
|
||||
public final IntegerOption craftingCalculationTimePerTick;
|
||||
|
||||
// Spatial IO/Dimension
|
||||
public final ConfigValue<Double> spatialPowerExponent;
|
||||
public final ConfigValue<Double> spatialPowerMultiplier;
|
||||
public final DoubleOption spatialPowerExponent;
|
||||
public final DoubleOption spatialPowerMultiplier;
|
||||
|
||||
// Grindstone
|
||||
public final DoubleValue oreDoublePercentage;
|
||||
public final DoubleOption oreDoublePercentage;
|
||||
|
||||
// Batteries
|
||||
public final ConfigValue<Integer> wirelessTerminalBattery;
|
||||
public final ConfigValue<Integer> entropyManipulatorBattery;
|
||||
public final ConfigValue<Integer> matterCannonBattery;
|
||||
public final ConfigValue<Integer> portableCellBattery;
|
||||
public final ConfigValue<Integer> colorApplicatorBattery;
|
||||
public final ConfigValue<Integer> chargedStaffBattery;
|
||||
public final IntegerOption wirelessTerminalBattery;
|
||||
public final IntegerOption entropyManipulatorBattery;
|
||||
public final IntegerOption matterCannonBattery;
|
||||
public final IntegerOption portableCellBattery;
|
||||
public final IntegerOption colorApplicatorBattery;
|
||||
public final IntegerOption chargedStaffBattery;
|
||||
|
||||
// Certus quartz
|
||||
public final DoubleValue spawnChargedChance;
|
||||
public final ConfigValue<Integer> quartzOresPerCluster;
|
||||
public final ConfigValue<Integer> quartzOresClusterAmount;
|
||||
public final DoubleOption spawnChargedChance;
|
||||
public final IntegerOption quartzOresPerCluster;
|
||||
public final IntegerOption quartzOresClusterAmount;
|
||||
|
||||
// Meteors
|
||||
public final ConfigValue<Integer> meteoriteMaximumSpawnHeight;
|
||||
public final ConfigValue<List<? extends String>> meteoriteDimensionWhitelist;
|
||||
public final IntegerOption meteoriteMaximumSpawnHeight;
|
||||
public final StringListOption meteoriteDimensionWhitelist;
|
||||
|
||||
// Wireless
|
||||
public final ConfigValue<Double> wirelessBaseCost;
|
||||
public final ConfigValue<Double> wirelessCostMultiplier;
|
||||
public final ConfigValue<Double> wirelessTerminalDrainMultiplier;
|
||||
public final ConfigValue<Double> wirelessBaseRange;
|
||||
public final ConfigValue<Double> wirelessBoosterRangeMultiplier;
|
||||
public final ConfigValue<Double> wirelessBoosterExp;
|
||||
public final ConfigValue<Double> wirelessHighWirelessCount;
|
||||
public final DoubleOption wirelessBaseCost;
|
||||
public final DoubleOption wirelessCostMultiplier;
|
||||
public final DoubleOption wirelessTerminalDrainMultiplier;
|
||||
public final DoubleOption wirelessBaseRange;
|
||||
public final DoubleOption wirelessBoosterRangeMultiplier;
|
||||
public final DoubleOption wirelessBoosterExp;
|
||||
public final DoubleOption wirelessHighWirelessCount;
|
||||
|
||||
// Power Ratios
|
||||
public final ConfigValue<Double> powerRatioIc2;
|
||||
public final ConfigValue<Double> powerRatioForgeEnergy;
|
||||
public final DoubleValue powerUsageMultiplier;
|
||||
public final DoubleOption powerRatioIc2;
|
||||
public final DoubleOption powerRatioForgeEnergy;
|
||||
public final DoubleOption powerUsageMultiplier;
|
||||
|
||||
// Condenser Power Requirement
|
||||
public final ConfigValue<Integer> condenserMatterBallsPower;
|
||||
public final ConfigValue<Integer> condenserSingularityPower;
|
||||
public final IntegerOption condenserMatterBallsPower;
|
||||
public final IntegerOption condenserSingularityPower;
|
||||
|
||||
public final Map<TickRates, ConfigValue<Integer>> tickRateMin = new HashMap<>();
|
||||
public final Map<TickRates, ConfigValue<Integer>> tickRateMax = new HashMap<>();
|
||||
public final Map<TickRates, IntegerOption> tickRateMin = new HashMap<>();
|
||||
public final Map<TickRates, IntegerOption> tickRateMax = new HashMap<>();
|
||||
|
||||
public CommonConfig(ForgeConfigSpec.Builder builder) {
|
||||
public CommonConfig(ConfigSection root) {
|
||||
|
||||
// Feature switches
|
||||
builder.comment("Warning: Disabling a feature may disable other features depending on it.")
|
||||
.push("features");
|
||||
ConfigSection features = root.subsection("features", "Warning: Disabling a feature may disable other features depending on it.");
|
||||
|
||||
// We need to group by feature category
|
||||
Map<String, List<AEFeature>> groupedFeatures = Arrays.stream(AEFeature.values())
|
||||
@@ -497,96 +461,74 @@ public final class AEConfig {
|
||||
for (final String category : groupedFeatures.keySet()) {
|
||||
List<AEFeature> featuresInGroup = groupedFeatures.get(category);
|
||||
|
||||
builder.push(category);
|
||||
ConfigSection categorySection = features.subsection(category);
|
||||
for (AEFeature feature : featuresInGroup) {
|
||||
if (feature.isConfig()) {
|
||||
enabledFeatures.put(feature, builder.comment(Strings.nullToEmpty(feature.comment()))
|
||||
.define(feature.key(), feature.isEnabled()));
|
||||
enabledFeatures.put(feature, categorySection.addBoolean(feature.key(), feature.isEnabled(), feature.comment()));
|
||||
}
|
||||
}
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
builder.pop();
|
||||
ConfigSection general = root.subsection("general");
|
||||
removeCrashingItemsOnLoad = general.addBoolean("removeCrashingItemsOnLoad", false, "Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!");
|
||||
|
||||
builder.push("general");
|
||||
removeCrashingItemsOnLoad = builder.comment(
|
||||
"Will auto-remove items that crash when being loaded from storage. This will destroy those items instead of crashing the game!")
|
||||
.define("removeCrashingItemsOnLoad", false);
|
||||
builder.pop();
|
||||
ConfigSection automation = root.subsection("automation");
|
||||
formationPlaneEntityLimit = automation.addInt("formationPlaneEntityLimit", 128);
|
||||
|
||||
builder.push("automation");
|
||||
formationPlaneEntityLimit = builder.comment("TODO").define("formationPlaneEntityLimit", 128);
|
||||
builder.pop();
|
||||
ConfigSection craftingCPU = root.subsection("craftingCPU");
|
||||
this.craftingCalculationTimePerTick = craftingCPU.addInt("craftingCalculationTimePerTick", 5);
|
||||
|
||||
builder.push("craftingCPU");
|
||||
|
||||
this.craftingCalculationTimePerTick = builder.define("craftingCalculationTimePerTick", 5);
|
||||
ConfigSection spatialio = root.subsection("spatialio");
|
||||
this.spatialPowerMultiplier = spatialio.addDouble("spatialPowerMultiplier", 1250.0);
|
||||
this.spatialPowerExponent = spatialio.addDouble("spatialPowerExponent", 1.35);
|
||||
|
||||
builder.pop();
|
||||
ConfigSection grindStone = root.subsection("GrindStone");
|
||||
this.oreDoublePercentage = grindStone.addDouble("oreDoublePercentage", 90.0, 0.0, 100.0, "Chance to actually get an output with stacksize > 1.");
|
||||
|
||||
builder.push("spatialio");
|
||||
this.spatialPowerMultiplier = builder.define("spatialPowerMultiplier", 1250.0);
|
||||
this.spatialPowerExponent = builder.define("spatialPowerExponent", 1.35);
|
||||
builder.pop();
|
||||
ConfigSection battery = root.subsection("battery");
|
||||
this.wirelessTerminalBattery = battery.addInt("wirelessTerminal", 1600000);
|
||||
this.chargedStaffBattery = battery.addInt("chargedStaff", 8000);
|
||||
this.entropyManipulatorBattery = battery.addInt("entropyManipulator", 200000);
|
||||
this.portableCellBattery = battery.addInt("portableCell", 20000);
|
||||
this.colorApplicatorBattery = battery.addInt("colorApplicator", 20000);
|
||||
this.matterCannonBattery = battery.addInt("matterCannon", 200000);
|
||||
|
||||
builder.push("GrindStone");
|
||||
this.oreDoublePercentage = builder.comment("Chance to actually get an output with stacksize > 1.")
|
||||
.defineInRange("oreDoublePercentage", 90.0, 0.0, 100.0);
|
||||
builder.pop();
|
||||
ConfigSection worldGen = root.subsection("worldGen");
|
||||
|
||||
builder.push("battery");
|
||||
this.wirelessTerminalBattery = builder.define("wirelessTerminal", 1600000);
|
||||
this.chargedStaffBattery = builder.define("chargedStaff", 8000);
|
||||
this.entropyManipulatorBattery = builder.define("entropyManipulator", 200000);
|
||||
this.portableCellBattery = builder.define("portableCell", 20000);
|
||||
this.colorApplicatorBattery = builder.define("colorApplicator", 20000);
|
||||
this.matterCannonBattery = builder.define("matterCannon", 200000);
|
||||
builder.pop();
|
||||
|
||||
builder.push("worldGen");
|
||||
|
||||
this.spawnChargedChance = builder.defineInRange("spawnChargedChance", 0.08, 0.0, 1.0);
|
||||
this.meteoriteMaximumSpawnHeight = builder.define("meteoriteMaximumSpawnHeight", 180);
|
||||
this.spawnChargedChance = worldGen.addDouble("spawnChargedChance", 0.08, 0.0, 1.0);
|
||||
this.meteoriteMaximumSpawnHeight = worldGen.addInt("meteoriteMaximumSpawnHeight", 180);
|
||||
List<String> defaultDimensionWhitelist = new ArrayList<>();
|
||||
defaultDimensionWhitelist.add(DimensionType.getKey(DimensionType.OVERWORLD).toString());
|
||||
this.meteoriteDimensionWhitelist = builder.defineList("meteoriteDimensionWhitelist",
|
||||
defaultDimensionWhitelist, obj -> true);
|
||||
defaultDimensionWhitelist.add(DimensionType.OVERWORLD_REGISTRY_KEY.getValue().toString());
|
||||
this.meteoriteDimensionWhitelist = worldGen.addStringList("meteoriteDimensionWhitelist",
|
||||
defaultDimensionWhitelist);
|
||||
|
||||
this.quartzOresPerCluster = builder.define("quartzOresPerCluster", 4);
|
||||
this.quartzOresClusterAmount = builder.define("quartzOresClusterAmount", 20);
|
||||
this.quartzOresPerCluster = worldGen.addInt("quartzOresPerCluster", 4);
|
||||
this.quartzOresClusterAmount = worldGen.addInt("quartzOresClusterAmount", 20);
|
||||
|
||||
builder.pop();
|
||||
ConfigSection wireless = root.subsection("wireless");
|
||||
this.wirelessBaseCost = wireless.addDouble("wirelessBaseCost", 8.0);
|
||||
this.wirelessCostMultiplier = wireless.addDouble("wirelessCostMultiplier", 1.0);
|
||||
this.wirelessBaseRange = wireless.addDouble("wirelessBaseRange", 16.0);
|
||||
this.wirelessBoosterRangeMultiplier = wireless.addDouble("wirelessBoosterRangeMultiplier", 1.0);
|
||||
this.wirelessBoosterExp = wireless.addDouble("wirelessBoosterExp", 1.5);
|
||||
this.wirelessHighWirelessCount = wireless.addDouble("wirelessHighWirelessCount", 64.0);
|
||||
this.wirelessTerminalDrainMultiplier = wireless.addDouble("wirelessTerminalDrainMultiplier", 1.0);
|
||||
|
||||
builder.push("wireless");
|
||||
this.wirelessBaseCost = builder.define("wirelessBaseCost", 8.0);
|
||||
this.wirelessCostMultiplier = builder.define("wirelessCostMultiplier", 1.0);
|
||||
this.wirelessBaseRange = builder.define("wirelessBaseRange", 16.0);
|
||||
this.wirelessBoosterRangeMultiplier = builder.define("wirelessBoosterRangeMultiplier", 1.0);
|
||||
this.wirelessBoosterExp = builder.define("wirelessBoosterExp", 1.5);
|
||||
this.wirelessHighWirelessCount = builder.define("wirelessHighWirelessCount", 64.0);
|
||||
this.wirelessTerminalDrainMultiplier = builder.define("wirelessTerminalDrainMultiplier", 1.0);
|
||||
builder.pop();
|
||||
ConfigSection PowerRatios = root.subsection("PowerRatios");
|
||||
powerRatioIc2 = PowerRatios.addDouble("IC2", DEFAULT_IC2_EXCHANGE);
|
||||
powerRatioForgeEnergy = PowerRatios.addDouble("ForgeEnergy", DEFAULT_RF_EXCHANGE);
|
||||
powerUsageMultiplier = PowerRatios.addDouble("UsageMultiplier", 1.0, 0.01, Double.MAX_VALUE);
|
||||
|
||||
builder.push("PowerRatios");
|
||||
powerRatioIc2 = builder.define("IC2", DEFAULT_IC2_EXCHANGE);
|
||||
powerRatioForgeEnergy = builder.define("ForgeEnergy", DEFAULT_RF_EXCHANGE);
|
||||
powerUsageMultiplier = builder.defineInRange("UsageMultiplier", 1.0, 0.01, Double.MAX_VALUE);
|
||||
builder.pop();
|
||||
ConfigSection Condenser = root.subsection("Condenser");
|
||||
condenserMatterBallsPower = Condenser.addInt("MatterBalls", 256);
|
||||
condenserSingularityPower = Condenser.addInt("Singularity", 256000);
|
||||
|
||||
builder.push("Condenser");
|
||||
condenserMatterBallsPower = builder.define("MatterBalls", 256);
|
||||
condenserSingularityPower = builder.define("Singularity", 256000);
|
||||
builder.pop();
|
||||
|
||||
builder.comment(
|
||||
" Min / Max Tickrates for dynamic ticking, most of these components also use sleeping, to prevent constant ticking, adjust with care, non standard rates are not supported or tested.")
|
||||
.push("tickRates");
|
||||
ConfigSection tickrates = root.subsection("tickRates", " Min / Max Tickrates for dynamic ticking, most of these components also use sleeping, to prevent constant ticking, adjust with care, non standard rates are not supported or tested.");
|
||||
for (TickRates tickRate : TickRates.values()) {
|
||||
tickRateMin.put(tickRate, builder.define(tickRate.name() + "Min", tickRate.getDefaultMin()));
|
||||
tickRateMax.put(tickRate, builder.define(tickRate.name() + "Max", tickRate.getDefaultMax()));
|
||||
tickRateMin.put(tickRate, tickrates.addInt(tickRate.name() + "Min", tickRate.getDefaultMin()));
|
||||
tickRateMax.put(tickRate, tickrates.addInt(tickRate.name() + "Max", tickRate.getDefaultMax()));
|
||||
}
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,286 +18,260 @@
|
||||
|
||||
package appeng.core;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import appeng.api.parts.CableRenderMode;
|
||||
import appeng.block.AEBaseBlock;
|
||||
import appeng.client.ActionKey;
|
||||
import appeng.client.EffectType;
|
||||
import appeng.core.sync.BasePacket;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
public interface AppEng {
|
||||
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.particle.ParticleType;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.ModDimension;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.CrashReportExtender;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
String MOD_ID = "appliedenergistics2";
|
||||
|
||||
import appeng.block.paint.PaintSplotchesModel;
|
||||
import appeng.block.qnb.QnbFormedModel;
|
||||
import appeng.bootstrap.components.IClientSetupComponent;
|
||||
import appeng.bootstrap.components.IInitComponent;
|
||||
import appeng.bootstrap.components.IPostInitComponent;
|
||||
import appeng.capabilities.Capabilities;
|
||||
import appeng.client.ClientHelper;
|
||||
import appeng.client.render.DummyFluidItemModel;
|
||||
import appeng.client.render.FacadeItemModel;
|
||||
import appeng.client.render.SimpleModelLoader;
|
||||
import appeng.client.render.cablebus.CableBusModelLoader;
|
||||
import appeng.client.render.cablebus.P2PTunnelFrequencyModel;
|
||||
import appeng.client.render.crafting.CraftingCubeModelLoader;
|
||||
import appeng.client.render.crafting.EncodedPatternModelLoader;
|
||||
import appeng.client.render.model.*;
|
||||
import appeng.client.render.spatial.SpatialPylonModel;
|
||||
import appeng.core.crash.ModCrashEnhancement;
|
||||
import appeng.core.features.registries.PartModels;
|
||||
import appeng.core.stats.AdvancementTriggers;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
import appeng.entity.*;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.integration.Integrations;
|
||||
import appeng.parts.PartPlacement;
|
||||
import appeng.parts.automation.PlaneModelLoader;
|
||||
import appeng.server.ServerHelper;
|
||||
AppEng INSTANCE = null;
|
||||
|
||||
@Mod(AppEng.MOD_ID)
|
||||
public final class AppEng {
|
||||
public static CommonHelper proxy;
|
||||
|
||||
public static final String MOD_ID = "appliedenergistics2";
|
||||
public static final String MOD_NAME = "Applied Energistics 2";
|
||||
|
||||
private static AppEng INSTANCE;
|
||||
|
||||
private final Registration registration;
|
||||
|
||||
public AppEng() {
|
||||
if (INSTANCE != null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
INSTANCE = this;
|
||||
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
|
||||
|
||||
proxy = DistExecutor.runForDist(() -> ClientHelper::new, () -> ServerHelper::new);
|
||||
|
||||
CrashReportExtender.registerCrashCallable(new ModCrashEnhancement());
|
||||
|
||||
CreativeTab.init();
|
||||
new FacadeItemGroup(); // This call has a side-effect (adding it to the creative screen)
|
||||
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
registration = new Registration();
|
||||
modEventBus.addGenericListener(Block.class, registration::registerBlocks);
|
||||
modEventBus.addGenericListener(Item.class, registration::registerItems);
|
||||
modEventBus.addGenericListener(EntityType.class, registration::registerEntities);
|
||||
modEventBus.addGenericListener(ParticleType.class, registration::registerParticleTypes);
|
||||
modEventBus.addGenericListener(BlockEntityType.class, registration::registerTileEntities);
|
||||
modEventBus.addGenericListener(ContainerType.class, registration::registerContainerTypes);
|
||||
modEventBus.addGenericListener(RecipeSerializer.class, registration::registerRecipeSerializers);
|
||||
modEventBus.addGenericListener(Feature.class, registration::registerWorldGen);
|
||||
modEventBus.addGenericListener(Biome.class, registration::registerBiomes);
|
||||
modEventBus.addGenericListener(ModDimension.class, registration::registerModDimension);
|
||||
|
||||
modEventBus.addListener(Integrations::enqueueIMC);
|
||||
|
||||
modEventBus.addListener(this::commonSetup);
|
||||
|
||||
// Register client-only events
|
||||
DistExecutor.runWhenOn(EnvType.CLIENT, () -> registration::registerClientEvents);
|
||||
DistExecutor.runWhenOn(EnvType.CLIENT, () -> () -> modEventBus.addListener(this::clientSetup));
|
||||
|
||||
MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::unloadWorld);
|
||||
MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::onTick);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::onServerAboutToStart);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStopped);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
|
||||
MinecraftForge.EVENT_BUS.addListener(registration::registerCommands);
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new PartPlacement());
|
||||
}
|
||||
|
||||
private void commonSetup(FMLCommonSetupEvent event) {
|
||||
|
||||
ApiDefinitions definitions = Api.INSTANCE.definitions();
|
||||
definitions.getRegistry().getBootstrapComponents(IInitComponent.class)
|
||||
.forEachRemaining(IInitComponent::initialize);
|
||||
definitions.getRegistry().getBootstrapComponents(IPostInitComponent.class)
|
||||
.forEachRemaining(IPostInitComponent::postInitialize);
|
||||
|
||||
Capabilities.register();
|
||||
Registration.setupInternalRegistries();
|
||||
Registration.postInit();
|
||||
|
||||
registerNetworkHandler();
|
||||
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
private void clientSetup(FMLClientSetupEvent event) {
|
||||
|
||||
((ClientHelper) proxy).clientInit();
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(TinyTNTPrimedEntity.TYPE, TinyTNTPrimedRenderer::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(SingularityEntity.TYPE,
|
||||
m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
|
||||
RenderingRegistry.registerEntityRenderingHandler(GrowingCrystalEntity.TYPE,
|
||||
m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
|
||||
RenderingRegistry.registerEntityRenderingHandler(ChargedQuartzEntity.TYPE,
|
||||
m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
|
||||
|
||||
// TODO: Do not use the internal API
|
||||
final ApiDefinitions definitions = Api.INSTANCE.definitions();
|
||||
definitions.getRegistry().getBootstrapComponents(IClientSetupComponent.class)
|
||||
.forEachRemaining(IClientSetupComponent::setup);
|
||||
|
||||
addBuiltInModel("glass", GlassModel::new);
|
||||
addBuiltInModel("sky_compass", SkyCompassModel::new);
|
||||
addBuiltInModel("dummy_fluid_item", DummyFluidItemModel::new);
|
||||
addBuiltInModel("memory_card", MemoryCardModel::new);
|
||||
addBuiltInModel("biometric_card", BiometricCardModel::new);
|
||||
addBuiltInModel("drive", DriveModel::new);
|
||||
addBuiltInModel("color_applicator", ColorApplicatorModel::new);
|
||||
addBuiltInModel("spatial_pylon", SpatialPylonModel::new);
|
||||
addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
|
||||
addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
|
||||
addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
|
||||
addBuiltInModel("facade", FacadeItemModel::new);
|
||||
ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "encoded_pattern"),
|
||||
EncodedPatternModelLoader.INSTANCE);
|
||||
ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "part_plane"),
|
||||
PlaneModelLoader.INSTANCE);
|
||||
ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "crafting_cube"),
|
||||
CraftingCubeModelLoader.INSTANCE);
|
||||
ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "uvlightmap"), UVLModelLoader.INSTANCE);
|
||||
ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "cable_bus"),
|
||||
new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
|
||||
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
|
||||
ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, id),
|
||||
new SimpleModelLoader<>(modelFactory));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static AppEng instance() {
|
||||
if (INSTANCE == null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public AdvancementTriggers getAdvancementTriggers() {
|
||||
return this.registration.advancementTriggers;
|
||||
}
|
||||
|
||||
// @EventHandler
|
||||
// private void preInit( final FMLPreInitializationEvent event )
|
||||
// {
|
||||
// final Stopwatch watch = Stopwatch.createStarted();
|
||||
// this.configDirectory = new File( event.getModConfigurationDirectory().getPath(), "AppliedEnergistics2" );
|
||||
//
|
||||
// final File configFile = new File( this.configDirectory, "AppliedEnergistics2.cfg" );
|
||||
// final File facadeFile = new File( this.configDirectory, "Facades.cfg" );
|
||||
// final File versionFile = new File( this.configDirectory, "VersionChecker.cfg" );
|
||||
// final File recipeFile = new File( this.configDirectory, "CustomRecipes.cfg" );
|
||||
// final Configuration recipeConfiguration = new Configuration( recipeFile );
|
||||
//
|
||||
// AEConfig.init( configFile );
|
||||
// FacadeConfig.init( facadeFile );
|
||||
//
|
||||
// AELog.info( "Pre Initialization ( started )" );
|
||||
//
|
||||
//
|
||||
// for( final IntegrationType type : IntegrationType.values() )
|
||||
// {
|
||||
// IntegrationRegistry.INSTANCE.add( type );
|
||||
// }
|
||||
//
|
||||
// this.registration.preInitialize( event );
|
||||
//
|
||||
// if( Platform.isClient() )
|
||||
// {
|
||||
// AppEng.proxy.preinit();
|
||||
// }
|
||||
//
|
||||
// IntegrationRegistry.INSTANCE.preInit();
|
||||
//
|
||||
// AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
//
|
||||
// // Instantiate all Plugins
|
||||
// List<Object> injectables = Lists.newArrayList(
|
||||
// AEApi.instance() );
|
||||
// new PluginLoader().loadPlugins( injectables, event.getAsmData() );
|
||||
// }
|
||||
|
||||
private void startService(final String serviceName, final Thread thread) {
|
||||
thread.setName(serviceName);
|
||||
thread.setPriority(Thread.MIN_PRIORITY);
|
||||
|
||||
AELog.info("Starting " + serviceName);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private void registerNetworkHandler() {
|
||||
final Stopwatch start = Stopwatch.createStarted();
|
||||
AELog.info("Post Initialization ( started )");
|
||||
|
||||
// FIXME IntegrationRegistry.INSTANCE.postInit();
|
||||
// FIXME CrashReportExtender.registerCrashCallable( new
|
||||
// IntegrationCrashEnhancement() );
|
||||
|
||||
AppEng.proxy.postInit();
|
||||
AEConfig.instance().save();
|
||||
|
||||
NetworkHandler.init(new Identifier(MOD_ID, "main"));
|
||||
|
||||
AELog.info("Post Initialization ( ended after " + start.elapsed(TimeUnit.MILLISECONDS) + "ms )");
|
||||
}
|
||||
|
||||
private void onServerAboutToStart(final FMLServerAboutToStartEvent evt) {
|
||||
WorldData.onServerStarting(evt.getServer());
|
||||
}
|
||||
|
||||
private void serverStopping(final FMLServerStoppingEvent event) {
|
||||
WorldData.instance().onServerStopping();
|
||||
}
|
||||
|
||||
private void serverStopped(final FMLServerStoppedEvent event) {
|
||||
WorldData.instance().onServerStoppped();
|
||||
TickHandler.INSTANCE.shutdown();
|
||||
}
|
||||
|
||||
public static Identifier makeId(String id) {
|
||||
static Identifier makeId(String id) {
|
||||
return new Identifier(MOD_ID, id);
|
||||
}
|
||||
|
||||
void bindTileEntitySpecialRenderer(Class<? extends BlockEntity> tile, AEBaseBlock blk);
|
||||
|
||||
List<? extends PlayerEntity> getPlayers();
|
||||
|
||||
void sendToAllNearExcept(PlayerEntity p, double x, double y, double z, double dist, World w,
|
||||
BasePacket packet);
|
||||
|
||||
void spawnEffect(EffectType effect, World world, double posX, double posY, double posZ,
|
||||
Object extra);
|
||||
|
||||
boolean shouldAddParticles(Random r);
|
||||
|
||||
HitResult getRTR();
|
||||
|
||||
void postInit();
|
||||
|
||||
CableRenderMode getRenderMode();
|
||||
|
||||
void triggerUpdates();
|
||||
|
||||
void updateRenderMode(PlayerEntity player);
|
||||
|
||||
boolean isActionKey(@Nonnull final ActionKey key, InputUtil.Key input);
|
||||
|
||||
// public static final String MOD_NAME = "Applied Energistics 2";
|
||||
//
|
||||
// private static AppEng INSTANCE;
|
||||
//
|
||||
// private final Registration registration;
|
||||
//
|
||||
// public AppEng() {
|
||||
// if (INSTANCE != null) {
|
||||
// throw new IllegalStateException();
|
||||
// }
|
||||
// INSTANCE = this;
|
||||
// ParticleTypes.register();
|
||||
// ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
|
||||
// ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
|
||||
//
|
||||
// proxy = DistExecutor.runForDist(() -> ClientHelper::new, () -> ServerHelper::new);
|
||||
//
|
||||
// CrashReportExtender.registerCrashCallable(new ModCrashEnhancement());
|
||||
//
|
||||
// CreativeTab.init();
|
||||
// new FacadeItemGroup(); // This call has a side-effect (adding it to the creative screen)
|
||||
//
|
||||
// IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
// registration = new Registration();
|
||||
// modEventBus.addGenericListener(Block.class, registration::registerBlocks);
|
||||
// modEventBus.addGenericListener(Item.class, registration::registerItems);
|
||||
// modEventBus.addGenericListener(EntityType.class, registration::registerEntities);
|
||||
// modEventBus.addGenericListener(ParticleType.class, registration::registerParticleTypes);
|
||||
// modEventBus.addGenericListener(BlockEntityType.class, registration::registerTileEntities);
|
||||
// modEventBus.addGenericListener(ScreenHandlerType.class, registration::registerContainerTypes);
|
||||
// modEventBus.addGenericListener(RecipeSerializer.class, registration::registerRecipeSerializers);
|
||||
// modEventBus.addGenericListener(Feature.class, registration::registerWorldGen);
|
||||
// modEventBus.addGenericListener(Biome.class, registration::registerBiomes);
|
||||
// modEventBus.addGenericListener(ModDimension.class, registration::registerModDimension);
|
||||
//
|
||||
// modEventBus.addListener(Integrations::enqueueIMC);
|
||||
//
|
||||
// modEventBus.addListener(this::commonSetup);
|
||||
//
|
||||
// // Register client-only events
|
||||
// DistExecutor.runWhenOn(EnvType.CLIENT, () -> registration::registerClientEvents);
|
||||
// DistExecutor.runWhenOn(EnvType.CLIENT, () -> () -> modEventBus.addListener(this::clientSetup));
|
||||
//
|
||||
// MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::unloadWorld);
|
||||
// MinecraftForge.EVENT_BUS.addListener(TickHandler.INSTANCE::onTick);
|
||||
// MinecraftForge.EVENT_BUS.addListener(this::onServerAboutToStart);
|
||||
// MinecraftForge.EVENT_BUS.addListener(this::serverStopped);
|
||||
// MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
|
||||
// MinecraftForge.EVENT_BUS.addListener(registration::registerCommands);
|
||||
//
|
||||
// MinecraftForge.EVENT_BUS.register(new PartPlacement());
|
||||
// }
|
||||
//
|
||||
// private void commonSetup(FMLCommonSetupEvent event) {
|
||||
//
|
||||
// ApiDefinitions definitions = Api.INSTANCE.definitions();
|
||||
// definitions.getRegistry().getBootstrapComponents(IInitComponent.class)
|
||||
// .forEachRemaining(IInitComponent::initialize);
|
||||
// definitions.getRegistry().getBootstrapComponents(IPostInitComponent.class)
|
||||
// .forEachRemaining(IPostInitComponent::postInitialize);
|
||||
//
|
||||
// Capabilities.register();
|
||||
// Registration.setupInternalRegistries();
|
||||
// Registration.postInit();
|
||||
//
|
||||
// registerNetworkHandler();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Environment(EnvType.CLIENT)
|
||||
// private void clientSetup(FMLClientSetupEvent event) {
|
||||
//
|
||||
// ((ClientHelper) proxy).clientInit();
|
||||
//
|
||||
// RenderingRegistry.registerEntityRenderingHandler(TinyTNTPrimedEntity.TYPE, TinyTNTPrimedRenderer::new);
|
||||
// RenderingRegistry.registerEntityRenderingHandler(SingularityEntity.TYPE,
|
||||
// m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
|
||||
// RenderingRegistry.registerEntityRenderingHandler(GrowingCrystalEntity.TYPE,
|
||||
// m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
|
||||
// RenderingRegistry.registerEntityRenderingHandler(ChargedQuartzEntity.TYPE,
|
||||
// m -> new ItemRenderer(m, MinecraftClient.getInstance().getItemRenderer()));
|
||||
//
|
||||
// // TODO: Do not use the internal API
|
||||
// final ApiDefinitions definitions = Api.INSTANCE.definitions();
|
||||
// definitions.getRegistry().getBootstrapComponents(IClientSetupComponent.class)
|
||||
// .forEachRemaining(IClientSetupComponent::setup);
|
||||
//
|
||||
// addBuiltInModel("glass", GlassModel::new);
|
||||
// addBuiltInModel("sky_compass", SkyCompassModel::new);
|
||||
// addBuiltInModel("dummy_fluid_item", DummyFluidItemModel::new);
|
||||
// addBuiltInModel("memory_card", MemoryCardModel::new);
|
||||
// addBuiltInModel("biometric_card", BiometricCardModel::new);
|
||||
// addBuiltInModel("drive", DriveModel::new);
|
||||
// addBuiltInModel("color_applicator", ColorApplicatorModel::new);
|
||||
// addBuiltInModel("spatial_pylon", SpatialPylonModel::new);
|
||||
// addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
|
||||
// addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
|
||||
// addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
|
||||
// addBuiltInModel("facade", FacadeItemModel::new);
|
||||
// ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "encoded_pattern"),
|
||||
// EncodedPatternModelLoader.INSTANCE);
|
||||
// ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "part_plane"),
|
||||
// PlaneModelLoader.INSTANCE);
|
||||
// ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "crafting_cube"),
|
||||
// CraftingCubeModelLoader.INSTANCE);
|
||||
// ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "uvlightmap"), UVLModelLoader.INSTANCE);
|
||||
// ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, "cable_bus"),
|
||||
// new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Environment(EnvType.CLIENT)
|
||||
// private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
|
||||
// ModelLoaderRegistry.registerLoader(new Identifier(AppEng.MOD_ID, id),
|
||||
// new SimpleModelLoader<>(modelFactory));
|
||||
// }
|
||||
//
|
||||
// @Nonnull
|
||||
// public static AppEng instance() {
|
||||
// if (INSTANCE == null) {
|
||||
// throw new IllegalStateException();
|
||||
// }
|
||||
// return INSTANCE;
|
||||
// }
|
||||
//
|
||||
// public AdvancementTriggers getAdvancementTriggers() {
|
||||
// return this.registration.advancementTriggers;
|
||||
// }
|
||||
//
|
||||
//// @EventHandler
|
||||
//// private void preInit( final FMLPreInitializationEvent event )
|
||||
//// {
|
||||
//// final Stopwatch watch = Stopwatch.createStarted();
|
||||
//// this.configDirectory = new File( event.getModConfigurationDirectory().getPath(), "AppliedEnergistics2" );
|
||||
////
|
||||
//// final File configFile = new File( this.configDirectory, "AppliedEnergistics2.cfg" );
|
||||
//// final File facadeFile = new File( this.configDirectory, "Facades.cfg" );
|
||||
//// final File versionFile = new File( this.configDirectory, "VersionChecker.cfg" );
|
||||
//// final File recipeFile = new File( this.configDirectory, "CustomRecipes.cfg" );
|
||||
//// final Configuration recipeConfiguration = new Configuration( recipeFile );
|
||||
////
|
||||
//// AEConfig.init( configFile );
|
||||
//// FacadeConfig.init( facadeFile );
|
||||
////
|
||||
//// AELog.info( "Pre Initialization ( started )" );
|
||||
////
|
||||
////
|
||||
//// for( final IntegrationType type : IntegrationType.values() )
|
||||
//// {
|
||||
//// IntegrationRegistry.INSTANCE.add( type );
|
||||
//// }
|
||||
////
|
||||
//// this.registration.preInitialize( event );
|
||||
////
|
||||
//// if( Platform.isClient() )
|
||||
//// {
|
||||
//// AppEng.proxy.preinit();
|
||||
//// }
|
||||
////
|
||||
//// IntegrationRegistry.INSTANCE.preInit();
|
||||
////
|
||||
//// AELog.info( "Pre Initialization ( ended after " + watch.elapsed( TimeUnit.MILLISECONDS ) + "ms )" );
|
||||
////
|
||||
//// // Instantiate all Plugins
|
||||
//// List<Object> injectables = Lists.newArrayList(
|
||||
//// AEApi.instance() );
|
||||
//// new PluginLoader().loadPlugins( injectables, event.getAsmData() );
|
||||
//// }
|
||||
//
|
||||
// private void startService(final String serviceName, final Thread thread) {
|
||||
// thread.setName(serviceName);
|
||||
// thread.setPriority(Thread.MIN_PRIORITY);
|
||||
//
|
||||
// AELog.info("Starting " + serviceName);
|
||||
// thread.start();
|
||||
// }
|
||||
//
|
||||
// private void registerNetworkHandler() {
|
||||
// final Stopwatch start = Stopwatch.createStarted();
|
||||
// AELog.info("Post Initialization ( started )");
|
||||
//
|
||||
// // FIXME IntegrationRegistry.INSTANCE.postInit();
|
||||
// // FIXME CrashReportExtender.registerCrashCallable( new
|
||||
// // IntegrationCrashEnhancement() );
|
||||
//
|
||||
// AppEng.proxy.postInit();
|
||||
// AEConfig.instance().save();
|
||||
//
|
||||
// NetworkHandler.init(new Identifier(MOD_ID, "main"));
|
||||
//
|
||||
// AELog.info("Post Initialization ( ended after " + start.elapsed(TimeUnit.MILLISECONDS) + "ms )");
|
||||
// }
|
||||
//
|
||||
// private void onServerAboutToStart(final FMLServerAboutToStartEvent evt) {
|
||||
// WorldData.onServerStarting(evt.getServer());
|
||||
// }
|
||||
//
|
||||
// private void serverStopping(final FMLServerStoppingEvent event) {
|
||||
// WorldData.instance().onServerStopping();
|
||||
// }
|
||||
//
|
||||
// private void serverStopped(final FMLServerStoppedEvent event) {
|
||||
// WorldData.instance().onServerStoppped();
|
||||
// TickHandler.INSTANCE.shutdown();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IBlocks;
|
||||
import appeng.api.definitions.IDefinitions;
|
||||
import appeng.api.definitions.IItemDefinition;
|
||||
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class CreativeTab {
|
||||
|
||||
private static final List<IItemDefinition> itemDefs = new ArrayList<>();
|
||||
|
||||
public static ItemGroup INSTANCE;
|
||||
|
||||
public static void init() {
|
||||
INSTANCE = FabricItemGroupBuilder.create(AppEng.makeId("main"))
|
||||
.icon(() -> {
|
||||
final IDefinitions definitions = AEApi.instance().definitions();
|
||||
final IBlocks blocks = definitions.blocks();
|
||||
return blocks.controller().stack(1);
|
||||
})
|
||||
.appendItems(CreativeTab::fill)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static void add(IItemDefinition itemDef) {
|
||||
itemDefs.add(itemDef);
|
||||
}
|
||||
|
||||
private static void fill(List<ItemStack> items) {
|
||||
for (IItemDefinition itemDef : itemDefs) {
|
||||
itemDef.item().appendStacks(INSTANCE, new ListWrapper(items));
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListWrapper extends DefaultedList<ItemStack> {
|
||||
|
||||
public ListWrapper(List<ItemStack> items) {
|
||||
super(items, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package appeng.core.config;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
public abstract class BaseOption {
|
||||
|
||||
protected final ConfigSection parent;
|
||||
|
||||
protected final String id;
|
||||
|
||||
protected final String comment;
|
||||
|
||||
public BaseOption(ConfigSection parent, String id, String comment) {
|
||||
this.parent = parent;
|
||||
this.id = id;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
protected abstract JsonElement write();
|
||||
|
||||
protected abstract void read(JsonElement element);
|
||||
|
||||
public abstract boolean isDifferentFromDefault();
|
||||
|
||||
public abstract String getDefaultAsString();
|
||||
|
||||
public abstract String getCurrentValueAsString();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package appeng.core.config;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
public class BooleanOption extends BaseOption {
|
||||
|
||||
private final boolean defaultValue;
|
||||
private boolean currentValue;
|
||||
|
||||
public BooleanOption(ConfigSection parent, String id, String comment, boolean defaultValue) {
|
||||
super(parent, id, comment);
|
||||
this.defaultValue = defaultValue;
|
||||
this.currentValue = defaultValue;
|
||||
}
|
||||
|
||||
public boolean get() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
public void set(boolean value) {
|
||||
if (value == currentValue) {
|
||||
return;
|
||||
}
|
||||
currentValue = value;
|
||||
parent.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement write() {
|
||||
return new JsonPrimitive(currentValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(JsonElement element) {
|
||||
if (!element.isJsonPrimitive()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON primitive, but found: " + element);
|
||||
}
|
||||
JsonPrimitive primitive = element.getAsJsonPrimitive();
|
||||
if (!primitive.isBoolean()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON boolean, but found: " + primitive);
|
||||
}
|
||||
currentValue = primitive.getAsBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentFromDefault() {
|
||||
return currentValue != defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultAsString() {
|
||||
return String.valueOf(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentValueAsString() {
|
||||
return String.valueOf(currentValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package appeng.core.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigSection {
|
||||
|
||||
private final ConfigSection parent;
|
||||
|
||||
private final String id;
|
||||
|
||||
private final String fullId;
|
||||
|
||||
private final String comment;
|
||||
|
||||
private Runnable changeListener;
|
||||
|
||||
private ConfigSection(String id, String comment) {
|
||||
this.parent = null;
|
||||
this.id = id;
|
||||
this.fullId = id;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
private ConfigSection(ConfigSection parent, String id, String comment) {
|
||||
this.parent = parent;
|
||||
this.id = id;
|
||||
this.comment = comment;
|
||||
if (parent.fullId != null) {
|
||||
this.fullId = parent.fullId + "." + id;
|
||||
} else {
|
||||
this.fullId = id;
|
||||
}
|
||||
}
|
||||
|
||||
public static ConfigSection createRoot() {
|
||||
return new ConfigSection(null, null);
|
||||
}
|
||||
|
||||
public ConfigSection subsection(String id) {
|
||||
return this.subsection(id, null);
|
||||
}
|
||||
|
||||
public ConfigSection subsection(String id, String comment) {
|
||||
return new ConfigSection(this, id, comment);
|
||||
}
|
||||
|
||||
public IntegerOption addInt(String id, int defaultValue) {
|
||||
return addInt(id, defaultValue, comment);
|
||||
}
|
||||
|
||||
public IntegerOption addInt(String id, int defaultValue, String comment) {
|
||||
return addInt(id, defaultValue, Integer.MIN_VALUE, Integer.MAX_VALUE, comment);
|
||||
}
|
||||
|
||||
public IntegerOption addInt(String id, int defaultValue, int minValue, int maxValue, String comment) {
|
||||
return new IntegerOption(this, id, comment, defaultValue, minValue, maxValue);
|
||||
}
|
||||
|
||||
public DoubleOption addDouble(String id, double defaultValue) {
|
||||
return addDouble(id, defaultValue, Double.MIN_VALUE, Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
public DoubleOption addDouble(String id, double defaultValue, String comment) {
|
||||
return addDouble(id, defaultValue, Double.MIN_VALUE, Double.MAX_VALUE, comment);
|
||||
}
|
||||
|
||||
public DoubleOption addDouble(String id, double defaultValue, double minValue, double maxValue) {
|
||||
return addDouble(id, defaultValue, minValue, maxValue, null);
|
||||
}
|
||||
|
||||
public DoubleOption addDouble(String id, double defaultValue, double minValue, double maxValue, String comment) {
|
||||
return new DoubleOption(this, id, comment, defaultValue, minValue, maxValue);
|
||||
}
|
||||
|
||||
public BooleanOption addBoolean(String id, boolean defaultValue) {
|
||||
return addBoolean(id, defaultValue, null);
|
||||
}
|
||||
|
||||
public BooleanOption addBoolean(String id, boolean defaultValue, String comment) {
|
||||
return new BooleanOption(this, id, comment, defaultValue);
|
||||
}
|
||||
|
||||
public StringListOption addStringList(String id, List<String> defaultValue) {
|
||||
return addStringList(id, defaultValue, null);
|
||||
}
|
||||
|
||||
public StringListOption addStringList(String id, List<String> defaultValue, String comment) {
|
||||
return new StringListOption(this, id, comment, defaultValue);
|
||||
}
|
||||
|
||||
public <T extends Enum<T>> EnumOption<T> addEnum(String id, T defaultValue) {
|
||||
return addEnum(id, defaultValue, null);
|
||||
}
|
||||
|
||||
public <T extends Enum<T>> EnumOption<T> addEnum(String id, T defaultValue, String comment) {
|
||||
return new EnumOption<>(this, id, comment, defaultValue);
|
||||
}
|
||||
|
||||
public void setChangeListener(Runnable changeListener) {
|
||||
this.changeListener = changeListener;
|
||||
}
|
||||
|
||||
public void markDirty() {
|
||||
if (changeListener != null) {
|
||||
this.changeListener.run();
|
||||
}
|
||||
if (this.parent != null) {
|
||||
this.parent.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package appeng.core.config;
|
||||
|
||||
public class ConfigValidationException extends RuntimeException {
|
||||
|
||||
public ConfigValidationException(BaseOption option, String message) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package appeng.core.config;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
public class DoubleOption extends BaseOption {
|
||||
|
||||
private final double defaultValue;
|
||||
private final double minValue;
|
||||
private final double maxValue;
|
||||
private double currentValue;
|
||||
|
||||
public DoubleOption(ConfigSection parent, String id, String comment, double defaultValue, double minValue, double maxValue) {
|
||||
super(parent, id, comment);
|
||||
this.defaultValue = defaultValue;
|
||||
this.currentValue = defaultValue;
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
public double get() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
public void set(double value) {
|
||||
if (value == currentValue) {
|
||||
return;
|
||||
}
|
||||
checkValue(value);
|
||||
currentValue = value;
|
||||
parent.markDirty();
|
||||
}
|
||||
|
||||
private void checkValue(double value) {
|
||||
if (value < minValue || value > maxValue) {
|
||||
StringBuilder rangeDescription = new StringBuilder();
|
||||
if (minValue != Double.MIN_VALUE) {
|
||||
rangeDescription.append("min: ").append(minValue);
|
||||
}
|
||||
if (maxValue != Double.MAX_VALUE) {
|
||||
if (rangeDescription.length() > 0) {
|
||||
rangeDescription.append(", ");
|
||||
}
|
||||
rangeDescription.append("max: ").append(maxValue);
|
||||
}
|
||||
|
||||
throw new ConfigValidationException(this, "Value out of range: " + value + " (" + rangeDescription + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement write() {
|
||||
return new JsonPrimitive(currentValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(JsonElement element) {
|
||||
if (!element.isJsonPrimitive()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON primitive, but found: " + element);
|
||||
}
|
||||
JsonPrimitive primitive = element.getAsJsonPrimitive();
|
||||
if (!primitive.isNumber()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON number, but found: " + primitive);
|
||||
}
|
||||
double value = primitive.getAsDouble();
|
||||
checkValue(value);
|
||||
currentValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentFromDefault() {
|
||||
return currentValue != defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultAsString() {
|
||||
return String.valueOf(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentValueAsString() {
|
||||
return String.valueOf(currentValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package appeng.core.config;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EnumOption<T extends Enum<T>> extends BaseOption {
|
||||
|
||||
private final T defaultValue;
|
||||
private T currentValue;
|
||||
|
||||
public EnumOption(ConfigSection parent, String id, String comment, T defaultValue) {
|
||||
super(parent, id, comment);
|
||||
this.defaultValue = defaultValue;
|
||||
this.currentValue = defaultValue;
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
public void set(T value) {
|
||||
Preconditions.checkNotNull(value);
|
||||
if (value == currentValue) {
|
||||
return;
|
||||
}
|
||||
currentValue = value;
|
||||
parent.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement write() {
|
||||
return new JsonPrimitive(currentValue.name().toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(JsonElement element) {
|
||||
if (!element.isJsonPrimitive()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON primitive, but found: " + element);
|
||||
}
|
||||
JsonPrimitive primitive = element.getAsJsonPrimitive();
|
||||
if (!primitive.isString()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON string, but found: " + primitive);
|
||||
}
|
||||
String enumName = primitive.getAsString();
|
||||
|
||||
T[] enumConstants = defaultValue.getDeclaringClass().getEnumConstants();
|
||||
for (T enumConstant : enumConstants) {
|
||||
if (enumConstant.name().equalsIgnoreCase(enumName)) {
|
||||
currentValue = enumConstant;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String allowedValues = Arrays.stream(enumConstants)
|
||||
.map(e -> e.name().toLowerCase())
|
||||
.collect(Collectors.joining(", "));
|
||||
throw new ConfigValidationException(this, "Expected one of: " + allowedValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentFromDefault() {
|
||||
return currentValue != defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultAsString() {
|
||||
return String.valueOf(defaultValue.name().toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentValueAsString() {
|
||||
return String.valueOf(currentValue.name().toLowerCase());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package appeng.core.config;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
public class IntegerOption extends BaseOption {
|
||||
|
||||
private final int defaultValue;
|
||||
private final int minValue;
|
||||
private final int maxValue;
|
||||
private int currentValue;
|
||||
|
||||
public IntegerOption(ConfigSection parent, String id, String comment, int defaultValue, int minValue, int maxValue) {
|
||||
super(parent, id, comment);
|
||||
this.defaultValue = defaultValue;
|
||||
this.currentValue = defaultValue;
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
public int get() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
public void set(int value) {
|
||||
if (value == currentValue) {
|
||||
return;
|
||||
}
|
||||
checkValue(value);
|
||||
currentValue = value;
|
||||
parent.markDirty();
|
||||
}
|
||||
|
||||
private void checkValue(int value) {
|
||||
if (value < minValue || value > maxValue) {
|
||||
StringBuilder rangeDescription = new StringBuilder();
|
||||
if (minValue != Integer.MIN_VALUE) {
|
||||
rangeDescription.append("min: ").append(minValue);
|
||||
}
|
||||
if (maxValue != Integer.MAX_VALUE) {
|
||||
if (rangeDescription.length() > 0) {
|
||||
rangeDescription.append(", ");
|
||||
}
|
||||
rangeDescription.append("max: ").append(maxValue);
|
||||
}
|
||||
|
||||
throw new ConfigValidationException(this, "Value out of range: " + value + " (" + rangeDescription + ")");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement write() {
|
||||
return new JsonPrimitive(currentValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(JsonElement element) {
|
||||
if (!element.isJsonPrimitive()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON primitive, but found: " + element);
|
||||
}
|
||||
JsonPrimitive primitive = element.getAsJsonPrimitive();
|
||||
if (!primitive.isNumber()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON number, but found: " + primitive);
|
||||
}
|
||||
int value;
|
||||
try {
|
||||
value = primitive.getAsInt();
|
||||
} catch (NumberFormatException ignored) {
|
||||
throw new ConfigValidationException(this, "Expected an integer value, but found: " + primitive);
|
||||
}
|
||||
checkValue(value);
|
||||
currentValue = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentFromDefault() {
|
||||
return currentValue != defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultAsString() {
|
||||
return String.valueOf(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentValueAsString() {
|
||||
return String.valueOf(currentValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package appeng.core.config;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StringListOption extends BaseOption {
|
||||
|
||||
private final List<String> defaultValue;
|
||||
private List<String> currentValue;
|
||||
|
||||
public StringListOption(ConfigSection parent, String id, String comment, List<String> defaultValue) {
|
||||
super(parent, id, comment);
|
||||
this.defaultValue = ImmutableList.copyOf(defaultValue);
|
||||
this.currentValue = this.defaultValue;
|
||||
}
|
||||
|
||||
public List<String> get() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
public void set(List<String> value) {
|
||||
Preconditions.checkNotNull(value);
|
||||
if (value.equals(currentValue)) {
|
||||
return;
|
||||
}
|
||||
currentValue = ImmutableList.copyOf(value);
|
||||
parent.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonElement write() {
|
||||
JsonArray arr = new JsonArray();
|
||||
for (String s : currentValue) {
|
||||
arr.add(s);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(JsonElement element) {
|
||||
if (!element.isJsonArray()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON array, but found: " + element);
|
||||
}
|
||||
JsonArray array = element.getAsJsonArray();
|
||||
List<String> values = new ArrayList<>(array.size());
|
||||
for (JsonElement arrEl : array) {
|
||||
if (!arrEl.isJsonPrimitive()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON array of strings, but found: " + arrEl);
|
||||
}
|
||||
JsonPrimitive primitive = arrEl.getAsJsonPrimitive();
|
||||
if (!primitive.isString()) {
|
||||
throw new ConfigValidationException(this, "Expected a JSON array of strings, but found: " + arrEl);
|
||||
}
|
||||
values.add(primitive.getAsString());
|
||||
}
|
||||
|
||||
this.currentValue = ImmutableList.copyOf(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentFromDefault() {
|
||||
return currentValue != defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultAsString() {
|
||||
return String.join(",", defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentValueAsString() {
|
||||
return String.join(",", currentValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.sync;
|
||||
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
|
||||
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.NetworkSide;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public abstract class BasePacket {
|
||||
|
||||
// KEEP THIS SHORT. It's serialized as a string!
|
||||
public static final Identifier CHANNEL = new Identifier("ae2:m");
|
||||
|
||||
private PacketByteBuf p;
|
||||
|
||||
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
|
||||
throw new UnsupportedOperationException(
|
||||
"This packet ( " + this.getPacketID() + " does not implement a server side handler.");
|
||||
}
|
||||
|
||||
public final int getPacketID() {
|
||||
throw new IllegalStateException();
|
||||
// FIXME FABRIC return BasePacketHandler.PacketTypes.getID(this.getClass()).ordinal();
|
||||
}
|
||||
|
||||
public void clientPacketData(final INetworkInfo network, final PlayerEntity player) {
|
||||
throw new UnsupportedOperationException(
|
||||
"This packet ( " + this.getPacketID() + " does not implement a client side handler.");
|
||||
}
|
||||
|
||||
protected void configureWrite(final PacketByteBuf data) {
|
||||
data.capacity(data.readableBytes());
|
||||
this.p = data;
|
||||
}
|
||||
|
||||
public Packet<?> toPacket(NetworkSide direction) {
|
||||
if (this.p.array().length > 2 * 1024 * 1024) // 2k walking room :)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Sorry AE2 made a " + this.p.array().length + " byte packet by accident!");
|
||||
}
|
||||
|
||||
if (AEConfig.instance().isFeatureEnabled(AEFeature.PACKET_LOGGING)) {
|
||||
AELog.info(this.getClass().getName() + " : " + p.readableBytes());
|
||||
}
|
||||
|
||||
if (direction == NetworkSide.SERVERBOUND) {
|
||||
return ClientSidePacketRegistry.INSTANCE.toPacket(CHANNEL, this.p);
|
||||
} else {
|
||||
return ServerSidePacketRegistry.INSTANCE.toPacket(CHANNEL, this.p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.sync.network;
|
||||
|
||||
public interface INetworkInfo {
|
||||
|
||||
}
|
||||
+17
-23
@@ -16,38 +16,32 @@
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.features;
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import appeng.services.CompassService;
|
||||
|
||||
import appeng.items.materials.MaterialType;
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 30.05.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
final class CompassData implements IWorldCompassData {
|
||||
@Nonnull
|
||||
private final CompassService service;
|
||||
|
||||
public class MaterialStackSrc implements IStackSrc {
|
||||
private final MaterialType src;
|
||||
private final boolean enabled;
|
||||
public CompassData(@Nonnull final CompassService service) {
|
||||
Preconditions.checkNotNull(service);
|
||||
|
||||
public MaterialStackSrc(final MaterialType src, boolean enabled) {
|
||||
Preconditions.checkNotNull(src);
|
||||
|
||||
this.src = src;
|
||||
this.enabled = enabled;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack stack(final int stackSize) {
|
||||
return this.src.stack(stackSize);
|
||||
public CompassService service() {
|
||||
return this.service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItem() {
|
||||
return this.src.getItemInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import appeng.services.CompassService;
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 30.05.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
public interface IWorldCompassData {
|
||||
CompassService service();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 02.11.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
public interface IWorldData {
|
||||
void onServerStopping();
|
||||
|
||||
void onServerStoppped();
|
||||
|
||||
@Nonnull
|
||||
IWorldGridStorageData storageData();
|
||||
|
||||
@Nonnull
|
||||
IWorldPlayerData playerData();
|
||||
|
||||
@Nonnull
|
||||
IWorldCompassData compassData();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.me.GridStorage;
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 30.05.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
public interface IWorldGridStorageData {
|
||||
GridStorage getGridStorage(long storageID);
|
||||
|
||||
@Nonnull
|
||||
GridStorage getNewGridStorage();
|
||||
|
||||
void destroyGridStorage(long id);
|
||||
|
||||
int getNextOrderedValue(String name, int firstValue);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 30.05.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
public interface IWorldPlayerData {
|
||||
/**
|
||||
* Gets the UUID of the Minecraft profile associated with the given ME player
|
||||
* id.
|
||||
*
|
||||
* @param playerID An ME player id.
|
||||
* @return Null if the ME player id is unknown, otherwise the unique id of the
|
||||
* Minecraft profile it originates from.
|
||||
*/
|
||||
@Nullable
|
||||
UUID getProfileId(int playerID);
|
||||
|
||||
int getMePlayerId(GameProfile profile);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* encodes data into a common name
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 05.06.2015
|
||||
* @since rv3 05.06.2015
|
||||
*/
|
||||
public class MeteorDataNameEncoder {
|
||||
private final int bitScale;
|
||||
|
||||
/**
|
||||
* @param bitScale how often the coordinates will be shifted right (will scale
|
||||
* coordinates down)
|
||||
*/
|
||||
public MeteorDataNameEncoder(final int bitScale) {
|
||||
Preconditions.checkArgument(bitScale >= 0);
|
||||
this.bitScale = bitScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param chunkX X coordinate of the chunk. Can be any integer
|
||||
* @param chunkZ Z coordinate of the chunk. Can be any integer
|
||||
*
|
||||
* @return encoded file name suggestion in form of <tt>dim_x_y.dat</tt> where
|
||||
* <tt>x</tt> and <tt>y</tt> will be shifted to stay conform with the
|
||||
* vanilla chunk system
|
||||
*
|
||||
* @since rv3 05.06.2015
|
||||
*/
|
||||
public String encode(final int chunkX, final int chunkZ) {
|
||||
final int shiftedX = chunkX >> this.bitScale;
|
||||
final int shiftedZ = chunkZ >> this.bitScale;
|
||||
return shiftedX + "_" + shiftedZ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.PersistentState;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
|
||||
/**
|
||||
* Handles the matching between UUIDs and internal IDs for security systems.
|
||||
* This whole system could be replaced by storing directly the UUID, using a lot
|
||||
* more traffic though
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 30.05.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
final class PlayerData extends PersistentState implements IWorldPlayerData {
|
||||
|
||||
public static final String NAME = AppEng.MOD_ID + "_players";
|
||||
public static final String TAG_PLAYER_IDS = "playerIds";
|
||||
public static final String TAG_PROFILE_IDS = "profileIds";
|
||||
|
||||
private final BiMap<UUID, Integer> mapping = HashBiMap.create();
|
||||
|
||||
// Caches the highest assigned player id + 1
|
||||
private int nextPlayerId = 0;
|
||||
|
||||
public PlayerData() {
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public UUID getProfileId(final int playerId) {
|
||||
return this.mapping.inverse().get(playerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMePlayerId(@Nonnull final GameProfile profile) {
|
||||
Preconditions.checkNotNull(profile);
|
||||
|
||||
final UUID uuid = profile.getId();
|
||||
Integer playerId = mapping.get(uuid);
|
||||
|
||||
if (playerId == null) {
|
||||
playerId = this.nextPlayerId++;
|
||||
this.mapping.put(profile.getId(), playerId);
|
||||
markDirty();
|
||||
|
||||
AELog.info("Assigning ME player id {} to Minecraft profile {} ({})", playerId, profile.getId(),
|
||||
profile.getName());
|
||||
}
|
||||
|
||||
return playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
int[] playerIds = nbt.getIntArray(TAG_PLAYER_IDS);
|
||||
long[] profileIds = nbt.getLongArray(TAG_PROFILE_IDS);
|
||||
|
||||
if (playerIds.length * 2 != profileIds.length) {
|
||||
throw new IllegalStateException("Plaer ID mapping is corrupted. " + playerIds.length + " player IDs vs. "
|
||||
+ profileIds.length + " profile IDs (latter must be 2 * the former)");
|
||||
}
|
||||
|
||||
this.mapping.clear();
|
||||
int highestPlayerId = -1;
|
||||
for (int i = 0; i < playerIds.length; i++) {
|
||||
int playerId = playerIds[i];
|
||||
UUID profileId = new UUID(profileIds[i * 2], profileIds[i * 2 + 1]);
|
||||
highestPlayerId = Math.max(playerId, highestPlayerId);
|
||||
mapping.put(profileId, playerId);
|
||||
AELog.debug("AE player ID {} is assigned to profile ID {}", playerId, profileId);
|
||||
}
|
||||
this.nextPlayerId = highestPlayerId + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag compound) {
|
||||
int index = 0;
|
||||
int[] playerIds = new int[mapping.size()];
|
||||
long[] profileIds = new long[mapping.size() * 2];
|
||||
for (Map.Entry<UUID, Integer> entry : mapping.entrySet()) {
|
||||
profileIds[index * 2] = entry.getKey().getMostSignificantBits();
|
||||
profileIds[index * 2 + 1] = entry.getKey().getLeastSignificantBits();
|
||||
playerIds[index++] = entry.getValue();
|
||||
}
|
||||
|
||||
compound.putIntArray(TAG_PLAYER_IDS, playerIds);
|
||||
compound.putLongArray(TAG_PROFILE_IDS, profileIds);
|
||||
|
||||
return compound;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.PersistentState;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.me.GridStorage;
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 30.05.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
final class StorageData extends PersistentState implements IWorldGridStorageData {
|
||||
|
||||
public static final String NAME = AppEng.MOD_ID + "_storage";
|
||||
|
||||
private static final String TAG_NEXT_ID = "nextId";
|
||||
public static final String TAG_ORDERED_VALUES = "orderedValues";
|
||||
public static final String TAG_STORAGE = "storage";
|
||||
|
||||
private final Map<Long, GridStorage> storage = new HashMap<>();
|
||||
|
||||
// id that will be assigned to the next new grid, this needs to be persisted
|
||||
// because grids can be removed and we do not want to re-assign the same id
|
||||
// twice
|
||||
private long nextGridId;
|
||||
|
||||
// Stores once-per-save values. I.e. which storage press to drop next in a
|
||||
// spawned meteor
|
||||
private final Map<String, Integer> orderedValues = new HashMap<>();
|
||||
|
||||
public StorageData() {
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* lazy loading, can load any id, even ones that don't exist anymore.
|
||||
*
|
||||
* @param storageID ID of grid storage
|
||||
*
|
||||
* @return corresponding grid storage
|
||||
*/
|
||||
@Override
|
||||
public GridStorage getGridStorage(final long storageID) {
|
||||
GridStorage result = storage.get(storageID);
|
||||
|
||||
if (result == null) {
|
||||
result = new GridStorage(storageID);
|
||||
storage.put(storageID, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new storage
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public GridStorage getNewGridStorage() {
|
||||
return getGridStorage(nextGridId++);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyGridStorage(final long id) {
|
||||
this.storage.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNextOrderedValue(final String name, int firstValue) {
|
||||
return orderedValues.merge(name, firstValue, (oldValue, value) -> oldValue + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag tag) {
|
||||
|
||||
nextGridId = tag.getLong(TAG_NEXT_ID);
|
||||
|
||||
// Load serialized grid storage
|
||||
CompoundTag storageTag = tag.getCompound(TAG_STORAGE);
|
||||
for (String storageIdStr : storageTag.getKeys()) {
|
||||
long storageId;
|
||||
try {
|
||||
storageId = Long.parseLong(storageIdStr);
|
||||
} catch (NumberFormatException e) {
|
||||
AELog.warn("Unable to load grid storage with malformed id: '{}'", storageIdStr);
|
||||
continue;
|
||||
}
|
||||
storage.put(storageId, new GridStorage(storageId, storageTag.getCompound(storageIdStr)));
|
||||
}
|
||||
|
||||
// Load ordered values map
|
||||
CompoundTag orderedValuesTag = tag.getCompound(TAG_ORDERED_VALUES);
|
||||
this.orderedValues.clear();
|
||||
for (String key : orderedValuesTag.getKeys()) {
|
||||
this.orderedValues.put(key, orderedValuesTag.getInt(key));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
|
||||
tag.putLong(TAG_NEXT_ID, nextGridId);
|
||||
|
||||
// Save serialized grid storage
|
||||
CompoundTag storageTag = new CompoundTag();
|
||||
for (Map.Entry<Long, GridStorage> entry : storage.entrySet()) {
|
||||
|
||||
GridStorage gridStorage = entry.getValue();
|
||||
|
||||
if (gridStorage.getGrid() == null || gridStorage.getGrid().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
entry.getValue().saveState();
|
||||
} catch (Exception e) {
|
||||
AELog.warn("Failed to save state of Grid {}, storing last known value instead.", entry.getKey(), e);
|
||||
}
|
||||
storageTag.put(String.valueOf(entry.getKey()), entry.getValue().dataObject());
|
||||
}
|
||||
tag.put(TAG_STORAGE, storageTag);
|
||||
|
||||
// Save ordered values
|
||||
CompoundTag orderedValuesTag = new CompoundTag();
|
||||
for (Map.Entry<String, Integer> entry : orderedValues.entrySet()) {
|
||||
orderedValuesTag.putInt(entry.getKey(), entry.getValue());
|
||||
}
|
||||
tag.put(TAG_ORDERED_VALUES, orderedValuesTag);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.core.worlddata;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
import appeng.services.CompassService;
|
||||
import appeng.services.compass.CompassThreadFactory;
|
||||
|
||||
/**
|
||||
* Singleton access to anything related to world-based data.
|
||||
*
|
||||
* Data will change depending which world is loaded. Will probably not affect
|
||||
* SMP at all since only one world is loaded, but SSP more, cause they play on
|
||||
* different worlds.
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 02.11.2015
|
||||
* @since rv3 30.05.2015
|
||||
*/
|
||||
public final class WorldData implements IWorldData {
|
||||
|
||||
/**
|
||||
* Is null while no MinecraftServer exists.
|
||||
*/
|
||||
@Nullable
|
||||
private static IWorldData instance;
|
||||
|
||||
@Nullable
|
||||
private static MinecraftServer server;
|
||||
|
||||
private final IWorldPlayerData playerData;
|
||||
private final IWorldGridStorageData storageData;
|
||||
private final IWorldCompassData compassData;
|
||||
|
||||
private WorldData(@Nonnull final ServerWorld overworld) {
|
||||
Preconditions.checkNotNull(overworld);
|
||||
|
||||
// Attach shared data to the server's overworld dimension
|
||||
if (overworld.getDimension() != DimensionType.getOverworldDimensionType()) {
|
||||
throw new IllegalStateException(
|
||||
"The server doesn't have an Overworld dimension we could store our data on!");
|
||||
}
|
||||
|
||||
final PlayerData playerData = overworld.getPersistentStateManager().getOrCreate(PlayerData::new, PlayerData.NAME);
|
||||
final StorageData storageData = overworld.getPersistentStateManager().getOrCreate(StorageData::new, StorageData.NAME);
|
||||
|
||||
final ThreadFactory compassThreadFactory = new CompassThreadFactory();
|
||||
final CompassService compassService = new CompassService(server, compassThreadFactory);
|
||||
final CompassData compassData = new CompassData(compassService);
|
||||
|
||||
this.playerData = playerData;
|
||||
this.storageData = storageData;
|
||||
this.compassData = compassData;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ae2 data related to a specific world
|
||||
*
|
||||
* @deprecated do not use singletons which are dependent on specific world state
|
||||
*/
|
||||
@Deprecated
|
||||
@Nonnull
|
||||
public synchronized static IWorldData instance() {
|
||||
// The overworld is lazily loaded, meaning we cannot access it right away
|
||||
// when the server is starting, but the first time the instance is accessed,
|
||||
// we create the actual world data
|
||||
if (instance == null) {
|
||||
if (server == null) {
|
||||
throw new IllegalStateException("No server set.");
|
||||
}
|
||||
|
||||
ServerWorld overworld = server.getOverworld();
|
||||
instance = new WorldData(overworld);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires to start up from external from here
|
||||
*
|
||||
* drawback of the singleton build style
|
||||
*/
|
||||
public static void onServerStarting(MinecraftServer server) {
|
||||
WorldData.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerStopping() {
|
||||
compassData.service().kill();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerStoppped() {
|
||||
Preconditions.checkNotNull(server);
|
||||
instance = null;
|
||||
WorldData.server = null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IWorldGridStorageData storageData() {
|
||||
return this.storageData;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IWorldPlayerData playerData() {
|
||||
return this.playerData;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IWorldCompassData compassData() {
|
||||
return this.compassData;
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class ChargedQuartzOreBlock extends QuartzOreBlock {
|
||||
break;
|
||||
}
|
||||
|
||||
if (AppEng.proxy.shouldAddParticles(r)) {
|
||||
if (AppEng.INSTANCE.shouldAddParticles(r)) {
|
||||
MinecraftClient.getInstance().particleManager.addParticle(ParticleTypes.CHARGED_ORE, pos.getX() + xOff,
|
||||
pos.getY() + yOff, pos.getZ() + zOff, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class QuartzLampBlock extends QuartzGlassBlock {
|
||||
return;
|
||||
}
|
||||
|
||||
if (AppEng.proxy.shouldAddParticles(r)) {
|
||||
if (AppEng.INSTANCE.shouldAddParticles(r)) {
|
||||
final double d0 = (r.nextFloat() - 0.5F) * 0.96D;
|
||||
final double d1 = (r.nextFloat() - 0.5F) * 0.96D;
|
||||
final double d2 = (r.nextFloat() - 0.5F) * 0.96D;
|
||||
|
||||
@@ -18,22 +18,15 @@
|
||||
|
||||
package appeng.decorative.solid;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.inventory.EquipmentSlotType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
import appeng.block.AEBaseBlock;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
public class SkyStoneBlock extends AEBaseBlock {
|
||||
private static final float BREAK_SPEAK_SCALAR = 0.1f;
|
||||
@@ -43,47 +36,50 @@ public class SkyStoneBlock extends AEBaseBlock {
|
||||
public SkyStoneBlock(SkystoneType type, Settings props) {
|
||||
super(props);
|
||||
this.type = type;
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void breakFaster(final PlayerEvent.BreakSpeed event) {
|
||||
if (event.getState().getBlock() == this && event.getPlayer() != null) {
|
||||
final ItemStack is = event.getPlayer().getItemStackFromSlot(EquipmentSlotType.MAINHAND);
|
||||
int level = -1;
|
||||
|
||||
if (!is.isEmpty()) {
|
||||
level = is.getItem().getHarvestLevel(is, FabricToolTags.PICKAXES, event.getPlayer(), event.getState());
|
||||
}
|
||||
|
||||
if (this.type != SkystoneType.STONE || level >= 3 || event.getOriginalSpeed() > BREAK_SPEAK_THRESHOLD) {
|
||||
event.setNewSpeed(event.getNewSpeed() / BREAK_SPEAK_SCALAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME FABRIC
|
||||
// @SubscribeEvent
|
||||
// public void breakFaster(final PlayerEvent.BreakSpeed event) {
|
||||
// if (event.getState().getBlock() == this && event.getPlayer() != null) {
|
||||
// final ItemStack is = event.getPlayer().getItemStackFromSlot(EquipmentSlot.MAINHAND);
|
||||
// int level = -1;
|
||||
//
|
||||
// if (!is.isEmpty()) {
|
||||
// level = is.getItem().getHarvestLevel(is, FabricToolTags.PICKAXES, event.getPlayer(), event.getState());
|
||||
// }
|
||||
//
|
||||
// if (this.type != SkystoneType.STONE || level >= 3 || event.getOriginalSpeed() > BREAK_SPEAK_THRESHOLD) {
|
||||
// event.setNewSpeed(event.getNewSpeed() / BREAK_SPEAK_SCALAR);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public BlockState getStateForNeighborUpdate(BlockState stateIn, Direction facing, BlockState facingState, WorldAccess worldIn,
|
||||
BlockPos currentPos, BlockPos facingPos) {
|
||||
if (worldIn instanceof ServerWorld) {
|
||||
WorldData.instance().compassData().service().updateArea(worldIn, new ChunkPos(currentPos),
|
||||
ServerWorld serverWorld = (ServerWorld) worldIn;
|
||||
WorldData.instance().compassData().service().updateArea(serverWorld, new ChunkPos(currentPos),
|
||||
currentPos.getY());
|
||||
}
|
||||
|
||||
return super.getStateForNeighborUpdate(stateIn, facing, facingState, worldIn, currentPos, facingPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState state, World w, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
public void onStateReplaced(BlockState state, World w, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
if (newState.getBlock() == state.getBlock()) {
|
||||
return; // Just a block state change
|
||||
}
|
||||
|
||||
super.onReplaced(state, w, pos, newState, isMoving);
|
||||
super.onStateReplaced(state, w, pos, newState, isMoving);
|
||||
|
||||
if (w instanceof ServerWorld) {
|
||||
WorldData.instance().compassData().service().updateArea(w, new ChunkPos(pos), pos.getY());
|
||||
ServerWorld serverWorld = (ServerWorld) w;
|
||||
WorldData.instance().compassData().service().updateArea(serverWorld, new ChunkPos(pos), pos.getY());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class AEBaseItemEntity extends ItemEntity {
|
||||
|
||||
protected AEBaseItemEntity(EntityType<? extends AEBaseItemEntity> entityType, final World world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
protected AEBaseItemEntity(EntityType<? extends AEBaseItemEntity> entityType, final World world, final double x,
|
||||
final double y, final double z, final ItemStack stack) {
|
||||
this(entityType, world);
|
||||
this.updatePosition(x, y, z);
|
||||
this.yaw = this.random.nextFloat() * 360.0F;
|
||||
this.setVelocity(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D);
|
||||
this.setStack(stack);
|
||||
// FIXME FABRIC Needs replacement hook this.lifespan = stack.getEntityLifespan(world);
|
||||
}
|
||||
|
||||
protected List<Entity> getCheckedEntitiesWithinAABBExcludingEntity(final Box region) {
|
||||
return this.world.getEntities(this, region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import appeng.client.render.effects.ParticleTypes;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IMaterials;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public final class ChargedQuartzEntity extends AEBaseItemEntity {
|
||||
|
||||
public static EntityType<ChargedQuartzEntity> TYPE;
|
||||
|
||||
private int delay = 0;
|
||||
private int transformTime = 0;
|
||||
|
||||
public ChargedQuartzEntity(EntityType<? extends ChargedQuartzEntity> entityType, World world) {
|
||||
super(entityType, world);
|
||||
}
|
||||
|
||||
public ChargedQuartzEntity(final World w, final double x, final double y, final double z, final ItemStack is) {
|
||||
super(TYPE, w, x, y, z, is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (this.removed || !AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_FLUIX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (world.isClient && this.delay > 30 && AEConfig.instance().isEnableEffects()) {
|
||||
MinecraftClient.getInstance().particleManager.addParticle(ParticleTypes.LIGHTNING, this.getX(), this.getY() + 0.3f, this.getZ(), 0.0f, 0.0f,
|
||||
0.0f);
|
||||
this.delay = 0;
|
||||
}
|
||||
|
||||
this.delay++;
|
||||
|
||||
final int j = MathHelper.floor(this.getX());
|
||||
final int i = MathHelper.floor((this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D);
|
||||
final int k = MathHelper.floor(this.getZ());
|
||||
|
||||
BlockState state = this.world.getBlockState(new BlockPos(j, i, k));
|
||||
final Material mat = state.getMaterial();
|
||||
|
||||
if (Platform.isServer() && mat.isLiquid()) {
|
||||
this.transformTime++;
|
||||
if (this.transformTime > 60) {
|
||||
if (!this.transform()) {
|
||||
this.transformTime = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.transformTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean transform() {
|
||||
final ItemStack item = this.getStack();
|
||||
final IMaterials materials = AEApi.instance().definitions().materials();
|
||||
|
||||
if (materials.certusQuartzCrystalCharged().isSameAs(item)) {
|
||||
final Box region = new Box(this.getX() - 1, this.getY() - 1, this.getZ() - 1,
|
||||
this.getX() + 1, this.getY() + 1, this.getZ() + 1);
|
||||
final List<Entity> l = this.getCheckedEntitiesWithinAABBExcludingEntity(region);
|
||||
|
||||
ItemEntity redstone = null;
|
||||
ItemEntity netherQuartz = null;
|
||||
|
||||
for (final Entity e : l) {
|
||||
if (e instanceof ItemEntity && !e.removed) {
|
||||
final ItemStack other = ((ItemEntity) e).getStack();
|
||||
if (!other.isEmpty()) {
|
||||
if (ItemStack.areItemsEqual(other, new ItemStack(Items.REDSTONE))) {
|
||||
redstone = (ItemEntity) e;
|
||||
}
|
||||
|
||||
if (ItemStack.areItemsEqual(other, new ItemStack(Items.QUARTZ))) {
|
||||
netherQuartz = (ItemEntity) e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (redstone != null && netherQuartz != null) {
|
||||
this.getStack().increment(-1);
|
||||
redstone.getStack().increment(-1);
|
||||
netherQuartz.getStack().increment(-1);
|
||||
|
||||
if (this.getStack().getCount() <= 0) {
|
||||
this.remove();
|
||||
}
|
||||
|
||||
if (redstone.getStack().getCount() <= 0) {
|
||||
redstone.remove();
|
||||
}
|
||||
|
||||
if (netherQuartz.getStack().getCount() <= 0) {
|
||||
netherQuartz.remove();
|
||||
}
|
||||
|
||||
materials.fluixCrystal().maybeStack(2).ifPresent(is -> {
|
||||
final ItemEntity entity = new ItemEntity(this.world, this.getX(), this.getY(), this.getZ(),
|
||||
is);
|
||||
|
||||
this.world.spawnEntity(entity);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.entity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.api.implementations.items.IGrowableCrystal;
|
||||
import appeng.api.implementations.tiles.ICrystalGrowthAccelerator;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public final class GrowingCrystalEntity extends AEBaseItemEntity {
|
||||
|
||||
public static EntityType<GrowingCrystalEntity> TYPE;
|
||||
|
||||
private int progress_1000 = 0;
|
||||
|
||||
public GrowingCrystalEntity(EntityType<? extends GrowingCrystalEntity> type, World world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
public GrowingCrystalEntity(final World w, final double x, final double y, final double z, final ItemStack is) {
|
||||
super(TYPE, w, x, y, z, is);
|
||||
this.setCovetedItem();
|
||||
// FIXME FABRIC This does not actually fix despawning, we need to Mixin, probably.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (!AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_PURIFICATION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack is = this.getStack();
|
||||
final Item gc = is.getItem();
|
||||
|
||||
if (gc instanceof IGrowableCrystal) // if it changes this just stops being an issue...
|
||||
{
|
||||
final int j = MathHelper.floor(this.getX());
|
||||
final int i = MathHelper.floor((this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D);
|
||||
final int k = MathHelper.floor(this.getZ());
|
||||
|
||||
final BlockState state = this.world.getBlockState(new BlockPos(j, i, k));
|
||||
final Material mat = state.getMaterial();
|
||||
final IGrowableCrystal cry = (IGrowableCrystal) is.getItem();
|
||||
|
||||
final float multiplier = cry.getMultiplier(state.getBlock(), mat);
|
||||
final int speed = (int) Math.max(1, this.getSpeed(j, i, k) * multiplier);
|
||||
|
||||
final boolean isClient = Platform.isClient();
|
||||
|
||||
if (mat.isLiquid()) {
|
||||
if (isClient) {
|
||||
this.progress_1000++;
|
||||
} else {
|
||||
this.progress_1000 += speed;
|
||||
}
|
||||
} else {
|
||||
this.progress_1000 = 0;
|
||||
}
|
||||
|
||||
if (isClient) {
|
||||
int len = 40;
|
||||
|
||||
if (speed > 2) {
|
||||
len = 20;
|
||||
}
|
||||
|
||||
if (speed > 90) {
|
||||
len = 15;
|
||||
}
|
||||
|
||||
if (speed > 150) {
|
||||
len = 10;
|
||||
}
|
||||
|
||||
if (speed > 240) {
|
||||
len = 7;
|
||||
}
|
||||
|
||||
if (speed > 360) {
|
||||
len = 3;
|
||||
}
|
||||
|
||||
if (speed > 500) {
|
||||
len = 1;
|
||||
}
|
||||
|
||||
if (this.progress_1000 >= len) {
|
||||
this.progress_1000 = 0;
|
||||
// FIXME FABRIC AppEng.proxy.spawnEffect(EffectType.Vibrant, this.world, this.getX(), this.getY() + 0.2,
|
||||
// FIXME FABRIC this.getZ(), null);
|
||||
}
|
||||
} else {
|
||||
if (this.progress_1000 > 1000) {
|
||||
this.progress_1000 -= 1000;
|
||||
// We need to copy the stack or the change detection will not work and not sync
|
||||
// this new stack to the client
|
||||
ItemStack newItem = cry.triggerGrowth(is.copy());
|
||||
this.setStack(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getSpeed(final int x, final int y, final int z) {
|
||||
final int per = 80;
|
||||
final float mul = 0.3f;
|
||||
|
||||
int qty = 0;
|
||||
|
||||
if (this.isAccelerated(x + 1, y, z)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y + 1, z)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y, z + 1)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x - 1, y, z)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y - 1, z)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y, z - 1)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
return qty;
|
||||
}
|
||||
|
||||
private boolean isAccelerated(final int x, final int y, final int z) {
|
||||
final BlockEntity te = this.world.getBlockEntity(new BlockPos(x, y, z));
|
||||
|
||||
return te instanceof ICrystalGrowthAccelerator && ((ICrystalGrowthAccelerator) te).isPowered();
|
||||
}
|
||||
|
||||
// Don't let seeds "float" on water surface
|
||||
@Override
|
||||
public void applyBuoyancy() {
|
||||
ItemStack item = getStack();
|
||||
throw new IllegalStateException();
|
||||
// FIXME FABRIC if (item.getItem() instanceof CrystalSeedItem) {
|
||||
// FIXME FABRIC return;
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC super.applyBuoyancy();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.entity;
|
||||
|
||||
public interface ICanDie {
|
||||
|
||||
public boolean isDead();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.entity;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.definitions.IMaterials;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public final class SingularityEntity extends AEBaseItemEntity {
|
||||
|
||||
public static EntityType<SingularityEntity> TYPE;
|
||||
|
||||
private static int randTickSeed = 0;
|
||||
|
||||
public SingularityEntity(EntityType<? extends SingularityEntity> entityType, final World w) {
|
||||
super(entityType, w);
|
||||
}
|
||||
|
||||
public SingularityEntity(final World w, final double x, final double y, final double z, final ItemStack is) {
|
||||
super(TYPE, w, x, y, z, is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean damage(final DamageSource src, final float dmg) {
|
||||
if (src.isExplosive()) {
|
||||
this.doExplosion();
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.damage(src, dmg);
|
||||
}
|
||||
|
||||
private void doExplosion() {
|
||||
if (Platform.isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_SINGULARITY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack item = this.getStack();
|
||||
|
||||
final IMaterials materials = AEApi.instance().definitions().materials();
|
||||
|
||||
if (materials.singularity().isSameAs(item)) {
|
||||
final Box region = new Box(this.getX() - 4, this.getY() - 4, this.getZ() - 4,
|
||||
this.getX() + 4, this.getY() + 4, this.getZ() + 4);
|
||||
final List<Entity> l = this.getCheckedEntitiesWithinAABBExcludingEntity(region);
|
||||
|
||||
for (final Entity e : l) {
|
||||
if (e instanceof ItemEntity) {
|
||||
final ItemStack other = ((ItemEntity) e).getStack();
|
||||
if (!other.isEmpty()) {
|
||||
boolean matches = false;
|
||||
|
||||
if (matches) {
|
||||
while (item.getCount() > 0 && other.getCount() > 0) {
|
||||
other.increment(-1);
|
||||
;
|
||||
if (other.getCount() == 0) {
|
||||
e.remove();
|
||||
}
|
||||
|
||||
materials.qESingularity().maybeStack(2).ifPresent(singularityStack -> {
|
||||
final CompoundTag cmp = singularityStack.getOrCreateTag();
|
||||
cmp.putLong("freq", (new Date()).getTime() * 100 + (randTickSeed) % 100);
|
||||
randTickSeed++;
|
||||
item.increment(-1);
|
||||
|
||||
final SingularityEntity entity = new SingularityEntity(this.world, this.getX(),
|
||||
this.getY(), this.getZ(), singularityStack);
|
||||
this.world.spawnEntity(entity);
|
||||
});
|
||||
}
|
||||
|
||||
if (item.getCount() <= 0) {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.entity;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Material;
|
||||
import net.minecraft.entity.*;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class TinyTNTPrimedEntity extends TntEntity {
|
||||
|
||||
public static EntityType<TinyTNTPrimedEntity> TYPE;
|
||||
|
||||
public TinyTNTPrimedEntity(EntityType<? extends TinyTNTPrimedEntity> type, World worldIn) {
|
||||
super(type, worldIn);
|
||||
this.inanimate = true;
|
||||
}
|
||||
|
||||
public TinyTNTPrimedEntity(final World w, final double x, final double y, final double z,
|
||||
final LivingEntity igniter) {
|
||||
super(w, x, y, z, igniter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
@Override
|
||||
public void tick() {
|
||||
this.updateWaterState();
|
||||
|
||||
this.prevX = this.getX();
|
||||
this.prevY = this.getY();
|
||||
this.prevZ = this.getZ();
|
||||
this.setVelocity(this.getVelocity().subtract(0, 0.03999999910593033D, 0));
|
||||
this.move(MovementType.SELF, this.getVelocity());
|
||||
this.setVelocity(this.getVelocity().multiply(0.9800000190734863D, 0.9800000190734863D, 0.9800000190734863D));
|
||||
|
||||
if (this.onGround) {
|
||||
this.setVelocity(this.getVelocity().multiply(0.699999988079071D, 0.699999988079071D, -0.5D));
|
||||
}
|
||||
|
||||
if (this.isSubmergedInWater() && Platform.isServer()) // put out the fuse.
|
||||
{
|
||||
AEApi.instance().definitions().blocks().tinyTNT().maybeStack(1).ifPresent(tntStack -> {
|
||||
final ItemEntity item = new ItemEntity(this.world, this.getX(), this.getY(), this.getZ(),
|
||||
tntStack);
|
||||
|
||||
item.setVelocity(this.getVelocity());
|
||||
item.prevX = this.prevX;
|
||||
item.prevY = this.prevY;
|
||||
item.prevZ = this.prevZ;
|
||||
|
||||
this.world.spawnEntity(item);
|
||||
this.remove();
|
||||
});
|
||||
}
|
||||
|
||||
if (this.getFuse() <= 0) {
|
||||
this.remove();
|
||||
|
||||
if (!this.world.isClient) {
|
||||
this.explode();
|
||||
}
|
||||
} else {
|
||||
this.world.addParticle(ParticleTypes.SMOKE, this.getX(), this.getY(), this.getZ(), 0.0D, 0.0D,
|
||||
0.0D);
|
||||
}
|
||||
this.setFuse(this.getFuse() - 1);
|
||||
}
|
||||
|
||||
private void explode() {
|
||||
this.world.playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.ENTITY_GENERIC_EXPLODE,
|
||||
SoundCategory.BLOCKS, 4.0F,
|
||||
(1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 32.9F);
|
||||
|
||||
if (this.isSubmergedInWater()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Explosion ex = new Explosion(this.world, this, this.getX(), this.getY(), this.getZ(), 0.2f,
|
||||
false, Explosion.DestructionType.BREAK);
|
||||
|
||||
final Box area = new Box(this.getX() - 1.5, this.getY() - 1.5f, this.getZ() - 1.5,
|
||||
this.getX() + 1.5, this.getY() + 1.5, this.getZ() + 1.5);
|
||||
final List<Entity> list = this.world.getEntities(this, area);
|
||||
|
||||
for (final Entity e : list) {
|
||||
e.damage(DamageSource.explosion(ex), 6);
|
||||
}
|
||||
|
||||
if (AEConfig.instance().isFeatureEnabled(AEFeature.TINY_TNT_BLOCK_DAMAGE)) {
|
||||
this.updatePosition(this.getX(), this.getY() - 0.25, this.getZ());
|
||||
|
||||
// For reference see Explosion.affectWorld
|
||||
for (int x = (int) (this.getX() - 2); x <= this.getX() + 2; x++) {
|
||||
for (int y = (int) (this.getY() - 2); y <= this.getY() + 2; y++) {
|
||||
for (int z = (int) (this.getZ() - 2); z <= this.getZ() + 2; z++) {
|
||||
final BlockPos blockPos = new BlockPos(x, y, z);
|
||||
final BlockState state = this.world.getBlockState(blockPos);
|
||||
final Block block = state.getBlock();
|
||||
|
||||
if (block != null && !state.isAir()) {
|
||||
float strength = (float) (2.3f
|
||||
- (((x + 0.5f) - this.getX()) * ((x + 0.5f) - this.getX())
|
||||
+ ((y + 0.5f) - this.getY()) * ((y + 0.5f) - this.getY())
|
||||
+ ((z + 0.5f) - this.getZ()) * ((z + 0.5f) - this.getZ())));
|
||||
|
||||
final float resistance = block.getBlastResistance();
|
||||
strength -= (resistance + 0.3F) * 0.11f;
|
||||
|
||||
if (strength > 0.01) {
|
||||
if (state.getMaterial() == Material.AIR) {
|
||||
if (block.shouldDropItemsOnExplosion(ex)) {
|
||||
Block.dropStacks(state, this.world, blockPos);
|
||||
}
|
||||
|
||||
block.onDestroyedByExplosion(this.world, blockPos, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException();
|
||||
// FIXME FABRIC
|
||||
// AppEng.proxy.sendToAllNearExcept(null, this.getX(), this.getY(), this.getZ(), 64, this.world,
|
||||
// new MockExplosionPacket(this.getX(), this.getY(), this.getZ()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.entity;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.TntMinecartEntityRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.client.render.entity.EntityRenderer;
|
||||
import net.minecraft.client.render.entity.EntityRenderDispatcher;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class TinyTNTPrimedRenderer extends EntityRenderer<TinyTNTPrimedEntity> {
|
||||
|
||||
public TinyTNTPrimedRenderer(final EntityRenderDispatcher manager) {
|
||||
super(manager);
|
||||
this.shadowRadius = 0.5F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(TinyTNTPrimedEntity tnt, float entityYaw, float partialTicks, MatrixStack mStack,
|
||||
VertexConsumerProvider buffers, int packedLight) {
|
||||
final BlockRenderManager blockrendererdispatcher = MinecraftClient.getInstance().getBlockRenderManager();
|
||||
mStack.push();
|
||||
mStack.translate(0, 0.25F, 0);
|
||||
float f2;
|
||||
|
||||
if (tnt.getFuse() - partialTicks + 1.0F < 10.0F) {
|
||||
f2 = 1.0F - (tnt.getFuse() - partialTicks + 1.0F) / 10.0F;
|
||||
|
||||
if (f2 < 0.0F) {
|
||||
f2 = 0.0F;
|
||||
}
|
||||
|
||||
if (f2 > 1.0F) {
|
||||
f2 = 1.0F;
|
||||
}
|
||||
|
||||
f2 *= f2;
|
||||
f2 *= f2;
|
||||
final float f3 = 1.0F + f2 * 0.3F;
|
||||
mStack.scale(f3, f3, f3);
|
||||
}
|
||||
|
||||
mStack.scale(0.5f, 0.5f, 0.5f);
|
||||
f2 = (1.0F - (tnt.getFuse() - partialTicks + 1.0F) / 100.0F) * 0.8F;
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(-90.0F));
|
||||
mStack.translate(-0.5D, -0.5D, 0.5D);
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90.0F));
|
||||
TntMinecartEntityRenderer.method_23190(Blocks.TNT.getDefaultState(), mStack, buffers, packedLight,
|
||||
tnt.getFuse() / 5 % 2 == 0);
|
||||
mStack.pop();
|
||||
super.render(tnt, entityYaw, partialTicks, mStack, buffers, packedLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getTexture(final TinyTNTPrimedEntity entity) {
|
||||
return SpriteAtlasTexture.BLOCK_ATLAS_TEX;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2018, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.fluids.items;
|
||||
|
||||
import alexiil.mc.lib.attributes.fluid.FluidVolumeUtil;
|
||||
import alexiil.mc.lib.attributes.fluid.amount.FluidAmount;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidKeys;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
|
||||
import appeng.items.AEBaseItem;
|
||||
|
||||
/**
|
||||
* Dummy item to display the fluid Icon
|
||||
*
|
||||
* @author DrummerMC
|
||||
* @version rv6 - 2018-01-22
|
||||
* @since rv6 2018-01-22
|
||||
*/
|
||||
public class FluidDummyItem extends AEBaseItem {
|
||||
|
||||
public FluidDummyItem(Settings properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(ItemStack stack) {
|
||||
FluidVolume fluidStack = this.getFluidStack(stack);
|
||||
if (fluidStack.isEmpty()) {
|
||||
fluidStack = FluidKeys.WATER.withAmount(FluidAmount.BUCKET);
|
||||
}
|
||||
return fluidStack.getName().getString();
|
||||
}
|
||||
|
||||
public FluidVolume getFluidStack(ItemStack is) {
|
||||
CompoundTag tag = is.getTag();
|
||||
if (tag != null) {
|
||||
return FluidVolume.fromTag(tag);
|
||||
}
|
||||
return FluidVolumeUtil.EMPTY;
|
||||
}
|
||||
|
||||
public void setFluidStack(ItemStack is, FluidVolume fs) {
|
||||
if (fs.isEmpty()) {
|
||||
is.setTag(null);
|
||||
} else {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
fs.toTag(tag);
|
||||
is.setTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendStacks(ItemGroup group, DefaultedList<ItemStack> items) {
|
||||
// Don't show this item in CreativeTabs
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.fluids.util;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import alexiil.mc.lib.attributes.fluid.amount.FluidAmount;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidKey;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidKeys;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.fabricmc.fabric.api.util.NbtType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.storage.IStorageChannel;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.fluids.items.FluidDummyItem;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEStack;
|
||||
|
||||
public final class AEFluidStack extends AEStack<IAEFluidStack> implements IAEFluidStack, Comparable<AEFluidStack> {
|
||||
private static final String NBT_STACKSIZE = "cnt";
|
||||
private static final String NBT_REQUESTABLE = "req";
|
||||
private static final String NBT_CRAFTABLE = "craft";
|
||||
private static final String NBT_FLUID_ID = "f";
|
||||
private static final String NBT_FLUID_TAG = "ft";
|
||||
|
||||
private final FluidKey fluid;
|
||||
private CompoundTag tagCompound;
|
||||
|
||||
private AEFluidStack(final AEFluidStack fluidStack) {
|
||||
this.fluid = fluidStack.fluid;
|
||||
this.setStackSize(fluidStack.getStackSize());
|
||||
|
||||
// priority = is.priority;
|
||||
this.setCraftable(fluidStack.isCraftable());
|
||||
this.setCountRequestable(fluidStack.getCountRequestable());
|
||||
|
||||
if (fluidStack.hasTagCompound()) {
|
||||
this.tagCompound = fluidStack.tagCompound.copy();
|
||||
}
|
||||
}
|
||||
|
||||
private AEFluidStack(@Nonnull FluidKey fluid, long amount, @Nullable CompoundTag tag) {
|
||||
this.fluid = Preconditions.checkNotNull(fluid);
|
||||
this.setStackSize(amount);
|
||||
this.setCraftable(false);
|
||||
this.setCountRequestable(0);
|
||||
this.tagCompound = tag;
|
||||
}
|
||||
|
||||
public static AEFluidStack fromFluidStack(final FluidVolume input) {
|
||||
if (input.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FluidKey fluid = input.getFluidKey();
|
||||
if (fluid == null) {
|
||||
throw new IllegalArgumentException("Fluid is null.");
|
||||
}
|
||||
|
||||
CompoundTag tag = input.toTag();
|
||||
if (tag.isEmpty()) {
|
||||
tag = null;
|
||||
}
|
||||
|
||||
// FIXME FABRIC NOPE NO FRACTIONS YOU FREAKS THIS IS NOT FROG FRACTIONS
|
||||
long amount = (long)(input.amount().asInexactDouble() * 1000.0);
|
||||
|
||||
return new AEFluidStack(fluid, amount, tag);
|
||||
}
|
||||
|
||||
public static IAEFluidStack fromNBT(final CompoundTag data) {
|
||||
CompoundTag fluidId = data.getCompound(NBT_FLUID_ID);
|
||||
FluidKey fluid = FluidKey.fromTag(fluidId);
|
||||
if (fluid == FluidKeys.EMPTY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CompoundTag tag = null;
|
||||
if (data.contains(NBT_FLUID_TAG, NbtType.COMPOUND)) {
|
||||
tag = data.getCompound(NBT_FLUID_TAG);
|
||||
}
|
||||
|
||||
long amount = data.getLong(NBT_STACKSIZE);
|
||||
|
||||
AEFluidStack fluidStack = new AEFluidStack(fluid, amount, tag);
|
||||
fluidStack.setCountRequestable(data.getLong(NBT_REQUESTABLE));
|
||||
fluidStack.setCraftable(data.getBoolean(NBT_CRAFTABLE));
|
||||
return fluidStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(final IAEFluidStack option) {
|
||||
if (option == null) {
|
||||
return;
|
||||
}
|
||||
this.incStackSize(option.getStackSize());
|
||||
this.setCountRequestable(this.getCountRequestable() + option.getCountRequestable());
|
||||
this.setCraftable(this.isCraftable() || option.isCraftable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(final CompoundTag data) {
|
||||
data.put(NBT_FLUID_ID, this.fluid.toTag());
|
||||
if (this.hasTagCompound()) {
|
||||
data.put(NBT_FLUID_TAG, this.tagCompound);
|
||||
}
|
||||
data.putLong(NBT_STACKSIZE, this.getStackSize());
|
||||
data.putLong(NBT_REQUESTABLE, this.getCountRequestable());
|
||||
data.putBoolean(NBT_CRAFTABLE, this.isCraftable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fuzzyComparison(final IAEFluidStack other, final FuzzyMode mode) {
|
||||
return this.fluid == other.getFluid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack copy() {
|
||||
return new AEFluidStack(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAEFluidStack empty() {
|
||||
final IAEFluidStack dup = this.copy();
|
||||
dup.reset();
|
||||
return dup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItem() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFluid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStorageChannel<IAEFluidStack> getChannel() {
|
||||
return AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final AEFluidStack other) {
|
||||
if (this.fluid != other.fluid) {
|
||||
return this.fluid.entry.getId().compareTo(other.fluid.entry.getId());
|
||||
}
|
||||
|
||||
if (Platform.itemComparisons().isNbtTagEqual(this.tagCompound, other.tagCompound)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.tagCompound.hashCode() - other.tagCompound.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.fluid == null) ? 0 : this.fluid.hashCode());
|
||||
result = prime * result + ((this.tagCompound == null) ? 0 : this.tagCompound.hashCode());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object other) {
|
||||
if (other instanceof AEFluidStack) {
|
||||
final AEFluidStack is = (AEFluidStack) other;
|
||||
return is.fluid == this.fluid && Platform.itemComparisons().isNbtTagEqual(this.tagCompound, is.tagCompound);
|
||||
} else if (other instanceof FluidVolume) {
|
||||
final FluidVolume is = (FluidVolume) other;
|
||||
return is.getFluidKey() == this.fluid
|
||||
&& Platform.itemComparisons().isNbtTagEqual(this.tagCompound, is.toTag());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getStackSize() + "x" + this.getFluidStack().getFluidKey().entry.getId() + " " + this.tagCompound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTagCompound() {
|
||||
return this.tagCompound != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidVolume getFluidStack() {
|
||||
FluidAmount amount = FluidAmount.of(this.getStackSize(), 1000);
|
||||
return this.fluid.readVolume(tagCompound).withAmount(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidKey getFluid() {
|
||||
return this.fluid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack asItemStackRepresentation() {
|
||||
ItemStack is = AEApi.instance().definitions().items().dummyFluidItem().maybeStack(1).orElse(ItemStack.EMPTY);
|
||||
if (!is.isEmpty()) {
|
||||
FluidDummyItem item = (FluidDummyItem) is.getItem();
|
||||
item.setFluidStack(is, this.getFluidStack());
|
||||
return is;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public static IAEFluidStack fromPacket(final PacketByteBuf buffer) {
|
||||
final boolean isCraftable = buffer.readBoolean();
|
||||
|
||||
CompoundTag volumeTag = buffer.readCompoundTag();
|
||||
final long stackSize = buffer.readVarLong();
|
||||
final long countRequestable = buffer.readVarLong();
|
||||
|
||||
if (volumeTag == null) {
|
||||
return null;
|
||||
}
|
||||
FluidVolume fluidStack = FluidVolume.fromTag(volumeTag);
|
||||
if (fluidStack.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final AEFluidStack fluid = AEFluidStack.fromFluidStack(fluidStack);
|
||||
fluid.setStackSize(stackSize);
|
||||
fluid.setCountRequestable(countRequestable);
|
||||
fluid.setCraftable(isCraftable);
|
||||
return fluid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToPacket(final PacketByteBuf buffer) {
|
||||
buffer.writeBoolean(this.isCraftable());
|
||||
buffer.writeCompoundTag(this.getFluidStack().toTag());
|
||||
buffer.writeVarLong(this.getStackSize());
|
||||
buffer.writeVarLong(this.getCountRequestable());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.helpers;
|
||||
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IPriorityHost {
|
||||
|
||||
/**
|
||||
* get current priority.
|
||||
*/
|
||||
int getPriority();
|
||||
|
||||
/**
|
||||
* set new priority
|
||||
*/
|
||||
void setPriority(int newValue);
|
||||
|
||||
ItemStack getItemStackRepresentation();
|
||||
|
||||
/**
|
||||
* Used to show the user interface of this part when returning from the priority
|
||||
* GUI.
|
||||
*/
|
||||
ScreenHandlerType<?> getContainerType();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.items.materials;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.entity.ChargedQuartzEntity;
|
||||
import appeng.entity.SingularityEntity;
|
||||
|
||||
public enum MaterialType {
|
||||
CERTUS_QUARTZ_CRYSTAL("certus_quartz_crystal", EnumSet.of(AEFeature.CERTUS), "crystalCertusQuartz"),
|
||||
CERTUS_QUARTZ_CRYSTAL_CHARGED("charged_certus_quartz_crystal", EnumSet.of(AEFeature.CERTUS),
|
||||
ChargedQuartzEntity.class),
|
||||
|
||||
CERTUS_QUARTZ_DUST("certus_quartz_dust", EnumSet.of(AEFeature.DUSTS, AEFeature.CERTUS), "dustCertusQuartz"),
|
||||
NETHER_QUARTZ_DUST("nether_quartz_dust", EnumSet.of(AEFeature.DUSTS), "dustNetherQuartz,dustQuartz"),
|
||||
FLOUR("flour", EnumSet.of(AEFeature.FLOUR), "dustWheat"),
|
||||
GOLD_DUST("gold_dust", EnumSet.of(AEFeature.DUSTS), "dustGold"),
|
||||
IRON_DUST("iron_dust", EnumSet.of(AEFeature.DUSTS), "dustIron"),
|
||||
|
||||
SILICON("silicon", EnumSet.of(AEFeature.SILICON), "itemSilicon"),
|
||||
MATTER_BALL("matter_ball", EnumSet.of(AEFeature.MATTER_BALL)),
|
||||
|
||||
FLUIX_CRYSTAL("fluix_crystal", EnumSet.of(AEFeature.FLUIX), "crystalFluix"),
|
||||
FLUIX_DUST("fluix_dust", EnumSet.of(AEFeature.FLUIX, AEFeature.DUSTS), "dustFluix"),
|
||||
FLUIX_PEARL("fluix_pearl", EnumSet.of(AEFeature.FLUIX), "pearlFluix"),
|
||||
|
||||
PURIFIED_CERTUS_QUARTZ_CRYSTAL("purified_certus_quartz_crystal",
|
||||
EnumSet.of(AEFeature.CERTUS, AEFeature.PURE_CRYSTALS), "crystalPureCertusQuartz"),
|
||||
PURIFIED_NETHER_QUARTZ_CRYSTAL("purified_nether_quartz_crystal", EnumSet.of(AEFeature.PURE_CRYSTALS),
|
||||
"crystalPureNetherQuartz"),
|
||||
PURIFIED_FLUIX_CRYSTAL("purified_fluix_crystal", EnumSet.of(AEFeature.FLUIX, AEFeature.PURE_CRYSTALS),
|
||||
"crystalPureFluix"),
|
||||
|
||||
CALCULATION_PROCESSOR_PRESS("calculation_processor_press", EnumSet.of(AEFeature.PRESSES)),
|
||||
ENGINEERING_PROCESSOR_PRESS("engineering_processor_press", EnumSet.of(AEFeature.PRESSES)),
|
||||
LOGIC_PROCESSOR_PRESS("logic_processor_press", EnumSet.of(AEFeature.PRESSES)),
|
||||
|
||||
CALCULATION_PROCESSOR_PRINT("printed_calculation_processor", EnumSet.of(AEFeature.PRINTED_CIRCUITS)),
|
||||
ENGINEERING_PROCESSOR_PRINT("printed_engineering_processor", EnumSet.of(AEFeature.PRINTED_CIRCUITS)),
|
||||
LOGIC_PROCESSOR_PRINT("printed_logic_processor", EnumSet.of(AEFeature.PRINTED_CIRCUITS)),
|
||||
|
||||
SILICON_PRESS("silicon_press", EnumSet.of(AEFeature.PRESSES)),
|
||||
SILICON_PRINT("printed_silicon", EnumSet.of(AEFeature.PRINTED_CIRCUITS)),
|
||||
|
||||
NAME_PRESS("name_press", EnumSet.of(AEFeature.PRESSES)),
|
||||
|
||||
LOGIC_PROCESSOR("logic_processor", EnumSet.of(AEFeature.PROCESSORS)),
|
||||
CALCULATION_PROCESSOR("calculation_processor", EnumSet.of(AEFeature.PROCESSORS)),
|
||||
ENGINEERING_PROCESSOR("engineering_processor", EnumSet.of(AEFeature.PROCESSORS)),
|
||||
|
||||
// Basic Cards
|
||||
BASIC_CARD("basic_card", EnumSet.of(AEFeature.BASIC_CARDS)),
|
||||
CARD_REDSTONE("redstone_card", EnumSet.of(AEFeature.BASIC_CARDS)),
|
||||
CARD_CAPACITY("capacity_card", EnumSet.of(AEFeature.BASIC_CARDS)),
|
||||
|
||||
// Adv Cards
|
||||
ADVANCED_CARD("advanced_card", EnumSet.of(AEFeature.ADVANCED_CARDS)),
|
||||
CARD_FUZZY("fuzzy_card", EnumSet.of(AEFeature.ADVANCED_CARDS)),
|
||||
CARD_SPEED("speed_card", EnumSet.of(AEFeature.ADVANCED_CARDS)),
|
||||
CARD_INVERTER("inverter_card", EnumSet.of(AEFeature.ADVANCED_CARDS)),
|
||||
|
||||
SPATIAL_2_CELL_COMPONENT("2_cubed_spatial_cell_component", EnumSet.of(AEFeature.SPATIAL_IO)),
|
||||
SPATIAL_16_CELL_COMPONENT("16_cubed_spatial_cell_component", EnumSet.of(AEFeature.SPATIAL_IO)),
|
||||
SPATIAL_128_CELL_COMPONENT("128_cubed_spatial_cell_component", EnumSet.of(AEFeature.SPATIAL_IO)),
|
||||
|
||||
ITEM_1K_CELL_COMPONENT("1k_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
ITEM_4K_CELL_COMPONENT("4k_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
ITEM_16K_CELL_COMPONENT("16k_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
ITEM_64K_CELL_COMPONENT("64k_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
EMPTY_STORAGE_CELL("empty_storage_cell", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
|
||||
WOODEN_GEAR("wooden_gear", EnumSet.of(AEFeature.GRIND_STONE), "gearWood"),
|
||||
|
||||
WIRELESS_RECEIVER("wireless_receiver", EnumSet.of(AEFeature.WIRELESS_ACCESS_TERMINAL)),
|
||||
WIRELESS_BOOSTER("wireless_booster", EnumSet.of(AEFeature.WIRELESS_ACCESS_TERMINAL)),
|
||||
|
||||
FORMATION_CORE("formation_core", EnumSet.of(AEFeature.CORES)),
|
||||
ANNIHILATION_CORE("annihilation_core", EnumSet.of(AEFeature.CORES)),
|
||||
|
||||
SKY_DUST("sky_dust", EnumSet.of(AEFeature.DUSTS)),
|
||||
|
||||
ENDER_DUST("ender_dust", EnumSet.of(AEFeature.QUANTUM_NETWORK_BRIDGE), "dustEnder,dustEnderPearl",
|
||||
SingularityEntity.class),
|
||||
SINGULARITY("singularity", EnumSet.of(AEFeature.QUANTUM_NETWORK_BRIDGE), SingularityEntity.class),
|
||||
QUANTUM_ENTANGLED_SINGULARITY("quantum_entangled_singularity", EnumSet.of(AEFeature.QUANTUM_NETWORK_BRIDGE),
|
||||
SingularityEntity.class),
|
||||
|
||||
BLANK_PATTERN("blank_pattern", EnumSet.of(AEFeature.PATTERNS)),
|
||||
CARD_CRAFTING("crafting_card", EnumSet.of(AEFeature.ADVANCED_CARDS, AEFeature.CRAFTING_CPU)),
|
||||
|
||||
FLUID_1K_CELL_COMPONENT("1k_fluid_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
FLUID_4K_CELL_COMPONENT("4k_fluid_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
FLUID_16K_CELL_COMPONENT("16k_fluid_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS)),
|
||||
FLUID_64K_CELL_COMPONENT("64k_fluid_cell_component", EnumSet.of(AEFeature.STORAGE_CELLS));
|
||||
|
||||
private final Set<AEFeature> features;
|
||||
private final Identifier registryName;
|
||||
private Item itemInstance;
|
||||
private String oreName;
|
||||
private Class<? extends Entity> droppedEntity;
|
||||
private boolean isRegistered = false;
|
||||
|
||||
MaterialType(String id, final Set<AEFeature> features) {
|
||||
this.features = features;
|
||||
this.registryName = new Identifier(AppEng.MOD_ID, id);
|
||||
}
|
||||
|
||||
MaterialType(String id, final Set<AEFeature> features, final Class<? extends Entity> c) {
|
||||
this(id, features);
|
||||
this.droppedEntity = c;
|
||||
}
|
||||
|
||||
MaterialType(String id, final Set<AEFeature> features, final String oreDictionary,
|
||||
final Class<? extends Entity> c) {
|
||||
this(id, features);
|
||||
this.oreName = oreDictionary;
|
||||
this.droppedEntity = c;
|
||||
}
|
||||
|
||||
MaterialType(String id, final Set<AEFeature> features, final String oreDictionary) {
|
||||
this(id, features);
|
||||
this.oreName = oreDictionary;
|
||||
}
|
||||
|
||||
public ItemStack stack(final int size) {
|
||||
return new ItemStack(this.getItemInstance(), size);
|
||||
}
|
||||
|
||||
public Set<AEFeature> getFeature() {
|
||||
return this.features;
|
||||
}
|
||||
|
||||
public String getOreName() {
|
||||
return this.oreName;
|
||||
}
|
||||
|
||||
boolean hasCustomEntity() {
|
||||
return this.droppedEntity != null;
|
||||
}
|
||||
|
||||
Class<? extends Entity> getCustomEntityClass() {
|
||||
return this.droppedEntity;
|
||||
}
|
||||
|
||||
public boolean isRegistered() {
|
||||
return this.isRegistered;
|
||||
}
|
||||
|
||||
public void markReady() {
|
||||
this.isRegistered = true;
|
||||
}
|
||||
|
||||
public Item getItemInstance() {
|
||||
return this.itemInstance;
|
||||
}
|
||||
|
||||
public void setItemInstance(final Item itemInstance) {
|
||||
this.itemInstance = itemInstance;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return registryName.getPath();
|
||||
}
|
||||
|
||||
public Identifier getRegistryName() {
|
||||
return this.registryName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.me;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridStorage;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
|
||||
public class GridStorage implements IGridStorage {
|
||||
|
||||
private final long myID;
|
||||
private final CompoundTag data;
|
||||
private final WeakHashMap<GridStorage, Boolean> divided = new WeakHashMap<>();
|
||||
private WeakReference<IGrid> internalGrid = null;
|
||||
|
||||
/**
|
||||
* for use with world settings
|
||||
*
|
||||
* @param id ID of grid storage
|
||||
*/
|
||||
public GridStorage(final long id) {
|
||||
this.myID = id;
|
||||
this.data = new CompoundTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* for use with world settings
|
||||
*
|
||||
* @param data The Grid data.
|
||||
* @param id ID of grid storage
|
||||
*/
|
||||
public GridStorage(final long id, final CompoundTag data) {
|
||||
this.myID = id;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* fake storage.
|
||||
*/
|
||||
public GridStorage() {
|
||||
this.myID = 0;
|
||||
this.data = new CompoundTag();
|
||||
}
|
||||
|
||||
public void saveState() {
|
||||
throw new IllegalStateException();
|
||||
// FIXME FABRIC final Grid currentGrid = (Grid) this.getGrid();
|
||||
// FIXME FABRIC if (currentGrid != null) {
|
||||
// FIXME FABRIC currentGrid.saveState();
|
||||
// FIXME FABRIC }
|
||||
}
|
||||
|
||||
public IGrid getGrid() {
|
||||
return this.internalGrid == null ? null : this.internalGrid.get();
|
||||
}
|
||||
|
||||
void setGrid(final IGrid grid) {
|
||||
this.internalGrid = new WeakReference<>(grid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag dataObject() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getID() {
|
||||
return this.myID;
|
||||
}
|
||||
|
||||
void addDivided(final GridStorage gs) {
|
||||
this.divided.put(gs, true);
|
||||
}
|
||||
|
||||
boolean hasDivided(final GridStorage myStorage) {
|
||||
return this.divided.containsKey(myStorage);
|
||||
}
|
||||
|
||||
void remove() {
|
||||
WorldData.instance().storageData().destroyGridStorage(this.myID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.me.helpers;
|
||||
|
||||
import appeng.api.networking.IGridBlock;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
|
||||
public interface IGridProxyable extends IGridHost {
|
||||
|
||||
IGridBlock getProxy(); // FIXME AENetworkProxy return type
|
||||
|
||||
DimensionalCoord getLocation();
|
||||
|
||||
void gridChanged();
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services;
|
||||
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.services.compass.CompassReader;
|
||||
import appeng.services.compass.ICompassCallback;
|
||||
|
||||
public final class CompassService {
|
||||
private static final int CHUNK_SIZE = 16;
|
||||
|
||||
private final MinecraftServer server;
|
||||
private final WeakHashMap<ServerWorld, CompassReader> worldSet = new WeakHashMap<>(10);
|
||||
private final ExecutorService executor;
|
||||
|
||||
private int jobSize;
|
||||
|
||||
public CompassService(MinecraftServer server, @Nonnull final ThreadFactory factory) {
|
||||
this.server = server;
|
||||
this.executor = Executors.newSingleThreadExecutor(factory);
|
||||
this.jobSize = 0;
|
||||
}
|
||||
|
||||
public Future<?> getCompassDirection(final DimensionalCoord coord, final int maxRange, final ICompassCallback cc) {
|
||||
this.jobSize++;
|
||||
return this.executor.submit(new CMDirectionRequest(coord, maxRange, cc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the a compass service is removed once a world gets unloaded by forge.
|
||||
*
|
||||
* @param event the event containing the unloaded world.
|
||||
*/
|
||||
// FIXME FABRIC this is never registered
|
||||
// FIXME @SubscribeEvent
|
||||
// FIXME public void unloadWorld(final WorldEvent.Unload event) {
|
||||
// FIXME DimensionType dim = event.getWorld().getDimension().getType();
|
||||
// FIXME
|
||||
// FIXME if (Platform.isServer() && this.worldSet.containsKey(dim)) {
|
||||
// FIXME final CompassReader compassReader = this.worldSet.remove(dim);
|
||||
// FIXME compassReader.close();
|
||||
// FIXME }
|
||||
// FIXME }
|
||||
|
||||
private int jobSize() {
|
||||
return this.jobSize;
|
||||
}
|
||||
|
||||
private void cleanUp() {
|
||||
for (final CompassReader cr : this.worldSet.values()) {
|
||||
cr.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void tryUpdateArea(final WorldAccess w, ChunkPos chunkPos) {
|
||||
// If this seems weird: during worldgen, WorldAccess is a specific region, but getWorld is
|
||||
// still the server world
|
||||
World world = w.getWorld();
|
||||
if (!(world instanceof ServerWorld)) {
|
||||
return;
|
||||
}
|
||||
updateArea((ServerWorld) world, chunkPos);
|
||||
}
|
||||
|
||||
public void updateArea(final ServerWorld w, ChunkPos chunkPos) {
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE);
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE + 32);
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE + 64);
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE + 96);
|
||||
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE + 128);
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE + 160);
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE + 192);
|
||||
this.updateArea(w, chunkPos, CHUNK_SIZE + 224);
|
||||
}
|
||||
|
||||
public Future<?> updateArea(final ServerWorld w, ChunkPos chunkPos, int y) {
|
||||
this.jobSize++;
|
||||
|
||||
final int cx = chunkPos.x;
|
||||
final int cdy = y >> 5;
|
||||
final int cz = chunkPos.z;
|
||||
|
||||
final int low_y = cdy << 5;
|
||||
final int hi_y = low_y + 32;
|
||||
|
||||
// lower level...
|
||||
final Chunk c = w.getChunk(cx, cz);
|
||||
|
||||
Block skyStoneBlock = AEApi.instance().definitions().blocks().skyStoneBlock().block();
|
||||
BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
for (int i = 0; i < CHUNK_SIZE; i++) {
|
||||
pos.setX(i);
|
||||
for (int j = 0; j < CHUNK_SIZE; j++) {
|
||||
pos.setZ(j);
|
||||
for (int k = low_y; k < hi_y; k++) {
|
||||
pos.setY(k);
|
||||
final Block blk = c.getBlockState(pos).getBlock();
|
||||
if (blk == skyStoneBlock) {
|
||||
return this.executor.submit(new CMUpdatePost(w, cx, cz, cdy, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.executor.submit(new CMUpdatePost(w, cx, cz, cdy, false));
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
this.executor.shutdown();
|
||||
|
||||
try {
|
||||
this.executor.awaitTermination(6, TimeUnit.MINUTES);
|
||||
this.jobSize = 0;
|
||||
|
||||
for (final CompassReader cr : this.worldSet.values()) {
|
||||
cr.close();
|
||||
}
|
||||
|
||||
this.worldSet.clear();
|
||||
} catch (final InterruptedException e) {
|
||||
// wrap this up..
|
||||
}
|
||||
}
|
||||
|
||||
private CompassReader getReader(final ServerWorld world) {
|
||||
CompassReader cr = this.worldSet.get(world);
|
||||
|
||||
if (cr == null) {
|
||||
cr = new CompassReader(world);
|
||||
this.worldSet.put(world, cr);
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
private int dist(final int ax, final int az, final int bx, final int bz) {
|
||||
final int up = (bz - az) * CHUNK_SIZE;
|
||||
final int side = (bx - ax) * CHUNK_SIZE;
|
||||
|
||||
return up * up + side * side;
|
||||
}
|
||||
|
||||
private double rad(final int ax, final int az, final int bx, final int bz) {
|
||||
final int up = bz - az;
|
||||
final int side = bx - ax;
|
||||
|
||||
return Math.atan2(-up, side) - Math.PI / 2.0;
|
||||
}
|
||||
|
||||
private class CMUpdatePost implements Runnable {
|
||||
|
||||
public final ServerWorld world;
|
||||
|
||||
public final int chunkX;
|
||||
public final int chunkZ;
|
||||
public final int doubleChunkY; // 32 blocks instead of 16.
|
||||
public final boolean value;
|
||||
|
||||
public CMUpdatePost(final ServerWorld world, final int cx, final int cz, final int dcy, final boolean val) {
|
||||
this.world = world;
|
||||
this.chunkX = cx;
|
||||
this.doubleChunkY = dcy;
|
||||
this.chunkZ = cz;
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
CompassService.this.jobSize--;
|
||||
|
||||
final CompassReader cr = CompassService.this.getReader(this.world);
|
||||
cr.setHasBeacon(this.chunkX, this.chunkZ, this.doubleChunkY, this.value);
|
||||
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CMDirectionRequest implements Runnable {
|
||||
|
||||
public final int maxRange;
|
||||
public final DimensionalCoord coord;
|
||||
public final ICompassCallback callback;
|
||||
|
||||
public CMDirectionRequest(final DimensionalCoord coord, final int getMaxRange, final ICompassCallback cc) {
|
||||
this.coord = coord;
|
||||
this.maxRange = getMaxRange;
|
||||
this.callback = cc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
ServerWorld world = (ServerWorld) this.coord.getWorld();
|
||||
|
||||
CompassService.this.jobSize--;
|
||||
|
||||
final int cx = this.coord.x >> 4;
|
||||
final int cz = this.coord.z >> 4;
|
||||
|
||||
final CompassReader cr = CompassService.this.getReader(world);
|
||||
|
||||
// Am I standing on it?
|
||||
if (cr.hasBeacon(cx, cz)) {
|
||||
this.callback.calculatedDirection(true, true, -999, 0);
|
||||
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// spiral outward...
|
||||
for (int offset = 1; offset < this.maxRange; offset++) {
|
||||
final int minX = cx - offset;
|
||||
final int minZ = cz - offset;
|
||||
final int maxX = cx + offset;
|
||||
final int maxZ = cz + offset;
|
||||
|
||||
int closest = Integer.MAX_VALUE;
|
||||
int chosen_x = cx;
|
||||
int chosen_z = cz;
|
||||
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
if (cr.hasBeacon(minX, z)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, minX, z);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = minX;
|
||||
chosen_z = z;
|
||||
}
|
||||
}
|
||||
|
||||
if (cr.hasBeacon(maxX, z)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, maxX, z);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = maxX;
|
||||
chosen_z = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = minX + 1; x < maxX; x++) {
|
||||
if (cr.hasBeacon(x, minZ)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, x, minZ);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = x;
|
||||
chosen_z = minZ;
|
||||
}
|
||||
}
|
||||
|
||||
if (cr.hasBeacon(x, maxZ)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, x, maxZ);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = x;
|
||||
chosen_z = maxZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closest < Integer.MAX_VALUE) {
|
||||
this.callback.calculatedDirection(true, false, CompassService.this.rad(cx, cz, chosen_x, chosen_z),
|
||||
CompassService.this.dist(cx, cz, chosen_x, chosen_z));
|
||||
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find shit...
|
||||
this.callback.calculatedDirection(false, true, -999, 999);
|
||||
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.compass;
|
||||
|
||||
public class CompassException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 8825268683203860877L;
|
||||
|
||||
private final Throwable inner;
|
||||
|
||||
public CompassException(final Throwable t) {
|
||||
this.inner = t;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.compass;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
|
||||
public final class CompassReader {
|
||||
private final Map<Long, CompassRegion> regions = new HashMap<>(100);
|
||||
private final ServerWorld world;
|
||||
|
||||
public CompassReader(ServerWorld world) {
|
||||
this.world = Preconditions.checkNotNull(world);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
for (final CompassRegion r : this.regions.values()) {
|
||||
r.close();
|
||||
}
|
||||
|
||||
this.regions.clear();
|
||||
}
|
||||
|
||||
public void setHasBeacon(final int cx, final int cz, final int cdy, final boolean hasBeacon) {
|
||||
final CompassRegion r = this.getRegion(cx, cz);
|
||||
|
||||
r.setHasBeacon(cx, cz, cdy, hasBeacon);
|
||||
}
|
||||
|
||||
public boolean hasBeacon(final int cx, final int cz) {
|
||||
final CompassRegion r = this.getRegion(cx, cz);
|
||||
|
||||
return r.hasBeacon(cx, cz);
|
||||
}
|
||||
|
||||
private CompassRegion getRegion(final int cx, final int cz) {
|
||||
long pos = cx >> 10;
|
||||
pos <<= 32;
|
||||
pos |= (cz >> 10);
|
||||
|
||||
CompassRegion cr = this.regions.get(pos);
|
||||
|
||||
if (cr == null) {
|
||||
cr = new CompassRegion(world, cx, cz);
|
||||
this.regions.put(pos, cr);
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.compass;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.world.PersistentState;
|
||||
|
||||
final class CompassRegion {
|
||||
private final int lowX;
|
||||
private final int lowZ;
|
||||
private final ServerWorld world;
|
||||
private SaveData data;
|
||||
|
||||
public CompassRegion(ServerWorld world, final int cx, final int cz) {
|
||||
Preconditions.checkNotNull(world);
|
||||
|
||||
this.world = world;
|
||||
|
||||
final int region_x = cx >> 10;
|
||||
final int region_z = cz >> 10;
|
||||
|
||||
this.lowX = region_x << 10;
|
||||
this.lowZ = region_z << 10;
|
||||
|
||||
this.openData(false);
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (this.data != null) {
|
||||
this.data = null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasBeacon(int cx, int cz) {
|
||||
if (this.data != null) {
|
||||
cx &= 0x3FF;
|
||||
cz &= 0x3FF;
|
||||
|
||||
final int val = this.read(cx, cz);
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void setHasBeacon(int cx, int cz, final int cdy, final boolean hasBeacon) {
|
||||
cx &= 0x3FF;
|
||||
cz &= 0x3FF;
|
||||
|
||||
this.openData(hasBeacon);
|
||||
|
||||
if (this.data != null) {
|
||||
int val = this.read(cx, cz);
|
||||
final int originalVal = val;
|
||||
|
||||
if (hasBeacon) {
|
||||
val |= 1 << cdy;
|
||||
} else {
|
||||
val &= ~(1 << cdy);
|
||||
}
|
||||
|
||||
if (originalVal != val) {
|
||||
this.write(cx, cz, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void openData(final boolean create) {
|
||||
if (this.data != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String name = this.lowX + "_" + this.lowZ;
|
||||
|
||||
if (create) {
|
||||
this.data = world.getPersistentStateManager().getOrCreate(() -> new SaveData(name), name);
|
||||
if (this.data.bitmap == null) {
|
||||
this.data.bitmap = new byte[SaveData.BITMAP_LENGTH];
|
||||
}
|
||||
} else {
|
||||
this.data = world.getPersistentStateManager().get(() -> new SaveData(name), name);
|
||||
}
|
||||
}
|
||||
|
||||
private int read(final int cx, final int cz) {
|
||||
try {
|
||||
return this.data.bitmap[cx + cz * 0x400];
|
||||
} catch (final IndexOutOfBoundsException outOfBounds) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void write(final int cx, final int cz, final int val) {
|
||||
this.data.bitmap[cx + cz * 0x400] = (byte) val;
|
||||
this.data.markDirty();
|
||||
}
|
||||
|
||||
private static class SaveData extends PersistentState {
|
||||
|
||||
private static final int BITMAP_LENGTH = 0x400 * 0x400;
|
||||
|
||||
private byte[] bitmap;
|
||||
|
||||
public SaveData(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
this.bitmap = nbt.getByteArray("b");
|
||||
if (this.bitmap.length != BITMAP_LENGTH) {
|
||||
throw new IllegalStateException("Invalid bitmap length: " + bitmap.length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag compound) {
|
||||
compound.putByteArray("b", bitmap);
|
||||
return compound;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.compass;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* @author thatsIch
|
||||
* @version rv3 - 31.05.2015
|
||||
* @since rv3 31.05.2015
|
||||
*/
|
||||
public final class CompassThreadFactory implements ThreadFactory {
|
||||
@Override
|
||||
public Thread newThread(@Nonnull final Runnable job) {
|
||||
Preconditions.checkNotNull(job);
|
||||
|
||||
return new Thread(job, "AE Compass Service");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.services.compass;
|
||||
|
||||
public interface ICompassCallback {
|
||||
|
||||
/**
|
||||
* Called from another thread.
|
||||
*
|
||||
* @param hasResult true if found a target
|
||||
* @param spin true if should spin
|
||||
* @param radians radians
|
||||
* @param dist distance
|
||||
*/
|
||||
void calculatedDirection(boolean hasResult, boolean spin, double radians, double dist);
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package appeng.tile;
|
||||
|
||||
import alexiil.mc.lib.attributes.AttributeList;
|
||||
import alexiil.mc.lib.attributes.AttributeProvider;
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import appeng.api.implementations.tiles.ISegmentedInventory;
|
||||
import appeng.api.util.ICommonTile;
|
||||
@@ -30,10 +32,10 @@ import appeng.core.AELog;
|
||||
import appeng.core.features.IStackSrc;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.SettingsFrom;
|
||||
import com.sun.org.apache.bcel.internal.classfile.AttributeReader;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachmentBlockEntity;
|
||||
@@ -58,7 +60,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AEBaseBlockEntity extends BlockEntity implements IOrientable, ICommonTile, ICustomNameObject, BlockEntityClientSerializable, RenderAttachmentBlockEntity {
|
||||
public class AEBaseBlockEntity extends BlockEntity implements IOrientable, ICommonTile, ICustomNameObject, BlockEntityClientSerializable, RenderAttachmentBlockEntity, AttributeProvider {
|
||||
|
||||
private static final ThreadLocal<WeakReference<AEBaseBlockEntity>> DROP_NO_ITEMS = new ThreadLocal<>();
|
||||
private static final Map<Class<? extends BlockEntity>, IStackSrc> ITEM_STACKS = new HashMap<>();
|
||||
@@ -299,10 +301,10 @@ public class AEBaseBlockEntity extends BlockEntity implements IOrientable, IComm
|
||||
final FixedItemInv inv = ((ISegmentedInventory) this).getInventoryByName("config");
|
||||
if (inv instanceof AppEngInternalAEInventory) {
|
||||
final AppEngInternalAEInventory target = (AppEngInternalAEInventory) inv;
|
||||
final AppEngInternalAEInventory tmp = new AppEngInternalAEInventory(null, target.getSlots());
|
||||
final AppEngInternalAEInventory tmp = new AppEngInternalAEInventory(null, target.getSlotCount());
|
||||
tmp.readFromNBT(compound, "config");
|
||||
for (int x = 0; x < tmp.getSlots(); x++) {
|
||||
target.setStackInSlot(x, tmp.getStackInSlot(x));
|
||||
for (int x = 0; x < tmp.getSlotCount(); x++) {
|
||||
target.forceSetInvStack(x, tmp.getInvStack(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,8 +398,9 @@ public class AEBaseBlockEntity extends BlockEntity implements IOrientable, IComm
|
||||
if (this.world != null) {
|
||||
this.world.markDirty(this.pos, this);
|
||||
if (!this.markDirtyQueued) {
|
||||
TickHandler.INSTANCE.addCallable(null, this::markDirtyAtEndOfTick);
|
||||
// FIXME FABRIC TickHandler.INSTANCE.addCallable(null, this::markDirtyAtEndOfTick);
|
||||
this.markDirtyQueued = true;
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -417,4 +420,8 @@ public class AEBaseBlockEntity extends BlockEntity implements IOrientable, IComm
|
||||
return new AEModelData(up, forward);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAllAttributes(World world, BlockPos pos, BlockState state, AttributeList<?> to) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
|
||||
package appeng.tile;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import alexiil.mc.lib.attributes.AttributeList;
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import alexiil.mc.lib.attributes.item.impl.EmptyFixedItemInv;
|
||||
import net.minecraft.block.BlockState;
|
||||
@@ -31,10 +32,9 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
@@ -102,18 +102,34 @@ public abstract class AEBaseInvBlockEntity extends AEBaseBlockEntity implements
|
||||
return this.getInternalInventory();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nonnull
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, Direction facing) {
|
||||
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||
if (facing == null) {
|
||||
return (LazyOptional<T>) LazyOptional.of(this::getInternalInventory);
|
||||
} else {
|
||||
return (LazyOptional<T>) LazyOptional.of(() -> getItemHandlerForSide(facing));
|
||||
public void addAllAttributes(World world, BlockPos pos, BlockState state, AttributeList<?> to) {
|
||||
super.addAllAttributes(world, pos, state, to);
|
||||
offerItemInventory(to);
|
||||
}
|
||||
|
||||
private void offerItemInventory(AttributeList<?> to) {
|
||||
FixedItemInv internalHandler = getInternalInventory();
|
||||
|
||||
// Offer up the directional ones first
|
||||
for (Direction side : Direction.values()) {
|
||||
FixedItemInv inv = getItemHandlerForSide(side);
|
||||
if (inv != internalHandler) {
|
||||
to.offer(inv, FACE_SHAPES.get(side));
|
||||
}
|
||||
}
|
||||
return super.getCapability(capability, facing);
|
||||
|
||||
to.offer(internalHandler);
|
||||
}
|
||||
|
||||
private static final EnumMap<Direction, VoxelShape> FACE_SHAPES = new EnumMap<>(Direction.class);
|
||||
static {
|
||||
FACE_SHAPES.put(Direction.UP, VoxelShapes.cuboid(0f, 15f, 0f, 16f, 16f, 16f));
|
||||
FACE_SHAPES.put(Direction.DOWN, VoxelShapes.cuboid(0f, 0f, 0f, 16f, 1f, 16f));
|
||||
FACE_SHAPES.put(Direction.NORTH, VoxelShapes.cuboid(0f, 0f, 0f, 16f, 16f, 1f));
|
||||
FACE_SHAPES.put(Direction.SOUTH, VoxelShapes.cuboid(0f, 0f, 15f, 16f, 16f, 16f));
|
||||
FACE_SHAPES.put(Direction.WEST, VoxelShapes.cuboid(0f, 0f, 0f, 1f, 16f, 16f));
|
||||
FACE_SHAPES.put(Direction.EAST, VoxelShapes.cuboid(15f, 0f, 0f, 16f, 16f, 16f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.tile.inventory;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import alexiil.mc.lib.attributes.ListenerRemovalToken;
|
||||
import alexiil.mc.lib.attributes.ListenerToken;
|
||||
import alexiil.mc.lib.attributes.Simulation;
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import alexiil.mc.lib.attributes.item.InvMarkDirtyListener;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
import appeng.util.inv.InvOperation;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import appeng.util.iterators.InvIterator;
|
||||
|
||||
public class AppEngInternalAEInventory implements FixedItemInv, Iterable<ItemStack> {
|
||||
private final IAEAppEngInventory te;
|
||||
private final IAEItemStack[] inv;
|
||||
private final int size;
|
||||
private int maxStack;
|
||||
private boolean dirtyFlag = false;
|
||||
|
||||
public AppEngInternalAEInventory(final IAEAppEngInventory te, final int s) {
|
||||
this.te = te;
|
||||
this.size = s;
|
||||
this.maxStack = 64;
|
||||
this.inv = new IAEItemStack[s];
|
||||
}
|
||||
|
||||
public void setMaxStackSize(final int s) {
|
||||
this.maxStack = s;
|
||||
}
|
||||
|
||||
public IAEItemStack getAEStackInSlot(final int var1) {
|
||||
return this.inv[var1];
|
||||
}
|
||||
|
||||
public void writeToNBT(final CompoundTag data, final String name) {
|
||||
final CompoundTag c = new CompoundTag();
|
||||
this.writeToNBT(c);
|
||||
data.put(name, c);
|
||||
}
|
||||
|
||||
private void writeToNBT(final CompoundTag target) {
|
||||
for (int x = 0; x < this.size; x++) {
|
||||
try {
|
||||
final CompoundTag c = new CompoundTag();
|
||||
|
||||
if (this.inv[x] != null) {
|
||||
this.inv[x].writeToNBT(c);
|
||||
}
|
||||
|
||||
target.put("#" + x, c);
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void readFromNBT(final CompoundTag data, final String name) {
|
||||
final CompoundTag c = data.getCompound(name);
|
||||
if (c != null) {
|
||||
this.readFromNBT(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void readFromNBT(final CompoundTag target) {
|
||||
for (int x = 0; x < this.size; x++) {
|
||||
try {
|
||||
final CompoundTag c = target.getCompound("#" + x);
|
||||
|
||||
if (c != null) {
|
||||
this.inv[x] = AEItemStack.fromNBT(c);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected int getStackLimit(int slot, @Nonnull ItemStack stack) {
|
||||
return Math.min(this.getMaxAmount(slot, stack), stack.getMaxCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getInvStack(int slot) {
|
||||
if (this.inv[slot] == null) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
return this.inv[slot].createItemStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setInvStack(int slot, ItemStack to, Simulation simulation) {
|
||||
if (this.te == null || !Platform.isServer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: We need to implement the actual checks here, stacking /caninsert/canremove
|
||||
if (true) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
if (simulation == Simulation.SIMULATE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack oldStack = this.getInvStack(slot).copy();
|
||||
this.inv[slot] = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
|
||||
.createStack(to);
|
||||
|
||||
ItemStack newStack = to.copy();
|
||||
InvOperation op = InvOperation.SET;
|
||||
|
||||
if (ItemStack.areItemsEqual(oldStack, newStack)) {
|
||||
if (newStack.getCount() > oldStack.getCount()) {
|
||||
newStack.decrement(oldStack.getCount());
|
||||
oldStack = ItemStack.EMPTY;
|
||||
op = InvOperation.INSERT;
|
||||
} else {
|
||||
oldStack.decrement(newStack.getCount());
|
||||
newStack = ItemStack.EMPTY;
|
||||
op = InvOperation.EXTRACT;
|
||||
}
|
||||
}
|
||||
this.fireOnChangeInventory(slot, op, oldStack, newStack);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotCount() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int slot, ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChangeValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ListenerToken addListener(InvMarkDirtyListener listener, ListenerRemovalToken removalToken) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void fireOnChangeInventory(int slot, InvOperation op, ItemStack removed, ItemStack inserted) {
|
||||
if (this.te != null && Platform.isServer() && !this.dirtyFlag) {
|
||||
this.dirtyFlag = true;
|
||||
this.te.onChangeInventory(this, slot, op, removed, inserted);
|
||||
this.te.saveChanges();
|
||||
this.dirtyFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxAmount(int slot, ItemStack is) {
|
||||
return Math.min(this.maxStack, 64);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemStack> iterator() {
|
||||
return new InvIterator(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.tile.inventory;
|
||||
|
||||
import alexiil.mc.lib.attributes.Simulation;
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInvView;
|
||||
import alexiil.mc.lib.attributes.item.filter.ConstantItemFilter;
|
||||
import alexiil.mc.lib.attributes.item.filter.ItemFilter;
|
||||
import alexiil.mc.lib.attributes.item.impl.FullFixedItemInv;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
import appeng.util.inv.InvOperation;
|
||||
import appeng.util.inv.filter.IAEItemFilter;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
// FIXME: the filtering is not correctly implemented and need to be reworked
|
||||
public class AppEngInternalInventory extends FullFixedItemInv implements Iterable<ItemStack> {
|
||||
private boolean enableClientEvents = false;
|
||||
private IAEAppEngInventory te;
|
||||
private final int[] maxStack;
|
||||
private IAEItemFilter filter;
|
||||
private boolean dirtyFlag = false;
|
||||
|
||||
public AppEngInternalInventory(final IAEAppEngInventory inventory, final int size, final int maxStack,
|
||||
IAEItemFilter filter) {
|
||||
super(size);
|
||||
this.setTileEntity(inventory);
|
||||
this.setFilter(filter);
|
||||
this.maxStack = new int[size];
|
||||
Arrays.fill(this.maxStack, maxStack);
|
||||
|
||||
setOwnerListener(this::onContentsChanged);
|
||||
}
|
||||
|
||||
public AppEngInternalInventory(final IAEAppEngInventory inventory, final int size, final int maxStack) {
|
||||
this(inventory, size, maxStack, null);
|
||||
}
|
||||
|
||||
public AppEngInternalInventory(final IAEAppEngInventory inventory, final int size) {
|
||||
this(inventory, size, 64);
|
||||
}
|
||||
|
||||
public void setFilter(IAEItemFilter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxAmount(int slot, ItemStack stack) {
|
||||
return Math.min(maxStack[slot], super.getMaxAmount(slot, stack));
|
||||
}
|
||||
|
||||
protected void onContentsChanged(FixedItemInvView inv, int slot, ItemStack previous, ItemStack current) {
|
||||
if (this.getBlockEntity() != null && this.eventsEnabled() && !this.dirtyFlag) {
|
||||
this.dirtyFlag = true;
|
||||
ItemStack newStack = current.copy();
|
||||
ItemStack oldStack = previous;
|
||||
InvOperation op = InvOperation.SET;
|
||||
|
||||
if (newStack.isEmpty() || oldStack.isEmpty() || ItemStack.areItemsEqual(newStack, oldStack)) {
|
||||
if (newStack.getCount() > oldStack.getCount()) {
|
||||
newStack.decrement(oldStack.getCount());
|
||||
oldStack = ItemStack.EMPTY;
|
||||
op = InvOperation.INSERT;
|
||||
} else {
|
||||
oldStack.decrement(newStack.getCount());
|
||||
newStack = ItemStack.EMPTY;
|
||||
op = InvOperation.EXTRACT;
|
||||
}
|
||||
}
|
||||
|
||||
this.getBlockEntity().onChangeInventory(this, slot, op, oldStack, newStack);
|
||||
this.getBlockEntity().saveChanges();
|
||||
this.dirtyFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean eventsEnabled() {
|
||||
return Platform.isServer() || this.isEnableClientEvents();
|
||||
}
|
||||
|
||||
public void setMaxStackSize(final int slot, final int size) {
|
||||
this.maxStack[slot] = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemFilter getFilterForSlot(int slot) {
|
||||
if (this.maxStack[slot] == 0) {
|
||||
return ConstantItemFilter.NOTHING;
|
||||
}
|
||||
if (this.filter != null) {
|
||||
return stack -> {
|
||||
// FIXME: This is not correct...
|
||||
if (stack == ItemStack.EMPTY) {
|
||||
return filter.allowExtract(this, slot, this.getSlot(slot).get().getCount());
|
||||
} else {
|
||||
return filter.allowExtract(this, slot, this.getSlot(slot).get().getCount());
|
||||
}
|
||||
};
|
||||
}
|
||||
return ConstantItemFilter.ANYTHING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int slot, ItemStack stack) {
|
||||
if (this.maxStack[slot] == 0) {
|
||||
return false;
|
||||
}
|
||||
if (this.filter != null) {
|
||||
return this.filter.allowInsert(this, slot, stack);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeToNBT(final CompoundTag data, final String name) {
|
||||
data.put(name, this.toTag());
|
||||
}
|
||||
|
||||
public void readFromNBT(final CompoundTag data, final String name) {
|
||||
final CompoundTag c = data.getCompound(name);
|
||||
if (c != null) {
|
||||
this.readFromNBT(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void readFromNBT(final CompoundTag data) {
|
||||
this.fromTag(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ItemStack> iterator() {
|
||||
return stackIterable().iterator();
|
||||
}
|
||||
|
||||
private boolean isEnableClientEvents() {
|
||||
return this.enableClientEvents;
|
||||
}
|
||||
|
||||
public void setEnableClientEvents(final boolean enableClientEvents) {
|
||||
this.enableClientEvents = enableClientEvents;
|
||||
}
|
||||
|
||||
private IAEAppEngInventory getBlockEntity() {
|
||||
return this.te;
|
||||
}
|
||||
|
||||
public void setTileEntity(final IAEAppEngInventory te) {
|
||||
this.te = te;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
package appeng.tile.storage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.block.ChestAnimationProgress;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Tickable;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
|
||||
import appeng.block.storage.SkyChestBlock;
|
||||
import appeng.tile.AEBaseInvBlockEntity;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.util.inv.InvOperation;
|
||||
|
||||
public class SkyChestBlockEntity extends AEBaseInvBlockEntity implements Tickable, ChestAnimationProgress {
|
||||
|
||||
private final AppEngInternalInventory inv = new AppEngInternalInventory(this, 9 * 4);
|
||||
|
||||
// server
|
||||
private int numPlayersUsing;
|
||||
// client..
|
||||
private long lastEvent;
|
||||
private float lidAngle;
|
||||
private float prevLidAngle;
|
||||
|
||||
public SkyChestBlockEntity(BlockEntityType<? extends SkyChestBlockEntity> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeToStream(final PacketByteBuf data) throws IOException {
|
||||
super.writeToStream(data);
|
||||
data.writeBoolean(this.getPlayerOpen() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean readFromStream(final PacketByteBuf data) throws IOException {
|
||||
final boolean c = super.readFromStream(data);
|
||||
final int wasOpen = this.getPlayerOpen();
|
||||
this.setPlayerOpen(data.readBoolean() ? 1 : 0);
|
||||
|
||||
if (wasOpen != this.getPlayerOpen()) {
|
||||
this.setLastEvent(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
return c; // TESR yo!
|
||||
}
|
||||
|
||||
@Override
|
||||
public FixedItemInv getInternalInventory() {
|
||||
return this.inv;
|
||||
}
|
||||
|
||||
public void openInventory(final PlayerEntity player) {
|
||||
if (!player.isSpectator()) {
|
||||
this.setPlayerOpen(this.getPlayerOpen() + 1);
|
||||
onOpenOrClose();
|
||||
|
||||
if (this.getPlayerOpen() == 1) {
|
||||
this.getWorld().playSound(player, this.pos.getX() + 0.5D, this.pos.getY() + 0.5D,
|
||||
this.pos.getZ() + 0.5D, SoundEvents.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.5F,
|
||||
this.getWorld().random.nextFloat() * 0.1F + 0.9F);
|
||||
this.markForUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeInventory(final PlayerEntity player) {
|
||||
if (!player.isSpectator()) {
|
||||
this.setPlayerOpen(this.getPlayerOpen() - 1);
|
||||
onOpenOrClose();
|
||||
|
||||
if (this.getPlayerOpen() < 0) {
|
||||
this.setPlayerOpen(0);
|
||||
}
|
||||
|
||||
if (this.getPlayerOpen() == 0) {
|
||||
this.getWorld().playSound(player, this.pos.getX() + 0.5D, this.pos.getY() + 0.5D,
|
||||
this.pos.getZ() + 0.5D, SoundEvents.BLOCK_CHEST_CLOSE, SoundCategory.BLOCKS, 0.5F,
|
||||
this.getWorld().random.nextFloat() * 0.1F + 0.9F);
|
||||
this.markForUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See ChestTileEntity
|
||||
private void onOpenOrClose() {
|
||||
Block block = getCachedState().getBlock();
|
||||
if (block instanceof SkyChestBlock) {
|
||||
this.world.addSyncedBlockEvent(this.pos, block, 1, this.numPlayersUsing);
|
||||
this.world.updateNeighborsAlways(this.pos, block);
|
||||
// FIXME: Uhm, we are we doing this?
|
||||
this.world.updateNeighborsAlways(this.pos.down(), block);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.prevLidAngle = this.lidAngle;
|
||||
if (this.numPlayersUsing == 0 && this.lidAngle > 0.0F || this.numPlayersUsing > 0 && this.lidAngle < 1.0F) {
|
||||
if (this.numPlayersUsing > 0) {
|
||||
this.lidAngle += 0.1F;
|
||||
} else {
|
||||
this.lidAngle -= 0.1F;
|
||||
}
|
||||
|
||||
this.lidAngle = MathHelper.clamp(this.lidAngle, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeInventory(final FixedItemInv inv, final int slot, final InvOperation mc,
|
||||
final ItemStack removed, final ItemStack added) {
|
||||
|
||||
}
|
||||
|
||||
public int getPlayerOpen() {
|
||||
return this.numPlayersUsing;
|
||||
}
|
||||
|
||||
private void setPlayerOpen(final int playerOpen) {
|
||||
this.numPlayersUsing = playerOpen;
|
||||
}
|
||||
|
||||
public long getLastEvent() {
|
||||
return this.lastEvent;
|
||||
}
|
||||
|
||||
private void setLastEvent(final long lastEvent) {
|
||||
this.lastEvent = lastEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAnimationProgress(float partialTicks) {
|
||||
return MathHelper.lerp(partialTicks, this.prevLidAngle, this.lidAngle);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,11 +48,6 @@ import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.stats.AeStats;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.integration.abstraction.JEIFacade;
|
||||
import appeng.me.GridAccessException;
|
||||
import appeng.me.GridNode;
|
||||
import appeng.me.helpers.AENetworkProxy;
|
||||
import appeng.util.helpers.ItemComparisonHelper;
|
||||
import appeng.util.helpers.P2PHelper;
|
||||
import appeng.util.item.AEItemStack;
|
||||
@@ -887,43 +882,43 @@ public class Platform {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean securityCheck(final GridNode a, final GridNode b) {
|
||||
if (a.getLastSecurityKey() == -1 && b.getLastSecurityKey() == -1) {
|
||||
return true;
|
||||
} else if (a.getLastSecurityKey() == b.getLastSecurityKey()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final boolean a_isSecure = isPowered(a.getGrid()) && a.getLastSecurityKey() != -1;
|
||||
final boolean b_isSecure = isPowered(b.getGrid()) && b.getLastSecurityKey() != -1;
|
||||
|
||||
if (AEConfig.instance().isFeatureEnabled(AEFeature.LOG_SECURITY_AUDITS)) {
|
||||
final String locationA = a.getGridBlock().isWorldAccessible() ? a.getGridBlock().getLocation().toString()
|
||||
: "notInWorld";
|
||||
final String locationB = b.getGridBlock().isWorldAccessible() ? b.getGridBlock().getLocation().toString()
|
||||
: "notInWorld";
|
||||
|
||||
AELog.info(
|
||||
"Audit: Node A [isSecure=%b, key=%d, playerID=%d, location={%s}] vs Node B[isSecure=%b, key=%d, playerID=%d, location={%s}]",
|
||||
a_isSecure, a.getLastSecurityKey(), a.getPlayerID(), locationA, b_isSecure, b.getLastSecurityKey(),
|
||||
b.getPlayerID(), locationB);
|
||||
}
|
||||
|
||||
// can't do that son...
|
||||
if (a_isSecure && b_isSecure) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a_isSecure && b_isSecure) {
|
||||
return checkPlayerPermissions(b.getGrid(), a.getPlayerID());
|
||||
}
|
||||
|
||||
if (a_isSecure && !b_isSecure) {
|
||||
return checkPlayerPermissions(a.getGrid(), b.getPlayerID());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// FIXME FABRIC public static boolean securityCheck(final GridNode a, final GridNode b) {
|
||||
// FIXME FABRIC if (a.getLastSecurityKey() == -1 && b.getLastSecurityKey() == -1) {
|
||||
// FIXME FABRIC return true;
|
||||
// FIXME FABRIC } else if (a.getLastSecurityKey() == b.getLastSecurityKey()) {
|
||||
// FIXME FABRIC return true;
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC final boolean a_isSecure = isPowered(a.getGrid()) && a.getLastSecurityKey() != -1;
|
||||
// FIXME FABRIC final boolean b_isSecure = isPowered(b.getGrid()) && b.getLastSecurityKey() != -1;
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC if (AEConfig.instance().isFeatureEnabled(AEFeature.LOG_SECURITY_AUDITS)) {
|
||||
// FIXME FABRIC final String locationA = a.getGridBlock().isWorldAccessible() ? a.getGridBlock().getLocation().toString()
|
||||
// FIXME FABRIC : "notInWorld";
|
||||
// FIXME FABRIC final String locationB = b.getGridBlock().isWorldAccessible() ? b.getGridBlock().getLocation().toString()
|
||||
// FIXME FABRIC : "notInWorld";
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC AELog.info(
|
||||
// FIXME FABRIC "Audit: Node A [isSecure=%b, key=%d, playerID=%d, location={%s}] vs Node B[isSecure=%b, key=%d, playerID=%d, location={%s}]",
|
||||
// FIXME FABRIC a_isSecure, a.getLastSecurityKey(), a.getPlayerID(), locationA, b_isSecure, b.getLastSecurityKey(),
|
||||
// FIXME FABRIC b.getPlayerID(), locationB);
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC // can't do that son...
|
||||
// FIXME FABRIC if (a_isSecure && b_isSecure) {
|
||||
// FIXME FABRIC return false;
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC if (!a_isSecure && b_isSecure) {
|
||||
// FIXME FABRIC return checkPlayerPermissions(b.getGrid(), a.getPlayerID());
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC if (a_isSecure && !b_isSecure) {
|
||||
// FIXME FABRIC return checkPlayerPermissions(a.getGrid(), b.getPlayerID());
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC return true;
|
||||
// FIXME FABRIC }
|
||||
|
||||
private static boolean isPowered(final IGrid grid) {
|
||||
if (grid == null) {
|
||||
@@ -985,26 +980,26 @@ public class Platform {
|
||||
yaw, pitch);
|
||||
}
|
||||
|
||||
public static boolean canAccess(final AENetworkProxy gridProxy, final IActionSource src) {
|
||||
try {
|
||||
if (src.player().isPresent()) {
|
||||
return gridProxy.getSecurity().hasPermission(src.player().get(), SecurityPermissions.BUILD);
|
||||
} else if (src.machine().isPresent()) {
|
||||
final IActionHost te = src.machine().get();
|
||||
final IGridNode n = te.getActionableNode();
|
||||
if (n == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int playerID = n.getPlayerID();
|
||||
return gridProxy.getSecurity().hasPermission(playerID, SecurityPermissions.BUILD);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (final GridAccessException gae) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// FIXME FABRIC public static boolean canAccess(final AENetworkProxy gridProxy, final IActionSource src) {
|
||||
// FIXME FABRIC try {
|
||||
// FIXME FABRIC if (src.player().isPresent()) {
|
||||
// FIXME FABRIC return gridProxy.getSecurity().hasPermission(src.player().get(), SecurityPermissions.BUILD);
|
||||
// FIXME FABRIC } else if (src.machine().isPresent()) {
|
||||
// FIXME FABRIC final IActionHost te = src.machine().get();
|
||||
// FIXME FABRIC final IGridNode n = te.getActionableNode();
|
||||
// FIXME FABRIC if (n == null) {
|
||||
// FIXME FABRIC return false;
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC
|
||||
// FIXME FABRIC final int playerID = n.getPlayerID();
|
||||
// FIXME FABRIC return gridProxy.getSecurity().hasPermission(playerID, SecurityPermissions.BUILD);
|
||||
// FIXME FABRIC } else {
|
||||
// FIXME FABRIC return false;
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC } catch (final GridAccessException gae) {
|
||||
// FIXME FABRIC return false;
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC }
|
||||
|
||||
public static ItemStack extractItemsByRecipe(final IEnergySource energySrc, final IActionSource mySrc,
|
||||
final IMEMonitor<IAEItemStack> src, final World w, final Recipe<CraftingInventory> r,
|
||||
@@ -1094,7 +1089,8 @@ public class Platform {
|
||||
|
||||
public static void notifyBlocksOfNeighbors(final World world, final BlockPos pos) {
|
||||
if (!world.isClient) {
|
||||
TickHandler.INSTANCE.addCallable(world, new BlockUpdate(pos));
|
||||
throw new IllegalStateException();
|
||||
// FIXME FABRIC TickHandler.INSTANCE.addCallable(world, new BlockUpdate(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1139,7 +1135,8 @@ public class Platform {
|
||||
|
||||
public static boolean isSearchModeAvailable(SearchBoxMode mode) {
|
||||
if (mode.isRequiresJei()) {
|
||||
return JEIFacade.instance().isEnabled();
|
||||
throw new IllegalStateException();
|
||||
// FIXME FABRIC return JEIFacade.instance().isEnabled();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
accessWidener v1 named
|
||||
accessible method net/minecraft/client/particle/RedDustParticle <init> (Lnet/minecraft/client/world/ClientWorld;DDDDDDLnet/minecraft/particle/DustParticleEffect;Lnet/minecraft/client/particle/SpriteProvider;)V
|
||||
|
||||
# To disable water-bobbing of item entities (for growing crystals)
|
||||
extendable method net/minecraft/entity/ItemEntity applyBuoyancy ()V
|
||||
@@ -32,5 +32,6 @@
|
||||
},
|
||||
"suggests": {
|
||||
"flamingo": "*"
|
||||
}
|
||||
},
|
||||
"accessWidener" : "appliedenergistics2.accesswidener"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user