mirror of
https://github.com/GTNewHorizons/StructureLib.git
synced 2026-11-09 15:04:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6337536dc3 | ||
|
|
9b96560119 | ||
|
|
3ce1c877e3 | ||
|
|
3d150d95cb | ||
|
|
03e84e3d37 | ||
|
|
547833bedb | ||
|
|
61e0d4b7e7 | ||
|
|
6867ed50e6 | ||
|
|
e7a47c199b | ||
|
|
b2bc474382 |
No files matched your search
+2
-2
@@ -1,8 +1,8 @@
|
||||
// Add your dependencies here
|
||||
|
||||
dependencies {
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.2.11:dev")
|
||||
runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.6.0-GTNH:dev")
|
||||
api("com.github.GTNewHorizons:GTNHLib:0.5.19:dev")
|
||||
runtimeOnly("com.github.GTNewHorizons:NotEnoughItems:2.6.44-GTNH:dev")
|
||||
|
||||
testImplementation(platform('org.junit:junit-bom:5.9.2'))
|
||||
testImplementation('org.junit.jupiter:junit-jupiter')
|
||||
|
||||
+21
-10
@@ -41,19 +41,19 @@ developmentEnvironmentUserName = "Developer"
|
||||
|
||||
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
|
||||
# See https://github.com/bsideup/jabel for details on how this works.
|
||||
enableModernJavaSyntax = false
|
||||
enableModernJavaSyntax = true
|
||||
|
||||
# Enables injecting missing generics into the decompiled source code for a better coding experience.
|
||||
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
|
||||
enableGenericInjection = false
|
||||
enableGenericInjection = true
|
||||
|
||||
# Generate a class with a String field for the mod version named as defined below.
|
||||
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
|
||||
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
|
||||
generateGradleTokenClass =
|
||||
generateGradleTokenClass = com.gtnewhorizon.structurelib.Tags
|
||||
|
||||
# Name of the token containing the project's current version to generate/replace.
|
||||
gradleTokenVersion = GRADLETOKEN_VERSION
|
||||
gradleTokenVersion = VERSION
|
||||
|
||||
# [DEPRECATED] Mod ID replacement token.
|
||||
gradleTokenModId =
|
||||
@@ -70,7 +70,7 @@ gradleTokenGroupName =
|
||||
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
|
||||
# version in @Mod([...], version = VERSION, [...]).
|
||||
# Leave these properties empty to skip individual token replacements.
|
||||
replaceGradleTokenInFile = StructureLib.java
|
||||
replaceGradleTokenInFile =
|
||||
|
||||
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
|
||||
# leave this property empty.
|
||||
@@ -83,7 +83,12 @@ apiPackage =
|
||||
accessTransformersFile =
|
||||
|
||||
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
|
||||
usesMixins = false
|
||||
usesMixins = true
|
||||
|
||||
# Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main.
|
||||
# This can speed up compile times thanks to not running the mixin annotation processor on all input sources.
|
||||
# Mixin classes will have access to "main" classes, but not the other way around.
|
||||
separateMixinSourceSet =
|
||||
|
||||
# Adds some debug arguments like verbose output and class export.
|
||||
usesMixinDebug = false
|
||||
@@ -92,12 +97,12 @@ usesMixinDebug = false
|
||||
mixinPlugin =
|
||||
|
||||
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
|
||||
mixinsPackage =
|
||||
mixinsPackage = mixins
|
||||
|
||||
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
|
||||
# This parameter is for legacy compatibility only
|
||||
# Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin
|
||||
coreModClass =
|
||||
coreModClass = core.StructureLibCore
|
||||
|
||||
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
|
||||
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
|
||||
@@ -117,9 +122,15 @@ minimizeShadowedDependencies = true
|
||||
# If disabled, won't rename the shadowed classes.
|
||||
relocateShadowedDependencies = true
|
||||
|
||||
# Adds the GTNH maven, CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
|
||||
# Adds CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
|
||||
includeWellKnownRepositories = true
|
||||
|
||||
# A list of repositories to exclude from the includeWellKnownRepositories setting. Should be a space separated
|
||||
# list of strings, with the acceptable keys being(case does not matter):
|
||||
# cursemaven
|
||||
# modrinth
|
||||
excludeWellKnownRepositories =
|
||||
|
||||
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
|
||||
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
|
||||
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
|
||||
@@ -176,7 +187,7 @@ curseForgeRelations =
|
||||
# disableSpotless = true
|
||||
|
||||
# Uncomment this to disable Checkstyle checks (currently wildcard import check).
|
||||
disableCheckstyle = true
|
||||
# disableCheckstyle = true
|
||||
|
||||
# Override the IDEA build type. Valid values are: "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
|
||||
# (force use delegated build).
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -55,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -84,7 +86,8 @@ done
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||
' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
Vendored
+2
@@ -13,6 +13,8 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.22'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.29'
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,13 @@ package com.gtnewhorizon.structurelib;
|
||||
import static com.gtnewhorizon.structurelib.StructureLib.RANDOM;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
@@ -42,7 +42,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
@Mod(
|
||||
modid = StructureLibAPI.MOD_ID,
|
||||
name = "StructureLib",
|
||||
version = "GRADLETOKEN_VERSION",
|
||||
version = Tags.VERSION,
|
||||
acceptableRemoteVersions = "*",
|
||||
guiFactory = "com.gtnewhorizon.structurelib.GuiFactory")
|
||||
public class StructureLib {
|
||||
|
||||
@@ -72,7 +72,7 @@ public class StructureLibAPI {
|
||||
*/
|
||||
public static void enableInstrument(Object identifier) {
|
||||
if (isInstrumentEnabled()) throw new IllegalStateException();
|
||||
instrument.set(instrument);
|
||||
instrument.set(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+11
-2
@@ -4,9 +4,18 @@ import static com.gtnewhorizon.structurelib.alignment.IAlignment.FLIPS_COUNT;
|
||||
import static com.gtnewhorizon.structurelib.alignment.IAlignment.ROTATIONS_COUNT;
|
||||
import static java.lang.Math.abs;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.stream.Collectors.*;
|
||||
import static java.util.stream.Collectors.collectingAndThen;
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraft.util.Vec3;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class CommandConfigureChannels extends CommandBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<?> addTabCompletionOptions(ICommandSender p_71516_1_, String[] p_71516_2_) {
|
||||
public List<String> addTabCompletionOptions(ICommandSender p_71516_1_, String[] p_71516_2_) {
|
||||
if (p_71516_2_.length == 1)
|
||||
return getListOfStringsMatchingLastWord(p_71516_2_, "get", "set", "unset", "wipe", "getall");
|
||||
return null;
|
||||
|
||||
@@ -28,7 +28,7 @@ public class CommandRegistryDebug extends CommandBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<?> addTabCompletionOptions(ICommandSender p_71516_1_, String[] p_71516_2_) {
|
||||
public List<String> addTabCompletionOptions(ICommandSender p_71516_1_, String[] p_71516_2_) {
|
||||
if (p_71516_2_.length == 1) return getListOfStringsMatchingLastWord(
|
||||
p_71516_2_,
|
||||
SortedRegistry.getRegistryNames().toArray(new String[0]));
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.gtnewhorizon.structurelib.core;
|
||||
|
||||
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;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModContainerClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSetupClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectData(Map<String, Object> data) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTransformerClass() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.gtnewhorizon.structurelib.event;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
public interface BlockChangeListener {
|
||||
|
||||
void onBlockChange(World world, Chunk chunk, int x, int y, int z, Block oldBlock, Block newBlock, int oldMeta,
|
||||
int newMeta);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.gtnewhorizon.structurelib.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
@SuppressWarnings("ForLoopReplaceableByForEach")
|
||||
public class BlockChangeNotifier {
|
||||
|
||||
private static final List<BlockChangeListener> listeners = new ArrayList<>();
|
||||
|
||||
public static synchronized void addListener(BlockChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public static void onBlockChange(World world, Chunk chunk, int x, int y, int z, Block oldBlock, Block newBlock,
|
||||
int oldMeta, int newMeta) {
|
||||
if (oldBlock == newBlock && oldMeta == newMeta) return;
|
||||
|
||||
if (chunk == null) {
|
||||
chunk = world.getChunkFromBlockCoords(x, z);
|
||||
}
|
||||
|
||||
final int numListeners = listeners.size();
|
||||
for (int i = 0; i < numListeners; i++) {
|
||||
final BlockChangeListener listener = listeners.get(i);
|
||||
listener.onBlockChange(world, chunk, x, y, z, oldBlock, newBlock, oldMeta, newMeta);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class ItemFrontRotationTool extends Item {
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List aList, boolean p_77624_4_) {
|
||||
public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List<String> aList, boolean p_77624_4_) {
|
||||
aList.add(translateToLocal("item.structurelib.frontRotationTool.desc.0")); // Triggers Front Rotation Interface
|
||||
aList.add(EnumChatFormatting.BLUE + translateToLocal("item.structurelib.frontRotationTool.desc.1")); // Rotates
|
||||
// only the
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.gtnewhorizon.structurelib.mixins;
|
||||
|
||||
import cpw.mods.fml.common.Mod;
|
||||
|
||||
public enum TargetedMod {
|
||||
|
||||
VANILLA("Minecraft", null);
|
||||
|
||||
/** The "name" in the {@link Mod @Mod} annotation */
|
||||
public final String modName;
|
||||
/** Class that implements the IFMLLoadingPlugin interface */
|
||||
public final String coreModClass;
|
||||
/** The "modid" in the {@link Mod @Mod} annotation */
|
||||
public final String modId;
|
||||
|
||||
TargetedMod(String modName, String coreModClass) {
|
||||
this(modName, coreModClass, null);
|
||||
}
|
||||
|
||||
TargetedMod(String modName, String coreModClass, String modId) {
|
||||
this.modName = modName;
|
||||
this.coreModClass = coreModClass;
|
||||
this.modId = modId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TargetedMod{modName='" + modName + "', coreModClass='" + coreModClass + "', modId='" + modId + "'}";
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.gtnewhorizon.structurelib.mixins.early.blockChangeNotifier;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.util.BlockSnapshot;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.gtnewhorizon.structurelib.event.BlockChangeNotifier;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
|
||||
@Mixin(ForgeHooks.class)
|
||||
public class MixinForgeHooks {
|
||||
|
||||
@Inject(
|
||||
method = "onPlaceItemIntoWorld",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/World;markAndNotifyBlock(IIILnet/minecraft/world/chunk/Chunk;Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;I)V",
|
||||
shift = At.Shift.AFTER),
|
||||
remap = false)
|
||||
private static void onBlockChange(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z,
|
||||
int side, float hitX, float hitY, float hitZ, CallbackInfoReturnable<Boolean> cir,
|
||||
@Local(name = "blocksnapshot") BlockSnapshot blocksnapshot, @Local(name = "newBlock") Block newBlock,
|
||||
@Local(name = "metadata") int newMetadata) {
|
||||
BlockChangeNotifier.onBlockChange(
|
||||
world,
|
||||
null,
|
||||
blocksnapshot.x,
|
||||
blocksnapshot.y,
|
||||
blocksnapshot.z,
|
||||
blocksnapshot.replacedBlock,
|
||||
newBlock,
|
||||
blocksnapshot.meta,
|
||||
newMetadata);
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.gtnewhorizon.structurelib.mixins.early.blockChangeNotifier;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.gtnewhorizon.structurelib.event.BlockChangeNotifier;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.llamalad7.mixinextras.sugar.Share;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalIntRef;
|
||||
import com.llamalad7.mixinextras.sugar.ref.LocalRef;
|
||||
|
||||
@Mixin(World.class)
|
||||
public class MixinWorld {
|
||||
|
||||
@Inject(
|
||||
method = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;II)Z",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/World;markAndNotifyBlock(IIILnet/minecraft/world/chunk/Chunk;Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;I)V",
|
||||
shift = At.Shift.AFTER,
|
||||
remap = false))
|
||||
public void setBlockObserve(int x, int y, int z, Block newBlock, int newMeta, int flags,
|
||||
CallbackInfoReturnable<Boolean> cir, @Local(name = "block1") Block originalBlock,
|
||||
@Share("originalMeta") LocalIntRef originalMeta, @Share("chunk") LocalRef<Chunk> chunkLocalRef) {
|
||||
BlockChangeNotifier.onBlockChange(
|
||||
(World) ((Object) (this)),
|
||||
chunkLocalRef.get(),
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
originalBlock,
|
||||
newBlock,
|
||||
originalMeta.get(),
|
||||
newMeta);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "Lnet/minecraft/world/World;setBlock(IIILnet/minecraft/block/Block;II)Z",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/chunk/Chunk;func_150807_a(IIILnet/minecraft/block/Block;I)Z",
|
||||
shift = At.Shift.BEFORE))
|
||||
public void captureChunkAndOriginalMetadata(int x, int y, int z, Block blockIn, int metadataIn, int flags,
|
||||
CallbackInfoReturnable<Boolean> cir, @Local(name = "chunk") Chunk chunk,
|
||||
@Share("originalMeta") LocalIntRef originalMeta, @Share("chunk") LocalRef<Chunk> chunkLocalRef) {
|
||||
chunkLocalRef.set(chunk);
|
||||
originalMeta.set(chunk.getBlockMetadata(x & 15, y, z & 15));
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,8 @@ public interface IStructureElementChain<T> extends IStructureElement<T> {
|
||||
if (e == null) continue;
|
||||
if (predicate == null) predicate = e.getPredicate();
|
||||
else predicate = predicate.or(e.getPredicate());
|
||||
is.add(e.getStacks());
|
||||
Iterable<ItemStack> stacks = e.getStacks();
|
||||
if (stacks != null) is.add(stacks);
|
||||
}
|
||||
if (predicate == null) return null;
|
||||
return new BlocksToPlace(predicate, Iterables.concat(is));
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import static com.gtnewhorizon.structurelib.structure.StructureUtility.*;
|
||||
import static com.gtnewhorizon.structurelib.structure.StructureUtility.isAir;
|
||||
import static com.gtnewhorizon.structurelib.structure.StructureUtility.notAir;
|
||||
import static com.gtnewhorizon.structurelib.structure.StructureUtility.step;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.gtnewhorizon.structurelib.util.Vec3Impl;
|
||||
|
||||
@@ -2,9 +2,26 @@ package com.gtnewhorizon.structurelib.structure;
|
||||
|
||||
import static java.lang.Integer.MIN_VALUE;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.*;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
*/
|
||||
package com.gtnewhorizon.structurelib.util;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.gtnewhorizon.structurelib.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Spliterator;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SortedRegistry<V> implements Iterable<V> {
|
||||
|
||||
private final NavigableMap<String, V> store = new TreeMap<>();
|
||||
/**
|
||||
* Store stuff in an array for faster iteration access than a red black tree
|
||||
*/
|
||||
private List<V> baked = Collections.emptyList();
|
||||
|
||||
public void register(String key, V val) {
|
||||
if (key == null || val == null) throw new NullPointerException();
|
||||
V old = store.putIfAbsent(key, val);
|
||||
if (old != null) {
|
||||
throw new IllegalArgumentException("Duplicate key: " + key);
|
||||
}
|
||||
// TODO allow a user to edit the order with a configuration file
|
||||
baked = new ArrayList<>(store.values());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return store.size();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return store.isEmpty();
|
||||
}
|
||||
|
||||
public boolean containsKey(String key) {
|
||||
return store.containsKey(key);
|
||||
}
|
||||
|
||||
public boolean containsValue(V value) {
|
||||
return store.containsValue(value);
|
||||
}
|
||||
|
||||
public V get(String key) {
|
||||
return store.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<V> iterator() {
|
||||
return baked.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super V> action) {
|
||||
baked.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<V> spliterator() {
|
||||
return baked.spliterator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8.5-GTNH",
|
||||
"package": "com.gtnewhorizon.structurelib.mixins.early",
|
||||
"refmap": "mixins.structurelib.refmap.json",
|
||||
"target": "@env(DEFAULT)",
|
||||
"compatibilityLevel": "JAVA_8"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8.5-GTNH",
|
||||
"package": "com.gtnewhorizon.structurelib.mixins",
|
||||
"refmap": "mixins.structurelib.refmap.json",
|
||||
"target": "@env(DEFAULT)",
|
||||
"compatibilityLevel": "JAVA_8"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8.5-GTNH",
|
||||
"package": "com.gtnewhorizon.structurelib.mixins.late",
|
||||
"refmap": "mixins.structurelib.refmap.json",
|
||||
"target": "@env(DEFAULT)",
|
||||
"compatibilityLevel": "JAVA_8"
|
||||
}
|
||||
Reference in new issue
Block a user