More moves and compilation fixes

This commit is contained in:
Sebastian Hartte
2020-06-29 02:15:31 +02:00
parent 3df93fc66d
commit 0d63f560d3
240 changed files with 2221 additions and 1926 deletions
-1
View File
@@ -1,4 +1,3 @@
archivesBaseName = artifact_basename + "-core"
dependencies {
@@ -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);
}
}
+183 -241
View File
@@ -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();
}
}
+247 -273
View File
@@ -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 {
}
@@ -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);
}
}
+61 -64
View File
@@ -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
+2 -1
View File
@@ -32,5 +32,6 @@
},
"suggests": {
"flamingo": "*"
}
},
"accessWidener" : "appliedenergistics2.accesswidener"
}