Compare commits

...

16 Commits

Author SHA1 Message Date
shartte 0632925653 Remove the use of SlotItemHandler since we are only faking an inventory-backed slot, (#4654)
we might as well use what we had used pre-2017, which is simply extending a normal Slot.
This should also fix #4652.
2020-08-29 21:50:06 +02:00
shartte 98b758e6f9 Fixes #4648: Inverted logic for the annihilation plane dropping no items. (#4649) 2020-08-28 16:28:34 +02:00
shartte faa00cd894 Backport Model Registration Changes (#4647)
* Fix Special Model Registration (#4577)

* Fixes #4575 by updating Forge (ModelRegistryEvent is a modbus event but was misflagged as not being one). And update Forge because their breaking change breaks our mod.

* Update gradle.properties

Co-authored-by: yueh <yueh@users.noreply.github.com>

* Update src/main/resources/META-INF/mods.toml

Co-authored-by: yueh <yueh@users.noreply.github.com>

Co-authored-by: yueh <yueh@users.noreply.github.com>

(cherry picked from commit 8733c2c11f)

* Strip pom.xml dependencies.

(cherry picked from commit 00d4c20d9f)
2020-08-28 15:57:47 +02:00
shartte 544491064d Fixes #4635: Actually remove requesters when removing requesters. (#4637) 2020-08-24 19:23:48 +02:00
shartte e533ae5f3f Added step to publish to modmaven (#4607) (#4630)
(cherry picked from commit 7e1bfdb5ac)

Co-authored-by: yueh <yueh@users.noreply.github.com>
2020-08-23 22:30:34 +02:00
shartte 98733844a6 Fixes #4602: Prevent encoding invalid patterns and handle corrupted patterns a little more gracefully. (#4608) (#4629)
(cherry picked from commit 1f9707e256)
2020-08-21 19:24:47 +02:00
shartte ef97381e5f Fixes #4574 by referencing only non-pure fluix crystals in the fluix dust grinder recipe. (#4579) 2020-08-09 12:28:43 +02:00
shartte 27b8c5f3ac Plane Connection Refactor (#4556) (#4565)
* Refactors all plane parts to use a common helper for
calculating connections to adjacent planes.
Also fixes problems with updating these connections on neighbor updates.

* Fix conflicting GuiSync ID.

* Slightly refactor PlaneConnectionHelper, and fix an issue where the bounding box was calculated incorrectly by using the wrong up-direction.

(cherry picked from commit 8617dc8340)
2020-08-05 22:39:04 +02:00
shartte 3043887915 Makes formation planes a bit more consistent and less violent. (#4553) (#4564)
* Makes formation planes a bit more consistent and less violent.

Items will now have a slower speed when spawning as well as a narrower area to avoid having them glitch into a wall and be teleported around

* Removed debug output, added clarifying parenthesis and extracted method.

* Fixes various other issues with the formation plane

Also removed now useless code

(cherry picked from commit 12e3fa9127)
2020-08-05 22:25:48 +02:00
yueh e0abe9b9a9 Fixes #4559: Use visual bounding box for overlay (#4562) 2020-08-05 22:08:48 +02:00
shartte e19991f1f9 Fixes #4547: Name clash between ITooltip#getWidth, ITooltip#getHeight and Vanilla Widget methods leads to missing methods at runtime, since the implementing methods will be remapped to SRG names, while referees of the interface will try to call the renamed methods by their name in the interface, leading to an AbstractMethodError. (#4558) 2020-08-05 18:21:13 +02:00
shartte 3d97b1e3ec Fixes #4551: Bounding box of annihilation planes is too small. (#4552) 2020-08-05 17:45:53 +02:00
yueh 6b1bccffb9 Apply the FE tunnel behaviour to the fluid tunnel (#4550) (#4555) 2020-08-04 23:37:15 +02:00
yueh 6fab7b91b7 Fixes 4529: Updated IPart to match new ICapabilityProvider (#4534) (#4536) 2020-08-01 21:57:26 +02:00
shartte 7b6bab4967 Fix #4521: Register RecipeTypes. (#4523) (#4525) 2020-07-31 20:34:44 +02:00
yueh 04766e5325 Limit gradle to 1 worker for 1.15 (#4526) 2020-07-31 18:51:41 +02:00
46 changed files with 713 additions and 753 deletions
+3 -3
View File
@@ -22,14 +22,14 @@ jobs:
path: ~/.gradle/caches path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Clean gradle - name: Clean gradle
run: ./gradlew clean --no-daemon run: ./gradlew clean --no-daemon --max-workers 1
- name: Validate no assets - name: Validate no assets
run: test ! -d ./src/generated run: test ! -d ./src/generated
- name: Generate assets - name: Generate assets
uses: GabrielBB/xvfb-action@v1.2 uses: GabrielBB/xvfb-action@v1.2
with: with:
run: ./gradlew runData --no-daemon run: ./gradlew runData --no-daemon --max-workers 1
- name: Validate assets - name: Validate assets
run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew build --no-daemon run: ./gradlew build --no-daemon --max-workers 1
+3 -3
View File
@@ -22,14 +22,14 @@ jobs:
path: ~/.gradle/caches path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Clean gradle - name: Clean gradle
run: ./gradlew clean --no-daemon run: ./gradlew clean --no-daemon --max-workers 1
- name: Validate no assets - name: Validate no assets
run: test ! -d ./src/generated run: test ! -d ./src/generated
- name: Generate assets - name: Generate assets
uses: GabrielBB/xvfb-action@v1.2 uses: GabrielBB/xvfb-action@v1.2
with: with:
run: ./gradlew runData --no-daemon run: ./gradlew runData --no-daemon --max-workers 1
- name: Validate assets - name: Validate assets
run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew build --no-daemon run: ./gradlew build --no-daemon --max-workers 1
+3 -3
View File
@@ -22,19 +22,19 @@ jobs:
path: ~/.gradle/caches path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Clean gradle - name: Clean gradle
run: ./gradlew clean --no-daemon run: ./gradlew clean --no-daemon --max-workers 1
- name: Validate no assets - name: Validate no assets
run: test ! -d ./src/generated run: test ! -d ./src/generated
- name: Generate assets - name: Generate assets
uses: GabrielBB/xvfb-action@v1.2 uses: GabrielBB/xvfb-action@v1.2
with: with:
run: ./gradlew runData --no-daemon run: ./gradlew runData --no-daemon --max-workers 1
- name: Validate assets - name: Validate assets
run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache
- name: Build with Gradle - name: Build with Gradle
env: env:
PR_NUMBER: ${{ github.event.pull_request.number }} PR_NUMBER: ${{ github.event.pull_request.number }}
run: ./gradlew build --no-daemon run: ./gradlew build --no-daemon --max-workers 1
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: dist name: dist
+12 -4
View File
@@ -33,7 +33,7 @@ jobs:
- name: Generate assets - name: Generate assets
uses: GabrielBB/xvfb-action@v1.2 uses: GabrielBB/xvfb-action@v1.2
with: with:
run: ./gradlew runData --no-daemon run: ./gradlew runData --no-daemon --max-workers 1
- name: Validate assets - name: Validate assets
run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache run: test -d ./src/generated -a -f ./src/generated/resources/.cache/cache
- name: Build with Gradle - name: Build with Gradle
@@ -42,7 +42,7 @@ jobs:
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }} KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }} KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew build --no-daemon run: ./gradlew build --no-daemon --max-workers 1
- name: Upload to curseforge - name: Upload to curseforge
env: env:
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }} KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
@@ -50,14 +50,22 @@ jobs:
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }} KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
CHANGELOG: ${{ github.event.release.body }} CHANGELOG: ${{ github.event.release.body }}
CURSEFORGE: ${{ secrets.CURSEFORGE }} CURSEFORGE: ${{ secrets.CURSEFORGE }}
run: ./gradlew curseforge --no-daemon run: ./gradlew curseforge --no-daemon --max-workers 1
- name: Publish to github packages - name: Publish to github packages
env: env:
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }} KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }} KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }} KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew publish --no-daemon run: ./gradlew publishMavenPublicationToGitHubPackagesRepository --no-daemon --max-workers 1
- name: Publish to modmaven
env:
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
MODMAVEN_USER: ${{ secrets.MODMAVEN_USER }}
MODMAVEN_PASSWORD: ${{ secrets.MODMAVEN_PASSWORD }}
run: ./gradlew publishMavenPublicationToModmavenRepository --no-daemon --max-workers 1
- name: Prepare artifact metadata - name: Prepare artifact metadata
id: prepare_artifact_metadata id: prepare_artifact_metadata
run: | run: |
+15
View File
@@ -174,6 +174,13 @@ publishing {
groupId = project.group groupId = project.group
artifactId = project.archivesBaseName artifactId = project.archivesBaseName
version = project.version version = project.version
// ForgeGradle will generate wild dependency definitions, see https://github.com/MinecraftForge/ForgeGradle/issues/584
// Since we don't actually depend on anything, just remove the entire node.
pom.withXml {
asNode().remove(asNode().dependencies)
}
from components.java from components.java
artifact sourcesJar artifact sourcesJar
artifact javadocJar artifact javadocJar
@@ -189,5 +196,13 @@ publishing {
name = "GitHubPackages" name = "GitHubPackages"
url = "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2" url = "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2"
} }
maven {
credentials {
username System.getenv("MODMAVEN_USER")
password System.getenv("MODMAVEN_PASSWORD")
}
name = "modmaven"
url = "https://modmaven.k-4u.nl/artifactory/local-releases/"
}
} }
} }
@@ -53,6 +53,8 @@ public interface ICraftingHelper {
* @param stack If null, a new item will be created to hold the encoded pattern. * @param stack If null, a new item will be created to hold the encoded pattern.
* Otherwise the given item must already contains an encoded * Otherwise the given item must already contains an encoded
* pattern that will be overwritten. * pattern that will be overwritten.
* @throws IllegalArgumentException If either in or out contain only empty
* ItemStacks.
* @return A new encoded pattern, or the given stack with the pattern encoded in * @return A new encoded pattern, or the given stack with the pattern encoded in
* it. * it.
*/ */
@@ -73,6 +75,8 @@ public interface ICraftingHelper {
* operation by the ME system. * operation by the ME system.
* @param allowSubstitutes Controls whether the ME system will allow the use of * @param allowSubstitutes Controls whether the ME system will allow the use of
* equivalent items to craft this recipe. * equivalent items to craft this recipe.
* @throws IllegalArgumentException If either in or out contain only empty
* ItemStacks.
*/ */
ItemStack encodeCraftingPattern(@Nullable ItemStack stack, ICraftingRecipe recipe, ItemStack[] in, ItemStack out, ItemStack encodeCraftingPattern(@Nullable ItemStack stack, ICraftingRecipe recipe, ItemStack[] in, ItemStack out,
boolean allowSubstitutes); boolean allowSubstitutes);
+5 -2
View File
@@ -50,6 +50,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.EmptyModelData; import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityProvider;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
@@ -346,10 +347,12 @@ public interface IPart extends ICustomCableConnection {
* capabilities on the cable bus will be forwarded to parts on the appropriate * capabilities on the cable bus will be forwarded to parts on the appropriate
* side. * side.
* *
* @see TileEntity#getCapability(Capability, net.minecraft.util.Direction) * @see CapabilityProvider#getCapability(Capability,
* net.minecraft.util.Direction)
* *
* @return The capability or null. * @return The capability
*/ */
@Nonnull
default <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) { default <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
return LazyOptional.empty(); return LazyOptional.empty();
} }
@@ -154,14 +154,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
protected void drawGuiSlot(CustomSlotWidget slot, int mouseX, int mouseY, float partialTicks) { protected void drawGuiSlot(CustomSlotWidget slot, int mouseX, int mouseY, float partialTicks) {
if (slot.isSlotEnabled()) { if (slot.isSlotEnabled()) {
final int left = slot.xPos(); final int left = slot.getTooltipAreaX();
final int top = slot.yPos(); final int top = slot.getTooltipAreaY();
final int right = left + slot.getWidth(); final int right = left + slot.getTooltipAreaWidth();
final int bottom = top + slot.getHeight(); final int bottom = top + slot.getTooltipAreaHeight();
slot.drawContent(getMinecraft(), mouseX, mouseY, partialTicks); slot.drawContent(getMinecraft(), mouseX, mouseY, partialTicks);
if (this.isPointInRegion(left, top, slot.getWidth(), slot.getHeight(), mouseX, mouseY) if (this.isPointInRegion(left, top, slot.getTooltipAreaWidth(), slot.getTooltipAreaHeight(), mouseX, mouseY)
&& slot.canClick(getPlayer())) { && slot.canClick(getPlayer())) {
RenderSystem.colorMask(true, true, true, false); RenderSystem.colorMask(true, true, true, false);
this.fillGradient(left, top, right, bottom, -2130706433, -2130706433); this.fillGradient(left, top, right, bottom, -2130706433, -2130706433);
@@ -171,16 +171,16 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
} }
private void drawTooltip(ITooltip tooltip, int mouseX, int mouseY) { private void drawTooltip(ITooltip tooltip, int mouseX, int mouseY) {
final int x = tooltip.xPos(); // ((GuiImgButton) c).x; final int x = tooltip.getTooltipAreaX();
int y = tooltip.yPos(); // ((GuiImgButton) c).y; int y = tooltip.getTooltipAreaY();
if (x < mouseX && x + tooltip.getWidth() > mouseX && tooltip.isVisible()) { if (x < mouseX && x + tooltip.getTooltipAreaWidth() > mouseX && tooltip.isTooltipAreaVisible()) {
if (y < mouseY && y + tooltip.getHeight() > mouseY) { if (y < mouseY && y + tooltip.getTooltipAreaHeight() > mouseY) {
if (y < 15) { if (y < 15) {
y = 15; y = 15;
} }
final String msg = tooltip.getMessage(); final String msg = tooltip.getTooltipMessage();
if (msg != null && !msg.isEmpty()) { if (msg != null && !msg.isEmpty()) {
this.drawTooltip(x + 11, y + 4, msg); this.drawTooltip(x + 11, y + 4, msg);
} }
@@ -275,8 +275,8 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
} }
for (CustomSlotWidget slot : this.guiSlots) { for (CustomSlotWidget slot : this.guiSlots) {
if (this.isPointInRegion(slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord) if (this.isPointInRegion(slot.getTooltipAreaX(), slot.getTooltipAreaY(), slot.getTooltipAreaWidth(),
&& slot.canClick(getPlayer())) { slot.getTooltipAreaHeight(), xCoord, yCoord) && slot.canClick(getPlayer())) {
slot.slotClicked(getPlayer().inventory.getItemStack(), btn); slot.slotClicked(getPlayer().inventory.getItemStack(), btn);
} }
} }
@@ -8,19 +8,18 @@ import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.SlotItemHandler;
/** /**
* A proxy for a slot that will always return an itemstack with size 1, if there * A proxy for a slot that will always return an itemstack with size 1, if there
* is an item in the slot. Used to prevent the default item count from * is an item in the slot. Used to prevent the default item count from
* rendering. * rendering.
*/ */
class Size1Slot extends SlotItemHandler { class Size1Slot extends Slot {
private final SlotItemHandler delegate; private final Slot delegate;
public Size1Slot(SlotItemHandler delegate) { public Size1Slot(Slot delegate) {
super(delegate.getItemHandler(), delegate.getSlotIndex(), delegate.xPos, delegate.yPos); super(delegate.inventory, delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
this.delegate = delegate; this.delegate = delegate;
} }
@@ -24,7 +24,7 @@ import java.util.regex.Pattern;
import appeng.api.config.ActionItems; import appeng.api.config.ActionItems;
import appeng.core.localization.ButtonToolTips; import appeng.core.localization.ButtonToolTips;
public class ActionButton extends IconButton implements ITooltip { public class ActionButton extends IconButton {
private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL); private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL);
private final int iconIndex; private final int iconIndex;
@@ -34,32 +34,32 @@ public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
} }
@Override @Override
public String getMessage() { public String getTooltipMessage() {
return null; return null;
} }
@Override @Override
public int xPos() { public int getTooltipAreaX() {
return this.x; return this.x;
} }
@Override @Override
public int yPos() { public int getTooltipAreaY() {
return this.y; return this.y;
} }
@Override @Override
public int getWidth() { public int getTooltipAreaWidth() {
return 16; return 16;
} }
@Override @Override
public int getHeight() { public int getTooltipAreaHeight() {
return 16; return 16;
} }
@Override @Override
public boolean isVisible() { public boolean isTooltipAreaVisible() {
return false; return false;
} }
@@ -28,38 +28,38 @@ public interface ITooltip {
* *
* @return tooltip message * @return tooltip message
*/ */
String getMessage(); String getTooltipMessage();
/** /**
* x Location for the object that triggers the tooltip. * x Location for the object that triggers the tooltip.
* *
* @return xPosition * @return xPosition
*/ */
int xPos(); int getTooltipAreaX();
/** /**
* y Location for the object that triggers the tooltip. * y Location for the object that triggers the tooltip.
* *
* @return yPosition * @return yPosition
*/ */
int yPos(); int getTooltipAreaY();
/** /**
* Width of the object that triggers the tooltip. * Width of the object that triggers the tooltip.
* *
* @return width * @return width
*/ */
int getWidth(); int getTooltipAreaWidth();
/** /**
* Height for the object that triggers the tooltip. * Height for the object that triggers the tooltip.
* *
* @return height * @return height
*/ */
int getHeight(); int getTooltipAreaHeight();
/** /**
* @return true if button being drawn * @return true if button being drawn
*/ */
boolean isVisible(); boolean isTooltipAreaVisible();
} }
@@ -95,27 +95,32 @@ public abstract class IconButton extends Button implements ITooltip {
protected abstract int getIconIndex(); protected abstract int getIconIndex();
@Override @Override
public int xPos() { public String getTooltipMessage() {
return getMessage();
}
@Override
public int getTooltipAreaX() {
return this.x; return this.x;
} }
@Override @Override
public int yPos() { public int getTooltipAreaY() {
return this.y; return this.y;
} }
@Override @Override
public int getWidth() { public int getTooltipAreaWidth() {
return this.halfSize ? 8 : 16; return this.halfSize ? 8 : 16;
} }
@Override @Override
public int getHeight() { public int getTooltipAreaHeight() {
return this.halfSize ? 8 : 16; return this.halfSize ? 8 : 16;
} }
@Override @Override
public boolean isVisible() { public boolean isTooltipAreaVisible() {
return this.visible; return this.visible;
} }
@@ -76,7 +76,7 @@ public class ProgressBar extends Widget implements ITooltip {
} }
@Override @Override
public String getMessage() { public String getTooltipMessage() {
if (this.fullMsg != null) { if (this.fullMsg != null) {
return this.fullMsg; return this.fullMsg;
} }
@@ -86,27 +86,27 @@ public class ProgressBar extends Widget implements ITooltip {
} }
@Override @Override
public int xPos() { public int getTooltipAreaX() {
return this.x - 2; return this.x - 2;
} }
@Override @Override
public int yPos() { public int getTooltipAreaY() {
return this.y - 2; return this.y - 2;
} }
@Override @Override
public int getWidth() { public int getTooltipAreaWidth() {
return this.width + 4; return this.width + 4;
} }
@Override @Override
public int getHeight() { public int getTooltipAreaHeight() {
return this.height + 4; return this.height + 4;
} }
@Override @Override
public boolean isVisible() { public boolean isTooltipAreaVisible() {
return true; return true;
} }
@@ -278,7 +278,7 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
} }
@Override @Override
public String getMessage() { public String getTooltipMessage() {
ITextComponent displayName = null; ITextComponent displayName = null;
ITextComponent displayValue = null; ITextComponent displayValue = null;
@@ -97,27 +97,32 @@ public class TabButton extends Button implements ITooltip {
} }
@Override @Override
public int xPos() { public String getTooltipMessage() {
return getMessage();
}
@Override
public int getTooltipAreaX() {
return this.x; return this.x;
} }
@Override @Override
public int yPos() { public int getTooltipAreaY() {
return this.y; return this.y;
} }
@Override @Override
public int getWidth() { public int getTooltipAreaWidth() {
return 22; return 22;
} }
@Override @Override
public int getHeight() { public int getTooltipAreaHeight() {
return 22; return 22;
} }
@Override @Override
public boolean isVisible() { public boolean isTooltipAreaVisible() {
return this.visible; return this.visible;
} }
@@ -74,7 +74,7 @@ public class ToggleButton extends Button implements ITooltip {
} }
@Override @Override
public String getMessage() { public String getTooltipMessage() {
if (this.displayName != null) { if (this.displayName != null) {
String name = I18n.format(this.displayName); String name = I18n.format(this.displayName);
String value = I18n.format(this.displayHint); String value = I18n.format(this.displayHint);
@@ -103,27 +103,27 @@ public class ToggleButton extends Button implements ITooltip {
} }
@Override @Override
public int xPos() { public int getTooltipAreaX() {
return this.x; return this.x;
} }
@Override @Override
public int yPos() { public int getTooltipAreaY() {
return this.y; return this.y;
} }
@Override @Override
public int getWidth() { public int getTooltipAreaWidth() {
return 16; return 16;
} }
@Override @Override
public int getHeight() { public int getTooltipAreaHeight() {
return 16; return 16;
} }
@Override @Override
public boolean isVisible() { public boolean isTooltipAreaVisible() {
return this.visible; return this.visible;
} }
} }
@@ -41,11 +41,6 @@ import appeng.fluids.util.FluidSorters;
import appeng.util.Platform; import appeng.util.Platform;
import appeng.util.prioritylist.IPartitionList; import appeng.util.prioritylist.IPartitionList;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class FluidRepo { public class FluidRepo {
private final IItemList<IAEFluidStack> list = Api.instance().storage().getStorageChannel(IFluidStorageChannel.class) private final IItemList<IAEFluidStack> list = Api.instance().storage().getStorageChannel(IFluidStorageChannel.class)
.createList(); .createList();
+11 -12
View File
@@ -21,23 +21,22 @@ package appeng.client.me;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.items.SlotItemHandler;
import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEFluidStack;
import appeng.fluids.container.slots.IMEFluidSlot; import appeng.fluids.container.slots.IMEFluidSlot;
/** public class SlotFluidME extends Slot implements IMEFluidSlot {
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
private InternalFluidSlotME slot; private static final IInventory EMPTY_INVENTORY = new Inventory(0);
private final InternalFluidSlotME slot;
public SlotFluidME(InternalFluidSlotME slot) { public SlotFluidME(InternalFluidSlotME slot) {
super(null, 0, slot.getxPosition(), slot.getyPosition()); super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
this.slot = slot; this.slot = slot;
} }
@@ -50,7 +49,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
} }
@Override @Override
public boolean isItemValid(final ItemStack par1ItemStack) { public boolean isItemValid(final ItemStack stack) {
return false; return false;
} }
@@ -69,7 +68,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
} }
@Override @Override
public void putStack(final ItemStack par1ItemStack) { public void putStack(final ItemStack stack) {
} }
@@ -85,7 +84,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
} }
@Override @Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) { public boolean canTakeStack(final PlayerEntity player) {
return false; return false;
} }
} }
+15 -11
View File
@@ -19,23 +19,27 @@
package appeng.client.me; package appeng.client.me;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.items.SlotItemHandler;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
public class SlotME extends SlotItemHandler { public class SlotME extends Slot {
private final InternalSlotME mySlot; private static final IInventory EMPTY_INVENTORY = new Inventory(0);
public SlotME(final InternalSlotME me) { private final InternalSlotME slot;
super(null, 0, me.getxPosition(), me.getyPosition());
this.mySlot = me; public SlotME(final InternalSlotME slot) {
super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
this.slot = slot;
} }
public IAEItemStack getAEStack() { public IAEItemStack getAEStack() {
if (this.mySlot.hasPower()) { if (this.slot.hasPower()) {
return this.mySlot.getAEStack(); return this.slot.getAEStack();
} }
return null; return null;
} }
@@ -47,15 +51,15 @@ public class SlotME extends SlotItemHandler {
@Override @Override
public ItemStack getStack() { public ItemStack getStack() {
if (this.mySlot.hasPower()) { if (this.slot.hasPower()) {
return this.mySlot.getStack(); return this.slot.getStack();
} }
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
@Override @Override
public boolean getHasStack() { public boolean getHasStack() {
if (this.mySlot.hasPower()) { if (this.slot.hasPower()) {
return !this.getStack().isEmpty(); return !this.getStack().isEmpty();
} }
return false; return false;
@@ -52,7 +52,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
return helper.open(player, locator); return helper.open(player, locator);
} }
@GuiSync(6) @GuiSync(7)
public YesNo placeMode; public YesNo placeMode;
public FormationPlaneContainer(int id, final PlayerInventory ip, final FormationPlanePart te) { public FormationPlaneContainer(int id, final PlayerInventory ip, final FormationPlanePart te) {
@@ -261,13 +261,19 @@ public class PatternTermContainer extends MEMonitorableContainer
return new ItemStack[] { out }; return new ItemStack[] { out };
} }
} else { } else {
boolean hasValue = false;
final ItemStack[] list = new ItemStack[3]; final ItemStack[] list = new ItemStack[3];
for (int i = 0; i < this.outputSlots.length; i++) { for (int i = 0; i < this.outputSlots.length; i++) {
final ItemStack out = this.outputSlots[i].getStack(); final ItemStack out = this.outputSlots[i].getStack();
list[i] = out; list[i] = out;
if (!out.isEmpty()) {
hasValue = true;
}
}
if (hasValue) {
return list;
} }
return list;
} }
return null; return null;
@@ -1,18 +0,0 @@
package appeng.core;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.util.ResourceLocation;
public class AERecipeType<T extends IRecipe<?>> implements IRecipeType<T> {
private final String id;
public AERecipeType(ResourceLocation registryName) {
this.id = registryName.toString();
}
@Override
public String toString() {
return id;
}
}
-56
View File
@@ -19,7 +19,6 @@
package appeng.core; package appeng.core;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@@ -39,8 +38,6 @@ import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.feature.Feature; import net.minecraft.world.gen.feature.Feature;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.ModDimension; import net.minecraftforge.common.ModDimension;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
@@ -56,29 +53,10 @@ import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import appeng.block.paint.PaintSplotchesModel;
import appeng.block.qnb.QnbFormedModel;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IInitComponent; import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.components.IPostInitComponent; import appeng.bootstrap.components.IPostInitComponent;
import appeng.capabilities.Capabilities; import appeng.capabilities.Capabilities;
import appeng.client.ClientHelper; 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.BiometricCardModel;
import appeng.client.render.model.ColorApplicatorModel;
import appeng.client.render.model.DriveModel;
import appeng.client.render.model.GlassModel;
import appeng.client.render.model.MemoryCardModel;
import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.model.UVLModelLoader;
import appeng.client.render.spatial.SpatialPylonModel;
import appeng.core.features.registries.PartModels;
import appeng.core.stats.AdvancementTriggers; import appeng.core.stats.AdvancementTriggers;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.worlddata.WorldData; import appeng.core.worlddata.WorldData;
@@ -90,7 +68,6 @@ import appeng.entity.TinyTNTPrimedRenderer;
import appeng.hooks.TickHandler; import appeng.hooks.TickHandler;
import appeng.integration.Integrations; import appeng.integration.Integrations;
import appeng.parts.PartPlacement; import appeng.parts.PartPlacement;
import appeng.parts.automation.PlaneModelLoader;
import appeng.server.ServerHelper; import appeng.server.ServerHelper;
@Mod(AppEng.MOD_ID) @Mod(AppEng.MOD_ID)
@@ -177,39 +154,6 @@ public final class AppEng {
RenderingRegistry.registerEntityRenderingHandler(ChargedQuartzEntity.TYPE, RenderingRegistry.registerEntityRenderingHandler(ChargedQuartzEntity.TYPE,
m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer())); m -> new ItemRenderer(m, Minecraft.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 ResourceLocation(AppEng.MOD_ID, "encoded_pattern"),
EncodedPatternModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "part_plane"),
PlaneModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "crafting_cube"),
CraftingCubeModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "uvlightmap"), UVLModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "cable_bus"),
new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
}
@OnlyIn(Dist.CLIENT)
private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, id),
new SimpleModelLoader<>(modelFactory));
} }
@Nonnull @Nonnull
+54 -5
View File
@@ -18,6 +18,8 @@
package appeng.core; package appeng.core;
import java.util.function.Supplier;
import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@@ -48,6 +50,8 @@ import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent; import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.common.ModDimension; import net.minecraftforge.common.ModDimension;
import net.minecraftforge.common.extensions.IForgeContainerType; import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
@@ -77,7 +81,10 @@ import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.spatial.ISpatialCache; import appeng.api.networking.spatial.ISpatialCache;
import appeng.api.networking.storage.IStorageGrid; import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager; import appeng.api.networking.ticking.ITickManager;
import appeng.block.paint.PaintSplotchesModel;
import appeng.block.qnb.QnbFormedModel;
import appeng.bootstrap.components.IBlockRegistrationComponent; import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IEntityRegistrationComponent; import appeng.bootstrap.components.IEntityRegistrationComponent;
import appeng.bootstrap.components.IItemColorRegistrationComponent; import appeng.bootstrap.components.IItemColorRegistrationComponent;
import appeng.bootstrap.components.IItemRegistrationComponent; import appeng.bootstrap.components.IItemRegistrationComponent;
@@ -116,6 +123,13 @@ import appeng.client.gui.implementations.UpgradeableScreen;
import appeng.client.gui.implementations.VibrationChamberScreen; import appeng.client.gui.implementations.VibrationChamberScreen;
import appeng.client.gui.implementations.WirelessScreen; import appeng.client.gui.implementations.WirelessScreen;
import appeng.client.gui.implementations.WirelessTermScreen; import appeng.client.gui.implementations.WirelessTermScreen;
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.effects.ChargedOreFX; import appeng.client.render.effects.ChargedOreFX;
import appeng.client.render.effects.CraftingFx; import appeng.client.render.effects.CraftingFx;
import appeng.client.render.effects.EnergyFx; import appeng.client.render.effects.EnergyFx;
@@ -125,8 +139,13 @@ import appeng.client.render.effects.MatterCannonFX;
import appeng.client.render.effects.ParticleTypes; import appeng.client.render.effects.ParticleTypes;
import appeng.client.render.effects.VibrantFX; import appeng.client.render.effects.VibrantFX;
import appeng.client.render.model.BiometricCardModel; import appeng.client.render.model.BiometricCardModel;
import appeng.client.render.model.ColorApplicatorModel;
import appeng.client.render.model.DriveModel;
import appeng.client.render.model.GlassModel;
import appeng.client.render.model.MemoryCardModel; import appeng.client.render.model.MemoryCardModel;
import appeng.client.render.model.SkyCompassModel; import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.model.UVLModelLoader;
import appeng.client.render.spatial.SpatialPylonModel;
import appeng.client.render.tesr.InscriberTESR; import appeng.client.render.tesr.InscriberTESR;
import appeng.client.render.tesr.SkyChestTESR; import appeng.client.render.tesr.SkyChestTESR;
import appeng.container.AEBaseContainer; import appeng.container.AEBaseContainer;
@@ -195,11 +214,10 @@ import appeng.me.cache.PathGridCache;
import appeng.me.cache.SecurityCache; import appeng.me.cache.SecurityCache;
import appeng.me.cache.SpatialPylonCache; import appeng.me.cache.SpatialPylonCache;
import appeng.me.cache.TickManagerCache; import appeng.me.cache.TickManagerCache;
import appeng.parts.automation.PlaneModelLoader;
import appeng.recipes.game.DisassembleRecipe; import appeng.recipes.game.DisassembleRecipe;
import appeng.recipes.game.FacadeRecipe; import appeng.recipes.game.FacadeRecipe;
import appeng.recipes.handlers.GrinderRecipe;
import appeng.recipes.handlers.GrinderRecipeSerializer; import appeng.recipes.handlers.GrinderRecipeSerializer;
import appeng.recipes.handlers.InscriberRecipe;
import appeng.recipes.handlers.InscriberRecipeSerializer; import appeng.recipes.handlers.InscriberRecipeSerializer;
import appeng.server.AECommand; import appeng.server.AECommand;
import appeng.spatial.StorageCellBiome; import appeng.spatial.StorageCellBiome;
@@ -245,6 +263,40 @@ final class Registration {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void modelRegistryEvent(ModelRegistryEvent event) { public void modelRegistryEvent(ModelRegistryEvent event) {
registerSpecialModels(); registerSpecialModels();
// 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 ResourceLocation(AppEng.MOD_ID, "encoded_pattern"),
EncodedPatternModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "part_plane"),
PlaneModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "crafting_cube"),
CraftingCubeModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "uvlightmap"), UVLModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "cable_bus"),
new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
}
@OnlyIn(Dist.CLIENT)
private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, id),
new SimpleModelLoader<>(modelFactory));
} }
/** /**
@@ -428,9 +480,6 @@ final class Registration {
public void registerRecipeSerializers(RegistryEvent.Register<IRecipeSerializer<?>> event) { public void registerRecipeSerializers(RegistryEvent.Register<IRecipeSerializer<?>> event) {
IForgeRegistry<IRecipeSerializer<?>> r = event.getRegistry(); IForgeRegistry<IRecipeSerializer<?>> r = event.getRegistry();
GrinderRecipe.TYPE = new AERecipeType<>(GrinderRecipeSerializer.INSTANCE.getRegistryName());
InscriberRecipe.TYPE = new AERecipeType<>(InscriberRecipeSerializer.INSTANCE.getRegistryName());
FacadeItem facadeItem = (FacadeItem) Api.INSTANCE.definitions().items().facade().item(); FacadeItem facadeItem = (FacadeItem) Api.INSTANCE.definitions().items().facade().item();
r.registerAll(DisassembleRecipe.SERIALIZER, GrinderRecipeSerializer.INSTANCE, r.registerAll(DisassembleRecipe.SERIALIZER, GrinderRecipeSerializer.INSTANCE,
InscriberRecipeSerializer.INSTANCE, FacadeRecipe.getSerializer(facadeItem)); InscriberRecipeSerializer.INSTANCE, FacadeRecipe.getSerializer(facadeItem));
@@ -115,7 +115,12 @@ public class ApiCrafting implements ICraftingHelper {
// We use the shared itemstack for an identity lookup. // We use the shared itemstack for an identity lookup.
IAEItemStack ais = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(is); IAEItemStack ais = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(is);
return new CraftingPatternDetails(ais, world); try {
return new CraftingPatternDetails(ais, world);
} catch (IllegalStateException e) {
AELog.warn("Could not decode an invalid pattern %s: %s", is, e);
return null;
}
} }
private boolean attemptRecovery(EncodedPatternItem patternItem, ItemStack itemStack, World world) { private boolean attemptRecovery(EncodedPatternItem patternItem, ItemStack itemStack, World world) {
+1 -1
View File
@@ -49,7 +49,7 @@ public class FacadePart implements IFacadePart {
@Override @Override
public void getBoxes(final IPartCollisionHelper ch, boolean livingEntity) { public void getBoxes(final IPartCollisionHelper ch, boolean livingEntity) {
if (livingEntity) { if (livingEntity || !ch.isBBCollision()) {
// prevent weird snag behavior // prevent weird snag behavior
ch.addBox(0.0, 0.0, 14, 16.0, 16.0, 16.0); ch.addBox(0.0, 0.0, 14, 16.0, 16.0, 16.0);
} else { } else {
@@ -52,7 +52,8 @@ public class FluidSlotWidget extends CustomSlotWidget {
final float blue = (attributes.getColor() & 255) / 255.0F; final float blue = (attributes.getColor() & 255) / 255.0F;
RenderSystem.color3f(red, green, blue); RenderSystem.color3f(red, green, blue);
blit(xPos(), yPos(), this.getBlitOffset(), getWidth(), getHeight(), sprite); blit(getTooltipAreaX(), getTooltipAreaY(), this.getBlitOffset(), getTooltipAreaWidth(),
getTooltipAreaHeight(), sprite);
} }
} }
@@ -76,7 +77,7 @@ public class FluidSlotWidget extends CustomSlotWidget {
} }
@Override @Override
public String getMessage() { public String getTooltipMessage() {
final IAEFluidStack fluid = this.getFluidStack(); final IAEFluidStack fluid = this.getFluidStack();
if (fluid != null) { if (fluid != null) {
return I18n.format(fluid.getFluidStack().getTranslationKey()); return I18n.format(fluid.getFluidStack().getTranslationKey());
@@ -85,7 +86,7 @@ public class FluidSlotWidget extends CustomSlotWidget {
} }
@Override @Override
public boolean isVisible() { public boolean isTooltipAreaVisible() {
return true; return true;
} }
@@ -85,7 +85,7 @@ public class FluidTankWidget extends Widget implements ITooltip {
} }
@Override @Override
public String getMessage() { public String getTooltipMessage() {
final IAEFluidStack fluid = this.tank.getFluidInSlot(this.slot); final IAEFluidStack fluid = this.tank.getFluidInSlot(this.slot);
if (fluid != null && fluid.getStackSize() > 0) { if (fluid != null && fluid.getStackSize() > 0) {
String desc = fluid.getFluid().getAttributes().getDisplayName(fluid.getFluidStack()).getFormattedText(); String desc = fluid.getFluid().getAttributes().getDisplayName(fluid.getFluidStack()).getFormattedText();
@@ -97,27 +97,27 @@ public class FluidTankWidget extends Widget implements ITooltip {
} }
@Override @Override
public int xPos() { public int getTooltipAreaX() {
return this.x - 2; return this.x - 2;
} }
@Override @Override
public int yPos() { public int getTooltipAreaY() {
return this.y - 2; return this.y - 2;
} }
@Override @Override
public int getWidth() { public int getTooltipAreaWidth() {
return this.width + 4; return this.width + 4;
} }
@Override @Override
public int getHeight() { public int getTooltipAreaHeight() {
return this.height + 4; return this.height + 4;
} }
@Override @Override
public boolean isVisible() { public boolean isTooltipAreaVisible() {
return true; return true;
} }
@@ -48,7 +48,8 @@ public class OptionalFluidSlotWidget extends FluidSlotWidget {
} else { } else {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.4F); RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.4F);
} }
GuiUtils.drawTexturedModalRect(guileft + this.xPos() - 1, guitop + this.yPos() - 1, this.srcX - 1, GuiUtils.drawTexturedModalRect(guileft + this.getTooltipAreaX() - 1, guitop + this.getTooltipAreaY() - 1,
this.srcY - 1, this.getWidth() + 2, this.getHeight() + 2, currentZIndex); this.srcX - 1, this.srcY - 1, this.getTooltipAreaWidth() + 2, this.getTooltipAreaHeight() + 2,
currentZIndex);
} }
} }
@@ -210,7 +210,7 @@ public class DualityFluidInterface
} else if (capabilityClass == Capabilities.STORAGE_MONITORABLE_ACCESSOR) { } else if (capabilityClass == Capabilities.STORAGE_MONITORABLE_ACCESSOR) {
return (LazyOptional<T>) LazyOptional.of(() -> this.accessor); return (LazyOptional<T>) LazyOptional.of(() -> this.accessor);
} }
return null; return LazyOptional.empty();
} }
private boolean hasConfig() { private boolean hasConfig() {
@@ -14,7 +14,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tags.FluidTags; import net.minecraft.tags.FluidTags;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
@@ -35,15 +34,12 @@ import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest; import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper; import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEInventory; import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IFluidStorageChannel; import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack; import appeng.api.storage.data.IAEFluidStack;
import appeng.api.util.AECableType; import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.core.Api; import appeng.core.Api;
import appeng.core.AppEng; import appeng.core.AppEng;
import appeng.core.settings.TickRates; import appeng.core.settings.TickRates;
@@ -53,6 +49,7 @@ import appeng.items.parts.PartModels;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource; import appeng.me.helpers.MachineSource;
import appeng.parts.BasicStatePart; import appeng.parts.BasicStatePart;
import appeng.parts.automation.PlaneConnectionHelper;
import appeng.parts.automation.PlaneConnections; import appeng.parts.automation.PlaneConnections;
import appeng.parts.automation.PlaneModelData; import appeng.parts.automation.PlaneModelData;
import appeng.parts.automation.PlaneModels; import appeng.parts.automation.PlaneModels;
@@ -73,115 +70,27 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
private final IActionSource mySrc = new MachineSource(this); private final IActionSource mySrc = new MachineSource(this);
private final PlaneConnectionHelper connectionHelper = new PlaneConnectionHelper(this);
public FluidAnnihilationPlanePart(final ItemStack is) { public FluidAnnihilationPlanePart(final ItemStack is) {
super(is); super(is);
} }
@Override @Override
public void getBoxes(final IPartCollisionHelper bch) { public void getBoxes(final IPartCollisionHelper bch) {
int minX = 1; connectionHelper.getBoxes(bch);
int minY = 1;
int maxX = 15;
int maxY = 15;
final IPartHost host = this.getHost();
if (host != null) {
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e.getOpposite())), this.getSide())) {
minX = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxX = 16;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(u.getOpposite())), this.getSide())) {
minY = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxY = 16;
}
}
bch.addBox(5, 5, 14, 11, 11, 15);
bch.addBox(minX, minY, 15, maxX, maxY, 16);
} }
public PlaneConnections getConnections() { public PlaneConnections getConnections() {
return connectionHelper.getConnections();
final Direction facingRight, facingUp;
AEPartLocation location = this.getSide();
switch (location) {
case UP:
facingRight = Direction.EAST;
facingUp = Direction.NORTH;
break;
case DOWN:
facingRight = Direction.WEST;
facingUp = Direction.NORTH;
break;
case NORTH:
facingRight = Direction.WEST;
facingUp = Direction.UP;
break;
case SOUTH:
facingRight = Direction.EAST;
facingUp = Direction.UP;
break;
case WEST:
facingRight = Direction.SOUTH;
facingUp = Direction.UP;
break;
case EAST:
facingRight = Direction.NORTH;
facingUp = Direction.UP;
break;
default:
case INTERNAL:
return PlaneConnections.of(false, false, false, false);
}
boolean left = false, right = false, down = false, up = false;
final IPartHost host = this.getHost();
if (host != null) {
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight.getOpposite())),
this.getSide())) {
left = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight)), this.getSide())) {
right = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp.getOpposite())),
this.getSide())) {
down = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp)), this.getSide())) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
} }
@Override @Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) { public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
if (pos.offset(this.getSide().getFacing()).equals(neighbor)) { if (pos.offset(this.getSide().getFacing()).equals(neighbor)) {
this.refresh(); this.refresh();
} else {
connectionHelper.updateConnections();
} }
} }
@@ -190,14 +99,6 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
return 1; return 1;
} }
private boolean isAnnihilationPlane(final TileEntity blockTileEntity, final AEPartLocation side) {
if (blockTileEntity instanceof IPartHost) {
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
return p != null && p.getClass() == this.getClass();
}
return false;
}
private void refresh() { private void refresh() {
try { try {
this.getProxy().getTick().alertDevice(this.getProxy().getNode()); this.getProxy().getTick().alertDevice(this.getProxy().getNode());
@@ -309,14 +309,27 @@ public class EncodedPatternItem extends AEBaseItem {
final ListNBT tagIn = new ListNBT(); final ListNBT tagIn = new ListNBT();
final ListNBT tagOut = new ListNBT(); final ListNBT tagOut = new ListNBT();
boolean hasInput = false;
for (final ItemStack i : in) { for (final ItemStack i : in) {
tagIn.add(createItemTag(i)); tagIn.add(createItemTag(i));
if (!i.isEmpty()) {
hasInput = true;
}
} }
Preconditions.checkArgument(hasInput, "cannot encode a pattern that has no inputs.");
boolean hasNonEmptyOutput = false;
for (final ItemStack i : out) { for (final ItemStack i : out) {
tagOut.add(createItemTag(i)); tagOut.add(createItemTag(i));
if (!i.isEmpty()) {
hasNonEmptyOutput = true;
}
} }
// Patterns without any outputs are corrupt! Never encode such a pattern.
Preconditions.checkArgument(hasNonEmptyOutput, "cannot encode a pattern that has no output.");
encodedValue.put(EncodedPatternItem.NBT_INGREDIENTS, tagIn); encodedValue.put(EncodedPatternItem.NBT_INGREDIENTS, tagIn);
encodedValue.put(EncodedPatternItem.NBT_PRODUCTS, tagOut); encodedValue.put(EncodedPatternItem.NBT_PRODUCTS, tagOut);
return encodedValue; return encodedValue;
+1 -1
View File
@@ -502,7 +502,7 @@ public class EnergyGridCache implements IEnergyGrid {
private void removeRequester(IAEPowerStorage requester) { private void removeRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation, Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected."); "Cannot modify energy requesters while energy is being injected.");
this.requesters.add(requester); this.requesters.remove(requester);
} }
private void addProvider(IAEPowerStorage provider) { private void addProvider(IAEPowerStorage provider) {
@@ -4,16 +4,13 @@ package appeng.parts.automation;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
import appeng.api.config.Settings; import appeng.api.config.Settings;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper; import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.storage.IMEInventory; import appeng.api.storage.IMEInventory;
import appeng.api.storage.cells.ICellContainer; import appeng.api.storage.cells.ICellContainer;
import appeng.api.storage.cells.ICellInventory; import appeng.api.storage.cells.ICellInventory;
@@ -30,6 +27,7 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
private boolean wasActive = false; private boolean wasActive = false;
private int priority = 0; private int priority = 0;
protected boolean blocked = false; protected boolean blocked = false;
private final PlaneConnectionHelper connectionHelper = new PlaneConnectionHelper(this);
public AbstractFormationPlanePart(ItemStack is) { public AbstractFormationPlanePart(ItemStack is) {
super(is); super(is);
@@ -64,103 +62,11 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
@Override @Override
public void getBoxes(final IPartCollisionHelper bch) { public void getBoxes(final IPartCollisionHelper bch) {
int minX = 1; connectionHelper.getBoxes(bch);
int minY = 1;
int maxX = 15;
int maxY = 15;
final IPartHost host = this.getHost();
if (host != null) {
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(e.getOpposite())), this.getSide())) {
minX = 0;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxX = 16;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(u.getOpposite())), this.getSide())) {
minY = 0;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(u)), this.getSide())) {
maxY = 16;
}
}
bch.addBox(5, 5, 14, 11, 11, 15);
bch.addBox(minX, minY, 15, maxX, maxY, 16);
} }
public PlaneConnections getConnections() { public PlaneConnections getConnections() {
return connectionHelper.getConnections();
final Direction facingRight, facingUp;
AEPartLocation location = this.getSide();
switch (location) {
case UP:
facingRight = Direction.EAST;
facingUp = Direction.NORTH;
break;
case DOWN:
facingRight = Direction.WEST;
facingUp = Direction.NORTH;
break;
case NORTH:
facingRight = Direction.WEST;
facingUp = Direction.UP;
break;
case SOUTH:
facingRight = Direction.EAST;
facingUp = Direction.UP;
break;
case WEST:
facingRight = Direction.SOUTH;
facingUp = Direction.UP;
break;
case EAST:
facingRight = Direction.NORTH;
facingUp = Direction.UP;
break;
default:
case INTERNAL:
return PlaneConnections.of(false, false, false, false);
}
boolean left = false, right = false, down = false, up = false;
final IPartHost host = this.getHost();
if (host != null) {
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingRight.getOpposite())),
this.getSide())) {
left = true;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingRight)), this.getSide())) {
right = true;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingUp.getOpposite())),
this.getSide())) {
down = true;
}
if (this.isTransitionPlane(te.getWorld().getTileEntity(pos.offset(facingUp)), this.getSide())) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
} }
@Override @Override
@@ -172,6 +78,8 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
final BlockPos tePos = te.getPos().offset(side.getFacing()); final BlockPos tePos = te.getPos().offset(side.getFacing());
this.blocked = !w.getBlockState(tePos).getMaterial().isReplaceable(); this.blocked = !w.getBlockState(tePos).getMaterial().isReplaceable();
} else {
connectionHelper.updateConnections();
} }
} }
@@ -180,14 +88,6 @@ public abstract class AbstractFormationPlanePart<T extends IAEStack<T>> extends
return 1; return 1;
} }
protected boolean isTransitionPlane(final TileEntity blockTileEntity, final AEPartLocation side) {
if (blockTileEntity instanceof IPartHost) {
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
return p != null && this.getClass() == p.getClass();
}
return false;
}
@Override @Override
public T extractItems(final T request, final Actionable mode, final IActionSource src) { public T extractItems(final T request, final Actionable mode, final IActionSource src) {
return null; return null;
@@ -35,7 +35,6 @@ import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags; import net.minecraft.tags.ItemTags;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -58,9 +57,7 @@ import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.IGridTickable; import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation; import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest; import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper; import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
@@ -96,53 +93,31 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
private boolean isAccepting = true; private boolean isAccepting = true;
private boolean breaking = false; private boolean breaking = false;
private final PlaneConnectionHelper connectionHelper = new PlaneConnectionHelper(this);
public AnnihilationPlanePart(final ItemStack is) { public AnnihilationPlanePart(final ItemStack is) {
super(is); super(is);
} }
@Override @Override
public TickRateModulation call(final World world) throws Exception { public TickRateModulation call(final World world) {
this.breaking = false; this.breaking = false;
return this.breakBlock(true); return this.breakBlock(true);
} }
@Override @Override
public void getBoxes(final IPartCollisionHelper bch) { public void getBoxes(final IPartCollisionHelper bch) {
int minX = 1;
int minY = 1;
int maxX = 15;
int maxY = 15;
final IPartHost host = this.getHost(); // For collision, we're using a simplified bounding box
if (host != null) { if (bch.isBBCollision()) {
final TileEntity te = host.getTile(); // The smaller collision hitbox here is needed to allow for the entity collision
// event
final BlockPos pos = te.getPos(); bch.addBox(0, 0, 14, 16, 16, 15.5);
return;
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e.getOpposite())), this.getSide())) {
minX = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxX = 16;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(u.getOpposite())), this.getSide())) {
minY = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxY = 16;
}
} }
bch.addBox(5, 5, 14, 11, 11, 15); connectionHelper.getBoxes(bch);
// The smaller collision hitbox here is needed to allow for the entity collision
// event
bch.addBox(minX, minY, 15, maxX, maxY, bch.isBBCollision() ? 15 : 16);
} }
/** /**
@@ -150,73 +125,15 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
* visually. * visually.
*/ */
public PlaneConnections getConnections() { public PlaneConnections getConnections() {
return connectionHelper.getConnections();
final Direction facingRight, facingUp;
AEPartLocation location = this.getSide();
switch (location) {
case UP:
facingRight = Direction.EAST;
facingUp = Direction.NORTH;
break;
case DOWN:
facingRight = Direction.WEST;
facingUp = Direction.NORTH;
break;
case NORTH:
facingRight = Direction.WEST;
facingUp = Direction.UP;
break;
case SOUTH:
facingRight = Direction.EAST;
facingUp = Direction.UP;
break;
case WEST:
facingRight = Direction.SOUTH;
facingUp = Direction.UP;
break;
case EAST:
facingRight = Direction.NORTH;
facingUp = Direction.UP;
break;
default:
case INTERNAL:
return PlaneConnections.of(false, false, false, false);
}
boolean left = false, right = false, down = false, up = false;
final IPartHost host = this.getHost();
if (host != null) {
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight.getOpposite())),
this.getSide())) {
left = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight)), this.getSide())) {
right = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp.getOpposite())),
this.getSide())) {
down = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp)), this.getSide())) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
} }
@Override @Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) { public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
if (pos.offset(this.getSide().getFacing()).equals(neighbor)) { if (pos.offset(this.getSide().getFacing()).equals(neighbor)) {
this.refresh(); this.refresh();
} else {
connectionHelper.updateConnections();
} }
} }
@@ -362,14 +279,6 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
return changed; return changed;
} }
protected boolean isAnnihilationPlane(final TileEntity blockTileEntity, final AEPartLocation side) {
if (blockTileEntity instanceof IPartHost) {
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
return p != null && p.getClass() == this.getClass();
}
return false;
}
@Override @Override
@MENetworkEventSubscribe @MENetworkEventSubscribe
public void chanRender(final MENetworkChannelsChanged c) { public void chanRender(final MENetworkChannelsChanged c) {
@@ -493,7 +402,7 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
ItemStack harvestTool = createHarvestTool(state); ItemStack harvestTool = createHarvestTool(state);
if (harvestTool == null) { if (harvestTool == null) {
if (!state.getMaterial().isToolNotRequired()) { if (state.getMaterial().isToolNotRequired()) {
harvestTool = ItemStack.EMPTY; harvestTool = ItemStack.EMPTY;
} else { } else {
// In case the block does NOT allow us to harvest it without a tool, or the // In case the block does NOT allow us to harvest it without a tool, or the
@@ -21,26 +21,23 @@ package appeng.parts.automation;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.DirectionalPlaceContext; import net.minecraft.item.DirectionalPlaceContext;
import net.minecraft.item.FireworkRocketItem;
import net.minecraft.item.FireworkStarItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.item.WallOrFloorItem;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -49,7 +46,6 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import appeng.api.config.AccessRestriction; import appeng.api.config.AccessRestriction;
@@ -64,7 +60,6 @@ import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource; import appeng.api.networking.security.IActionSource;
import appeng.api.parts.IPartItem;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEInventoryHandler; import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IStorageChannel; import appeng.api.storage.IStorageChannel;
@@ -89,6 +84,7 @@ import appeng.util.prioritylist.PrecisePriorityList;
public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack> { public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack> {
private static final PlaneModels MODELS = new PlaneModels("part/formation_plane", "part/formation_plane_on"); private static final PlaneModels MODELS = new PlaneModels("part/formation_plane", "part/formation_plane_on");
private static final Random RANDOM_OFFSET = new Random();
@PartModels @PartModels
public static List<IPartModel> getModels() { public static List<IPartModel> getModels() {
@@ -222,12 +218,12 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
final BlockPos placePos = te.getPos().offset(side.getFacing()); final BlockPos placePos = te.getPos().offset(side.getFacing());
if (w.getBlockState(placePos).getMaterial().isReplaceable()) { if (w.getBlockState(placePos).getMaterial().isReplaceable()) {
if (placeBlock == YesNo.YES && (i instanceof BlockItem || i instanceof IPlantable if (placeBlock == YesNo.YES) {
|| i instanceof FireworkStarItem || i instanceof FireworkRocketItem || i instanceof IPartItem)) {
final PlayerEntity player = Platform.getPlayer((ServerWorld) w); final PlayerEntity player = Platform.getPlayer((ServerWorld) w);
Platform.configurePlayer(player, side, this.getTile()); Platform.configurePlayer(player, side, this.getTile());
Hand hand = player.getActiveHand(); // Seems to work without...
player.setHeldItem(hand, is); // Hand hand = player.getActiveHand();
// player.setHeldItem(hand, is);
maxStorage = is.getCount(); maxStorage = is.getCount();
worked = true; worked = true;
@@ -235,84 +231,33 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
// The side the plane is attached to will be considered the look direction // The side the plane is attached to will be considered the look direction
// in terms of placing an item // in terms of placing an item
Direction lookDirection = side.getFacing(); Direction lookDirection = side.getFacing();
PlaneDirectionalPlaceContext context = new PlaneDirectionalPlaceContext(w, player, placePos,
lookDirection, is, lookDirection.getOpposite());
// FIXME No idea what any of this is _supposed_ to do, comment badly needed i.onItemUse(context);
if (i instanceof IPlantable || i instanceof WallOrFloorItem) { maxStorage -= is.getCount();
boolean Worked = false;
// Up or Down, Attempt 1??
if (side.xOffset == 0 && side.zOffset == 0) {
Worked = i.onItemUse(new DirectionalPlaceContext(w, placePos.offset(side.getFacing()),
lookDirection, is, side.getFacing())) == ActionResultType.SUCCESS;
}
// Up or Down, Attempt 2??
if (!Worked && side.xOffset == 0 && side.zOffset == 0) {
Worked = i.onItemUse(new DirectionalPlaceContext(w,
placePos.offset(side.getFacing().getOpposite()), lookDirection, is,
side.getFacing().getOpposite())) == ActionResultType.SUCCESS;
}
// Horizontal, attempt 1??
if (!Worked && side.yOffset == 0) {
Worked = i.onItemUse(new DirectionalPlaceContext(w, placePos.offset(Direction.DOWN),
lookDirection, is, Direction.DOWN)) == ActionResultType.SUCCESS;
}
if (!Worked) {
i.onItemUse(new DirectionalPlaceContext(w, placePos, lookDirection, is,
lookDirection.getOpposite()));
}
maxStorage -= is.getCount();
} else {
i.onItemUse(new DirectionalPlaceContext(w, placePos, lookDirection, is,
lookDirection.getOpposite()));
maxStorage -= is.getCount();
}
} else { } else {
maxStorage = 1; maxStorage = 1;
} }
// Safe keeping // Seems to work without... Safe keeping
player.setHeldItem(hand, ItemStack.EMPTY); // player.setHeldItem(hand, ItemStack.EMPTY);
} else { } else {
worked = true;
final int sum = this.countEntitesAround(w, placePos); final int sum = this.countEntitesAround(w, placePos);
// Disable spawning once there is a certain amount of entities in an area.
if (sum < AEConfig.instance().getFormationPlaneEntityLimit()) { if (sum < AEConfig.instance().getFormationPlaneEntityLimit()) {
worked = true;
if (type == Actionable.MODULATE) { if (type == Actionable.MODULATE) {
is.setCount((int) maxStorage); is.setCount((int) maxStorage);
final double x = (side.xOffset != 0 ? 0 : .7 * (Platform.getRandomFloat() - .5)) + side.xOffset if (!spawnItemEntity(w, te, side, is)) {
+ .5 + te.getPos().getX(); // revert in case something prevents spawning.
final double y = (side.yOffset != 0 ? 0 : .7 * (Platform.getRandomFloat() - .5)) + side.yOffset
+ .5 + te.getPos().getY();
final double z = (side.zOffset != 0 ? 0 : .7 * (Platform.getRandomFloat() - .5)) + side.zOffset
+ .5 + te.getPos().getZ();
final ItemEntity ei = new ItemEntity(w, x, y, z, is.copy());
Entity result = ei;
ei.setMotion(side.xOffset * 0.2, side.yOffset * 0.2, side.zOffset * 0.2);
if (is.getItem().hasCustomEntity(is)) {
result = is.getItem().createEntity(w, ei, is);
if (result != null) {
ei.remove();
} else {
result = ei;
}
}
if (!w.addEntity(result)) {
result.remove();
worked = false; worked = false;
} }
} }
} else {
worked = false;
} }
} }
} }
@@ -331,6 +276,57 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
return input; return input;
} }
private static boolean spawnItemEntity(World w, TileEntity te, AEPartLocation side, ItemStack is) {
// the item offset based on the entity height plus some offset
final double itemOffset = .55 + EntityType.ITEM.getHeight();
// The center of the block the plane is located in
final double centerX = te.getPos().getX() + .5;
final double centerY = te.getPos().getY() + .5;
final double centerZ = te.getPos().getZ() + .5;
// When spawning downwards, we have to take the item height of 0.25 into account
// Otherwise it will get stuck and be spit out in a random direction as
// minecraft spawns it at its feet position and not center
final double additionalYOffset = side.yOffset == -1 ? -.3 : 0;
// Calculate the offsets to spawn it into the adjacent block, taking the sign
// into account.
// Spawn it 0.8 blocks away from the center pos when facing in this direction
// Every other direction will select a position in a .5 block area around the
// block center.
final double offsetX = (side.xOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25)
: (side.xOffset * itemOffset);
final double offsetY = (side.yOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25)
: ((side.yOffset * itemOffset) + additionalYOffset);
final double offsetZ = (side.zOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25)
: (side.zOffset * itemOffset);
final double absoluteX = centerX + offsetX;
final double absoluteY = centerY + offsetY;
final double absoluteZ = centerZ + offsetZ;
final ItemEntity ei = new ItemEntity(w, absoluteX, absoluteY, absoluteZ, is.copy());
Entity result = ei;
ei.setMotion(side.xOffset * .1, side.yOffset * 0.1, side.zOffset * 0.1);
if (is.getItem().hasCustomEntity(is)) {
result = is.getItem().createEntity(w, ei, is);
if (result != null) {
ei.remove();
} else {
result = ei;
}
}
if (!w.addEntity(result)) {
result.remove();
return false;
}
return true;
}
@Override @Override
public IStorageChannel<IAEItemStack> getChannel() { public IStorageChannel<IAEItemStack> getChannel() {
return Api.instance().storage().getStorageChannel(IItemStorageChannel.class); return Api.instance().storage().getStorageChannel(IItemStorageChannel.class);
@@ -364,11 +360,69 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
return list.size(); return list.size();
} }
private class ForcedItemUseContext extends ItemUseContext { /**
protected ForcedItemUseContext(World worldIn, @Nullable PlayerEntity player, Hand handIn, ItemStack heldItem, * A custom {@link DirectionalPlaceContext} which also accepts a player needed
BlockRayTraceResult rayTraceResultIn) { * various blocks like seeds.
super(worldIn, player, handIn, heldItem, rayTraceResultIn); * <p>
* Also removed {@link DirectionalPlaceContext#replacingClickedOnBlock} as this
* can cause a {@link StackOverflowError} for certain replaceable blocks.
*/
private static class PlaneDirectionalPlaceContext extends BlockItemUseContext {
private final Direction lookDirection;
public PlaneDirectionalPlaceContext(World world, PlayerEntity player, BlockPos pos, Direction lookDirection,
ItemStack itemStack, Direction facing) {
super(world, player, Hand.MAIN_HAND, itemStack, new BlockRayTraceResult(
new Vec3d(pos.getX() + 0.5D, pos.getY(), pos.getZ() + 0.5D), facing, pos, false));
this.lookDirection = lookDirection;
}
public BlockPos getPos() {
return this.rayTraceResult.getPos();
}
public boolean canPlace() {
return this.world.getBlockState(this.rayTraceResult.getPos()).isReplaceable(this);
}
public Direction getNearestLookingDirection() {
return Direction.DOWN;
}
public Direction[] getNearestLookingDirections() {
switch (this.lookDirection) {
case DOWN:
default:
return new Direction[] { Direction.DOWN, Direction.NORTH, Direction.EAST, Direction.SOUTH,
Direction.WEST, Direction.UP };
case UP:
return new Direction[] { Direction.DOWN, Direction.UP, Direction.NORTH, Direction.EAST,
Direction.SOUTH, Direction.WEST };
case NORTH:
return new Direction[] { Direction.DOWN, Direction.NORTH, Direction.EAST, Direction.WEST,
Direction.UP, Direction.SOUTH };
case SOUTH:
return new Direction[] { Direction.DOWN, Direction.SOUTH, Direction.EAST, Direction.WEST,
Direction.UP, Direction.NORTH };
case WEST:
return new Direction[] { Direction.DOWN, Direction.WEST, Direction.SOUTH, Direction.UP,
Direction.NORTH, Direction.EAST };
case EAST:
return new Direction[] { Direction.DOWN, Direction.EAST, Direction.SOUTH, Direction.UP,
Direction.NORTH, Direction.WEST };
}
}
public Direction getPlacementHorizontalFacing() {
return this.lookDirection.getAxis() == Axis.Y ? Direction.NORTH : this.lookDirection;
}
public boolean func_225518_g_() {
return false;
}
public float getPlacementYaw() {
return (float) (this.lookDirection.getHorizontalIndex() * 90);
} }
} }
} }
@@ -55,15 +55,6 @@ public class IdentityAnnihilationPlanePart extends AnnihilationPlanePart {
super(is); super(is);
} }
@Override
protected boolean isAnnihilationPlane(final TileEntity blockTileEntity, final AEPartLocation side) {
if (blockTileEntity instanceof IPartHost) {
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
return p != null && p.getClass() == this.getClass();
}
return false;
}
@Override @Override
protected float calculateEnergyUsage(final ServerWorld w, final BlockPos pos, final List<ItemStack> items) { protected float calculateEnergyUsage(final ServerWorld w, final BlockPos pos, final List<ItemStack> items) {
final float requiredEnergy = super.calculateEnergyUsage(w, pos, items); final float requiredEnergy = super.calculateEnergyUsage(w, pos, items);
@@ -0,0 +1,160 @@
package appeng.parts.automation;
import javax.annotation.Nullable;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.util.AEPartLocation;
import appeng.parts.AEBasePart;
/**
* Helps plane parts (annihilation, formation) with determining and checking for
* connections to adjacent plane parts of the same type to form a visually
* larger plane.
*/
public final class PlaneConnectionHelper {
private final AEBasePart part;
public PlaneConnectionHelper(AEBasePart part) {
this.part = part;
}
/**
* Gets on which sides this part has adjacent planes that it visually connects
* to
*/
public PlaneConnections getConnections() {
TileEntity hostTileEntity = getHostTileEntity();
AEPartLocation side = part.getSide();
final Direction facingRight, facingUp;
switch (side) {
case UP:
facingRight = Direction.EAST;
facingUp = Direction.NORTH;
break;
case DOWN:
facingRight = Direction.WEST;
facingUp = Direction.NORTH;
break;
case NORTH:
facingRight = Direction.WEST;
facingUp = Direction.UP;
break;
case SOUTH:
facingRight = Direction.EAST;
facingUp = Direction.UP;
break;
case WEST:
facingRight = Direction.SOUTH;
facingUp = Direction.UP;
break;
case EAST:
facingRight = Direction.NORTH;
facingUp = Direction.UP;
break;
default:
case INTERNAL:
return PlaneConnections.of(false, false, false, false);
}
boolean left = false, right = false, down = false, up = false;
if (hostTileEntity != null) {
World world = hostTileEntity.getWorld();
BlockPos pos = hostTileEntity.getPos();
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingRight.getOpposite())))) {
left = true;
}
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingRight)))) {
right = true;
}
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingUp.getOpposite())))) {
down = true;
}
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(facingUp)))) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
}
/**
* Get the bounding boxes of this plane parts components.
*/
public void getBoxes(IPartCollisionHelper bch) {
int minX = 1;
int minY = 1;
int maxX = 15;
int maxY = 15;
TileEntity hostTile = getHostTileEntity();
if (hostTile != null) {
World world = hostTile.getWorld();
final BlockPos pos = hostTile.getPos();
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(e.getOpposite())))) {
minX = 0;
}
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(e)))) {
maxX = 16;
}
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(u.getOpposite())))) {
minY = 0;
}
if (isCompatiblePlaneAdjacent(world.getTileEntity(pos.offset(u)))) {
maxY = 16;
}
}
bch.addBox(5, 5, 14, 11, 11, 15);
bch.addBox(minX, minY, 15, maxX, maxY, 16);
}
/**
* Call this when an adjacent block has changed since the connections need to be
* recalculated.
*/
public void updateConnections() {
TileEntity hostTile = getHostTileEntity();
if (hostTile != null) {
hostTile.requestModelDataUpdate();
}
}
private boolean isCompatiblePlaneAdjacent(@Nullable TileEntity adjacentTileEntity) {
if (adjacentTileEntity instanceof IPartHost) {
final IPart p = ((IPartHost) adjacentTileEntity).getPart(part.getSide());
return p != null && p.getClass() == part.getClass();
}
return false;
}
private TileEntity getHostTileEntity() {
IPartHost host = part.getHost();
if (host != null) {
return host.getTile();
}
return null;
}
}
@@ -18,15 +18,10 @@
package appeng.parts.p2p; package appeng.parts.p2p;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -37,18 +32,18 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
import appeng.api.config.PowerUnits;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.items.parts.PartModels; import appeng.items.parts.PartModels;
import appeng.me.GridAccessException; import appeng.me.GridAccessException;
public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implements IFluidHandler { public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> {
private static final P2PModels MODELS = new P2PModels("part/p2p/p2p_tunnel_fluids"); private static final P2PModels MODELS = new P2PModels("part/p2p/p2p_tunnel_fluids");
private static final IFluidHandler NULL_FLUID_HANDLER = new NullFluidHandler();
private static final ThreadLocal<Deque<FluidP2PTunnelPart>> DEPTH = new ThreadLocal<>();; private final IFluidHandler inputHandler = new InputFluidHandler();
private final IFluidHandler outputHandler = new OutputFluidHandler();
private LazyOptional<IFluidHandler> cachedTank;
private int tmpUsed;
public FluidP2PTunnelPart(final ItemStack is) { public FluidP2PTunnelPart(final ItemStack is) {
super(is); super(is);
@@ -65,13 +60,10 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
@Override @Override
public void onTunnelNetworkChange() { public void onTunnelNetworkChange() {
this.cachedTank = null;
} }
@Override @Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) { public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
this.cachedTank = null;
if (this.isOutput()) { if (this.isOutput()) {
final FluidP2PTunnelPart in = this.getInput(); final FluidP2PTunnelPart in = this.getInput();
if (in != null) { if (in != null) {
@@ -84,7 +76,10 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
@Override @Override
public <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) { public <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { if (capabilityClass == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return (LazyOptional<T>) LazyOptional.of(() -> this); if (this.isOutput()) {
return (LazyOptional<T>) LazyOptional.of(() -> this.outputHandler);
}
return (LazyOptional<T>) LazyOptional.of(() -> this.inputHandler);
} }
return super.getCapability(capabilityClass); return super.getCapability(capabilityClass);
@@ -95,168 +90,173 @@ public class FluidP2PTunnelPart extends P2PTunnelPart<FluidP2PTunnelPart> implem
return MODELS.getModel(this.isPowered(), this.isActive()); return MODELS.getModel(this.isPowered(), this.isActive());
} }
@Override private IFluidHandler getAttachedFluidHandler() {
public int getTanks() { LazyOptional<IFluidHandler> fluidHandler = LazyOptional.empty();
return 0; if (this.isActive()) {
} final TileEntity self = this.getTile();
final TileEntity te = self.getWorld().getTileEntity(self.getPos().offset(this.getSide().getFacing()));
@Override if (te != null) {
@Nonnull fluidHandler = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
public FluidStack getFluidInTank(int tank) { this.getSide().getOpposite().getFacing());
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
return 1000;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return false;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
final Deque<FluidP2PTunnelPart> stack = this.getDepth();
for (final FluidP2PTunnelPart t : stack) {
if (t == this) {
return 0;
} }
} }
return fluidHandler.orElse(NULL_FLUID_HANDLER);
}
stack.push(this); private class InputFluidHandler implements IFluidHandler {
final List<FluidP2PTunnelPart> list = this.getOutputs(resource.getFluid()); @Override
int requestTotal = 0; public int getTanks() {
return 1;
Iterator<FluidP2PTunnelPart> i = list.iterator();
while (i.hasNext()) {
final FluidP2PTunnelPart l = i.next();
final IFluidHandler tank = l.getTarget().orElse(null);
if (tank != null) {
l.tmpUsed = tank.fill(resource.copy(), FluidAction.SIMULATE);
} else {
l.tmpUsed = 0;
}
if (l.tmpUsed <= 0) {
i.remove();
} else {
requestTotal += l.tmpUsed;
}
} }
if (requestTotal <= 0) { @Override
if (stack.pop() != this) { @Nonnull
throw new IllegalStateException("Invalid Recursion detected."); public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
return Integer.MAX_VALUE;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return true;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
int total = 0;
try {
final int outputTunnels = FluidP2PTunnelPart.this.getOutputs().size();
final int amount = resource.getAmount();
if (outputTunnels == 0 || amount == 0) {
return 0;
}
final int amountPerOutput = Math.max(1, amount / outputTunnels);
int overflow = amountPerOutput == 0 ? amount : amount % amountPerOutput;
for (FluidP2PTunnelPart target : FluidP2PTunnelPart.this.getOutputs()) {
final IFluidHandler output = target.getAttachedFluidHandler();
final int toSend = amountPerOutput + overflow;
final FluidStack fillWithFluidStack = resource.copy();
fillWithFluidStack.setAmount(toSend);
final int received = output.fill(fillWithFluidStack, action);
overflow = toSend - received;
total += received;
}
if (action == FluidAction.EXECUTE) {
FluidP2PTunnelPart.this.queueTunnelDrain(PowerUnits.RF, total);
}
} catch (GridAccessException ignored) {
} }
return total;
}
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
}
private class OutputFluidHandler implements IFluidHandler {
@Override
public int getTanks() {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getTanks();
}
@Override
@Nonnull
public FluidStack getFluidInTank(int tank) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getFluidInTank(tank);
}
@Override
public int getTankCapacity(int tank) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().getTankCapacity(tank);
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return FluidP2PTunnelPart.this.getAttachedFluidHandler().isFluidValid(tank, stack);
}
@Override
public int fill(FluidStack resource, FluidAction action) {
return 0; return 0;
} }
if (action != FluidAction.EXECUTE) { @Override
if (stack.pop() != this) { @Nonnull
throw new IllegalStateException("Invalid Recursion detected."); public FluidStack drain(FluidStack resource, FluidAction action) {
} return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(resource, action);
return Math.min(resource.getAmount(), requestTotal);
} }
int available = resource.getAmount(); @Override
@Nonnull
i = list.iterator(); public FluidStack drain(int maxDrain, FluidAction action) {
int used = 0; return FluidP2PTunnelPart.this.getAttachedFluidHandler().drain(maxDrain, action);
while (i.hasNext() && available > 0) {
final FluidP2PTunnelPart l = i.next();
final FluidStack insert = resource.copy();
insert.setAmount((int) Math.ceil(insert.getAmount() * ((double) l.tmpUsed / (double) requestTotal)));
if (insert.getAmount() > available) {
insert.setAmount(available);
}
final IFluidHandler tank = l.getTarget().orElse(null);
if (tank != null) {
l.tmpUsed = tank.fill(insert.copy(), action);
} else {
l.tmpUsed = 0;
}
available -= insert.getAmount();
used += l.tmpUsed;
} }
if (stack.pop() != this) {
throw new IllegalStateException("Invalid Recursion detected.");
}
return used;
} }
@Override private static class NullFluidHandler implements IFluidHandler {
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override @Override
@Nonnull public int getTanks() {
public FluidStack drain(int maxDrain, FluidAction action) { return 0;
return FluidStack.EMPTY;
}
private Deque<FluidP2PTunnelPart> getDepth() {
Deque<FluidP2PTunnelPart> s = DEPTH.get();
if (s == null) {
DEPTH.set(s = new ArrayDeque<>());
} }
return s; @Override
} @Nonnull
public FluidStack getFluidInTank(int tank) {
private List<FluidP2PTunnelPart> getOutputs(final Fluid input) { return FluidStack.EMPTY;
final List<FluidP2PTunnelPart> outs = new ArrayList<>();
try {
for (final FluidP2PTunnelPart l : this.getOutputs()) {
final IFluidHandler handler = l.getTarget().orElse(null);
if (handler != null) {
outs.add(l);
}
}
} catch (final GridAccessException e) {
// :P
} }
return outs; @Override
} public int getTankCapacity(int tank) {
return 0;
private LazyOptional<IFluidHandler> getTarget() {
if (!this.getProxy().isActive()) {
return null;
} }
if (this.cachedTank != null) { @Override
return this.cachedTank; public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return false;
} }
final TileEntity te = this.getTile().getWorld() @Override
.getTileEntity(this.getTile().getPos().offset(this.getSide().getFacing())); public int fill(FluidStack resource, FluidAction action) {
return 0;
if (te != null && te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getFacing().getOpposite()).isPresent()) {
return this.cachedTank = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
this.getSide().getFacing().getOpposite());
} }
return null; @Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
} }
} }
@@ -14,9 +14,13 @@ import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.core.AppEng;
public class GrinderRecipe implements IRecipe<IInventory> { public class GrinderRecipe implements IRecipe<IInventory> {
public static IRecipeType<GrinderRecipe> TYPE; public static final ResourceLocation TYPE_ID = new ResourceLocation(AppEng.MOD_ID, "grinder");
public static final IRecipeType<GrinderRecipe> TYPE = IRecipeType.register(TYPE_ID.toString());
private final ResourceLocation id; private final ResourceLocation id;
private final String group; private final String group;
@@ -29,7 +29,7 @@ public class GrinderRecipeSerializer extends ForgeRegistryEntry<IRecipeSerialize
public static final GrinderRecipeSerializer INSTANCE = new GrinderRecipeSerializer(); public static final GrinderRecipeSerializer INSTANCE = new GrinderRecipeSerializer();
static { static {
INSTANCE.setRegistryName(AppEng.MOD_ID, "grinder"); INSTANCE.setRegistryName(GrinderRecipe.TYPE_ID);
} }
private GrinderRecipeSerializer() { private GrinderRecipeSerializer() {
@@ -11,10 +11,13 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import appeng.api.features.InscriberProcessType; import appeng.api.features.InscriberProcessType;
import appeng.core.AppEng;
public class InscriberRecipe implements IRecipe<IInventory> { public class InscriberRecipe implements IRecipe<IInventory> {
public static IRecipeType<InscriberRecipe> TYPE; public static final ResourceLocation TYPE_ID = new ResourceLocation(AppEng.MOD_ID, "inscriber");
public static final IRecipeType<InscriberRecipe> TYPE = IRecipeType.register(TYPE_ID.toString());
private final ResourceLocation id; private final ResourceLocation id;
private final String group; private final String group;
@@ -23,7 +23,7 @@ public class InscriberRecipeSerializer extends ForgeRegistryEntry<IRecipeSeriali
public static final InscriberRecipeSerializer INSTANCE = new InscriberRecipeSerializer(); public static final InscriberRecipeSerializer INSTANCE = new InscriberRecipeSerializer();
static { static {
INSTANCE.setRegistryName(AppEng.MOD_ID, "inscriber"); INSTANCE.setRegistryName(InscriberRecipe.TYPE_ID);
} }
private InscriberRecipeSerializer() { private InscriberRecipeSerializer() {
@@ -310,7 +310,7 @@ public class CableBusTileEntity extends AEBaseTileEntity implements AEMultiTile
IPart part = this.getPart(partLocation); IPart part = this.getPart(partLocation);
LazyOptional<T> result = part == null ? LazyOptional.empty() : part.getCapability(capabilityClass); LazyOptional<T> result = part == null ? LazyOptional.empty() : part.getCapability(capabilityClass);
if (result != null) { if (result.isPresent()) {
return result; return result;
} }
@@ -1,7 +1,7 @@
{ {
"type": "appliedenergistics2:grinder", "type": "appliedenergistics2:grinder",
"input": { "input": {
"tag": "appliedenergistics2:crystals/fluix" "item": "appliedenergistics2:fluix_crystal"
}, },
"result": { "result": {
"primary": { "primary": {