mirror of
https://github.com/GTNewHorizons/StructureLib.git
synced 2026-11-09 15:04:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd4f3617be | ||
|
|
256bc60d35 | ||
|
|
70426ab7b3 | ||
|
|
0030c02e9a | ||
|
|
7382db1bbd | ||
|
|
b669cbecf1 | ||
|
|
6283931667 | ||
|
|
3b3bc4b9ad | ||
|
|
bef4fdd949 |
No files matched your search
+2
-2
@@ -1,8 +1,8 @@
|
||||
// Add your dependencies here
|
||||
|
||||
dependencies {
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.6.31:dev")
|
||||
implementation("com.github.GTNewHorizons:NotEnoughItems:2.7.56-GTNH:dev")
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.6.39:dev")
|
||||
implementation("com.github.GTNewHorizons:NotEnoughItems:2.7.86-GTNH:dev")
|
||||
|
||||
testImplementation(platform('org.junit:junit-bom:5.9.2'))
|
||||
testImplementation('org.junit.jupiter:junit-jupiter')
|
||||
|
||||
+1
-1
@@ -151,7 +151,7 @@ modrinthProjectId =
|
||||
# type can be one of [project, version],
|
||||
# and the name is the Modrinth project or version slug/id of the other mod.
|
||||
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
|
||||
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
|
||||
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
|
||||
modrinthRelations =
|
||||
|
||||
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.38'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.42'
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,28 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
|
||||
|
||||
public interface IAlignmentLimits {
|
||||
|
||||
/**
|
||||
* Can be placed in any orientation.
|
||||
*/
|
||||
IAlignmentLimits UNLIMITED = (direction, rotation, flip) -> true;
|
||||
|
||||
/**
|
||||
* Must be standing upright; i.e., top side of the block facing up.
|
||||
*/
|
||||
IAlignmentLimits UPRIGHT = (direction, rotation, flip) -> direction.offsetY == 0
|
||||
&& (flip.isVerticallyFliped() ? rotation.isUpsideDown() : rotation.isNotRotated());
|
||||
|
||||
/**
|
||||
* Can be in any orientation except upside down; i.e., top side of the block facing down.
|
||||
*/
|
||||
IAlignmentLimits NOT_UPSIDE_DOWN = (direction, rotation, flip) -> direction.offsetY != 0
|
||||
|| (flip.isVerticallyFliped() ? !rotation.isNotRotated() : !rotation.isUpsideDown());
|
||||
|
||||
/**
|
||||
* Front side of the block must be facing up.
|
||||
*/
|
||||
IAlignmentLimits FACING_UP = (direction, rotation, flip) -> direction == ForgeDirection.UP;
|
||||
|
||||
boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip);
|
||||
|
||||
default boolean isNewExtendedFacingValid(ExtendedFacing alignment) {
|
||||
|
||||
@@ -1,34 +1,20 @@
|
||||
package com.gtnewhorizon.structurelib.core;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader;
|
||||
import com.gtnewhorizon.structurelib.mixins.Mixins;
|
||||
|
||||
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
|
||||
|
||||
@IFMLLoadingPlugin.MCVersion("1.7.10")
|
||||
public class StructureLibCore implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
||||
|
||||
public static final Logger log = LogManager.getLogger("StructureLibCore");
|
||||
|
||||
@Override
|
||||
public String getMixinConfig() {
|
||||
return "mixins.structurelib.early.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixins(Set<String> loadedCoreMods) {
|
||||
return Mixins.getEarlyMixins(loadedCoreMods);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getASMTransformerClass() {
|
||||
return new String[0];
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,4 +36,14 @@ public class StructureLibCore implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
||||
public String getAccessTransformerClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMixinConfig() {
|
||||
return "mixins.structurelib.early.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixins(Set<String> loadedCoreMods) {
|
||||
return Arrays.asList("blockChangeNotifier.MixinForgeHooks", "blockChangeNotifier.MixinWorld");
|
||||
}
|
||||
}
|
||||
@@ -164,40 +164,17 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
|
||||
list.onGuiInit(this);
|
||||
autoCompleteList.onGuiInit(this);
|
||||
|
||||
addButton(
|
||||
new GuiButton(
|
||||
ADD_BTN,
|
||||
guiLeft + 12,
|
||||
guiTop + 157,
|
||||
47,
|
||||
20,
|
||||
I18n.format("item.structurelib.constructableTrigger.gui.add")));
|
||||
addButton(
|
||||
new GuiButton(
|
||||
UNSET_BTN,
|
||||
guiLeft + 65,
|
||||
guiTop + 157,
|
||||
47,
|
||||
20,
|
||||
I18n.format("item.structurelib.constructableTrigger.gui.unset")));
|
||||
addButton(
|
||||
new GuiButton(
|
||||
WIPE_BTN,
|
||||
guiLeft + 118,
|
||||
guiTop + 157,
|
||||
47,
|
||||
20,
|
||||
I18n.format("item.structurelib.constructableTrigger.gui.wipe")));
|
||||
addButton(new GuiButton(ADD_BTN, guiLeft + 12, guiTop + 157, 47, 20, I18n.format(I18N_PREFIX + "add")));
|
||||
addButton(new GuiButton(UNSET_BTN, guiLeft + 65, guiTop + 157, 47, 20, I18n.format(I18N_PREFIX + "unset")));
|
||||
addButton(new GuiButton(WIPE_BTN, guiLeft + 118, guiTop + 157, 47, 20, I18n.format(I18N_PREFIX + "wipe")));
|
||||
|
||||
updateButtons();
|
||||
tooltipSplitCache.clear();
|
||||
info = StreamSupport
|
||||
.stream(
|
||||
Splitter.on("\\n").split(
|
||||
StatCollector.translateToLocal("item.structurelib.constructableTrigger.gui.info"))
|
||||
.spliterator(),
|
||||
Splitter.on("\\n").split(StatCollector.translateToLocal(I18N_PREFIX + "info")).spliterator(),
|
||||
false)
|
||||
.flatMap(line -> fontRendererObj.listFormattedStringToWidth(line, width * 3 / 5).stream())
|
||||
.flatMap(line -> fontRendererObj.listFormattedStringToWidth(line, width * 1 / 3).stream())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -241,8 +218,7 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
|
||||
actionPerformed(but);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<GuiButton> getButtonList() {
|
||||
public List<GuiButton> getButtonList() {
|
||||
return buttonList;
|
||||
}
|
||||
|
||||
@@ -397,22 +373,10 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
|
||||
int topLeftY = (this.height - this.getYSize()) / 2;
|
||||
drawTexturedModalRect(topLeftX, topLeftY, 0, 0, getXSize(), getYSize());
|
||||
list.drawScreen(mX, mY, partialTick);
|
||||
fontRendererObj.drawString(
|
||||
I18n.format("item.structurelib.constructableTrigger.gui.title"),
|
||||
guiLeft + 12,
|
||||
guiTop + 9,
|
||||
0);
|
||||
fontRendererObj.drawString(
|
||||
I18n.format("item.structurelib.constructableTrigger.gui.key"),
|
||||
guiLeft + 12,
|
||||
guiTop + 122,
|
||||
0);
|
||||
fontRendererObj.drawString(I18n.format(I18N_PREFIX + "title"), guiLeft + 12, guiTop + 9, 0);
|
||||
fontRendererObj.drawString(I18n.format(I18N_PREFIX + "key"), guiLeft + 12, guiTop + 122, 0);
|
||||
key.drawTextBox();
|
||||
fontRendererObj.drawString(
|
||||
I18n.format("item.structurelib.constructableTrigger.gui.value"),
|
||||
guiLeft + 12,
|
||||
guiTop + 142,
|
||||
0);
|
||||
fontRendererObj.drawString(I18n.format(I18N_PREFIX + "value"), guiLeft + 12, guiTop + 142, 0);
|
||||
value.drawTextBox();
|
||||
}
|
||||
|
||||
@@ -455,7 +419,7 @@ public class GuiScreenConfigureChannels extends GuiContainer implements IGuiScre
|
||||
tooltip.addAll(
|
||||
fontRendererObj.listFormattedStringToWidth(
|
||||
StatCollector.translateToLocalFormatted(
|
||||
"item.structurelib.constructableTrigger.gui.channels.from",
|
||||
I18N_PREFIX + "channels.from",
|
||||
Loader.instance().getIndexedModList().get(e.getKey()).getName()),
|
||||
maxLine));
|
||||
tooltip.addAll(
|
||||
|
||||
@@ -28,11 +28,12 @@ public class ItemConstructableTrigger extends Item {
|
||||
|
||||
@Override
|
||||
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) {
|
||||
if (!world.isRemote && getMovingObjectPositionFromPlayer(world, player, true) == null) {
|
||||
if (player.isSneaking()) {
|
||||
StructureLib.instance().proxy().displayConfigGUI("registries");
|
||||
} else {
|
||||
if (getMovingObjectPositionFromPlayer(world, player, true) == null) {
|
||||
// channel gui is opened from server and config gui from client
|
||||
if (!world.isRemote && !player.isSneaking()) {
|
||||
player.openGui(StructureLib.instance(), 0, world, player.inventory.currentItem, 0, 0);
|
||||
} else if (world.isRemote && player.isSneaking()) {
|
||||
StructureLib.instance().proxy().displayConfigGUI("registries");
|
||||
}
|
||||
}
|
||||
return super.onItemRightClick(stack, world, player);
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
package com.gtnewhorizon.structurelib.mixins;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.gtnewhorizon.structurelib.core.StructureLibCore;
|
||||
|
||||
import cpw.mods.fml.relauncher.FMLLaunchHandler;
|
||||
|
||||
public enum Mixins {
|
||||
|
||||
BLOCK_CHANGE_NOTIFIER(new Builder("Block Change Notifier").setPhase(Phase.EARLY)
|
||||
.addMixinClasses("blockChangeNotifier.MixinForgeHooks", "blockChangeNotifier.MixinWorld")
|
||||
.addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH).setApplyIf(() -> true));
|
||||
|
||||
private final List<String> mixinClasses;
|
||||
private final List<TargetedMod> targetedMods;
|
||||
private final List<TargetedMod> excludedMods;
|
||||
private final Supplier<Boolean> applyIf;
|
||||
private final Phase phase;
|
||||
private final Side side;
|
||||
|
||||
Mixins(Builder builder) {
|
||||
this.mixinClasses = builder.mixinClasses;
|
||||
this.targetedMods = builder.targetedMods;
|
||||
this.excludedMods = builder.excludedMods;
|
||||
this.applyIf = builder.applyIf;
|
||||
this.phase = builder.phase;
|
||||
this.side = builder.side;
|
||||
if (this.mixinClasses.isEmpty()) {
|
||||
throw new RuntimeException("No mixin class specified for Mixin : " + this.name());
|
||||
}
|
||||
if (this.targetedMods.isEmpty()) {
|
||||
throw new RuntimeException("No targeted mods specified for Mixin : " + this.name());
|
||||
}
|
||||
if (this.applyIf == null) {
|
||||
throw new RuntimeException("No ApplyIf function specified for Mixin : " + this.name());
|
||||
}
|
||||
if (this.phase == null) {
|
||||
throw new RuntimeException("No Phase specified for Mixin : " + this.name());
|
||||
}
|
||||
if (this.side == null) {
|
||||
throw new RuntimeException("No Side function specified for Mixin : " + this.name());
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getEarlyMixins(Set<String> loadedCoreMods) {
|
||||
final List<String> mixins = new ArrayList<>();
|
||||
final List<String> notLoading = new ArrayList<>();
|
||||
for (Mixins mixin : Mixins.values()) {
|
||||
if (mixin.phase == Phase.EARLY) {
|
||||
if (mixin.shouldLoad(loadedCoreMods, Collections.emptySet())) {
|
||||
mixins.addAll(mixin.mixinClasses);
|
||||
} else {
|
||||
notLoading.addAll(mixin.mixinClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
StructureLibCore.log.info("Not loading the following EARLY mixins: {}", notLoading.toString());
|
||||
return mixins;
|
||||
}
|
||||
|
||||
public static List<String> getLateMixins(Set<String> loadedMods) {
|
||||
// NOTE: Any targetmod here needs a modid, not a coremod id
|
||||
final List<String> mixins = new ArrayList<>();
|
||||
final List<String> notLoading = new ArrayList<>();
|
||||
for (Mixins mixin : Mixins.values()) {
|
||||
if (mixin.phase == Phase.LATE) {
|
||||
if (mixin.shouldLoad(Collections.emptySet(), loadedMods)) {
|
||||
mixins.addAll(mixin.mixinClasses);
|
||||
} else {
|
||||
notLoading.addAll(mixin.mixinClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
StructureLibCore.log.info("Not loading the following LATE mixins: {}", notLoading.toString());
|
||||
return mixins;
|
||||
}
|
||||
|
||||
private boolean shouldLoadSide() {
|
||||
return side == Side.BOTH || (side == Side.SERVER && FMLLaunchHandler.side().isServer())
|
||||
|| (side == Side.CLIENT && FMLLaunchHandler.side().isClient());
|
||||
}
|
||||
|
||||
private boolean allModsLoaded(List<TargetedMod> targetedMods, Set<String> loadedCoreMods, Set<String> loadedMods) {
|
||||
if (targetedMods.isEmpty()) return false;
|
||||
|
||||
for (TargetedMod target : targetedMods) {
|
||||
if (target == TargetedMod.VANILLA) continue;
|
||||
|
||||
// Check coremod first
|
||||
if (!loadedCoreMods.isEmpty() && target.coreModClass != null
|
||||
&& !loadedCoreMods.contains(target.coreModClass))
|
||||
return false;
|
||||
else if (!loadedMods.isEmpty() && target.modId != null && !loadedMods.contains(target.modId)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean noModsLoaded(List<TargetedMod> targetedMods, Set<String> loadedCoreMods, Set<String> loadedMods) {
|
||||
if (targetedMods.isEmpty()) return true;
|
||||
|
||||
for (TargetedMod target : targetedMods) {
|
||||
if (target == TargetedMod.VANILLA) continue;
|
||||
|
||||
// Check coremod first
|
||||
if (!loadedCoreMods.isEmpty() && target.coreModClass != null
|
||||
&& loadedCoreMods.contains(target.coreModClass))
|
||||
return false;
|
||||
else if (!loadedMods.isEmpty() && target.modId != null && loadedMods.contains(target.modId)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean shouldLoad(Set<String> loadedCoreMods, Set<String> loadedMods) {
|
||||
return (shouldLoadSide() && applyIf.get()
|
||||
&& allModsLoaded(targetedMods, loadedCoreMods, loadedMods)
|
||||
&& noModsLoaded(excludedMods, loadedCoreMods, loadedMods));
|
||||
}
|
||||
|
||||
private static class Builder {
|
||||
|
||||
private final String name;
|
||||
private final List<String> mixinClasses = new ArrayList<>();
|
||||
private final List<TargetedMod> targetedMods = new ArrayList<>();
|
||||
private final List<TargetedMod> excludedMods = new ArrayList<>();
|
||||
private Supplier<Boolean> applyIf = null;
|
||||
private Phase phase = null;
|
||||
private Side side = null;
|
||||
|
||||
public Builder(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Builder addMixinClasses(String... mixinClasses) {
|
||||
this.mixinClasses.addAll(Arrays.asList(mixinClasses));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setPhase(Phase phase) {
|
||||
if (this.phase != null) {
|
||||
throw new RuntimeException("Trying to define Phase twice for " + this.name);
|
||||
}
|
||||
this.phase = phase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSide(Side side) {
|
||||
if (this.side != null) {
|
||||
throw new RuntimeException("Trying to define Side twice for " + this.name);
|
||||
}
|
||||
this.side = side;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setApplyIf(Supplier<Boolean> applyIf) {
|
||||
this.applyIf = applyIf;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addTargetedMod(TargetedMod mod) {
|
||||
this.targetedMods.add(mod);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addExcludedMod(TargetedMod mod) {
|
||||
this.excludedMods.add(mod);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
private enum Side {
|
||||
BOTH,
|
||||
CLIENT,
|
||||
SERVER
|
||||
}
|
||||
|
||||
private enum Phase {
|
||||
EARLY,
|
||||
LATE,
|
||||
}
|
||||
}
|
||||
@@ -34,11 +34,11 @@ item.structurelib.constructableTrigger.gui.title=Sub Channels
|
||||
item.structurelib.constructableTrigger.gui.key=Key:
|
||||
item.structurelib.constructableTrigger.gui.value=Value:
|
||||
item.structurelib.constructableTrigger.gui.add=Add
|
||||
item.structurelib.constructableTrigger.gui.set=Set
|
||||
item.structurelib.constructableTrigger.gui.unset=Unset
|
||||
item.structurelib.constructableTrigger.gui.wipe=§4Wipe
|
||||
item.structurelib.constructableTrigger.gui.set=Update
|
||||
item.structurelib.constructableTrigger.gui.unset=Remove
|
||||
item.structurelib.constructableTrigger.gui.wipe=§4Clear
|
||||
item.structurelib.constructableTrigger.gui.channels.from=§rMod: §9§o%s
|
||||
item.structurelib.constructableTrigger.gui.info=Many multiblocks support some degree of variation in its structure and use sub channels to indicate which variant to use.\n Sub channels are has a sequence of lower case characters as key and a positive integer as value. Most known sub channels should be available as typeahead completions.\nYou can also drag and drop items from NEI to set the corresponding sub channel value. These items all have a tooltip of §oIndicates value X for sub channel Y§r.
|
||||
item.structurelib.constructableTrigger.gui.info=Many multiblocks support some degree of variation in their structure and a sub channel allows indication of which variant to use.\n All sub channels have a sequence of lowercase characters as key and a positive integer as value. Most known sub channels should be available as typeahead completions.\n You can also drag and drop items from NEI to set the corresponding sub channel value. These items all have a tooltip of "§oIndicates§r §ovalue§r §oX§r §ofor§r §osub§r §ochannel§r §oY§r".
|
||||
|
||||
channels.structurelib.show_errors=When set, will highlight parts of the multiblock that is definitely wrong
|
||||
|
||||
|
||||
Reference in new issue
Block a user