diff --git a/.gitignore b/.gitignore index d341f1c..12f8644 100644 --- a/.gitignore +++ b/.gitignore @@ -1,43 +1,25 @@ -## Based on GitHub's Eclipse .gitignore - -classes/ -run/ -.gradle/ -build/ -gradle-app.setting - -## IntelliJ IDEA - -.idea/ -*.iml -*.iws -*.ipr - -## Eclipse - -eclipse/ -*.pydevproject -.project -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.classpath -.settings/ -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" +# eclipse +bin *.launch +.settings +.metadata +.classpath +.project -# CDT-specific -.cproject +# idea +out +*.ipr +*.iws +*.iml +.idea -# PDT-specific -.buildpath +# gradle +build +.gradle + +# other +eclipse +run + +# Files from Forge MDK +forge*changelog.txt diff --git a/README.md b/README.md index 52d6175..a9638f5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1 @@ -This is the version for Minecraft 1.12. - -1.13 can be found here: https://bitbucket.org/Requios/effortless-building-1.13/src/master/ \ No newline at end of file +The 1.12 repository can be found here: https://bitbucket.org/Requios/effortless-building/src/master/ \ No newline at end of file diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..6904b37 --- /dev/null +++ b/README.txt @@ -0,0 +1,53 @@ +------------------------------------------- +Source installation information for modders +------------------------------------------- +This code follows the Minecraft Forge installation methodology. It will apply +some small patches to the vanilla MCP source code, giving you and it access +to some of the data and functions you need to build a successful mod. + +Note also that the patches are built against "unrenamed" MCP source code (aka +srgnames) - this means that you will not be able to read them directly against +normal code. + +Source pack installation information: + +Standalone source installation +============================== + +See the Forge Documentation online for more detailed instructions: +http://mcforge.readthedocs.io/en/latest/gettingstarted/ + +Step 1: Open your command-line and browse to the folder where you extracted the zip file. + +Step 2: You're left with a choice. +If you prefer to use Eclipse: +1. Run the following command: "gradlew genEclipseRuns" (./gradlew genEclipseRuns if you are on Mac/Linux) +2. Open Eclipse, Import > Existing Gradle Project > Select Folder + or run "gradlew eclipse" to generate the project. +(Current Issue) +4. Open Project > Run/Debug Settings > Edit runClient and runServer > Environment +5. Edit MOD_CLASSES to show [modid]%%[Path]; 2 times rather then the generated 4. + +If you prefer to use IntelliJ: +1. Open IDEA, and import project. +2. Select your build.gradle file and have it import. +3. Run the following command: "gradlew genIntellijRuns" (./gradlew genIntellijRuns if you are on Mac/Linux) +4. Refresh the Gradle Project in IDEA if required. + +If at any point you are missing libraries in your IDE, or you've run into problems you can run "gradlew --refresh-dependencies" to refresh the local cache. "gradlew clean" to reset everything {this does not affect your code} and then start the processs again. + +Should it still not work, +Refer to #ForgeGradle on EsperNet for more information about the gradle environment. +or the Forge Project Discord discord.gg/UvedJ9m + +Forge source installation +========================= +MinecraftForge ships with this code and installs it as part of the forge +installation process, no further action is required on your part. + +LexManos' Install Video +======================= +https://www.youtube.com/watch?v=8VEdtQLuLO0&feature=youtu.be + +For more details update more often refer to the Forge Forums: +http://www.minecraftforge.net/forum/index.php/topic,14048.0.html diff --git a/build.gradle b/build.gradle index 62b15e0..fab26fb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,82 +1,131 @@ buildscript { repositories { + maven { url = 'https://files.minecraftforge.net/maven' } jcenter() - maven { url = "http://files.minecraftforge.net/maven" } + mavenCentral() } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true } } -apply plugin: 'net.minecraftforge.gradle.forge' -//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. +apply plugin: 'net.minecraftforge.gradle' +// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. +apply plugin: 'eclipse' +apply plugin: 'maven-publish' +version = '1.13.2-2.15' +group = 'nl.requios.effortlessbuilding' // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = 'effortlessbuilding' -version = "1.12.2-2.15" -group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = "effortlessbuilding" - -sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. -compileJava { - sourceCompatibility = targetCompatibility = '1.8' -} +sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. minecraft { - version = "1.12.2-14.23.5.2825" - runDir = "run" - - // the mappings can be changed at any time, and must be in the following format. - // snapshot_YYYYMMDD snapshot are built nightly. - // stable_# stables are built at the discretion of the MCP team. + // The mappings can be changed at any time, and must be in the following format. + // snapshot_YYYYMMDD Snapshot are built nightly. + // stable_# Stables are built at the discretion of the MCP team. // Use non-default mappings at your own risk. they may not always work. - // simply re-run your setup task after changing the mappings to update your workspace. - mappings = "stable_39" + // Simply re-run your setup task after changing the mappings to update your workspace. + mappings channel: 'snapshot', version: '20180921-1.13' // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. -} + + // accessTransformer = file('build/resources/main/META-INF/accesstransformer.cfg') -repositories { - flatDir { dirs 'libs' } + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + client { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment (SCAN,REGISTRIES,REGISTRYDUMP) + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + property 'forge.logging.console.level', 'debug' + + mods { + effortlessbuilding { + source sourceSets.main + } + } + } + + server { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment (SCAN,REGISTRIES,REGISTRYDUMP) + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + property 'forge.logging.console.level', 'debug' + + mods { + effortlessbuilding { + source sourceSets.main + } + } + } + } } dependencies { - // you may put jars on which you depend on in ./libs - // or you may define them like so.. - //compile "some.group:artifact:version:classifier" - //compile "some.group:artifact:version" - - // real examples - //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env - //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env + // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed + // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. + // The userdev artifact is a special name and will get all sorts of transformations applied to it. + minecraft 'net.minecraftforge:forge:1.13.2-25.0.219' - // the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. - //provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + // You may put jars on which you depend on in ./libs or you may define them like so.. + // compile "some.group:artifact:version:classifier" + // compile "some.group:artifact:version" - // the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided, - // except that these dependencies get remapped to your current MCP mappings - //deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev' - //deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev' - provided 'mod.chiselsandbits:chiselsandbits:14.30' + // Real examples + // compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env + // compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env - // for more info... + // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. + // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // These dependencies get remapped to your current MCP mappings + // deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // For more info... // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html // http://www.gradle.org/docs/current/userguide/dependency_management.html } -processResources { - // this will ensure that this task is redone when the versions change. - inputs.property "version", project.version - inputs.property "mcversion", project.minecraft.version - - // replace stuff in mcmod.info, nothing else - from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - - // replace version and mcversion - expand 'version':project.version, 'mcversion':project.minecraft.version - } - - // copy everything else except the mcmod.info - from(sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' +// Example for how to get properties into the manifest for reading by the runtime.. +jar { + manifest { + attributes([ + "Specification-Title": "effortlessbuilding", + "Specification-Vendor": "requios", + "Specification-Version": "1", // We are version 1 of ourselves + "Implementation-Title": project.name, + "Implementation-Version": "${version}", + "Implementation-Vendor" :"requios", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) } } + +// Example configuration to allow publishing using the maven-publish task +// we define a custom artifact that is sourced from the reobfJar output task +// and then declare that to be published +// Note you'll need to add a repository here +def reobfFile = file("$buildDir/reobfJar/output.jar") +def reobfArtifact = artifacts.add('default', reobfFile) { + type 'jar' + builtBy 'reobfJar' +} +publishing { + publications { + mavenJava(MavenPublication) { + artifact reobfArtifact + } + } + repositories { + maven { + url "file:///${project.projectDir}/mcmodsrepo" + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..878bf1f --- /dev/null +++ b/gradle.properties @@ -0,0 +1,4 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 758de96..7a3265e 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2d80b69..949819d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip diff --git a/libs/chiselsandbits-14.30.jar b/libs/chiselsandbits-14.30.jar deleted file mode 100644 index 3598b64..0000000 Binary files a/libs/chiselsandbits-14.30.jar and /dev/null differ diff --git a/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java b/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java index 1663000..003af42 100644 --- a/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java +++ b/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java @@ -1,89 +1,134 @@ package nl.requios.effortlessbuilding; -import net.minecraftforge.common.config.Config; +import net.minecraftforge.common.ForgeConfigSpec; -import static net.minecraftforge.common.config.Config.*; - -@Config(modid = EffortlessBuilding.MODID, name = "EffortlessBuilding", type = Type.INSTANCE, category = "") public class BuildConfig { - public static Reach reach = new Reach(); - public static SurvivalBalancers survivalBalancers = new SurvivalBalancers(); - public static Visuals visuals = new Visuals(); + private static final ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder(); + public static final Reach reach = new Reach(builder); + public static final SurvivalBalancers survivalBalancers = new SurvivalBalancers(builder); + public static final Visuals visuals = new Visuals(builder); + public static final ForgeConfigSpec spec = builder.build(); public static class Reach { - @Comment({"Reach: how far away the player can place blocks using mirror/array etc.", - "Enable the crafting of reach upgrades to increase reach.", - "If disabled, reach is set to level 3 for survival players."}) - public boolean enableReachUpgrades = true; + public final ForgeConfigSpec.ConfigValue enableReachUpgrades; + public final ForgeConfigSpec.ConfigValue maxReachCreative; + public final ForgeConfigSpec.ConfigValue maxReachLevel0; + public final ForgeConfigSpec.ConfigValue maxReachLevel1; + public final ForgeConfigSpec.ConfigValue maxReachLevel2; + public final ForgeConfigSpec.ConfigValue maxReachLevel3; - @Comment({"Maximum reach in creative", - "Keep in mind that chunks need to be loaded to be able to place blocks inside."}) - public int maxReachCreative = 200; + public Reach(ForgeConfigSpec.Builder builder) { + builder.push("Reach"); + enableReachUpgrades = builder + .comment("Reach: how far away the player can place blocks using mirror/array etc.", + "Enable the crafting of reach upgrades to increase reach.", + "If disabled, reach is set to level 3 for survival players.") + .define("enableReachUpgrades", true); - @Comment({"Maximum reach in survival without upgrades", - "Reach upgrades are craftable consumables that permanently increase reach.", - "Set to 0 to disable Effortless Building until the player has consumed a reach upgrade."}) - public int maxReachLevel0 = 20; + maxReachCreative = builder + .comment("Maximum reach in creative", + "Keep in mind that chunks need to be loaded to be able to place blocks inside.") + .define("maxReachCreative", 200); - @Comment("Maximum reach in survival with one upgrade") - public int maxReachLevel1 = 50; + maxReachLevel0 = builder + .comment("Maximum reach in survival without upgrades", + "Reach upgrades are craftable consumables that permanently increase reach.", + "Set to 0 to disable Effortless Building until the player has consumed a reach upgrade.") + .define("maxReachLevel0", 20); - @Comment("Maximum reach in survival with two upgrades") - public int maxReachLevel2 = 100; + maxReachLevel1 = builder + .comment("Maximum reach in survival with one upgrade") + .define("maxReachLevel1", 50); - @Comment("Maximum reach in survival with three upgrades") - public int maxReachLevel3 = 200; + maxReachLevel2 = builder + .comment("Maximum reach in survival with two upgrades") + .define("maxReachLevel2", 100); + + maxReachLevel3 = builder + .comment("Maximum reach in survival with three upgrades") + .define("maxReachLevel3", 200); + + builder.pop(); + } } public static class SurvivalBalancers { - @Comment({"Allows a survival player to break blocks that are far away, in addition to placing blocks.", - "Note: this allows insta-breaking of blocks in survival."}) - public boolean breakFar = false; + public final ForgeConfigSpec.ConfigValue breakFar; + public final ForgeConfigSpec.ConfigValue increasedMiningTime; + public final ForgeConfigSpec.ConfigValue miningTimePercentage; + public final ForgeConfigSpec.ConfigValue quickReplaceMiningLevel; + public final ForgeConfigSpec.ConfigValue undoStackSize; - @Comment({"Increases the time to mine a block when breaking multiple at once.", - "Mining time depends on how many blocks, what type of blocks, and the percentage below.", - "Example: breaking 1 dirt + 1 obsidian takes the time of breaking 1 dirt + 1 obsidian."}) - public boolean increasedMiningTime = true; + public SurvivalBalancers(ForgeConfigSpec.Builder builder) { + builder.push("SurvivalBalancers"); - @Comment({"How much the mining time of each additional block counts towards an increased mining time.", - "A percentage between 0% and 100%, where 0% is the same as disabling it,", - "and 100% takes as much time as breaking each block individually.", - "The block in front of you always counts as 100%."}) - @RangeInt(min = 0, max = 200) - public int miningTimePercentage = 50; + breakFar = builder + .comment("Allows a survival player to break blocks that are far away, in addition to placing blocks.", + "Note: this allows insta-breaking of blocks in survival.") + .define("breakFar", false); - @Comment({"Determines what blocks can be replaced in survival.", - "-1: only blocks that can be harvested by hand (default)", - "0: blocks that can be harvested with wooden or gold tools", - "1: blocks that can be harvested with stone tools", - "2: blocks that can be harvested with iron tools", - "3: blocks that can be harvested with diamond tools", - }) - @RangeInt(min = -1, max = 3) - public int quickReplaceMiningLevel = -1; + increasedMiningTime = builder + .comment("Increases the time to mine a block when breaking multiple at once.", + "Mining time depends on how many blocks, what type of blocks, and the percentage below.", + "Example: breaking 1 dirt + 1 obsidian takes the time of breaking 1 dirt + 1 obsidian.") + .define("increasedMiningTime", true); - @Comment({"How many placements are remembered for the undo functionality."}) - @RequiresMcRestart - public int undoStackSize = 10; + miningTimePercentage = builder + .comment("How much the mining time of each additional block counts towards an increased mining time.", + "A percentage between 0% and 100%, where 0% is the same as disabling it,", + "and 100% takes as much time as breaking each block individually.", + "The block in front of you always counts as 100%.") + .defineInRange("miningTimePercentage", 50, 0, 200); + + quickReplaceMiningLevel = builder + .comment("Determines what blocks can be replaced in survival.", + "-1: only blocks that can be harvested by hand (default)", + "0: blocks that can be harvested with wooden or gold tools", + "1: blocks that can be harvested with stone tools", + "2: blocks that can be harvested with iron tools", + "3: blocks that can be harvested with diamond tools") + .defineInRange("quickReplaceMiningLevel", -1, -1, 3); + + undoStackSize = builder + .comment("How many placements are remembered for the undo functionality.") + .worldRestart() + .define("undoStackSize", 10); + + builder.pop(); + } } public static class Visuals { - @Comment({"Show a block preview if you have a block in hand on build mode NORMAL"}) - public boolean alwaysShowBlockPreview = false; + public final ForgeConfigSpec.ConfigValue alwaysShowBlockPreview; + public final ForgeConfigSpec.ConfigValue dissolveTimeMultiplier; + public final ForgeConfigSpec.ConfigValue shaderTreshold; + public final ForgeConfigSpec.ConfigValue useShaders; - @Comment({"How long the dissolve effect takes when placing blocks.", - "Default between 30 and 60 ticks, you can multiply that here.", - "Recommended values:", - "Snappy: 0.7", - "Relaxing: 1.5"}) - public double dissolveTimeMultiplier = 1.0; + public Visuals(ForgeConfigSpec.Builder builder) { + builder.push("Visuals"); - @Comment({"Switch to using the simple performance shader when placing more than this many blocks."}) - public int shaderTreshold = 1500; + alwaysShowBlockPreview = builder + .comment("Show a block preview if you have a block in hand even in the 'Normal' build mode") + .define("alwaysShowBlockPreview", false); - @Comment({"Use fancy shaders while placing blocks"}) - public boolean useShaders = true; + dissolveTimeMultiplier = builder + .comment("How long the dissolve effect takes when placing blocks.", + "Default between 30 and 60 ticks, you can multiply that here.", + "Recommended values:", + "Snappy: 0.7", + "Relaxing: 1.5") + .define("dissolveTimeMultiplier", 1.0); + shaderTreshold = builder + .comment("Switch to using the simple performance shader when placing more than this many blocks.") + .define("shaderTreshold", 1500); + + useShaders = builder + .comment("Use fancy shaders while placing blocks") + .define("useShaders", true); + + builder.pop(); + } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java index f2dc819..22d2406 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java +++ b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java @@ -4,55 +4,55 @@ import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.common.config.Config; -import net.minecraftforge.common.config.ConfigManager; +import net.minecraftforge.common.crafting.CraftingHelper; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.ExtensionPoint; +import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.event.FMLServerStartingEvent; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; -import net.minecraftforge.fml.relauncher.Side; -import nl.requios.effortlessbuilding.buildmode.BuildModes; +import net.minecraftforge.fml.config.ModConfig; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; +import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; +import net.minecraftforge.fml.event.server.FMLServerStartingEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.fml.network.NetworkRegistry; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.command.CommandReach; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.gui.RandomizerBagGuiHandler; +import nl.requios.effortlessbuilding.helper.ReachConditionFactory; import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.ItemReachUpgrade1; import nl.requios.effortlessbuilding.item.ItemReachUpgrade2; import nl.requios.effortlessbuilding.item.ItemReachUpgrade3; -import nl.requios.effortlessbuilding.network.*; +import nl.requios.effortlessbuilding.network.PacketHandler; +import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.IProxy; +import nl.requios.effortlessbuilding.proxy.ServerProxy; +import nl.requios.effortlessbuilding.render.ShaderHandler; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -@Mod(modid = EffortlessBuilding.MODID, name = EffortlessBuilding.NAME, version = EffortlessBuilding.VERSION) -@Mod.EventBusSubscriber +// The value here should match an entry in the META-INF/mods.toml file +@Mod(EffortlessBuilding.MODID) +@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) public class EffortlessBuilding { public static final String MODID = "effortlessbuilding"; public static final String NAME = "Effortless Building"; - public static final String VERSION = "1.12.2-2.15"; + public static final String VERSION = "1.13.2-2.15"; - @Mod.Instance(EffortlessBuilding.MODID) public static EffortlessBuilding instance; - public static Logger logger; + public static final Logger logger = LogManager.getLogger(); - @SidedProxy( - clientSide="nl.requios.effortlessbuilding.proxy.ClientProxy", - serverSide="nl.requios.effortlessbuilding.proxy.ServerProxy" - ) - public static IProxy proxy; - - public static final SimpleNetworkWrapper packetHandler = NetworkRegistry.INSTANCE.newSimpleChannel(EffortlessBuilding.MODID); + public static IProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> ServerProxy::new); public static final ItemRandomizerBag ITEM_RANDOMIZER_BAG = new ItemRandomizerBag(); public static final ItemReachUpgrade1 ITEM_REACH_UPGRADE_1 = new ItemReachUpgrade1(); @@ -69,73 +69,76 @@ public class EffortlessBuilding ITEM_REACH_UPGRADE_3 }; - public static final int RANDOMIZER_BAG_GUI = 0; + public static final ResourceLocation RANDOMIZER_BAG_GUI = new ResourceLocation(EffortlessBuilding.MODID, "randomizer_bag"); - @EventHandler - // preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the GameRegistry." - public void preInit(FMLPreInitializationEvent event) - { - logger = event.getModLog(); + public EffortlessBuilding() { + instance = this; - CapabilityManager.INSTANCE.register(ModifierCapabilityManager.IModifierCapability.class, new ModifierCapabilityManager.Storage(), ModifierCapabilityManager.ModifierCapability.class); - CapabilityManager.INSTANCE.register(ModeCapabilityManager.IModeCapability.class, new ModeCapabilityManager.Storage(), ModeCapabilityManager.ModeCapability.class); + // Register the setup method for modloading + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); + // Register the enqueueIMC method for modloading + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC); + // Register the processIMC method for modloading + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC); + // Register the clientSetup method for modloading + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); - EffortlessBuilding.packetHandler.registerMessage(ModifierSettingsMessage.MessageHandler.class, ModifierSettingsMessage.class, 0, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(ModifierSettingsMessage.MessageHandler.class, ModifierSettingsMessage.class, 0, Side.CLIENT); + //Register config + ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, BuildConfig.spec); - EffortlessBuilding.packetHandler.registerMessage(ModeSettingsMessage.MessageHandler.class, ModeSettingsMessage.class, 1, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(ModeSettingsMessage.MessageHandler.class, ModeSettingsMessage.class, 1, Side.CLIENT); - - EffortlessBuilding.packetHandler.registerMessage(ModeActionMessage.MessageHandler.class, ModeActionMessage.class, 2, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(ModeActionMessage.MessageHandler.class, ModeActionMessage.class, 2, Side.CLIENT); - - EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 3, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 3, Side.CLIENT); - - EffortlessBuilding.packetHandler.registerMessage(BlockBrokenMessage.MessageHandler.class, BlockBrokenMessage.class, 4, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(BlockBrokenMessage.MessageHandler.class, BlockBrokenMessage.class, 4, Side.CLIENT); - - EffortlessBuilding.packetHandler.registerMessage(CancelModeMessage.MessageHandler.class, CancelModeMessage.class, 5, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(CancelModeMessage.MessageHandler.class, CancelModeMessage.class, 5, Side.CLIENT); - - EffortlessBuilding.packetHandler.registerMessage(RequestLookAtMessage.MessageHandler.class, RequestLookAtMessage.class, 6, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(RequestLookAtMessage.MessageHandler.class, RequestLookAtMessage.class, 6, Side.CLIENT); - - EffortlessBuilding.packetHandler.registerMessage(AddUndoMessage.MessageHandler.class, AddUndoMessage.class, 7, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(AddUndoMessage.MessageHandler.class, AddUndoMessage.class, 7, Side.CLIENT); - - EffortlessBuilding.packetHandler.registerMessage(ClearUndoMessage.MessageHandler.class, ClearUndoMessage.class, 8, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(ClearUndoMessage.MessageHandler.class, ClearUndoMessage.class, 8, Side.CLIENT); - - proxy.preInit(event); + // Register ourselves for server and other game events we are interested in + MinecraftForge.EVENT_BUS.register(this); } - @EventHandler - // Do your mod setup. Build whatever data structures you care about. - // Register network handlers - public void init(FMLInitializationEvent event) + @SubscribeEvent + public void setup(final FMLCommonSetupEvent event) { - ConfigManager.sync(MODID, Config.Type.INSTANCE); - NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerBagGuiHandler()); + CapabilityManager.INSTANCE.register(ModifierCapabilityManager.IModifierCapability.class, new ModifierCapabilityManager.Storage(), ModifierCapabilityManager.ModifierCapability::new); + CapabilityManager.INSTANCE.register(ModeCapabilityManager.IModeCapability.class, new ModeCapabilityManager.Storage(), ModeCapabilityManager.ModeCapability::new); - proxy.init(event); + PacketHandler.register(); + + //Register recipe condition + CraftingHelper.register(new ResourceLocation(MODID, "enable_reach_upgrades"), new ReachConditionFactory()); + + //TODO 1.13 config +// ConfigManager.sync(MODID, Config.Type.INSTANCE); + + ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.GUIFACTORY, () -> RandomizerBagGuiHandler::openGui); + + proxy.setup(event); + + CompatHelper.setup(); } - @EventHandler - // postInit "Handle interaction with other mods, complete your setup based on this." - public void postInit(FMLPostInitializationEvent event) - { - proxy.postInit(event); - CompatHelper.postInit(); + @SubscribeEvent + public void clientSetup(final FMLClientSetupEvent event) { + + proxy.clientSetup(event); } - @EventHandler - public void serverStarting(FMLServerStartingEvent event) - { - event.registerServerCommand(new CommandReach()); - proxy.serverStarting(event); + @SubscribeEvent + public void enqueueIMC(final InterModEnqueueEvent event) { + + // some example code to dispatch IMC to another mod +// InterModComms.sendTo("examplemod", "helloworld", () -> { logger.info("Hello world from the MDK"); return "Hello world";}); } + @SubscribeEvent + public void processIMC(final InterModProcessEvent event) { + + // some example code to receive and process InterModComms from other mods +// logger.info("Got IMC {}", event.getIMCStream(). +// map(m->m.getMessageSupplier().get()). +// collect(Collectors.toList())); + } + + @SubscribeEvent + public void onServerStarting(FMLServerStartingEvent event) { + CommandReach.register(event.getCommandDispatcher()); + } + + public static void log(String msg){ logger.info(msg); } diff --git a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java index e56b66f..2c20061 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java @@ -1,29 +1,24 @@ package nl.requios.effortlessbuilding; -import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.item.Item; -import net.minecraft.item.ItemBlock; +import net.minecraft.stats.Stat; +import net.minecraft.stats.StatList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -import net.minecraftforge.common.config.Config; -import net.minecraftforge.common.config.ConfigManager; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.event.AttachCapabilitiesEvent; -import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.world.BlockEvent; -import net.minecraftforge.fml.client.event.ConfigChangedEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.network.PacketDistributor; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; -import nl.requios.effortlessbuilding.buildmodifier.BlockSet; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; @@ -32,12 +27,10 @@ import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.network.AddUndoMessage; -import nl.requios.effortlessbuilding.network.BlockBrokenMessage; import nl.requios.effortlessbuilding.network.ClearUndoMessage; +import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.network.RequestLookAtMessage; -import scala.actors.threadpool.Arrays; -import java.util.ArrayList; import java.util.List; import static net.minecraftforge.fml.common.gameevent.PlayerEvent.*; @@ -46,39 +39,23 @@ import static net.minecraftforge.fml.common.gameevent.PlayerEvent.*; public class EventHandler { - @SubscribeEvent - public static void registerBlocks(RegistryEvent.Register event) - { - event.getRegistry().registerAll(EffortlessBuilding.BLOCKS); - } - - @SubscribeEvent - public static void registerItems(RegistryEvent.Register event) - { - event.getRegistry().registerAll(EffortlessBuilding.ITEMS); - - for (Block block : EffortlessBuilding.BLOCKS) - { - event.getRegistry().register(new ItemBlock(block).setRegistryName(block.getRegistryName())); - } - } - @SubscribeEvent public static void attachCapabilities(AttachCapabilitiesEvent event) { if (event.getObject() instanceof EntityPlayer) { - event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "BuildModifier"), new ModifierCapabilityManager.Provider()); - event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "BuildMode"), new ModeCapabilityManager.Provider()); + event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_modifier"), new ModifierCapabilityManager.Provider()); + event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_mode"), new ModeCapabilityManager.Provider()); } } - @SubscribeEvent - public static void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event) - { - if (event.getModID().equals(EffortlessBuilding.MODID)) - { - ConfigManager.sync(EffortlessBuilding.MODID, Config.Type.INSTANCE); - } - } + //TODO 1.13 config +// @SubscribeEvent +// public static void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event) +// { +// if (event.getModID().equals(EffortlessBuilding.MODID)) +// { +// ConfigManager.sync(EffortlessBuilding.MODID, Config.Type.INSTANCE); +// } +// } // @SubscribeEvent // public static void onServerTick(TickEvent.ServerTickEvent event) { @@ -87,11 +64,13 @@ public class EventHandler @SubscribeEvent //Only called serverside (except with lilypads...) - public static void onBlockPlaced(BlockEvent.PlaceEvent event) { - if (event.getWorld().isRemote) return; + public static void onBlockPlaced(BlockEvent.EntityPlaceEvent event) { + if (event.getWorld().isRemote()) return; + + if (!(event.getEntity() instanceof EntityPlayer)) return; //Cancel event if necessary - EntityPlayer player = event.getPlayer(); + EntityPlayerMP player = ((EntityPlayerMP) event.getEntity()); BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); @@ -100,21 +79,26 @@ public class EventHandler } else if (modifierSettings.doQuickReplace()) { //Cancel event and send message if QuickReplace event.setCanceled(true); - EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(true), (EntityPlayerMP) player); - EffortlessBuilding.packetHandler.sendTo(new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState()), (EntityPlayerMP) player); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new RequestLookAtMessage(true)); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState())); } else { //NORMAL mode, let vanilla handle block placing //But modifiers should still work //Send message to client, which sends message back with raytrace info - EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(false), (EntityPlayerMP) player); - EffortlessBuilding.packetHandler.sendTo(new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState()), (EntityPlayerMP) player); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new RequestLookAtMessage(false)); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState())); } + +// Stat blocksPlacedStat = StatList.CUSTOM.get(new ResourceLocation(EffortlessBuilding.MODID, "blocks_placed")); +// player.getStats().increment(player, blocksPlacedStat, 1); +// +// System.out.println(player.getStats().getValue(blocksPlacedStat)); } @SubscribeEvent public static void onBlockBroken(BlockEvent.BreakEvent event) { - if (event.getWorld().isRemote) return; + if (event.getWorld().isRemote()) return; //Cancel event if necessary //If cant break far then dont cancel event ever @@ -123,19 +107,19 @@ public class EventHandler event.setCanceled(true); } else { //NORMAL mode, let vanilla handle block breaking - //But modifiers should still work + //But modifiers and QuickReplace should still work //Dont break the original block yourself, otherwise Tinkers Hammer and Veinminer won't work BuildModes.onBlockBroken(event.getPlayer(), event.getPos(), false); //Add to undo stack in client - EffortlessBuilding.packetHandler.sendTo(new AddUndoMessage(event.getPos(), event.getState(), Blocks.AIR.getDefaultState()), (EntityPlayerMP) event.getPlayer()); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) event.getPlayer()), new AddUndoMessage(event.getPos(), event.getState(), Blocks.AIR.getDefaultState())); } } @SubscribeEvent public static void breakSpeed(PlayerEvent.BreakSpeed event) { //Disable if config says so - if (!BuildConfig.survivalBalancers.increasedMiningTime) return; + if (!BuildConfig.survivalBalancers.increasedMiningTime.get()) return; EntityPlayer player = event.getEntityPlayer(); World world = player.world; @@ -158,7 +142,7 @@ public class EventHandler } //Grabbing percentage from config - float percentage = (float) BuildConfig.survivalBalancers.miningTimePercentage / 100; + float percentage = (float) BuildConfig.survivalBalancers.miningTimePercentage.get() / 100; totalBlockHardness *= percentage; totalBlockHardness += originalBlockHardness; @@ -171,36 +155,59 @@ public class EventHandler @SubscribeEvent public static void onPlayerLoggedIn(PlayerLoggedInEvent event) { - EntityPlayer player = event.player; + EntityPlayer player = event.getPlayer(); ModifierSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player); } @SubscribeEvent public static void onPlayerLoggedOut(PlayerLoggedOutEvent event) { - EntityPlayer player = event.player; + EntityPlayer player = event.getPlayer(); if (player.getEntityWorld().isRemote) return; UndoRedo.clear(player); - EffortlessBuilding.packetHandler.sendTo(new ClearUndoMessage(), (EntityPlayerMP) player); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) player), new ClearUndoMessage()); } @SubscribeEvent public static void onPlayerRespawn(PlayerRespawnEvent event) { - EntityPlayer player = event.player; + EntityPlayer player = event.getPlayer(); ModifierSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player); } @SubscribeEvent public static void onPlayerChangedDimension(PlayerChangedDimensionEvent event) { - EntityPlayer player = event.player; + EntityPlayer player = event.getPlayer(); if (player.getEntityWorld().isRemote) return; + //Set build mode to normal + ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); + modeSettings.setBuildMode(BuildModes.BuildModeEnum.NORMAL); + ModeSettingsManager.setModeSettings(player, modeSettings); + + //Disable modifiers + ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); + modifierSettings.getMirrorSettings().enabled = false; + modifierSettings.getRadialMirrorSettings().enabled = false; + modifierSettings.getArraySettings().enabled = false; + ModifierSettingsManager.setModifierSettings(player, modifierSettings); + ModifierSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player); UndoRedo.clear(player); - EffortlessBuilding.packetHandler.sendTo(new ClearUndoMessage(), (EntityPlayerMP) player); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) player), new ClearUndoMessage()); + } + + @SubscribeEvent + public static void onPlayerClone(PlayerEvent.Clone event) { + //Attach capabilities on death, otherwise crash + EntityPlayer oldPlayer = event.getOriginal(); + oldPlayer.revive(); + + EntityPlayer newPlayer = event.getEntityPlayer(); + ModifierSettingsManager.setModifierSettings(newPlayer, ModifierSettingsManager.getModifierSettings(oldPlayer)); + ModeSettingsManager.setModeSettings(newPlayer, ModeSettingsManager.getModeSettings(oldPlayer)); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/ModEventHandler.java b/src/main/java/nl/requios/effortlessbuilding/ModEventHandler.java new file mode 100644 index 0000000..2e7ca75 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/ModEventHandler.java @@ -0,0 +1,30 @@ +package nl.requios.effortlessbuilding; + +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +// You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD +// Event bus for receiving Registry Events) +@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) +public class ModEventHandler { + + @SubscribeEvent + public static void registerBlocks(RegistryEvent.Register event) { + event.getRegistry().registerAll(EffortlessBuilding.BLOCKS); + } + + @SubscribeEvent + public static void registerItems(RegistryEvent.Register event) + { + event.getRegistry().registerAll(EffortlessBuilding.ITEMS); + + for (Block block : EffortlessBuilding.BLOCKS) + { + event.getRegistry().register(new ItemBlock(block, new Item.Properties()).setRegistryName(block.getRegistryName())); + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BaseBuildMode.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BaseBuildMode.java new file mode 100644 index 0000000..ac4da0d --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BaseBuildMode.java @@ -0,0 +1,40 @@ +package nl.requios.effortlessbuilding.buildmode; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; +import java.util.UUID; + +public abstract class BaseBuildMode implements IBuildMode { + //In singleplayer client and server variables are shared + //Split everything that needs separate values and may not be called twice in one click + protected Dictionary rightClickClientTable = new Hashtable<>(); + protected Dictionary rightClickServerTable = new Hashtable<>(); + protected Dictionary firstPosTable = new Hashtable<>(); + protected Dictionary sideHitTable = new Hashtable<>(); + protected Dictionary hitVecTable = new Hashtable<>(); + + @Override + public void initialize(EntityPlayer player) { + rightClickClientTable.put(player.getUniqueID(), 0); + rightClickServerTable.put(player.getUniqueID(), 0); + firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); + sideHitTable.put(player.getUniqueID(), EnumFacing.UP); + hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); + } + + @Override + public EnumFacing getSideHit(EntityPlayer player) { + return sideHitTable.get(player.getUniqueID()); + } + + @Override + public Vec3d getHitVec(EntityPlayer player) { + return hitVecTable.get(player.getUniqueID()); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java index 2c557de..3ec456f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java @@ -2,13 +2,14 @@ package nl.requios.effortlessbuilding.buildmode; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceFluidMode; +import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmode.ModeOptions.ActionEnum; -import nl.requios.effortlessbuilding.buildmodifier.*; -import nl.requios.effortlessbuilding.compatibility.CompatHelper; +import nl.requios.effortlessbuilding.buildmode.buildmodes.*; +import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; +import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.network.BlockBrokenMessage; @@ -19,6 +20,8 @@ import java.util.Dictionary; import java.util.Hashtable; import java.util.List; +import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*; + public class BuildModes { //Static variables are shared between client and server in singleplayer @@ -27,21 +30,24 @@ public class BuildModes { public static Dictionary currentlyBreakingServer = new Hashtable<>(); public enum BuildModeEnum { - NORMAL("effortlessbuilding.mode.normal", new Normal(), new ActionEnum[]{}), - NORMAL_PLUS("effortlessbuilding.mode.normal_plus", new NormalPlus(), new ActionEnum[]{ActionEnum.NORMAL_SPEED, ActionEnum.FAST_SPEED}), - LINE("effortlessbuilding.mode.line", new Line(), new ActionEnum[]{/*ActionEnum.THICKNESS_1, ActionEnum.THICKNESS_3, ActionEnum.THICKNESS_5*/}), - WALL("effortlessbuilding.mode.wall", new Wall(), new ActionEnum[]{ActionEnum.FULL, ActionEnum.HOLLOW}), - FLOOR("effortlessbuilding.mode.floor", new Floor(), new ActionEnum[]{ActionEnum.FULL, ActionEnum.HOLLOW}), - DIAGONAL_LINE("effortlessbuilding.mode.diagonal_line", new DiagonalLine(), new ActionEnum[]{/*ActionEnum.THICKNESS_1, ActionEnum.THICKNESS_3, ActionEnum.THICKNESS_5*/}), - DIAGONAL_WALL("effortlessbuilding.mode.diagonal_wall", new DiagonalWall(), new ActionEnum[]{/*ActionEnum.FULL, ActionEnum.HOLLOW*/}), - SLOPE_FLOOR("effortlessbuilding.mode.slope_floor", new SlopeFloor(), new ActionEnum[]{ActionEnum.SHORT_EDGE, ActionEnum.LONG_EDGE}), - CUBE("effortlessbuilding.mode.cube", new Cube(), new ActionEnum[]{ActionEnum.CUBE_FULL, ActionEnum.CUBE_HOLLOW, ActionEnum.CUBE_SKELETON}); + NORMAL("effortlessbuilding.mode.normal", new Normal()), + NORMAL_PLUS("effortlessbuilding.mode.normal_plus", new NormalPlus(), OptionEnum.BUILD_SPEED), + LINE("effortlessbuilding.mode.line", new Line() /*, OptionEnum.THICKNESS*/), + WALL("effortlessbuilding.mode.wall", new Wall(), OptionEnum.FILL), + FLOOR("effortlessbuilding.mode.floor", new Floor(), OptionEnum.FILL), + DIAGONAL_LINE("effortlessbuilding.mode.diagonal_line", new DiagonalLine() /*, OptionEnum.THICKNESS*/), + DIAGONAL_WALL("effortlessbuilding.mode.diagonal_wall", new DiagonalWall() /*, OptionEnum.FILL*/), + SLOPE_FLOOR("effortlessbuilding.mode.slope_floor", new SlopeFloor(), OptionEnum.RAISED_EDGE), + CIRCLE("effortlessbuilding.mode.circle", new Circle(), OptionEnum.CIRCLE_START, OptionEnum.FILL), + CYLINDER("effortlessbuilding.mode.cylinder", new Cylinder(), OptionEnum.CIRCLE_START, OptionEnum.FILL), + SPHERE("effortlessbuilding.mode.sphere", new Sphere(), OptionEnum.CIRCLE_START, OptionEnum.FILL), + CUBE("effortlessbuilding.mode.cube", new Cube(), OptionEnum.CUBE_FILL); public String name; public IBuildMode instance; - public ActionEnum[] options; + public OptionEnum[] options; - BuildModeEnum(String name, IBuildMode instance, ActionEnum[] options) { + BuildModeEnum(String name, IBuildMode instance, OptionEnum... options) { this.name = name; this.instance = instance; this.options = options; @@ -71,7 +77,8 @@ public class BuildModes { startPos = message.getBlockPos(); //Offset in direction of sidehit if not quickreplace and not replaceable - boolean replaceable = player.world.getBlockState(startPos).getBlock().isReplaceable(player.world, startPos); + //TODO 1.13 replaceable + boolean replaceable = player.world.getBlockState(startPos).getMaterial().isReplaceable(); boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, message.getSideHit()); if (!modifierSettings.doQuickReplace() && !replaceable && !becomesDoubleSlab) { startPos = startPos.offset(message.getSideHit()); @@ -195,6 +202,8 @@ public class BuildModes { } + //-- Common build mode functionality --// + //Find coordinates on a line bound by a plane public static Vec3d findXBound(double x, Vec3d start, Vec3d look) { //then y and z are @@ -220,4 +229,17 @@ public class BuildModes { return new Vec3d(x, y, z); } + public static boolean isCriteriaValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace, Vec3d lineBound, Vec3d planeBound, double distToPlayerSq) { + boolean intersects = false; + if (!skipRaytrace) { + //collision within a 1 block radius to selected is fine + RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, lineBound, RayTraceFluidMode.NEVER, true, false); + intersects = rayTraceResult != null && rayTraceResult.type == RayTraceResult.Type.BLOCK && + planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4; + } + + return planeBound.subtract(start).dotProduct(look) > 0 && + distToPlayerSq > 2 && distToPlayerSq < reach * reach && + !intersects; + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Cube.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Cube.java deleted file mode 100644 index 12258bd..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Cube.java +++ /dev/null @@ -1,208 +0,0 @@ -package nl.requios.effortlessbuilding.buildmode; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import nl.requios.effortlessbuilding.helper.ReachHelper; - -import java.util.*; - -public class Cube implements IBuildMode { - //In singleplayer client and server variables are shared - //Split everything that needs separate values and may not be called twice in one click - private Dictionary rightClickClientTable = new Hashtable<>(); - private Dictionary rightClickServerTable = new Hashtable<>(); - private Dictionary firstPosTable = new Hashtable<>(); - private Dictionary secondPosTable = new Hashtable<>(); - private Dictionary sideHitTable = new Hashtable<>(); - private Dictionary hitVecTable = new Hashtable<>(); - - @Override - public void initialize(EntityPlayer player) { - rightClickClientTable.put(player.getUniqueID(), 0); - rightClickServerTable.put(player.getUniqueID(), 0); - firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); - sideHitTable.put(player.getUniqueID(), EnumFacing.UP); - hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); - } - - @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { - List list = new ArrayList<>(); - - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - rightClickNr++; - rightClickTable.put(player.getUniqueID(), rightClickNr); - - if (rightClickNr == 1) { - //If clicking in air, reset and try again - if (blockPos == null) { - rightClickTable.put(player.getUniqueID(), 0); - return list; - } - - //First click, remember starting position - firstPosTable.put(player.getUniqueID(), blockPos); - sideHitTable.put(player.getUniqueID(), sideHit); - hitVecTable.put(player.getUniqueID(), hitVec); - //Keep list empty, dont place any blocks yet - } else if (rightClickNr == 2) { - //Second click, find other floor point - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = Floor.findFloor(player, firstPos, skipRaytrace); - - if (secondPos == null) { - rightClickTable.put(player.getUniqueID(), 1); - return list; - } - - secondPosTable.put(player.getUniqueID(), secondPos); - - } else { - //Third click, place cube with height - list = findCoordinates(player, blockPos, skipRaytrace); - rightClickTable.put(player.getUniqueID(), 0); - } - - return list; - } - - @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { - List list = new ArrayList<>(); - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - - if (rightClickNr == 0) { - if (blockPos != null) - list.add(blockPos); - } else if (rightClickNr == 1) { - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - - BlockPos secondPos = Floor.findFloor(player, firstPos, skipRaytrace); - if (secondPos == null) return list; - - //Add whole floor - //Limit amount of blocks you can place per row - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - int x1 = firstPos.getX(), x2 = secondPos.getX(); - int y = firstPos.getY(); - int z1 = firstPos.getZ(), z2 = secondPos.getZ(); - - //limit axis - if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; - if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; - if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; - if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; - - if (ModeOptions.getCubeFill() == ModeOptions.ActionEnum.CUBE_SKELETON) { - //Hollow floor - Line.addXLineBlocks(list, x1, x2, y, z1); - Line.addXLineBlocks(list, x1, x2, y, z2); - Line.addZLineBlocks(list, z1, z2, x1, y); - Line.addZLineBlocks(list, z1, z2, x2, y); - } else { - //Filled floor - for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { - - for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { - - list.add(new BlockPos(l, y, n)); - } - } - } - - } else { - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = secondPosTable.get(player.getUniqueID()); - - BlockPos thirdPos = DiagonalLine.findHeight(player, secondPos, skipRaytrace); - if (thirdPos == null) return list; - - //Add whole cube - //Limit amount of blocks you can place per row - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - int x1 = firstPos.getX(), x2 = thirdPos.getX(); - int y1 = firstPos.getY(), y2 = thirdPos.getY(); - int z1 = firstPos.getZ(), z2 = thirdPos.getZ(); - - //limit axis - if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; - if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; - if (y2 - y1 >= axisLimit) y2 = y1 + axisLimit - 1; - if (y1 - y2 >= axisLimit) y2 = y1 - axisLimit + 1; - if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; - if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; - - switch (ModeOptions.getCubeFill()) { - case CUBE_FULL: - addCubeBlocks(list, x1, x2, y1, y2, z1, z2); - break; - case CUBE_HOLLOW: - addHollowCubeBlocks(list, x1, x2, y1, y2, z1, z2); - break; - case CUBE_SKELETON: - addSkeletonCubeBlocks(list, x1, x2, y1, y2, z1, z2); - break; - } - - } - - return list; - } - - public static void addCubeBlocks(List list, int x1, int x2, int y1, int y2, int z1, int z2) { - for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { - - for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { - - for (int m = y1; y1 < y2 ? m <= y2 : m >= y2; m += y1 < y2 ? 1 : -1) { - list.add(new BlockPos(l, m, n)); - } - } - } - } - - public static void addHollowCubeBlocks(List list, int x1, int x2, int y1, int y2, int z1, int z2) { - Wall.addXWallBlocks(list, x1, y1, y2, z1, z2); - Wall.addXWallBlocks(list, x2, y1, y2, z1, z2); - - Wall.addZWallBlocks(list, x1, x2, y1, y2, z1); - Wall.addZWallBlocks(list, x1, x2, y1, y2, z2); - - Floor.addFloorBlocks(list, x1, x2, y1, z1, z2); - Floor.addFloorBlocks(list, x1, x2, y2, z1, z2); - } - - public static void addSkeletonCubeBlocks(List list, int x1, int x2, int y1, int y2, int z1, int z2) { - Line.addXLineBlocks(list, x1, x2, y1, z1); - Line.addXLineBlocks(list, x1, x2, y1, z2); - Line.addXLineBlocks(list, x1, x2, y2, z1); - Line.addXLineBlocks(list, x1, x2, y2, z2); - - Line.addYLineBlocks(list, y1, y2, x1, z1); - Line.addYLineBlocks(list, y1, y2, x1, z2); - Line.addYLineBlocks(list, y1, y2, x2, z1); - Line.addYLineBlocks(list, y1, y2, x2, z2); - - Line.addZLineBlocks(list, z1, z2, x1, y1); - Line.addZLineBlocks(list, z1, z2, x1, y2); - Line.addZLineBlocks(list, z1, z2, x2, y1); - Line.addZLineBlocks(list, z1, z2, x2, y2); - } - - @Override - public EnumFacing getSideHit(EntityPlayer player) { - return sideHitTable.get(player.getUniqueID()); - } - - @Override - public Vec3d getHitVec(EntityPlayer player) { - return hitVecTable.get(player.getUniqueID()); - } - -} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalWall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalWall.java deleted file mode 100644 index 7ba351c..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalWall.java +++ /dev/null @@ -1,138 +0,0 @@ -package nl.requios.effortlessbuilding.buildmode; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import nl.requios.effortlessbuilding.helper.ReachHelper; - -import java.util.*; - -public class DiagonalWall implements IBuildMode { - //In singleplayer client and server variables are shared - //Split everything that needs separate values and may not be called twice in one click - private Dictionary rightClickClientTable = new Hashtable<>(); - private Dictionary rightClickServerTable = new Hashtable<>(); - private Dictionary firstPosTable = new Hashtable<>(); - private Dictionary secondPosTable = new Hashtable<>(); - private Dictionary sideHitTable = new Hashtable<>(); - private Dictionary hitVecTable = new Hashtable<>(); - - @Override - public void initialize(EntityPlayer player) { - rightClickClientTable.put(player.getUniqueID(), 0); - rightClickServerTable.put(player.getUniqueID(), 0); - firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); - sideHitTable.put(player.getUniqueID(), EnumFacing.UP); - hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); - } - - @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { - List list = new ArrayList<>(); - - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - rightClickNr++; - rightClickTable.put(player.getUniqueID(), rightClickNr); - - if (rightClickNr == 1) { - //If clicking in air, reset and try again - if (blockPos == null) { - rightClickTable.put(player.getUniqueID(), 0); - return list; - } - - //First click, remember starting position - firstPosTable.put(player.getUniqueID(), blockPos); - sideHitTable.put(player.getUniqueID(), sideHit); - hitVecTable.put(player.getUniqueID(), hitVec); - //Keep list empty, dont place any blocks yet - } else if (rightClickNr == 2) { - //Second click, find other floor point - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = Floor.findFloor(player, firstPos, true); - - if (secondPos == null) { - rightClickTable.put(player.getUniqueID(), 1); - return list; - } - - secondPosTable.put(player.getUniqueID(), secondPos); - - } else { - //Third click, place diagonal wall with height - list = findCoordinates(player, blockPos, skipRaytrace); - rightClickTable.put(player.getUniqueID(), 0); - } - - return list; - } - - @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { - List list = new ArrayList<>(); - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - - if (rightClickNr == 0) { - if (blockPos != null) - list.add(blockPos); - } else if (rightClickNr == 1) { - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - - BlockPos secondPos = Floor.findFloor(player, firstPos, true); - if (secondPos == null) return list; - - //Add diagonal line - list.addAll(DiagonalLine.getDiagonalLineBlocks(player, firstPos, secondPos, 1)); - - } else { - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = secondPosTable.get(player.getUniqueID()); - - BlockPos thirdPos = DiagonalLine.findHeight(player, secondPos, skipRaytrace); - if (thirdPos == null) return list; - - //Add diagonal wall - list.addAll(getDiagonalWallBlocks(player, firstPos, secondPos, thirdPos)); - } - - return list; - } - - //Add diagonal wall from first to second - public static List getDiagonalWallBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, BlockPos thirdPos) { - List list = new ArrayList<>(); - - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - //Get diagonal line blocks - List diagonalLineBlocks = DiagonalLine.getDiagonalLineBlocks(player, firstPos, secondPos, 1); - - //Limit amount of blocks we can place - int lowest = Math.min(firstPos.getY(), thirdPos.getY()); - int highest = Math.max(firstPos.getY(), thirdPos.getY()); - - if (highest - lowest >= axisLimit) highest = lowest + axisLimit - 1; - - //Copy diagonal line on y axis - for (int y = lowest; y <= highest; y++) { - for (BlockPos blockPos : diagonalLineBlocks) { - list.add(new BlockPos(blockPos.getX(), y, blockPos.getZ())); - } - } - - return list; - } - - @Override - public EnumFacing getSideHit(EntityPlayer player) { - return sideHitTable.get(player.getUniqueID()); - } - - @Override - public Vec3d getHitVec(EntityPlayer player) { - return hitVecTable.get(player.getUniqueID()); - } -} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java deleted file mode 100644 index 92aabbb..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java +++ /dev/null @@ -1,183 +0,0 @@ -package nl.requios.effortlessbuilding.buildmode; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import nl.requios.effortlessbuilding.helper.ReachHelper; - -import java.util.*; - -public class Floor implements IBuildMode { - //In singleplayer client and server variables are shared - //Split everything that needs separate values and may not be called twice in one click - private Dictionary rightClickClientTable = new Hashtable<>(); - private Dictionary rightClickServerTable = new Hashtable<>(); - private Dictionary firstPosTable = new Hashtable<>(); - private Dictionary sideHitTable = new Hashtable<>(); - private Dictionary hitVecTable = new Hashtable<>(); - - static class Criteria { - Vec3d planeBound; - double distToPlayerSq; - - Criteria(Vec3d planeBound, Vec3d start) { - this.planeBound = planeBound; - this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared(); - } - - //check if its not behind the player and its not too close and not too far - //also check if raytrace from player to block does not intersect blocks - public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) { - - boolean intersects = false; - if (!skipRaytrace) { - //collision within a 1 block radius to selected is fine - RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, planeBound, false, true, false); - intersects = rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK && - planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4; - } - - return planeBound.subtract(start).dotProduct(look) > 0 && - distToPlayerSq > 2 && distToPlayerSq < reach * reach && - !intersects; - } - } - - @Override - public void initialize(EntityPlayer player) { - rightClickClientTable.put(player.getUniqueID(), 0); - rightClickServerTable.put(player.getUniqueID(), 0); - firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); - sideHitTable.put(player.getUniqueID(), EnumFacing.UP); - hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); - } - - @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { - List list = new ArrayList<>(); - - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - rightClickNr++; - rightClickTable.put(player.getUniqueID(), rightClickNr); - - if (rightClickNr == 1) { - //If clicking in air, reset and try again - if (blockPos == null) { - rightClickTable.put(player.getUniqueID(), 0); - return list; - } - - //First click, remember starting position - firstPosTable.put(player.getUniqueID(), blockPos); - sideHitTable.put(player.getUniqueID(), sideHit); - hitVecTable.put(player.getUniqueID(), hitVec); - //Keep list empty, dont place any blocks yet - } else { - //Second click, place wall - - list = findCoordinates(player, blockPos, skipRaytrace); - rightClickTable.put(player.getUniqueID(), 0); - } - - return list; - } - - @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { - List list = new ArrayList<>(); - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - - if (rightClickNr == 0) { - if (blockPos != null) - list.add(blockPos); - } else { - BlockPos secondPos = findFloor(player, firstPos, skipRaytrace); - if (secondPos == null) return list; - - //Add whole floor - list.addAll(getFloorBlocks(player, firstPos, secondPos)); - } - - return list; - } - - public static BlockPos findFloor(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { - Vec3d look = player.getLookVec(); - Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); - - List criteriaList = new ArrayList<>(3); - - //Y - Vec3d yBound = BuildModes.findYBound(firstPos.getY(), start, look); - criteriaList.add(new Criteria(yBound, start)); - - //Remove invalid criteria - int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach - criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); - - //If none are valid, return empty list of blocks - if (criteriaList.isEmpty()) return null; - - //Then only 1 can be valid, return that one - Criteria selected = criteriaList.get(0); - - return new BlockPos(selected.planeBound); - } - - public static List getFloorBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos) { - List list = new ArrayList<>(); - - //Limit amount of blocks you can place per row - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - int x1 = firstPos.getX(), x2 = secondPos.getX(); - int y = firstPos.getY(); - int z1 = firstPos.getZ(), z2 = secondPos.getZ(); - - //limit axis - if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; - if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; - if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; - if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; - - if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) - addFloorBlocks(list, x1, x2, y, z1, z2); - else - addHollowFloorBlocks(list, x1, x2, y, z1, z2); - - return list; - } - - public static void addFloorBlocks(List list, int x1, int x2, int y, int z1, int z2) { - - for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { - - for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { - - list.add(new BlockPos(l, y, n)); - } - } - } - - public static void addHollowFloorBlocks(List list, int x1, int x2, int y, int z1, int z2) { - Line.addXLineBlocks(list, x1, x2, y, z1); - Line.addXLineBlocks(list, x1, x2, y, z2); - Line.addZLineBlocks(list, z1, z2, x1, y); - Line.addZLineBlocks(list, z1, z2, x2, y); - } - - @Override - public EnumFacing getSideHit(EntityPlayer player) { - return sideHitTable.get(player.getUniqueID()); - } - - @Override - public Vec3d getHitVec(EntityPlayer player) { - return hitVecTable.get(player.getUniqueID()); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java index e82ea70..42a1b5f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java @@ -30,7 +30,10 @@ public class ModeOptions { THICKNESS_1("effortlessbuilding.action.thickness_1"), THICKNESS_3("effortlessbuilding.action.thickness_3"), - THICKNESS_5("effortlessbuilding.action.thickness_5"); + THICKNESS_5("effortlessbuilding.action.thickness_5"), + + CIRCLE_START_CENTER("effortlessbuilding.action.start_center"), + CIRCLE_START_CORNER("effortlessbuilding.action.start_corner"); public String name; @@ -39,11 +42,48 @@ public class ModeOptions { } } + public enum OptionEnum { + BUILD_SPEED("effortlessbuilding.action.build_speed", ActionEnum.NORMAL_SPEED, ActionEnum.FAST_SPEED), + FILL("effortlessbuilding.action.filling", ActionEnum.FULL, ActionEnum.HOLLOW), + CUBE_FILL("effortlessbuilding.action.filling", ActionEnum.CUBE_FULL, ActionEnum.CUBE_HOLLOW, ActionEnum.CUBE_SKELETON), + RAISED_EDGE("effortlessbuilding.action.raised_edge", ActionEnum.SHORT_EDGE, ActionEnum.LONG_EDGE), + LINE_THICKNESS("effortlessbuilding.action.thickness", ActionEnum.THICKNESS_1, ActionEnum.THICKNESS_3, ActionEnum.THICKNESS_5), + CIRCLE_START("effortlessbuilding.action.circle_start", ActionEnum.CIRCLE_START_CENTER, ActionEnum.CIRCLE_START_CORNER); + + public String name; + public ActionEnum[] actions; + + OptionEnum(String name, ActionEnum... actions){ + this.name = name; + this.actions = actions; + } + } + private static ActionEnum buildSpeed = ActionEnum.NORMAL_SPEED; private static ActionEnum fill = ActionEnum.FULL; private static ActionEnum cubeFill = ActionEnum.CUBE_FULL; private static ActionEnum raisedEdge = ActionEnum.SHORT_EDGE; private static ActionEnum lineThickness = ActionEnum.THICKNESS_1; + private static ActionEnum circleStart = ActionEnum.CIRCLE_START_CENTER; + + public static ActionEnum getOptionSetting(OptionEnum option) { + switch (option) { + case BUILD_SPEED: + return getBuildSpeed(); + case FILL: + return getFill(); + case CUBE_FILL: + return getCubeFill(); + case RAISED_EDGE: + return getRaisedEdge(); + case LINE_THICKNESS: + return getLineThickness(); + case CIRCLE_START: + return getCircleStart(); + default: + return null; + } + } public static ActionEnum getBuildSpeed() { return buildSpeed; @@ -65,6 +105,10 @@ public class ModeOptions { return lineThickness; } + public static ActionEnum getCircleStart() { + return circleStart; + } + //Called on both client and server public static void performAction(EntityPlayer player, ActionEnum action) { if (action == null) return; @@ -123,6 +167,12 @@ public class ModeOptions { case THICKNESS_5: lineThickness = ActionEnum.THICKNESS_5; break; + case CIRCLE_START_CENTER: + circleStart = ActionEnum.CIRCLE_START_CENTER; + break; + case CIRCLE_START_CORNER: + circleStart = ActionEnum.CIRCLE_START_CORNER; + break; } if (player.world.isRemote && action != ActionEnum.REPLACE && action != ActionEnum.OPEN_MODIFIER_SETTINGS) { diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java index 4bc38c3..d6f2369 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java @@ -2,44 +2,57 @@ package nl.requios.effortlessbuilding.buildmode; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.network.PacketDistributor; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.network.ModeSettingsMessage; +import nl.requios.effortlessbuilding.network.PacketHandler; + +import javax.annotation.Nonnull; @Mod.EventBusSubscriber public class ModeSettingsManager { //Retrieves the buildsettings of a player through the modifierCapability capability //Never returns null + @Nonnull public static ModeSettings getModeSettings(EntityPlayer player) { - if (player.hasCapability(ModeCapabilityManager.modeCapability, null)) { - ModeCapabilityManager.IModeCapability capability = player.getCapability( - ModeCapabilityManager.modeCapability, null); + LazyOptional modeCapability = + player.getCapability(ModeCapabilityManager.modeCapability, null); + + if (modeCapability.isPresent()) { + ModeCapabilityManager.IModeCapability capability = modeCapability.orElse(null); if (capability.getModeData() == null) { capability.setModeData(new ModeSettings()); } return capability.getModeData(); } - throw new IllegalArgumentException("Player does not have modeCapability capability"); + + //Player does not have modeCapability capability + //Return dummy settings + return new ModeSettings(); +// throw new IllegalArgumentException("Player does not have modeCapability capability"); } public static void setModeSettings(EntityPlayer player, ModeSettings modeSettings) { if (player == null) { - EffortlessBuilding.log("Cannot set buildsettings, player is null"); + EffortlessBuilding.log("Cannot set buildmode settings, player is null"); return; } - if (player.hasCapability(ModeCapabilityManager.modeCapability, null)) { - ModeCapabilityManager.IModeCapability capability = player.getCapability( - ModeCapabilityManager.modeCapability, null); + LazyOptional modeCapability = + player.getCapability(ModeCapabilityManager.modeCapability, null); + modeCapability.ifPresent((capability) -> { capability.setModeData(modeSettings); - //Initialize new mode BuildModes.initializeMode(player); - } else { - EffortlessBuilding.log(player, "Saving buildsettings failed."); + }); + + if (!modeCapability.isPresent()) { + EffortlessBuilding.log(player, "Saving buildmode settings failed."); } } @@ -72,15 +85,14 @@ public class ModeSettingsManager { } public static void handleNewPlayer(EntityPlayer player){ - if (getModeSettings(player) == null) { - setModeSettings(player, new ModeSettings()); - } + //Makes sure player has mode settings (if it doesnt it will create it) + getModeSettings(player); //Only on server if (!player.world.isRemote) { //Send to client ModeSettingsMessage msg = new ModeSettingsMessage(getModeSettings(player)); - EffortlessBuilding.packetHandler.sendTo(msg, (EntityPlayerMP) player); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) player), msg); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/SlopeFloor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/SlopeFloor.java deleted file mode 100644 index 35fa01a..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/SlopeFloor.java +++ /dev/null @@ -1,178 +0,0 @@ -package nl.requios.effortlessbuilding.buildmode; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import nl.requios.effortlessbuilding.helper.ReachHelper; - -import java.util.*; - -public class SlopeFloor implements IBuildMode { - //In singleplayer client and server variables are shared - //Split everything that needs separate values and may not be called twice in one click - private Dictionary rightClickClientTable = new Hashtable<>(); - private Dictionary rightClickServerTable = new Hashtable<>(); - private Dictionary firstPosTable = new Hashtable<>(); - private Dictionary secondPosTable = new Hashtable<>(); - private Dictionary sideHitTable = new Hashtable<>(); - private Dictionary hitVecTable = new Hashtable<>(); - - @Override - public void initialize(EntityPlayer player) { - rightClickClientTable.put(player.getUniqueID(), 0); - rightClickServerTable.put(player.getUniqueID(), 0); - firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); - sideHitTable.put(player.getUniqueID(), EnumFacing.UP); - hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); - } - - @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { - List list = new ArrayList<>(); - - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - rightClickNr++; - rightClickTable.put(player.getUniqueID(), rightClickNr); - - if (rightClickNr == 1) { - //If clicking in air, reset and try again - if (blockPos == null) { - rightClickTable.put(player.getUniqueID(), 0); - return list; - } - - //First click, remember starting position - firstPosTable.put(player.getUniqueID(), blockPos); - sideHitTable.put(player.getUniqueID(), sideHit); - hitVecTable.put(player.getUniqueID(), hitVec); - //Keep list empty, dont place any blocks yet - } else if (rightClickNr == 2) { - //Second click, find other floor point - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = Floor.findFloor(player, firstPos, true); - - if (secondPos == null) { - rightClickTable.put(player.getUniqueID(), 1); - return list; - } - - secondPosTable.put(player.getUniqueID(), secondPos); - - } else { - //Third click, place slope floor with height - list = findCoordinates(player, blockPos, skipRaytrace); - rightClickTable.put(player.getUniqueID(), 0); - } - - return list; - } - - @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { - List list = new ArrayList<>(); - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - - if (rightClickNr == 0) { - if (blockPos != null) - list.add(blockPos); - } else if (rightClickNr == 1) { - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - - BlockPos secondPos = Floor.findFloor(player, firstPos, true); - if (secondPos == null) return list; - - //Add whole floor - list.addAll(Floor.getFloorBlocks(player, firstPos, secondPos)); - - } else { - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = secondPosTable.get(player.getUniqueID()); - - BlockPos thirdPos = DiagonalLine.findHeight(player, secondPos, skipRaytrace); - if (thirdPos == null) return list; - - //Add slope floor blocks - list.addAll(getSlopeFloorBlocks(player, firstPos, secondPos, thirdPos)); - } - - return list; - } - - //Add slope floor from first to second - public static List getSlopeFloorBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, BlockPos thirdPos) { - List list = new ArrayList<>(); - - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - //Determine whether to use x or z axis to slope up - boolean onXAxis = true; - - int xLength = Math.abs(secondPos.getX() - firstPos.getX()); - int zLength = Math.abs(secondPos.getZ() - firstPos.getZ()); - - if (ModeOptions.getRaisedEdge() == ModeOptions.ActionEnum.SHORT_EDGE) { - //Slope along short edge - if (zLength > xLength) onXAxis = false; - } else { - //Slope along long edge - if (zLength <= xLength) onXAxis = false; - } - - if (onXAxis) { - //Along X goes up - - //Get diagonal line blocks - BlockPos linePoint = new BlockPos(secondPos.getX(), thirdPos.getY(), firstPos.getZ()); - List diagonalLineBlocks = DiagonalLine.getDiagonalLineBlocks(player, firstPos, linePoint, 1f); - - //Limit amount of blocks we can place - int lowest = Math.min(firstPos.getZ(), secondPos.getZ()); - int highest = Math.max(firstPos.getZ(), secondPos.getZ()); - - if (highest - lowest >= axisLimit) highest = lowest + axisLimit - 1; - - //Copy diagonal line on x axis - for (int z = lowest; z <= highest; z++) { - for (BlockPos blockPos : diagonalLineBlocks) { - list.add(new BlockPos(blockPos.getX(), blockPos.getY(), z)); - } - } - - } else { - //Along Z goes up - - //Get diagonal line blocks - BlockPos linePoint = new BlockPos(firstPos.getX(), thirdPos.getY(), secondPos.getZ()); - List diagonalLineBlocks = DiagonalLine.getDiagonalLineBlocks(player, firstPos, linePoint, 1f); - - //Limit amount of blocks we can place - int lowest = Math.min(firstPos.getX(), secondPos.getX()); - int highest = Math.max(firstPos.getX(), secondPos.getX()); - - if (highest - lowest >= axisLimit) highest = lowest + axisLimit - 1; - - //Copy diagonal line on x axis - for (int x = lowest; x <= highest; x++) { - for (BlockPos blockPos : diagonalLineBlocks) { - list.add(new BlockPos(x, blockPos.getY(), blockPos.getZ())); - } - } - } - - - return list; - } - - @Override - public EnumFacing getSideHit(EntityPlayer player) { - return sideHitTable.get(player.getUniqueID()); - } - - @Override - public Vec3d getHitVec(EntityPlayer player) { - return hitVecTable.get(player.getUniqueID()); - } -} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalLine.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/ThreeClicksBuildMode.java similarity index 61% rename from src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalLine.java rename to src/main/java/nl/requios/effortlessbuilding/buildmode/ThreeClicksBuildMode.java index 734d251..a8f9ba5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalLine.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/ThreeClicksBuildMode.java @@ -3,21 +3,15 @@ package nl.requios.effortlessbuilding.buildmode; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.buildmodes.DiagonalLine; +import nl.requios.effortlessbuilding.buildmode.buildmodes.Floor; import nl.requios.effortlessbuilding.helper.ReachHelper; import java.util.*; -public class DiagonalLine implements IBuildMode { - //In singleplayer client and server variables are shared - //Split everything that needs separate values and may not be called twice in one click - private Dictionary rightClickClientTable = new Hashtable<>(); - private Dictionary rightClickServerTable = new Hashtable<>(); - private Dictionary firstPosTable = new Hashtable<>(); - private Dictionary secondPosTable = new Hashtable<>(); - private Dictionary sideHitTable = new Hashtable<>(); - private Dictionary hitVecTable = new Hashtable<>(); +public abstract class ThreeClicksBuildMode extends BaseBuildMode { + protected Dictionary secondPosTable = new Hashtable<>(); static class HeightCriteria { Vec3d planeBound; @@ -42,27 +36,14 @@ public class DiagonalLine implements IBuildMode { //also check if raytrace from player to block does not intersect blocks public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) { - boolean intersects = false; - if (!skipRaytrace) { - //collision within a 1 block radius to selected is fine - RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, lineBound, false, true, false); - intersects = rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK && - planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4; - } - - return planeBound.subtract(start).dotProduct(look) > 0 && - distToPlayerSq > 2 && distToPlayerSq < reach * reach && - !intersects; + return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq); } } - + @Override public void initialize(EntityPlayer player) { - rightClickClientTable.put(player.getUniqueID(), 0); - rightClickServerTable.put(player.getUniqueID(), 0); - firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); - sideHitTable.put(player.getUniqueID(), EnumFacing.UP); - hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); + super.initialize(player); + secondPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); } @Override @@ -89,7 +70,7 @@ public class DiagonalLine implements IBuildMode { } else if (rightClickNr == 2) { //Second click, find other floor point BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = Floor.findFloor(player, firstPos, true); + BlockPos secondPos = findSecondPos(player, firstPos, true); if (secondPos == null) { rightClickTable.put(player.getUniqueID(), 1); @@ -99,7 +80,7 @@ public class DiagonalLine implements IBuildMode { secondPosTable.put(player.getUniqueID(), secondPos); } else { - //Third click, place diagonal line with height + //Third click, place diagonal wall with height list = findCoordinates(player, blockPos, skipRaytrace); rightClickTable.put(player.getUniqueID(), 0); } @@ -119,26 +100,75 @@ public class DiagonalLine implements IBuildMode { } else if (rightClickNr == 1) { BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - BlockPos secondPos = Floor.findFloor(player, firstPos, true); + BlockPos secondPos = findSecondPos(player, firstPos, true); if (secondPos == null) return list; + //Limit amount of blocks you can place per row + int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); + + int x1 = firstPos.getX(), x2 = secondPos.getX(); + int y1 = firstPos.getY(), y2 = secondPos.getY(); + int z1 = firstPos.getZ(), z2 = secondPos.getZ(); + + //limit axis + if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; + if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; + if (y2 - y1 >= axisLimit) y2 = y1 + axisLimit - 1; + if (y1 - y2 >= axisLimit) y2 = y1 - axisLimit + 1; + if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; + if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; + //Add diagonal line from first to second - list.addAll(getDiagonalLineBlocks(player , firstPos, secondPos, 10)); + list.addAll(getIntermediateBlocks(player, x1, y1, z1, x2, y2, z2)); } else { BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos secondPos = secondPosTable.get(player.getUniqueID()); - BlockPos thirdPos = findHeight(player, secondPos, skipRaytrace); + BlockPos thirdPos = findThirdPos(player, firstPos, secondPos, skipRaytrace); if (thirdPos == null) return list; + //Limit amount of blocks you can place per row + int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); + + int x1 = firstPos.getX(), x2 = secondPos.getX(), x3 = thirdPos.getX(); + int y1 = firstPos.getY(), y2 = secondPos.getY(), y3 = thirdPos.getY(); + int z1 = firstPos.getZ(), z2 = secondPos.getZ(), z3 = thirdPos.getZ(); + + //limit axis + if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; + if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; + if (y2 - y1 >= axisLimit) y2 = y1 + axisLimit - 1; + if (y1 - y2 >= axisLimit) y2 = y1 - axisLimit + 1; + if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; + if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; + + if (x3 - x1 >= axisLimit) x3 = x1 + axisLimit - 1; + if (x1 - x3 >= axisLimit) x3 = x1 - axisLimit + 1; + if (y3 - y1 >= axisLimit) y3 = y1 + axisLimit - 1; + if (y1 - y3 >= axisLimit) y3 = y1 - axisLimit + 1; + if (z3 - z1 >= axisLimit) z3 = z1 + axisLimit - 1; + if (z1 - z3 >= axisLimit) z3 = z1 - axisLimit + 1; + //Add diagonal line from first to third - list.addAll(getDiagonalLineBlocks(player , firstPos, thirdPos, 10)); + list.addAll(getFinalBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3)); } return list; } - + + //Finds the place of the second block pos + protected abstract BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace); + + //Finds the place of the third block pos + protected abstract BlockPos findThirdPos(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace); + + //After first and second pos are known, we want to visualize the blocks in a way (like floor for cube) + protected abstract List getIntermediateBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2); + + //After first, second and third pos are known, we want all the blocks + protected abstract List getFinalBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3); + //Finds height after floor has been chosen in buildmodes with 3 clicks public static BlockPos findHeight(EntityPlayer player, BlockPos secondPos, boolean skipRaytrace) { Vec3d look = player.getLookVec(); @@ -182,47 +212,4 @@ public class DiagonalLine implements IBuildMode { } return new BlockPos(selected.lineBound); } - - //Add diagonal line from first to second - public static List getDiagonalLineBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, float sampleMultiplier) { - List list = new ArrayList<>(); - - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - int x1 = firstPos.getX(), x2 = secondPos.getX(); - int y1 = firstPos.getY(), y2 = secondPos.getY(); - int z1 = firstPos.getZ(), z2 = secondPos.getZ(); - - //limit axis - if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; - if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; - if (y2 - y1 >= axisLimit) y2 = y1 + axisLimit - 1; - if (y1 - y2 >= axisLimit) y2 = y1 - axisLimit + 1; - if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; - if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; - - Vec3d first = new Vec3d(x1, y1, z1).add(0.5, 0.5, 0.5); - Vec3d second = new Vec3d(x2, y2, z2).add(0.5, 0.5, 0.5); - - int iterations = (int) Math.ceil(first.distanceTo(second) * sampleMultiplier); - for (double t = 0; t <= 1.0; t += 1.0/iterations) { - Vec3d lerp = first.add(second.subtract(first).scale(t)); - BlockPos candidate = new BlockPos(lerp); - //Only add if not equal to the last in the list - if (list.isEmpty() || !list.get(list.size() - 1).equals(candidate)) - list.add(candidate); - } - - return list; - } - - @Override - public EnumFacing getSideHit(EntityPlayer player) { - return sideHitTable.get(player.getUniqueID()); - } - - @Override - public Vec3d getHitVec(EntityPlayer player) { - return hitVecTable.get(player.getUniqueID()); - } -} \ No newline at end of file +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/TwoClicksBuildMode.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/TwoClicksBuildMode.java new file mode 100644 index 0000000..265989f --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/TwoClicksBuildMode.java @@ -0,0 +1,86 @@ +package nl.requios.effortlessbuilding.buildmode; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.helper.ReachHelper; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.List; +import java.util.UUID; + +public abstract class TwoClicksBuildMode extends BaseBuildMode { + + @Override + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { + List list = new ArrayList<>(); + + Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; + int rightClickNr = rightClickTable.get(player.getUniqueID()); + rightClickNr++; + rightClickTable.put(player.getUniqueID(), rightClickNr); + + if (rightClickNr == 1) { + //If clicking in air, reset and try again + if (blockPos == null) { + rightClickTable.put(player.getUniqueID(), 0); + return list; + } + + //First click, remember starting position + firstPosTable.put(player.getUniqueID(), blockPos); + sideHitTable.put(player.getUniqueID(), sideHit); + hitVecTable.put(player.getUniqueID(), hitVec); + //Keep list empty, dont place any blocks yet + } else { + //Second click, place blocks + list = findCoordinates(player, blockPos, skipRaytrace); + rightClickTable.put(player.getUniqueID(), 0); + } + + return list; + } + + @Override + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { + List list = new ArrayList<>(); + Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; + int rightClickNr = rightClickTable.get(player.getUniqueID()); + BlockPos firstPos = firstPosTable.get(player.getUniqueID()); + + if (rightClickNr == 0) { + if (blockPos != null) + list.add(blockPos); + } else { + BlockPos secondPos = findSecondPos(player, firstPos, skipRaytrace); + if (secondPos == null) return list; + + //Limit amount of blocks we can place per row + int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); + + int x1 = firstPos.getX(), x2 = secondPos.getX(); + int y1 = firstPos.getY(), y2 = secondPos.getY(); + int z1 = firstPos.getZ(), z2 = secondPos.getZ(); + + //limit axis + if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; + if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; + if (y2 - y1 >= axisLimit) y2 = y1 + axisLimit - 1; + if (y1 - y2 >= axisLimit) y2 = y1 - axisLimit + 1; + if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; + if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; + + list.addAll(getAllBlocks(player, x1, y1, z1, x2, y2, z2)); + } + + return list; + } + + //Finds the place of the second block pos based on criteria (floor must be on same height as first click, wall on same plane etc) + protected abstract BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace); + + //After first and second pos are known, we want all the blocks + protected abstract List getAllBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2); +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java deleted file mode 100644 index efe6665..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java +++ /dev/null @@ -1,226 +0,0 @@ -package nl.requios.effortlessbuilding.buildmode; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import nl.requios.effortlessbuilding.helper.ReachHelper; - -import java.util.*; - -public class Wall implements IBuildMode { - //In singleplayer client and server variables are shared - //Split everything that needs separate values and may not be called twice in one click - private Dictionary rightClickClientTable = new Hashtable<>(); - private Dictionary rightClickServerTable = new Hashtable<>(); - private Dictionary firstPosTable = new Hashtable<>(); - private Dictionary sideHitTable = new Hashtable<>(); - private Dictionary hitVecTable = new Hashtable<>(); - - static class Criteria { - Vec3d planeBound; - double distToPlayerSq; - double angle; - - Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start, Vec3d look) { - this.planeBound = planeBound; - this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared(); - Vec3d wall = this.planeBound.subtract(new Vec3d(firstPos)); - this.angle = wall.x * look.x + wall.z * look.z; //dot product ignoring y (looking up/down should not affect this angle) - } - - //check if its not behind the player and its not too close and not too far - //also check if raytrace from player to block does not intersect blocks - public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) { - - boolean intersects = false; - if (!skipRaytrace) { - //collision within a 1 block radius to selected is fine - RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, planeBound, false, true, false); - intersects = rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK && - planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4; - } - - return planeBound.subtract(start).dotProduct(look) > 0 && - distToPlayerSq > 2 && distToPlayerSq < reach * reach && - !intersects; - } - } - - @Override - public void initialize(EntityPlayer player) { - rightClickClientTable.put(player.getUniqueID(), 0); - rightClickServerTable.put(player.getUniqueID(), 0); - firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); - sideHitTable.put(player.getUniqueID(), EnumFacing.UP); - hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); - } - - @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { - List list = new ArrayList<>(); - - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - rightClickNr++; - rightClickTable.put(player.getUniqueID(), rightClickNr); - - if (rightClickNr == 1) { - //If clicking in air, reset and try again - if (blockPos == null) { - rightClickTable.put(player.getUniqueID(), 0); - return list; - } - - //First click, remember starting position - firstPosTable.put(player.getUniqueID(), blockPos); - sideHitTable.put(player.getUniqueID(), sideHit); - hitVecTable.put(player.getUniqueID(), hitVec); - //Keep list empty, dont place any blocks yet - } else { - //Second click, place wall - - list = findCoordinates(player, blockPos, skipRaytrace); - rightClickTable.put(player.getUniqueID(), 0); - } - - return list; - } - - @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { - List list = new ArrayList<>(); - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - - if (rightClickNr == 0) { - if (blockPos != null) - list.add(blockPos); - } else { - BlockPos secondPos = findWall(player, firstPos, skipRaytrace); - if (secondPos == null) return list; - - //Add whole wall - list.addAll(getWallBlocks(player, firstPos, secondPos)); - } - - return list; - } - - public static BlockPos findWall(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { - Vec3d look = player.getLookVec(); - Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); - - List criteriaList = new ArrayList<>(3); - - //X - Vec3d xBound = BuildModes.findXBound(firstPos.getX(), start, look); - criteriaList.add(new Criteria(xBound, firstPos, start, look)); - - //Z - Vec3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look); - criteriaList.add(new Criteria(zBound, firstPos, start, look)); - - //Remove invalid criteria - int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach - criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); - - //If none are valid, return empty list of blocks - if (criteriaList.isEmpty()) return null; - - //If only 1 is valid, choose that one - Criteria selected = criteriaList.get(0); - - //If multiple are valid, choose based on criteria - if (criteriaList.size() > 1) { - //Select the one that is closest - //Limit the angle to not be too extreme - for (int i = 1; i < criteriaList.size(); i++) { - Criteria criteria = criteriaList.get(i); - if (criteria.distToPlayerSq < selected.distToPlayerSq && Math.abs(criteria.angle) - Math.abs(selected.angle) < 3) - selected = criteria; - } - } - - return new BlockPos(selected.planeBound); - } - - public static List getWallBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos) { - List list = new ArrayList<>(); - - //Limit amount of blocks we can place per row - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - int x1 = firstPos.getX(), x2 = secondPos.getX(); - int y1 = firstPos.getY(), y2 = secondPos.getY(); - int z1 = firstPos.getZ(), z2 = secondPos.getZ(); - - //limit axis - if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; - if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; - if (y2 - y1 >= axisLimit) y2 = y1 + axisLimit - 1; - if (y1 - y2 >= axisLimit) y2 = y1 - axisLimit + 1; - if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; - if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; - - if (x1 == x2) { - if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) - addXWallBlocks(list, x1, y1, y2, z1, z2); - else - addXHollowWallBlocks(list, x1, y1, y2, z1, z2); - } else { - if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) - addZWallBlocks(list, x1, x2, y1, y2, z1); - else - addZHollowWallBlocks(list, x1, x2, y1, y2, z1); - } - - return list; - } - - public static void addXWallBlocks(List list, int x, int y1, int y2, int z1, int z2) { - - for (int z = z1; z1 < z2 ? z <= z2 : z >= z2; z += z1 < z2 ? 1 : -1) { - - for (int y = y1; y1 < y2 ? y <= y2 : y >= y2; y += y1 < y2 ? 1 : -1) { - list.add(new BlockPos(x, y, z)); - } - } - } - - public static void addZWallBlocks(List list, int x1, int x2, int y1, int y2, int z) { - - for (int x = x1; x1 < x2 ? x <= x2 : x >= x2; x += x1 < x2 ? 1 : -1) { - - for (int y = y1; y1 < y2 ? y <= y2 : y >= y2; y += y1 < y2 ? 1 : -1) { - list.add(new BlockPos(x, y, z)); - } - } - } - - public static void addXHollowWallBlocks(List list, int x, int y1, int y2, int z1, int z2) { - Line.addZLineBlocks(list, z1, z2, x, y1); - Line.addZLineBlocks(list, z1, z2, x, y2); - Line.addYLineBlocks(list, y1, y2, x, z1); - Line.addYLineBlocks(list, y1, y2, x, z2); - } - - public static void addZHollowWallBlocks(List list, int x1, int x2, int y1, int y2, int z) { - Line.addXLineBlocks(list, x1, x2, y1, z); - Line.addXLineBlocks(list, x1, x2, y2, z); - Line.addYLineBlocks(list, y1, y2, x1, z); - Line.addYLineBlocks(list, y1, y2, x2, z); - } - - @Override - public EnumFacing getSideHit(EntityPlayer player) { - return sideHitTable.get(player.getUniqueID()); - } - - @Override - public Vec3d getHitVec(EntityPlayer player) { - return hitVecTable.get(player.getUniqueID()); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Circle.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Circle.java new file mode 100644 index 0000000..853a99c --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Circle.java @@ -0,0 +1,88 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; + +import java.util.*; + +public class Circle extends TwoClicksBuildMode { + + @Override + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return Floor.findFloor(player, firstPos, skipRaytrace); + } + + @Override + protected List getAllBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return getCircleBlocks(player, x1, y1, z1, x2, y2, z2); + } + + public static List getCircleBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + List list = new ArrayList<>(); + + float centerX = x1; + float centerZ = z1; + + //Adjust for CIRCLE_START + if (ModeOptions.getCircleStart() == ModeOptions.ActionEnum.CIRCLE_START_CORNER) { + centerX = x1 + (x2 - x1) / 2f; + centerZ = z1 + (z2 - z1) / 2f; + } else { + x1 = (int) (centerX - (x2 - centerX)); + z1 = (int) (centerZ - (z2 - centerZ)); + } + + float radiusX = MathHelper.abs(x2 - centerX); + float radiusZ = MathHelper.abs(z2 - centerZ); + + if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) + addCircleBlocks(list, x1, y1, z1, x2, y2, z2, centerX, centerZ, radiusX, radiusZ); + else + addHollowCircleBlocks(list, x1, y1, z1, x2, y2, z2, centerX, centerZ, radiusX, radiusZ, 1f); + + return list; + } + + public static void addCircleBlocks(List list, int x1, int y1, int z1, int x2, int y2, int z2, float centerX, float centerZ, float radiusX, float radiusZ) { + + for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { + + for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { + + float distance = distance(l, n, centerX, centerZ); + float radius = calculateEllipseRadius(centerX, centerZ, radiusX, radiusZ, l, n); + if (distance < radius + 0.5f) + list.add(new BlockPos(l, y1, n)); + } + } + } + + public static void addHollowCircleBlocks(List list, int x1, int y1, int z1, int x2, int y2, int z2, float centerX, float centerZ, float radiusX, float radiusZ, float thickness) { + + for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { + + for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { + + float distance = distance(l, n, centerX, centerZ); + float radius = calculateEllipseRadius(centerX, centerZ, radiusX, radiusZ, l, n); + if (distance < radius + (thickness / 2f) && distance > radius - (thickness / 2f)) + list.add(new BlockPos(l, y1, n)); + } + } + } + + private static float distance(float x1, float z1, float x2, float z2) { + return MathHelper.sqrt((z2 - z1) * (z2 - z1) + (x2 - x1) * (x2 - x1)); + } + + public static float calculateEllipseRadius(float centerX, float centerZ, float radiusX, float radiusZ, int x, int z) { + //https://math.stackexchange.com/questions/432902/how-to-get-the-radius-of-an-ellipse-at-a-specific-angle-by-knowing-its-semi-majo + float theta = (float) MathHelper.atan2(z - centerZ, x - centerX); + float part1 = radiusX * radiusX * MathHelper.sin(theta) * MathHelper.sin(theta); + float part2 = radiusZ * radiusZ * MathHelper.cos(theta) * MathHelper.cos(theta); + return radiusX * radiusZ / MathHelper.sqrt(part1 + part2); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cube.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cube.java new file mode 100644 index 0000000..95914b2 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cube.java @@ -0,0 +1,104 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.IBuildMode; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; +import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; +import nl.requios.effortlessbuilding.helper.ReachHelper; + +import java.util.*; + +public class Cube extends ThreeClicksBuildMode { + + @Override + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return Floor.findFloor(player, firstPos, skipRaytrace); + } + + @Override + protected BlockPos findThirdPos(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) { + return findHeight(player, secondPos, skipRaytrace); + } + + @Override + protected List getIntermediateBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return getFloorBlocksUsingCubeFill(player, x1, y1, z1, x2, y2, z2); + } + + @Override + protected List getFinalBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + return getCubeBlocks(player, x1, y1, z1, x3, y3, z3); + } + + public static List getFloorBlocksUsingCubeFill(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + List list = new ArrayList<>(); + + if (ModeOptions.getCubeFill() == ModeOptions.ActionEnum.CUBE_SKELETON) + Floor.addHollowFloorBlocks(list, x1, x2, y1, z1, z2); + else + Floor.addFloorBlocks(list, x1, x2, y1, z1, z2); + + return list; + } + + public static List getCubeBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + List list = new ArrayList<>(); + + switch (ModeOptions.getCubeFill()) { + case CUBE_FULL: + addCubeBlocks(list, x1, x2, y1, y2, z1, z2); + break; + case CUBE_HOLLOW: + addHollowCubeBlocks(list, x1, x2, y1, y2, z1, z2); + break; + case CUBE_SKELETON: + addSkeletonCubeBlocks(list, x1, x2, y1, y2, z1, z2); + break; + } + + return list; + } + + public static void addCubeBlocks(List list, int x1, int x2, int y1, int y2, int z1, int z2) { + for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { + + for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { + + for (int m = y1; y1 < y2 ? m <= y2 : m >= y2; m += y1 < y2 ? 1 : -1) { + list.add(new BlockPos(l, m, n)); + } + } + } + } + + public static void addHollowCubeBlocks(List list, int x1, int x2, int y1, int y2, int z1, int z2) { + Wall.addXWallBlocks(list, x1, y1, y2, z1, z2); + Wall.addXWallBlocks(list, x2, y1, y2, z1, z2); + + Wall.addZWallBlocks(list, x1, x2, y1, y2, z1); + Wall.addZWallBlocks(list, x1, x2, y1, y2, z2); + + Floor.addFloorBlocks(list, x1, x2, y1, z1, z2); + Floor.addFloorBlocks(list, x1, x2, y2, z1, z2); + } + + public static void addSkeletonCubeBlocks(List list, int x1, int x2, int y1, int y2, int z1, int z2) { + Line.addXLineBlocks(list, x1, x2, y1, z1); + Line.addXLineBlocks(list, x1, x2, y1, z2); + Line.addXLineBlocks(list, x1, x2, y2, z1); + Line.addXLineBlocks(list, x1, x2, y2, z2); + + Line.addYLineBlocks(list, y1, y2, x1, z1); + Line.addYLineBlocks(list, y1, y2, x1, z2); + Line.addYLineBlocks(list, y1, y2, x2, z1); + Line.addYLineBlocks(list, y1, y2, x2, z2); + + Line.addZLineBlocks(list, z1, z2, x1, y1); + Line.addZLineBlocks(list, z1, z2, x1, y2); + Line.addZLineBlocks(list, z1, z2, x2, y1); + Line.addZLineBlocks(list, z1, z2, x2, y2); + } +} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cylinder.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cylinder.java new file mode 100644 index 0000000..c57b62f --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Cylinder.java @@ -0,0 +1,50 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; + +import java.util.ArrayList; +import java.util.List; + +public class Cylinder extends ThreeClicksBuildMode { + + @Override + public BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return Floor.findFloor(player, firstPos, skipRaytrace); + } + + @Override + public BlockPos findThirdPos(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) { + return findHeight(player, secondPos, skipRaytrace); + } + + @Override + public List getIntermediateBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return Circle.getCircleBlocks(player, x1, y1, z1, x2, y2, z2); + } + + @Override + public List getFinalBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + return getCylinderBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3); + } + + public static List getCylinderBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + List list = new ArrayList<>(); + + //Get circle blocks (using CIRCLE_START and FILL options built-in) + List circleBlocks = Circle.getCircleBlocks(player, x1, y1, z1, x2, y2, z2); + + int lowest = Math.min(y1, y3); + int highest = Math.max(y1, y3); + + //Copy circle on y axis + for (int y = lowest; y <= highest; y++) { + for (BlockPos blockPos : circleBlocks) { + list.add(new BlockPos(blockPos.getX(), y, blockPos.getZ())); + } + } + + return list; + } +} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalLine.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalLine.java new file mode 100644 index 0000000..e95fa38 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalLine.java @@ -0,0 +1,54 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; +import nl.requios.effortlessbuilding.helper.ReachHelper; + +import java.util.ArrayList; +import java.util.List; + +public class DiagonalLine extends ThreeClicksBuildMode { + + @Override + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return Floor.findFloor(player, firstPos, skipRaytrace); + } + + @Override + protected BlockPos findThirdPos(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) { + return findHeight(player, secondPos, skipRaytrace); + } + + @Override + protected List getIntermediateBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + //Add diagonal line from first to second + return getDiagonalLineBlocks(player, x1, y1, z1, x2, y2, z2, 10); + } + + @Override + protected List getFinalBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + //Add diagonal line from first to third + return getDiagonalLineBlocks(player, x1, y1, z1, x3, y3, z3, 10); + } + + //Add diagonal line from first to second + public static List getDiagonalLineBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, float sampleMultiplier) { + List list = new ArrayList<>(); + + Vec3d first = new Vec3d(x1, y1, z1).add(0.5, 0.5, 0.5); + Vec3d second = new Vec3d(x2, y2, z2).add(0.5, 0.5, 0.5); + + int iterations = (int) Math.ceil(first.distanceTo(second) * sampleMultiplier); + for (double t = 0; t <= 1.0; t += 1.0/iterations) { + Vec3d lerp = first.add(second.subtract(first).scale(t)); + BlockPos candidate = new BlockPos(lerp); + //Only add if not equal to the last in the list + if (list.isEmpty() || !list.get(list.size() - 1).equals(candidate)) + list.add(candidate); + } + + return list; + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalWall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalWall.java new file mode 100644 index 0000000..6a4cebb --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/DiagonalWall.java @@ -0,0 +1,52 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; +import nl.requios.effortlessbuilding.helper.ReachHelper; + +import java.util.ArrayList; +import java.util.List; + +public class DiagonalWall extends ThreeClicksBuildMode { + + @Override + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return Floor.findFloor(player, firstPos, skipRaytrace); + } + + @Override + protected BlockPos findThirdPos(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) { + return findHeight(player, secondPos, skipRaytrace); + } + + @Override + protected List getIntermediateBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return DiagonalLine.getDiagonalLineBlocks(player, x1, y1, z1, x2, y2, z2, 1); + } + + @Override + protected List getFinalBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + return getDiagonalWallBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3); + } + + //Add diagonal wall from first to second + public static List getDiagonalWallBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + List list = new ArrayList<>(); + + //Get diagonal line blocks + List diagonalLineBlocks = DiagonalLine.getDiagonalLineBlocks(player, x1, y1, z1, x2, y2, z2, 1); + + int lowest = Math.min(y1, y3); + int highest = Math.max(y1, y3); + + //Copy diagonal line on y axis + for (int y = lowest; y <= highest; y++) { + for (BlockPos blockPos : diagonalLineBlocks) { + list.add(new BlockPos(blockPos.getX(), y, blockPos.getZ())); + } + } + + return list; + } +} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Floor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Floor.java new file mode 100644 index 0000000..89f4d04 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Floor.java @@ -0,0 +1,93 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.BuildModes; +import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; +import nl.requios.effortlessbuilding.helper.ReachHelper; + +import java.util.*; + +public class Floor extends TwoClicksBuildMode { + + static class Criteria { + Vec3d planeBound; + double distToPlayerSq; + + Criteria(Vec3d planeBound, Vec3d start) { + this.planeBound = planeBound; + this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared(); + } + + //check if its not behind the player and its not too close and not too far + //also check if raytrace from player to block does not intersect blocks + public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) { + + return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, planeBound, planeBound, distToPlayerSq); + } + } + + @Override + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return findFloor(player, firstPos, skipRaytrace); + } + + public static BlockPos findFloor(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + Vec3d look = player.getLookVec(); + Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); + + List criteriaList = new ArrayList<>(3); + + //Y + Vec3d yBound = BuildModes.findYBound(firstPos.getY(), start, look); + criteriaList.add(new Criteria(yBound, start)); + + //Remove invalid criteria + int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach + criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); + + //If none are valid, return empty list of blocks + if (criteriaList.isEmpty()) return null; + + //Then only 1 can be valid, return that one + Criteria selected = criteriaList.get(0); + + return new BlockPos(selected.planeBound); + } + + @Override + protected List getAllBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return getFloorBlocks(player, x1, y1, z1, x2, y2, z2); + } + + public static List getFloorBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + List list = new ArrayList<>(); + + if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) + addFloorBlocks(list, x1, x2, y1, z1, z2); + else + addHollowFloorBlocks(list, x1, x2, y1, z1, z2); + + return list; + } + + public static void addFloorBlocks(List list, int x1, int x2, int y, int z1, int z2) { + + for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { + + for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { + + list.add(new BlockPos(l, y, n)); + } + } + } + + public static void addHollowFloorBlocks(List list, int x1, int x2, int y, int z1, int z2) { + Line.addXLineBlocks(list, x1, x2, y, z1); + Line.addXLineBlocks(list, x1, x2, y, z2); + Line.addZLineBlocks(list, z1, z2, x1, y); + Line.addZLineBlocks(list, z1, z2, x2, y); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Line.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Line.java similarity index 52% rename from src/main/java/nl/requios/effortlessbuilding/buildmode/Line.java rename to src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Line.java index 2da9bc1..5d0e3ad 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Line.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Line.java @@ -1,22 +1,16 @@ -package nl.requios.effortlessbuilding.buildmode; +package nl.requios.effortlessbuilding.buildmode.buildmodes; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.BuildModes; +import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; import nl.requios.effortlessbuilding.helper.ReachHelper; -import java.util.*; +import java.util.ArrayList; +import java.util.List; -public class Line implements IBuildMode { - //In singleplayer client and server variables are shared - //Split everything that needs separate values and may not be called twice in one click - private Dictionary rightClickClientTable = new Hashtable<>(); - private Dictionary rightClickServerTable = new Hashtable<>(); - private Dictionary firstPosTable = new Hashtable<>(); - private Dictionary sideHitTable = new Hashtable<>(); - private Dictionary hitVecTable = new Hashtable<>(); +public class Line extends TwoClicksBuildMode { static class Criteria { Vec3d planeBound; @@ -55,78 +49,14 @@ public class Line implements IBuildMode { //also check if raytrace from player to block does not intersect blocks public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) { - boolean intersects = false; - if (!skipRaytrace) { - //collision within a 1 block radius to selected is fine - RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, lineBound, false, true, false); - intersects = rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK && - planeBound.subtract(rayTraceResult.hitVec).lengthSquared() > 4; - } - - return planeBound.subtract(start).dotProduct(look) > 0 && - distToPlayerSq > 2 && distToPlayerSq < reach * reach && - !intersects; + return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq); } + } @Override - public void initialize(EntityPlayer player) { - rightClickClientTable.put(player.getUniqueID(), 0); - rightClickServerTable.put(player.getUniqueID(), 0); - firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN); - sideHitTable.put(player.getUniqueID(), EnumFacing.UP); - hitVecTable.put(player.getUniqueID(), Vec3d.ZERO); - } - - @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { - List list = new ArrayList<>(); - - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - rightClickNr++; - rightClickTable.put(player.getUniqueID(), rightClickNr); - - if (rightClickNr == 1) { - //If clicking in air, reset and try again - if (blockPos == null) { - rightClickTable.put(player.getUniqueID(), 0); - return list; - } - - //First click, remember starting position - firstPosTable.put(player.getUniqueID(), blockPos); - sideHitTable.put(player.getUniqueID(), sideHit); - hitVecTable.put(player.getUniqueID(), hitVec); - //Keep list empty, dont place any blocks yet - } else { - //Second click, place wall - - list = findCoordinates(player, blockPos, skipRaytrace); - rightClickTable.put(player.getUniqueID(), 0); - } - - return list; - } - - @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { - List list = new ArrayList<>(); - Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; - int rightClickNr = rightClickTable.get(player.getUniqueID()); - BlockPos firstPos = firstPosTable.get(player.getUniqueID()); - - if (rightClickNr == 0) { - if (blockPos != null) - list.add(blockPos); - } else { - BlockPos secondPos = findLine(player, firstPos, skipRaytrace); - if (secondPos == null) return list; - - list.addAll(getLineBlocks(player, firstPos, secondPos)); - } - - return list; + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return findLine(player, firstPos, skipRaytrace); } public static BlockPos findLine(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { @@ -178,25 +108,14 @@ public class Line implements IBuildMode { return new BlockPos(selected.lineBound); } - public static List getLineBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos) { + @Override + protected List getAllBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return getLineBlocks(player, x1, y1, z1, x2, y2, z2); + } + + public static List getLineBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { List list = new ArrayList<>(); - //Limit amount of blocks we can place - int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); - - //Add whole line - int x1 = firstPos.getX(), x2 = secondPos.getX(); - int y1 = firstPos.getY(), y2 = secondPos.getY(); - int z1 = firstPos.getZ(), z2 = secondPos.getZ(); - - //limit axis - if (x2 - x1 >= axisLimit) x2 = x1 + axisLimit - 1; - if (x1 - x2 >= axisLimit) x2 = x1 - axisLimit + 1; - if (y2 - y1 >= axisLimit) y2 = y1 + axisLimit - 1; - if (y1 - y2 >= axisLimit) y2 = y1 - axisLimit + 1; - if (z2 - z1 >= axisLimit) z2 = z1 + axisLimit - 1; - if (z1 - z2 >= axisLimit) z2 = z1 - axisLimit + 1; - if (x1 != x2) { addXLineBlocks(list, x1, x2, y1, z1); } else if (y1 != y2) { @@ -225,15 +144,4 @@ public class Line implements IBuildMode { list.add(new BlockPos(x, y, z)); } } - - @Override - public EnumFacing getSideHit(EntityPlayer player) { - return sideHitTable.get(player.getUniqueID()); - } - - @Override - public Vec3d getHitVec(EntityPlayer player) { - return hitVecTable.get(player.getUniqueID()); - } - } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Normal.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Normal.java similarity index 89% rename from src/main/java/nl/requios/effortlessbuilding/buildmode/Normal.java rename to src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Normal.java index 430cb1b..f917a32 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Normal.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Normal.java @@ -1,9 +1,10 @@ -package nl.requios.effortlessbuilding.buildmode; +package nl.requios.effortlessbuilding.buildmode.buildmodes; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.IBuildMode; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/NormalPlus.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/NormalPlus.java similarity index 89% rename from src/main/java/nl/requios/effortlessbuilding/buildmode/NormalPlus.java rename to src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/NormalPlus.java index a503efa..63ec7e5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/NormalPlus.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/NormalPlus.java @@ -1,9 +1,10 @@ -package nl.requios.effortlessbuilding.buildmode; +package nl.requios.effortlessbuilding.buildmode.buildmodes; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.IBuildMode; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/SlopeFloor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/SlopeFloor.java new file mode 100644 index 0000000..df7c78e --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/SlopeFloor.java @@ -0,0 +1,95 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; +import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; +import nl.requios.effortlessbuilding.helper.ReachHelper; + +import java.util.ArrayList; +import java.util.List; + +public class SlopeFloor extends ThreeClicksBuildMode { + + @Override + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return Floor.findFloor(player, firstPos, skipRaytrace); + } + + @Override + protected BlockPos findThirdPos(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) { + return findHeight(player, secondPos, skipRaytrace); + } + + @Override + protected List getIntermediateBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return Floor.getFloorBlocks(player, x1, y1, z1, x2, y2, z2); + } + + @Override + protected List getFinalBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + return getSlopeFloorBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3); + } + + //Add slope floor from first to second + public static List getSlopeFloorBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + List list = new ArrayList<>(); + + int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); + + //Determine whether to use x or z axis to slope up + boolean onXAxis = true; + + int xLength = Math.abs(x2 - x1); + int zLength = Math.abs(z2 - z1); + + if (ModeOptions.getRaisedEdge() == ModeOptions.ActionEnum.SHORT_EDGE) { + //Slope along short edge + if (zLength > xLength) onXAxis = false; + } else { + //Slope along long edge + if (zLength <= xLength) onXAxis = false; + } + + if (onXAxis) { + //Along X goes up + + //Get diagonal line blocks + List diagonalLineBlocks = DiagonalLine.getDiagonalLineBlocks(player, x1, y1, z1, x2, y3, z1, 1f); + + //Limit amount of blocks we can place + int lowest = Math.min(z1, z2); + int highest = Math.max(z1, z2); + + if (highest - lowest >= axisLimit) highest = lowest + axisLimit - 1; + + //Copy diagonal line on x axis + for (int z = lowest; z <= highest; z++) { + for (BlockPos blockPos : diagonalLineBlocks) { + list.add(new BlockPos(blockPos.getX(), blockPos.getY(), z)); + } + } + + } else { + //Along Z goes up + + //Get diagonal line blocks + List diagonalLineBlocks = DiagonalLine.getDiagonalLineBlocks(player, x1, y1, z1, x1, y3, z2, 1f); + + //Limit amount of blocks we can place + int lowest = Math.min(x1, x2); + int highest = Math.max(x1, x2); + + if (highest - lowest >= axisLimit) highest = lowest + axisLimit - 1; + + //Copy diagonal line on x axis + for (int x = lowest; x <= highest; x++) { + for (BlockPos blockPos : diagonalLineBlocks) { + list.add(new BlockPos(x, blockPos.getY(), blockPos.getZ())); + } + } + } + + return list; + } +} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Sphere.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Sphere.java new file mode 100644 index 0000000..8483653 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Sphere.java @@ -0,0 +1,69 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; +import nl.requios.effortlessbuilding.buildmode.ThreeClicksBuildMode; + +import java.util.ArrayList; +import java.util.List; + +public class Sphere extends ThreeClicksBuildMode { + + @Override + public BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return Floor.findFloor(player, firstPos, skipRaytrace); + } + + @Override + public BlockPos findThirdPos(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, boolean skipRaytrace) { + return findHeight(player, secondPos, skipRaytrace); + } + + @Override + public List getIntermediateBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return Circle.getCircleBlocks(player, x1, y1, z1, x2, y2, z2); + } + + @Override + public List getFinalBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + return getSphereBlocks(player, x1, y1, z1, x2, y2, z2, x3, y3, z3); + } + + public static List getSphereBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) { + List list = new ArrayList<>(); + +// float centerX = x1; +// float centerZ = z1; +// +// //Adjust for CIRCLE_START +// if (ModeOptions.getCircleStart() == ModeOptions.ActionEnum.CIRCLE_START_CORNER) { +// centerX = x1 + (x2 - x1) / 2f; +// centerZ = z1 + (z2 - z1) / 2f; +// } else { +// x1 = (int) (centerX - (x2 - centerX)); +// z1 = (int) (centerZ - (z2 - centerZ)); +// } +// +// float radiusX = MathHelper.abs(x2 - centerX); +// float radiusZ = MathHelper.abs(z2 - centerZ); +// +// if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) +// addCircleBlocks(list, x1, y1, z1, x2, y2, z2, centerX, centerZ, radiusX, radiusZ); +// else +// addHollowCircleBlocks(list, x1, y1, z1, x2, y2, z2, centerX, centerZ, radiusX, radiusZ, 1f); +// +// return list; + + //Adjust for CIRCLE_START + + //Get center point + + //Get radius + + //Get blocks based on FILL + + return list; + } +} \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Wall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Wall.java new file mode 100644 index 0000000..60da58b --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/buildmodes/Wall.java @@ -0,0 +1,134 @@ +package nl.requios.effortlessbuilding.buildmode.buildmodes; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import nl.requios.effortlessbuilding.buildmode.BuildModes; +import nl.requios.effortlessbuilding.buildmode.TwoClicksBuildMode; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; +import nl.requios.effortlessbuilding.helper.ReachHelper; + +import java.util.*; + +public class Wall extends TwoClicksBuildMode { + + static class Criteria { + Vec3d planeBound; + double distToPlayerSq; + double angle; + + Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start, Vec3d look) { + this.planeBound = planeBound; + this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared(); + Vec3d wall = this.planeBound.subtract(new Vec3d(firstPos)); + this.angle = wall.x * look.x + wall.z * look.z; //dot product ignoring y (looking up/down should not affect this angle) + } + + //check if its not behind the player and its not too close and not too far + //also check if raytrace from player to block does not intersect blocks + public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) { + + return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, planeBound, planeBound, distToPlayerSq); + } + } + + @Override + protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + return findWall(player, firstPos, skipRaytrace); + } + + public static BlockPos findWall(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) { + Vec3d look = player.getLookVec(); + Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); + + List criteriaList = new ArrayList<>(3); + + //X + Vec3d xBound = BuildModes.findXBound(firstPos.getX(), start, look); + criteriaList.add(new Criteria(xBound, firstPos, start, look)); + + //Z + Vec3d zBound = BuildModes.findZBound(firstPos.getZ(), start, look); + criteriaList.add(new Criteria(zBound, firstPos, start, look)); + + //Remove invalid criteria + int reach = ReachHelper.getPlacementReach(player) * 4; //4 times as much as normal placement reach + criteriaList.removeIf(criteria -> !criteria.isValid(start, look, reach, player, skipRaytrace)); + + //If none are valid, return empty list of blocks + if (criteriaList.isEmpty()) return null; + + //If only 1 is valid, choose that one + Criteria selected = criteriaList.get(0); + + //If multiple are valid, choose based on criteria + if (criteriaList.size() > 1) { + //Select the one that is closest + //Limit the angle to not be too extreme + for (int i = 1; i < criteriaList.size(); i++) { + Criteria criteria = criteriaList.get(i); + if (criteria.distToPlayerSq < selected.distToPlayerSq && Math.abs(criteria.angle) - Math.abs(selected.angle) < 3) + selected = criteria; + } + } + + return new BlockPos(selected.planeBound); + } + + @Override + protected List getAllBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + return getWallBlocks(player, x1, y1, z1, x2, y2, z2); + } + + public static List getWallBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) { + List list = new ArrayList<>(); + + if (x1 == x2) { + if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) + addXWallBlocks(list, x1, y1, y2, z1, z2); + else + addXHollowWallBlocks(list, x1, y1, y2, z1, z2); + } else { + if (ModeOptions.getFill() == ModeOptions.ActionEnum.FULL) + addZWallBlocks(list, x1, x2, y1, y2, z1); + else + addZHollowWallBlocks(list, x1, x2, y1, y2, z1); + } + + return list; + } + + public static void addXWallBlocks(List list, int x, int y1, int y2, int z1, int z2) { + + for (int z = z1; z1 < z2 ? z <= z2 : z >= z2; z += z1 < z2 ? 1 : -1) { + + for (int y = y1; y1 < y2 ? y <= y2 : y >= y2; y += y1 < y2 ? 1 : -1) { + list.add(new BlockPos(x, y, z)); + } + } + } + + public static void addZWallBlocks(List list, int x1, int x2, int y1, int y2, int z) { + + for (int x = x1; x1 < x2 ? x <= x2 : x >= x2; x += x1 < x2 ? 1 : -1) { + + for (int y = y1; y1 < y2 ? y <= y2 : y >= y2; y += y1 < y2 ? 1 : -1) { + list.add(new BlockPos(x, y, z)); + } + } + } + + public static void addXHollowWallBlocks(List list, int x, int y1, int y2, int z1, int z2) { + Line.addZLineBlocks(list, z1, z2, x, y1); + Line.addZLineBlocks(list, z1, z2, x, y2); + Line.addYLineBlocks(list, y1, y2, x, z1); + Line.addYLineBlocks(list, y1, y2, x, z2); + } + + public static void addZHollowWallBlocks(List list, int x1, int x2, int y1, int y2, int z) { + Line.addXLineBlocks(list, x1, x2, y1, z); + Line.addXLineBlocks(list, x1, x2, y2, z); + Line.addYLineBlocks(list, y1, y2, x1, z); + Line.addYLineBlocks(list, y1, y2, x2, z); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java index 1fcdcdb..693a5a0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java @@ -4,6 +4,7 @@ import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; @@ -11,6 +12,7 @@ import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.InventoryHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; @@ -87,7 +89,6 @@ public class BuildModifiers { BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1); UndoRedo.addUndo(player, new BlockSet(coordinates, previousBlockStates, newBlockStates, hitVec, firstPos, secondPos)); } - } public static void onBlockBroken(EntityPlayer player, List startCoordinates, boolean breakStartPos) { @@ -108,7 +109,7 @@ public class BuildModifiers { BlockPreviewRenderer.onBlocksBroken(); //list of air blockstates - for (BlockPos coordinate : coordinates) { + for (int i = 0; i < coordinates.size(); i++) { newBlockStates.add(Blocks.AIR.getDefaultState()); } @@ -235,8 +236,8 @@ public class BuildModifiers { } public static IBlockState getBlockStateFromItem(ItemStack itemStack, EntityPlayer player, BlockPos blockPos, EnumFacing facing, Vec3d hitVec, EnumHand hand) { - return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(player.world, blockPos, facing, - ((float) hitVec.x), ((float) hitVec.y), ((float) hitVec.z), itemStack.getMetadata(), player, hand); + return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(new BlockItemUseContext(player.world, player, itemStack, blockPos, facing, + ((float) hitVec.x), ((float) hitVec.y), ((float) hitVec.z))); } //Returns true if equal (or both null) diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java index 34a9b21..7b5c850 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java @@ -7,6 +7,8 @@ import net.minecraft.block.BlockStairs; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.state.properties.Half; +import net.minecraft.state.properties.SlabType; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; @@ -118,7 +120,7 @@ public class Mirror { } //Find blockstate - IBlockState newBlockState = oldBlockState == null ? null : oldBlockState.withMirror(net.minecraft.util.Mirror.FRONT_BACK); + IBlockState newBlockState = oldBlockState == null ? null : oldBlockState.mirror(net.minecraft.util.Mirror.FRONT_BACK); //Store blockstate and itemstack blockStates.add(newBlockState); @@ -163,7 +165,7 @@ public class Mirror { } //Find blockstate - IBlockState newBlockState = oldBlockState == null ? null : oldBlockState.withMirror(net.minecraft.util.Mirror.LEFT_RIGHT); + IBlockState newBlockState = oldBlockState == null ? null : oldBlockState.mirror(net.minecraft.util.Mirror.LEFT_RIGHT); //Store blockstate and itemstack blockStates.add(newBlockState); @@ -185,38 +187,39 @@ public class Mirror { private static IBlockState getVerticalMirror(IBlockState blockState) { //Stairs if (blockState.getBlock() instanceof BlockStairs) { - if (blockState.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.BOTTOM) { - return blockState.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP); + if (blockState.get(BlockStairs.HALF) == Half.BOTTOM) { + return blockState.with(BlockStairs.HALF, Half.TOP); } else { - return blockState.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.BOTTOM); + return blockState.with(BlockStairs.HALF, Half.BOTTOM); } } //Slabs if (blockState.getBlock() instanceof BlockSlab) { - if (((BlockSlab) blockState.getBlock()).isDouble()) return blockState; - if (blockState.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) { - return blockState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP); + if (blockState.get(BlockSlab.TYPE) == SlabType.DOUBLE) { + return blockState; + } else if (blockState.get(BlockSlab.TYPE) == SlabType.BOTTOM) { + return blockState.with(BlockSlab.TYPE, SlabType.TOP); } else { - return blockState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.BOTTOM); + return blockState.with(BlockSlab.TYPE, SlabType.BOTTOM); } } //Buttons, endrod, observer, piston if (blockState.getBlock() instanceof BlockDirectional) { - if (blockState.getValue(BlockDirectional.FACING) == EnumFacing.DOWN) { - return blockState.withProperty(BlockDirectional.FACING, EnumFacing.UP); - } else if (blockState.getValue(BlockDirectional.FACING) == EnumFacing.UP) { - return blockState.withProperty(BlockDirectional.FACING, EnumFacing.DOWN); + if (blockState.get(BlockDirectional.FACING) == EnumFacing.DOWN) { + return blockState.with(BlockDirectional.FACING, EnumFacing.UP); + } else if (blockState.get(BlockDirectional.FACING) == EnumFacing.UP) { + return blockState.with(BlockDirectional.FACING, EnumFacing.DOWN); } } //Dispenser, dropper if (blockState.getBlock() instanceof BlockDispenser) { - if (blockState.getValue(BlockDispenser.FACING) == EnumFacing.DOWN) { - return blockState.withProperty(BlockDispenser.FACING, EnumFacing.UP); - } else if (blockState.getValue(BlockDispenser.FACING) == EnumFacing.UP) { - return blockState.withProperty(BlockDispenser.FACING, EnumFacing.DOWN); + if (blockState.get(BlockDispenser.FACING) == EnumFacing.DOWN) { + return blockState.with(BlockDispenser.FACING, EnumFacing.UP); + } else if (blockState.get(BlockDispenser.FACING) == EnumFacing.UP) { + return blockState.with(BlockDispenser.FACING, EnumFacing.DOWN); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java index 1d7bdfc..690f6b9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java @@ -2,28 +2,42 @@ package nl.requios.effortlessbuilding.buildmodifier; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.network.PacketDistributor; import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; +import nl.requios.effortlessbuilding.network.PacketHandler; + +import javax.annotation.Nonnull; +import java.util.HashMap; +import java.util.UUID; @Mod.EventBusSubscriber public class ModifierSettingsManager { //Retrieves the buildsettings of a player through the modifierCapability capability //Never returns null + @Nonnull public static ModifierSettings getModifierSettings(EntityPlayer player){ - if (player.hasCapability(ModifierCapabilityManager.modifierCapability, null)) { - ModifierCapabilityManager.IModifierCapability capability = player.getCapability( - ModifierCapabilityManager.modifierCapability, null); + LazyOptional modifierCapability = + player.getCapability(ModifierCapabilityManager.modifierCapability, null); + + if (modifierCapability.isPresent()) { + ModifierCapabilityManager.IModifierCapability capability = modifierCapability.orElse(null); if (capability.getModifierData() == null) { capability.setModifierData(new ModifierSettings()); } return capability.getModifierData(); } - throw new IllegalArgumentException("Player does not have modifierCapability capability"); + + //Player does not have modifierCapability capability + //Return dummy settings + return new ModifierSettings(); +// throw new IllegalArgumentException("Player does not have modifierCapability capability"); } public static void setModifierSettings(EntityPlayer player, ModifierSettings modifierSettings) { @@ -31,11 +45,15 @@ public class ModifierSettingsManager { EffortlessBuilding.log("Cannot set buildsettings, player is null"); return; } - if (player.hasCapability(ModifierCapabilityManager.modifierCapability, null)) { - ModifierCapabilityManager.IModifierCapability capability = player.getCapability( - ModifierCapabilityManager.modifierCapability, null); + + LazyOptional modifierCapability = + player.getCapability(ModifierCapabilityManager.modifierCapability, null); + + modifierCapability.ifPresent((capability) -> { capability.setModifierData(modifierSettings); - } else { + }); + + if (!modifierCapability.isPresent()) { EffortlessBuilding.log(player, "Saving buildsettings failed."); } } @@ -163,33 +181,28 @@ public class ModifierSettingsManager { //Set mirror radius to max int reach = 10; switch (reachUpgrade) { - case 0: reach = BuildConfig.reach.maxReachLevel0; break; - case 1: reach = BuildConfig.reach.maxReachLevel1; break; - case 2: reach = BuildConfig.reach.maxReachLevel2; break; - case 3: reach = BuildConfig.reach.maxReachLevel3; break; + case 0: reach = BuildConfig.reach.maxReachLevel0.get(); break; + case 1: reach = BuildConfig.reach.maxReachLevel1.get(); break; + case 2: reach = BuildConfig.reach.maxReachLevel2.get(); break; + case 3: reach = BuildConfig.reach.maxReachLevel3.get(); break; } - EffortlessBuilding.log("before "+this.mirrorSettings.radius); - if (this.mirrorSettings != null) this.mirrorSettings.radius = reach / 2; if (this.radialMirrorSettings != null) this.radialMirrorSettings.radius = reach / 2; - - EffortlessBuilding.log("after "+this.mirrorSettings.radius); } } public static void handleNewPlayer(EntityPlayer player){ - if (getModifierSettings(player) == null) { - setModifierSettings(player, new ModifierSettings()); - } + //Makes sure player has modifier settings (if it doesnt it will create it) + getModifierSettings(player); //Only on server if (!player.world.isRemote) { //Send to client ModifierSettingsMessage msg = new ModifierSettingsMessage(getModifierSettings(player)); - EffortlessBuilding.packetHandler.sendTo(msg, (EntityPlayerMP) player); + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) player), msg); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java index 32b4148..a57e8f1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java @@ -143,11 +143,11 @@ public class RadialMirror { IBlockState newBlockState = blockState; if (startAngleToCenter < -0.751 * Math.PI || startAngleToCenter > 0.749 * Math.PI) { - newBlockState = blockState.withRotation(Rotation.CLOCKWISE_180); + newBlockState = blockState.rotate(Rotation.CLOCKWISE_180); } else if (startAngleToCenter < -0.251 * Math.PI) { - newBlockState = blockState.withRotation(Rotation.COUNTERCLOCKWISE_90); + newBlockState = blockState.rotate(Rotation.COUNTERCLOCKWISE_90); } else if (startAngleToCenter > 0.249 * Math.PI) { - newBlockState = blockState.withRotation(Rotation.CLOCKWISE_90); + newBlockState = blockState.rotate(Rotation.CLOCKWISE_90); } return newBlockState; @@ -158,24 +158,24 @@ public class RadialMirror { double angleToCenter = MathHelper.atan2(relVec.x, relVec.z); //between -PI and PI if (angleToCenter < -0.751 * Math.PI || angleToCenter > 0.749 * Math.PI) { - newBlockState = blockState.withRotation(Rotation.CLOCKWISE_180); + newBlockState = blockState.rotate(Rotation.CLOCKWISE_180); if (alternate) { - newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK); + newBlockState = newBlockState.mirror(Mirror.FRONT_BACK); } } else if (angleToCenter < -0.251 * Math.PI) { - newBlockState = blockState.withRotation(Rotation.CLOCKWISE_90); + newBlockState = blockState.rotate(Rotation.CLOCKWISE_90); if (alternate) { - newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT); + newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT); } } else if (angleToCenter > 0.249 * Math.PI) { - newBlockState = blockState.withRotation(Rotation.COUNTERCLOCKWISE_90); + newBlockState = blockState.rotate(Rotation.COUNTERCLOCKWISE_90); if (alternate) { - newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT); + newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT); } } else { newBlockState = blockState; if (alternate) { - newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK); + newBlockState = newBlockState.mirror(Mirror.FRONT_BACK); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/UndoRedo.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/UndoRedo.java index ada64e0..f68c7b3 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/UndoRedo.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/UndoRedo.java @@ -34,7 +34,7 @@ public class UndoRedo { //Assert coordinates is as long as previous and new blockstate lists if (blockSet.getCoordinates().size() != blockSet.getPreviousBlockStates().size() || - blockSet.getCoordinates().size() != blockSet.getNewBlockStates().size()) { + blockSet.getCoordinates().size() != blockSet.getNewBlockStates().size()) { EffortlessBuilding.logger.error("Coordinates and blockstate lists are not equal length. Coordinates: {}. Previous blockstates: {}. New blockstates: {}.", blockSet.getCoordinates().size(), blockSet.getPreviousBlockStates().size(), blockSet.getNewBlockStates().size()); } @@ -50,10 +50,9 @@ public class UndoRedo { //If no stack exists, make one if (!undoStacks.containsKey(player.getUniqueID())) { - undoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize])); + undoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize.get()])); } - undoStacks.get(player.getUniqueID()).push(blockSet); } @@ -64,7 +63,7 @@ public class UndoRedo { //If no stack exists, make one if (!redoStacks.containsKey(player.getUniqueID())) { - redoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize])); + redoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize.get()])); } redoStacks.get(player.getUniqueID()).push(blockSet); @@ -214,7 +213,7 @@ public class UndoRedo { //then anything it drops if (itemStack.isEmpty()) { - Item itemDropped = blockState.getBlock().getItemDropped(blockState, player.world.rand, 10); + Item itemDropped = blockState.getBlock().getItemDropped(blockState, player.world, BlockPos.ORIGIN, 10).asItem(); if (itemDropped instanceof ItemBlock) { Block block = ((ItemBlock) itemDropped).getBlock(); itemStack = InventoryHelper.findItemStackInInventory(player, block); diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java b/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java index 238eb3b..f2d1648 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java +++ b/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java @@ -3,7 +3,9 @@ package nl.requios.effortlessbuilding.capability; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.ICapabilitySerializable; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemStackHandler; @@ -15,19 +17,10 @@ import javax.annotation.Nullable; public class ItemHandlerCapabilityProvider implements ICapabilitySerializable { IItemHandler itemHandler = new ItemStackHandler(ItemRandomizerBag.INV_SIZE); + @Nonnull @Override - public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { - if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - return true; - return false; - } - - @Nullable - @Override - public T getCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { - if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) - return (T) itemHandler; - return null; + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable EnumFacing side) { + return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.orEmpty(cap, LazyOptional.of(() -> itemHandler)); } @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java b/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java index 8002b4e..8999520 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java @@ -1,20 +1,21 @@ package nl.requios.effortlessbuilding.capability; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.ICapabilitySerializable; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import nl.requios.effortlessbuilding.buildmode.BuildModes; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.*; +import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.ModeSettings; @Mod.EventBusSubscriber public class ModeCapabilityManager { @@ -44,7 +45,7 @@ public class ModeCapabilityManager { public static class Storage implements Capability.IStorage { @Override - public NBTBase writeNBT(Capability capability, IModeCapability instance, EnumFacing side) { + public INBTBase writeNBT(Capability capability, IModeCapability instance, EnumFacing side) { NBTTagCompound compound = new NBTTagCompound(); ModeSettings modeSettings = instance.getModeData(); if (modeSettings == null) modeSettings = new ModeSettings(); @@ -57,7 +58,7 @@ public class ModeCapabilityManager { } @Override - public void readNBT(Capability capability, IModeCapability instance, EnumFacing side, NBTBase nbt) { + public void readNBT(Capability capability, IModeCapability instance, EnumFacing side, INBTBase nbt) { NBTTagCompound compound = (NBTTagCompound) nbt; //BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.values()[compound.getInteger("buildMode")]; @@ -69,36 +70,34 @@ public class ModeCapabilityManager { } } - public static class Provider implements ICapabilitySerializable { + public static class Provider implements ICapabilitySerializable { IModeCapability inst = modeCapability.getDefaultInstance(); + @Nonnull @Override - public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { - return capability == modeCapability; + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable EnumFacing side) { + return modeCapability.orEmpty(cap, LazyOptional.of(() -> inst)); } @Override - public T getCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { - if (capability == modeCapability) return modeCapability.cast(inst); - return null; - } - - @Override - public NBTBase serializeNBT() { + public INBTBase serializeNBT() { return modeCapability.getStorage().writeNBT(modeCapability, inst, null); } @Override - public void deserializeNBT(NBTBase nbt) { + public void deserializeNBT(INBTBase nbt) { modeCapability.getStorage().readNBT(modeCapability, inst, null, nbt); } + } // Allows for the capability to persist after death. @SubscribeEvent public static void clonePlayer(PlayerEvent.Clone event) { - IModeCapability original = event.getOriginal().getCapability(modeCapability, null); - IModeCapability clone = event.getEntity().getCapability(modeCapability, null); - clone.setModeData(original.getModeData()); + LazyOptional original = event.getOriginal().getCapability(modeCapability, null); + LazyOptional clone = event.getEntity().getCapability(modeCapability, null); + clone.ifPresent(cloneModeCapability -> + original.ifPresent(originalModeCapability -> + cloneModeCapability.setModeData(originalModeCapability.getModeData()))); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/ModifierCapabilityManager.java b/src/main/java/nl/requios/effortlessbuilding/capability/ModifierCapabilityManager.java index 183004f..0405c05 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ModifierCapabilityManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/capability/ModifierCapabilityManager.java @@ -1,6 +1,6 @@ package nl.requios.effortlessbuilding.capability; -import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.INBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; @@ -8,9 +8,11 @@ import net.minecraft.util.math.Vec3d; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.ICapabilitySerializable; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; @@ -18,6 +20,8 @@ import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.concurrent.Callable; + import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.*; @Mod.EventBusSubscriber @@ -48,7 +52,7 @@ public class ModifierCapabilityManager { public static class Storage implements Capability.IStorage { @Override - public NBTBase writeNBT(Capability capability, IModifierCapability instance, EnumFacing side) { + public INBTBase writeNBT(Capability capability, IModifierCapability instance, EnumFacing side) { NBTTagCompound compound = new NBTTagCompound(); ModifierSettings modifierSettings = instance.getModifierData(); if (modifierSettings == null) modifierSettings = new ModifierSettings(); @@ -63,7 +67,7 @@ public class ModifierCapabilityManager { compound.setBoolean("mirrorX", m.mirrorX); compound.setBoolean("mirrorY", m.mirrorY); compound.setBoolean("mirrorZ", m.mirrorZ); - compound.setInteger("mirrorRadius", m.radius); + compound.setInt("mirrorRadius", m.radius); compound.setBoolean("mirrorDrawLines", m.drawLines); compound.setBoolean("mirrorDrawPlanes", m.drawPlanes); @@ -71,12 +75,12 @@ public class ModifierCapabilityManager { Array.ArraySettings a = modifierSettings.getArraySettings(); if (a == null) a = new Array.ArraySettings(); compound.setBoolean("arrayEnabled", a.enabled); - compound.setInteger("arrayOffsetX", a.offset.getX()); - compound.setInteger("arrayOffsetY", a.offset.getY()); - compound.setInteger("arrayOffsetZ", a.offset.getZ()); - compound.setInteger("arrayCount", a.count); + compound.setInt("arrayOffsetX", a.offset.getX()); + compound.setInt("arrayOffsetY", a.offset.getY()); + compound.setInt("arrayOffsetZ", a.offset.getZ()); + compound.setInt("arrayCount", a.count); - compound.setInteger("reachUpgrade", modifierSettings.getReachUpgrade()); + compound.setInt("reachUpgrade", modifierSettings.getReachUpgrade()); //compound.setBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace @@ -87,9 +91,9 @@ public class ModifierCapabilityManager { compound.setDouble("radialMirrorPosX", r.position.x); compound.setDouble("radialMirrorPosY", r.position.y); compound.setDouble("radialMirrorPosZ", r.position.z); - compound.setInteger("radialMirrorSlices", r.slices); + compound.setInt("radialMirrorSlices", r.slices); compound.setBoolean("radialMirrorAlternate", r.alternate); - compound.setInteger("radialMirrorRadius", r.radius); + compound.setInt("radialMirrorRadius", r.radius); compound.setBoolean("radialMirrorDrawLines", r.drawLines); compound.setBoolean("radialMirrorDrawPlanes", r.drawPlanes); @@ -97,7 +101,7 @@ public class ModifierCapabilityManager { } @Override - public void readNBT(Capability capability, IModifierCapability instance, EnumFacing side, NBTBase nbt) { + public void readNBT(Capability capability, IModifierCapability instance, EnumFacing side, INBTBase nbt) { NBTTagCompound compound = (NBTTagCompound) nbt; //MIRROR @@ -109,7 +113,7 @@ public class ModifierCapabilityManager { boolean mirrorX = compound.getBoolean("mirrorX"); boolean mirrorY = compound.getBoolean("mirrorY"); boolean mirrorZ = compound.getBoolean("mirrorZ"); - int mirrorRadius = compound.getInteger("mirrorRadius"); + int mirrorRadius = compound.getInt("mirrorRadius"); boolean mirrorDrawLines = compound.getBoolean("mirrorDrawLines"); boolean mirrorDrawPlanes = compound.getBoolean("mirrorDrawPlanes"); Mirror.MirrorSettings mirrorSettings = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes); @@ -117,13 +121,13 @@ public class ModifierCapabilityManager { //ARRAY boolean arrayEnabled = compound.getBoolean("arrayEnabled"); BlockPos arrayOffset = new BlockPos( - compound.getInteger("arrayOffsetX"), - compound.getInteger("arrayOffsetY"), - compound.getInteger("arrayOffsetZ")); - int arrayCount = compound.getInteger("arrayCount"); + compound.getInt("arrayOffsetX"), + compound.getInt("arrayOffsetY"), + compound.getInt("arrayOffsetZ")); + int arrayCount = compound.getInt("arrayCount"); Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); - int reachUpgrade = compound.getInteger("reachUpgrade"); + int reachUpgrade = compound.getInt("reachUpgrade"); //boolean quickReplace = compound.getBoolean("quickReplace"); //dont load quickreplace @@ -133,9 +137,9 @@ public class ModifierCapabilityManager { compound.getDouble("radialMirrorPosX"), compound.getDouble("radialMirrorPosY"), compound.getDouble("radialMirrorPosZ")); - int radialMirrorSlices = compound.getInteger("radialMirrorSlices"); + int radialMirrorSlices = compound.getInt("radialMirrorSlices"); boolean radialMirrorAlternate = compound.getBoolean("radialMirrorAlternate"); - int radialMirrorRadius = compound.getInteger("radialMirrorRadius"); + int radialMirrorRadius = compound.getInt("radialMirrorRadius"); boolean radialMirrorDrawLines = compound.getBoolean("radialMirrorDrawLines"); boolean radialMirrorDrawPlanes = compound.getBoolean("radialMirrorDrawPlanes"); RadialMirror.RadialMirrorSettings radialMirrorSettings = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, @@ -146,36 +150,36 @@ public class ModifierCapabilityManager { } } - public static class Provider implements ICapabilitySerializable { + public static class Provider implements ICapabilitySerializable { + IModifierCapability inst = modifierCapability.getDefaultInstance(); + @Nonnull @Override - public boolean hasCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { - return capability == modifierCapability; + public LazyOptional getCapability(@Nonnull Capability cap, @Nullable EnumFacing side) { + return modifierCapability.orEmpty(cap, LazyOptional.of(() -> inst)); } @Override - public T getCapability(@Nonnull Capability capability, @Nullable EnumFacing facing) { - if (capability == modifierCapability) return modifierCapability.cast(inst); - return null; - } - - @Override - public NBTBase serializeNBT() { + public INBTBase serializeNBT() { return modifierCapability.getStorage().writeNBT(modifierCapability, inst, null); } @Override - public void deserializeNBT(NBTBase nbt) { + public void deserializeNBT(INBTBase nbt) { modifierCapability.getStorage().readNBT(modifierCapability, inst, null, nbt); } + } + // Allows for the capability to persist after death. @SubscribeEvent public static void clonePlayer(PlayerEvent.Clone event) { - IModifierCapability original = event.getOriginal().getCapability(modifierCapability, null); - IModifierCapability clone = event.getEntity().getCapability(modifierCapability, null); - clone.setModifierData(original.getModifierData()); + LazyOptional original = event.getOriginal().getCapability(modifierCapability, null); + LazyOptional clone = event.getEntity().getCapability(modifierCapability, null); + clone.ifPresent(cloneModifierCapability -> + original.ifPresent(originalModifierCapability -> + cloneModifierCapability.setModifierData(originalModifierCapability.getModifierData()))); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/command/CommandReach.java b/src/main/java/nl/requios/effortlessbuilding/command/CommandReach.java index 0249170..284f745 100644 --- a/src/main/java/nl/requios/effortlessbuilding/command/CommandReach.java +++ b/src/main/java/nl/requios/effortlessbuilding/command/CommandReach.java @@ -1,46 +1,44 @@ package nl.requios.effortlessbuilding.command; -import net.minecraft.command.CommandBase; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.command.WrongUsageException; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import net.minecraft.command.CommandSource; +import net.minecraft.command.Commands; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.server.MinecraftServer; import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.fml.network.PacketDistributor; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; +import nl.requios.effortlessbuilding.network.PacketHandler; +import nl.requios.effortlessbuilding.network.RequestLookAtMessage; -public class CommandReach extends CommandBase { - @Override - public String getName() { - return "reach"; +public class CommandReach { + + public static void register(CommandDispatcher dispatcher) { + dispatcher.register(Commands.literal("reach").then(Commands.literal("set").then(Commands.argument("level", IntegerArgumentType.integer(0, 3)).executes((context) -> { + return setReachLevel(context.getSource().asPlayer(), IntegerArgumentType.getInteger(context, "level")); + }))).then(Commands.literal("get").executes((context -> { + return getReachLevel(context.getSource().asPlayer()); + })))); } - @Override - public String getUsage(ICommandSender sender) { - return "commands.reach.usage"; + private static int setReachLevel(EntityPlayerMP player, int level){ + ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); + modifierSettings.setReachUpgrade(level); + ModifierSettingsManager.setModifierSettings(player, modifierSettings); + //Send to client + PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new ModifierSettingsMessage(modifierSettings)); + + player.sendMessage(new TextComponentString("Reach level of " + player.getName().getString() + " set to " + modifierSettings.getReachUpgrade())); + + return 1; } - @Override - public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException { - EntityPlayerMP player = (EntityPlayerMP) sender; - if (args.length != 1) { - int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade(); - EffortlessBuilding.log(player, "Current reach: level "+reachUpgrade); - throw new WrongUsageException("commands.reach.usage"); - } + private static int getReachLevel(EntityPlayerMP player){ + int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade(); + EffortlessBuilding.log(player, "Current reach: level "+reachUpgrade); - if (sender instanceof EntityPlayerMP) { - //Set reach level to args[0] - ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); - modifierSettings.setReachUpgrade(Integer.valueOf(args[0])); - ModifierSettingsManager.setModifierSettings(player, modifierSettings); - //Send to client - EffortlessBuilding.packetHandler.sendTo(new ModifierSettingsMessage(modifierSettings), player); - - sender.sendMessage(new TextComponentString("Reach level of " + sender.getName() + " set to " + modifierSettings - .getReachUpgrade())); - } + return 1; } } diff --git a/src/main/java/nl/requios/effortlessbuilding/compatibility/ActiveChiselsAndBitsProxy.java b/src/main/java/nl/requios/effortlessbuilding/compatibility/ActiveChiselsAndBitsProxy.java deleted file mode 100644 index 667991d..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/ActiveChiselsAndBitsProxy.java +++ /dev/null @@ -1,13 +0,0 @@ -package nl.requios.effortlessbuilding.compatibility; - -import mod.chiselsandbits.core.ClientSide; -import mod.chiselsandbits.helpers.ChiselToolType; -import net.minecraft.util.EnumHand; - -public class ActiveChiselsAndBitsProxy implements IChiselsAndBitsProxy { - @Override - public boolean isHoldingChiselTool(EnumHand hand) { - ChiselToolType toolType = ClientSide.instance.getHeldToolType(hand); - return toolType != null && toolType.hasMenu(); - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java index 4c10d7e..99c93ca 100644 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java @@ -6,31 +6,33 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; +import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.item.ItemRandomizerBag; public class CompatHelper { - // Get a handle to the dank null item instance. This will remain null if the mod doesn't load - // and all checks will fail, so it works. - @GameRegistry.ObjectHolder("danknull:dank_null") - public static final Item dankNullItem = null; - - public static IChiselsAndBitsProxy chiselsAndBitsProxy; - - public static void postInit() { - if (Loader.isModLoaded("chiselsandbits")) { - // reflection to avoid hard dependency - try { - chiselsAndBitsProxy = Class.forName("nl.requios.effortlessbuilding.compatibility.ActiveChiselsAndBitsProxy").asSubclass(ActiveChiselsAndBitsProxy.class).newInstance(); - } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { - e.printStackTrace(); - } - } else { - chiselsAndBitsProxy = new DummyChiselsAndBitsProxy(); - } + //TODO 1.13 compatibility +// // Get a handle to the dank null item instance. This will remain null if the mod doesn't load +// // and all checks will fail, so it works. +// @GameRegistry.ObjectHolder("danknull:dank_null") +// public static final Item dankNullItem = null; +// +// public static IChiselsAndBitsProxy chiselsAndBitsProxy; +// + public static void setup() { + //TODO 1.13 compatibility +// if (Loader.isModLoaded("chiselsandbits")) { +// // reflection to avoid hard dependency +// try { +// chiselsAndBitsProxy = Class.forName("nl.requios.effortlessbuilding.compatibility.ActiveChiselsAndBitsProxy").asSubclass(ActiveChiselsAndBitsProxy.class).newInstance(); +// } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { +// e.printStackTrace(); +// } +// } else { +// chiselsAndBitsProxy = new DummyChiselsAndBitsProxy(); +// } } // Check if the item given is a proxy for blocks. For now, we check for the randomizer bag, @@ -41,8 +43,9 @@ public class CompatHelper { return true; if ((item instanceof ItemRandomizerBag)) return true; - if (item == dankNullItem) - return true; + //TODO 1.13 compatibility +// if (item == dankNullItem) +// return true; return false; } @@ -64,47 +67,60 @@ public class CompatHelper { return itemStack; } + //TODO 1.13 compatibility //Dank Null - if (proxyItem == dankNullItem) { - int index = 0; - if (proxy.hasTagCompound() && proxy.getTagCompound().hasKey("selectedIndex")) - index = proxy.getTagCompound().getInteger("selectedIndex"); - return proxy.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index); - } +// if (proxyItem == dankNullItem) { +// int index = 0; +// if (proxy.hasTagCompound() && proxy.getTagCompound().hasKey("selectedIndex")) +// index = proxy.getTagCompound().getInteger("selectedIndex"); +// return proxy.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index); +// } return ItemStack.EMPTY; } public static ItemStack getItemBlockByState(ItemStack stack, IBlockState state) { + if (state == null) return ItemStack.EMPTY; + Item blockItem = Item.getItemFromBlock(state.getBlock()); if (stack.getItem() instanceof ItemBlock) return stack; else if (stack.getItem() instanceof ItemRandomizerBag) { IItemHandler bagInventory = ItemRandomizerBag.getBagInventory(stack); return ItemRandomizerBag.findStack(bagInventory, blockItem); - } else if (stack.getItem() == dankNullItem) { - int index = itemHandlerSlotForItem(stack, blockItem); - if (index >= 0) - return stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index); } + //TODO 1.13 compatibility +// else if (stack.getItem() == dankNullItem) { +// int index = itemHandlerSlotForItem(stack, blockItem); +// if (index >= 0) +// return stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index); +// } return ItemStack.EMPTY; } // Handle IItemHandler slot stacks not being modifiable. We must call IItemHandler#extractItem, // because the ItemStack returned by IItemHandler#getStackInSlot isn't modifiable. public static void shrinkStack(ItemStack origStack, ItemStack curStack, EntityPlayer player) { - //Hacky way to get the origstack, because given origStack is itemblock stack and never a proxy - origStack = player.getHeldItem(EnumHand.MAIN_HAND); + //TODO 1.13 compatibility, offhand support + //Hacky way to get the origstack, because given origStack is itemblock stack and never proxy +// origStack = player.getHeldItem(EnumHand.MAIN_HAND); - if (origStack.getItem() == dankNullItem) { - int index = itemHandlerSlotForItem(origStack, curStack.getItem()); - origStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).extractItem(index, 1, false); - } else +// if (origStack.getItem() == dankNullItem) { +// int index = itemHandlerSlotForItem(origStack, curStack.getItem()); +// origStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).extractItem(index, 1, false); +// } else curStack.shrink(1); } private static int itemHandlerSlotForItem(ItemStack stack, Item blockItem) { - IItemHandler handler = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); + LazyOptional itemHandlerLazyOptional = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); + IItemHandler handler = itemHandlerLazyOptional.orElse(null); + + if (handler == null) { + EffortlessBuilding.logger.warn("Itemblock proxy has no item handler capability!"); + return -1; + } + for (int i = 0; i < handler.getSlots(); i++) { ItemStack ref = handler.getStackInSlot(i); if (ref.getItem() instanceof ItemBlock) diff --git a/src/main/java/nl/requios/effortlessbuilding/compatibility/DummyChiselsAndBitsProxy.java b/src/main/java/nl/requios/effortlessbuilding/compatibility/DummyChiselsAndBitsProxy.java deleted file mode 100644 index 7c37894..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/DummyChiselsAndBitsProxy.java +++ /dev/null @@ -1,10 +0,0 @@ -package nl.requios.effortlessbuilding.compatibility; - -import net.minecraft.util.EnumHand; - -public class DummyChiselsAndBitsProxy implements IChiselsAndBitsProxy { - @Override - public boolean isHoldingChiselTool(EnumHand hand) { - return false; - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/compatibility/IChiselsAndBitsProxy.java b/src/main/java/nl/requios/effortlessbuilding/compatibility/IChiselsAndBitsProxy.java deleted file mode 100644 index ec288ba..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/IChiselsAndBitsProxy.java +++ /dev/null @@ -1,7 +0,0 @@ -package nl.requios.effortlessbuilding.compatibility; - -import net.minecraft.util.EnumHand; - -public interface IChiselsAndBitsProxy { - boolean isHoldingChiselTool(EnumHand hand); -} diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java index b5f3432..4c82643 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagContainer.java @@ -23,20 +23,20 @@ public class RandomizerBagContainer extends Container { bagInventory = parIInventory; sizeInventory = bagInventory.getSlots(); for (int i = 0; i < sizeInventory; ++i) { - this.addSlotToContainer(new SlotItemHandler(bagInventory, i, 44 + (18 * i), 20)); + this.addSlot(new SlotItemHandler(bagInventory, i, 44 + (18 * i), 20)); } // add player inventory slots int i; for (i = 0; i < 3; ++i) { for (int j = 0; j < 9; ++j) { - addSlotToContainer(new Slot(parInventoryPlayer, j + i * 9 + 9, 8 + j * 18, 51 + i * 18)); + addSlot(new Slot(parInventoryPlayer, j + i * 9 + 9, 8 + j * 18, 51 + i * 18)); } } // add hotbar slots for (i = 0; i < 9; ++i) { - addSlotToContainer(new Slot(parInventoryPlayer, i, 8 + i * 18, 109)); + addSlot(new Slot(parInventoryPlayer, i, 8 + i * 18, 109)); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiContainer.java b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiContainer.java index 3777817..20ed9b0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiContainer.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiContainer.java @@ -4,12 +4,12 @@ import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.EffortlessBuilding; -@SideOnly(Side.CLIENT) +@OnlyIn(Dist.CLIENT) public class RandomizerBagGuiContainer extends GuiContainer { private static final ResourceLocation guiTextures = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png"); @@ -25,9 +25,9 @@ public class RandomizerBagGuiContainer extends GuiContainer { } @Override - public void drawScreen(int mouseX, int mouseY, float partialTicks) { + public void render(int mouseX, int mouseY, float partialTicks) { drawDefaultBackground(); - super.drawScreen(mouseX, mouseY, partialTicks); + super.render(mouseX, mouseY, partialTicks); this.renderHoveredToolTip(mouseX, mouseY); } @@ -35,12 +35,12 @@ public class RandomizerBagGuiContainer extends GuiContainer { protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { String s = "Randomizer Bag"; fontRenderer.drawString(s, 8, 6, 0x404040); - fontRenderer.drawString(inventoryPlayer.getDisplayName().getUnformattedText(), 8, ySize - 96 + 2, 0x404040); + fontRenderer.drawString(inventoryPlayer.getDisplayName().getUnformattedComponentText(), 8, ySize - 96 + 2, 0x404040); } @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.color3f(1.0F, 1.0F, 1.0F); mc.getTextureManager().bindTexture(guiTextures); int marginHorizontal = (width - xSize) / 2; int marginVertical = (height - ySize) / 2; diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiHandler.java b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiHandler.java index ded862c..a46f68e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/RandomizerBagGuiHandler.java @@ -1,41 +1,112 @@ package nl.requios.effortlessbuilding.gui; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.util.EnumHand; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.IInteractionObject; import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fml.common.network.IGuiHandler; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.fml.network.FMLPlayMessages; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; +import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import javax.annotation.Nullable; -public class RandomizerBagGuiHandler implements IGuiHandler { - @Nullable - @Override - public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { - if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { - // Use the player's held item to create the container - IItemHandler capability = player.getHeldItemMainhand().hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) ? - player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) : - player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); - return new RandomizerBagContainer(player.inventory, capability); +public class RandomizerBagGuiHandler implements /*IGuiHandler, */IInteractionObject { +// @Nullable +// @Override +// public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { +// if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { +// // Use the player's held item to create the container +// LazyOptional capabilityOptional = player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); +// +// if (!capabilityOptional.isPresent()) { +// capabilityOptional = player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); +// } +// +// return new RandomizerBagContainer(player.inventory, capabilityOptional.orElse(null)); +// } +// return null; +// } +// +// @Nullable +// @Override +// @OnlyIn(Dist.CLIENT) +// public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { +// if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { +// // Use the player's held item to create the client-side gui container +// LazyOptional capabilityOptional = player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); +// +// if (!capabilityOptional.isPresent()) { +// capabilityOptional = player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); +// } +// +// return new RandomizerBagGuiContainer(player.inventory, capabilityOptional.orElse(null)); +// } +// return null; +// } + + @OnlyIn(Dist.CLIENT) + public static GuiScreen openGui(FMLPlayMessages.OpenContainer openContainer) { + if (openContainer.getId().equals(EffortlessBuilding.RANDOMIZER_BAG_GUI)) { + EntityPlayerSP player = Minecraft.getInstance().player; + if (player.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof ItemRandomizerBag) { + IItemHandler itemHandler = player.getHeldItem(EnumHand.MAIN_HAND).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null); + if (itemHandler != null) { + return new RandomizerBagGuiContainer(player.inventory, itemHandler); + } + } } return null; } - @Nullable @Override - @SideOnly(Side.CLIENT) - public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { - if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { - // Use the player's held item to create the client-side gui container - IItemHandler capability = player.getHeldItemMainhand().hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) ? - player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) : - player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); - return new RandomizerBagGuiContainer(player.inventory, capability); + public Container createContainer(InventoryPlayer inventory, EntityPlayer player) { + if (player.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof ItemRandomizerBag) { + IItemHandler itemHandler = player.getHeldItem(EnumHand.MAIN_HAND).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null); + if (itemHandler != null) { + return new RandomizerBagContainer(inventory, itemHandler); + } } return null; } + + @Override + public String getGuiID() { + return EffortlessBuilding.RANDOMIZER_BAG_GUI.toString(); + } + + @Override + public ITextComponent getName() { + return new TextComponentString("Randomizer Bag"); + } + + @Override + public boolean hasCustomName() { + return false; + } + + @Override + public ITextComponent getDisplayName() { + return new TextComponentString("Randomizer Bag"); + } + + @Nullable + @Override + public ITextComponent getCustomName() { + return null; + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java index 8b5a594..1c8a71d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java @@ -26,6 +26,7 @@ import net.minecraft.util.EnumFacing; import net.minecraftforge.client.model.ModelLoader; import static nl.requios.effortlessbuilding.buildmode.BuildModes.*; +import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*; /** * From Chisels and Bits by AlgorithmX2 @@ -39,7 +40,7 @@ public class RadialMenu extends GuiScreen { private float visibility = 0.0f; private Stopwatch lastChange = Stopwatch.createStarted(); public BuildModeEnum switchTo = null; - public ModeOptions.ActionEnum doAction = null; + public ActionEnum doAction = null; public boolean actionUsed = false; private float clampVis(final float f) { @@ -65,7 +66,7 @@ public class RadialMenu extends GuiScreen { } public void configure(final int scaledWidth, final int scaledHeight ) { - mc = Minecraft.getMinecraft(); + mc = Minecraft.getInstance(); fontRenderer = mc.fontRenderer; width = scaledWidth; height = scaledHeight; @@ -77,11 +78,11 @@ public class RadialMenu extends GuiScreen { public double y1, y2; public boolean highlighted; - public final ModeOptions.ActionEnum action; + public final ActionEnum action; public String name; public EnumFacing textSide; - public MenuButton(final String name, final ModeOptions.ActionEnum action, final double x, final double y, + public MenuButton(final String name, final ActionEnum action, final double x, final double y, final EnumFacing textSide) { this.name = I18n.format(name); this.action = action; @@ -108,13 +109,13 @@ public class RadialMenu extends GuiScreen { } @Override - public void drawScreen(final int mouseX, final int mouseY, final float partialTicks) { + public void render(final int mouseX, final int mouseY, final float partialTicks) { if (!isVisible()) return; - BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(Minecraft.getMinecraft().player).getBuildMode(); + BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(Minecraft.getInstance().player).getBuildMode(); GlStateManager.pushMatrix(); - GlStateManager.translate( 0.0F, 0.0F, 200.0F ); + GlStateManager.translatef( 0.0F, 0.0F, 200.0F ); final int startColor = (int) ( visibility * 98 ) << 24; final int endColor = (int) ( visibility * 128 ) << 24; @@ -123,8 +124,8 @@ public class RadialMenu extends GuiScreen { GlStateManager.disableTexture2D(); GlStateManager.enableBlend(); - GlStateManager.disableAlpha(); - GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + GlStateManager.disableAlphaTest(); + GlStateManager.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); GlStateManager.shadeModel(GL11.GL_SMOOTH); final Tessellator tessellator = Tessellator.getInstance(); final BufferBuilder buffer = tessellator.getBuffer(); @@ -135,13 +136,13 @@ public class RadialMenu extends GuiScreen { final double middleY = height / 2.0; final double mouseXCenter = mouseX - middleX; - final double mouseYCenter = mouseY - middleY; + final double mouseYCenter = -mouseY + middleY; double mouseRadians = Math.atan2(mouseYCenter, mouseXCenter); - final double ringInnerEdge = 20; - final double ringOuterEdge = 50; - final double textDistance = 60; - final double buttonDistance = 90; + final double ringInnerEdge = 30; + final double ringOuterEdge = 65; + final double textDistance = 75; + final double buttonDistance = 105; final double quarterCircle = Math.PI / 2.0; if ( mouseRadians < -quarterCircle ) { @@ -157,16 +158,18 @@ public class RadialMenu extends GuiScreen { } //Add actions - buttons.add(new MenuButton(ModeOptions.ActionEnum.UNDO.name, ModeOptions.ActionEnum.UNDO, -buttonDistance - 26, -13, EnumFacing.UP)); - buttons.add(new MenuButton(ModeOptions.ActionEnum.REDO.name, ModeOptions.ActionEnum.REDO, -buttonDistance, -13, EnumFacing.UP)); - buttons.add(new MenuButton(ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS.name, ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 26, 13, EnumFacing.DOWN)); - buttons.add(new MenuButton(ModeOptions.ActionEnum.REPLACE.name, ModeOptions.ActionEnum.REPLACE, -buttonDistance, 13, EnumFacing.DOWN)); + buttons.add(new MenuButton(ActionEnum.UNDO.name, ActionEnum.UNDO, -buttonDistance - 26, -13, EnumFacing.UP)); + buttons.add(new MenuButton(ActionEnum.REDO.name, ActionEnum.REDO, -buttonDistance, -13, EnumFacing.UP)); + buttons.add(new MenuButton(ActionEnum.OPEN_MODIFIER_SETTINGS.name, ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 26, 13, EnumFacing.DOWN)); + buttons.add(new MenuButton(ActionEnum.REPLACE.name, ActionEnum.REPLACE, -buttonDistance, 13, EnumFacing.DOWN)); //Add buildmode dependent options - ModeOptions.ActionEnum[] options = currentBuildMode.options; + OptionEnum[] options = currentBuildMode.options; for (int i = 0; i < options.length; i++) { - ModeOptions.ActionEnum action = options[i]; - buttons.add(new MenuButton(action.name, action, buttonDistance + i * 26, -13, EnumFacing.DOWN)); + for (int j = 0; j < options[i].actions.length; j++) { + ActionEnum action = options[i].actions[j]; + buttons.add(new MenuButton(action.name, action, buttonDistance + j * 26, -13 + i * 39, EnumFacing.DOWN)); + } } switchTo = null; @@ -245,11 +248,12 @@ public class RadialMenu extends GuiScreen { float a = 0.5f; //highlight when active option - if (btn.action == ModeOptions.getBuildSpeed() || - btn.action == ModeOptions.getFill() || - btn.action == ModeOptions.getCubeFill() || - btn.action == ModeOptions.getRaisedEdge() || - btn.action == ModeOptions.getLineThickness()) { + if (btn.action == getBuildSpeed() || + btn.action == getFill() || + btn.action == getCubeFill() || + btn.action == getRaisedEdge() || + btn.action == getLineThickness() || + btn.action == getCircleStart()) { r = 0.0f; g = 0.5f; b = 1f; @@ -276,12 +280,12 @@ public class RadialMenu extends GuiScreen { GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.translate(0f, 0f, 5f); + GlStateManager.translatef(0f, 0f, 5f); GlStateManager.enableTexture2D(); - GlStateManager.color(1f, 1f, 1f, 1f); + GlStateManager.color3f(1f, 1f, 1f); GlStateManager.disableBlend(); - GlStateManager.enableAlpha(); - GlStateManager.bindTexture(Minecraft.getMinecraft().getTextureMapBlocks().getGlTextureId()); + GlStateManager.enableAlphaTest(); + GlStateManager.bindTexture(Minecraft.getInstance().getTextureMap().getGlTextureId()); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); @@ -342,32 +346,12 @@ public class RadialMenu extends GuiScreen { //Draw strings //fontRenderer.drawStringWithShadow("Actions", (int) (middleX - buttonDistance - 13) - fontRenderer.getStringWidth("Actions") * 0.5f, (int) middleY - 38, 0xffffffff); - String title = ""; - if (currentBuildMode.options.length > 0) { - switch (currentBuildMode.options[0]) { - case NORMAL_SPEED: - case FAST_SPEED: - title = I18n.format("effortlessbuilding.action.build_speed"); - break; - case FULL: - case HOLLOW: - case CUBE_FULL: - case CUBE_HOLLOW: - case CUBE_SKELETON: - title = I18n.format("effortlessbuilding.action.filling"); - break; - case SHORT_EDGE: - case LONG_EDGE: - title = I18n.format("effortlessbuilding.action.raised_edge"); - break; - case THICKNESS_1: - case THICKNESS_3: - case THICKNESS_5: - title = I18n.format("effortlessbuilding.action.thickness"); - break; - } + + //Draw option strings + for (int i = 0; i < currentBuildMode.options.length; i++) { + OptionEnum option = options[i]; + fontRenderer.drawStringWithShadow(I18n.format(option.name), (int) (middleX + buttonDistance - 9), (int) middleY - 37 + i * 39, 0xeeeeeeff); } - fontRenderer.drawStringWithShadow(title, (int) (middleX + buttonDistance - 9), (int) middleY - 37, 0xeeeeeeff); String credits = "Effortless Building"; fontRenderer.drawStringWithShadow(credits, width - fontRenderer.getStringWidth(credits) - 4, height - 10, 0x88888888); @@ -402,17 +386,25 @@ public class RadialMenu extends GuiScreen { String keybindFormatted = ""; //Add keybind in brackets - if (button.action == ModeOptions.ActionEnum.UNDO) { - keybind = ClientProxy.keyBindings[4].getDisplayName(); + if (button.action == ActionEnum.UNDO) { + keybind = ClientProxy.keyBindings[4].getKey().getName(); } - if (button.action == ModeOptions.ActionEnum.REDO) { - keybind = ClientProxy.keyBindings[5].getDisplayName(); + if (button.action == ActionEnum.REDO) { + keybind = ClientProxy.keyBindings[5].getKey().getName(); } - if (button.action == ModeOptions.ActionEnum.REPLACE) { - keybind = ClientProxy.keyBindings[1].getDisplayName(); + if (button.action == ActionEnum.REPLACE) { + keybind = ClientProxy.keyBindings[1].getKey().getName(); } - if (button.action == ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) { - keybind = ClientProxy.keyBindings[0].getDisplayName(); + if (button.action == ActionEnum.OPEN_MODIFIER_SETTINGS) { + keybind = ClientProxy.keyBindings[0].getKey().getName(); + } + if (currentBuildMode.options.length > 0) { + //Add (ctrl) to first two actions of first option + if (button.action == currentBuildMode.options[0].actions[0] + || button.action == currentBuildMode.options[0].actions[1]) { + keybind = ClientProxy.keyBindings[6].getKey().getName(); + if (keybind.equals("Left Control")) keybind = "Ctrl"; + } } if (!keybind.isEmpty()) keybindFormatted = TextFormatting.GRAY + "(" + WordUtils.capitalizeFully(keybind) + ")"; @@ -466,7 +458,7 @@ public class RadialMenu extends GuiScreen { * Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton */ @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton ) { + public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { EffortlessBuilding.log("mouse clicked"); // KeyBinding.updateKeyBindState(); @@ -479,6 +471,8 @@ public class RadialMenu extends GuiScreen { // this.mc.setIngameFocus(); // } // } + return super.mouseClicked(mouseX, mouseY, mouseButton); } + } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java index 2f0e867..5ef4c13 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java @@ -4,6 +4,8 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.client.config.GuiCheckBox; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.Array; @@ -17,6 +19,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +@OnlyIn(Dist.CLIENT) public class ArraySettingsGui extends GuiCollapsibleScrollEntry { protected List arrayNumberFieldList = new ArrayList<>(); @@ -29,31 +32,37 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry { } @Override - public int initGui(int id, List buttonList) { - id = super.initGui(id, buttonList); + public int initGui(int id, List buttons) { + id = super.initGui(id, buttons); int y = top; - buttonArrayEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false); - buttonList.add(buttonArrayEnabled); + buttonArrayEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + setCollapsed(!buttonArrayEnabled.isChecked()); + } + }; + buttons.add(buttonArrayEnabled); y = top + 20; - textArrayOffsetX = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 70, y, 50, 18); + textArrayOffsetX = new GuiNumberField(id++, id++, id++, fontRenderer, buttons, left + 70, y, 50, 18); textArrayOffsetX.setNumber(0); textArrayOffsetX.setTooltip("How much each copy is shifted."); arrayNumberFieldList.add(textArrayOffsetX); - textArrayOffsetY = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 140, y, 50, 18); + textArrayOffsetY = new GuiNumberField(id++, id++, id++, fontRenderer, buttons, left + 140, y, 50, 18); textArrayOffsetY.setNumber(0); textArrayOffsetY.setTooltip("How much each copy is shifted."); arrayNumberFieldList.add(textArrayOffsetY); - textArrayOffsetZ = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 210, y, 50, 18); + textArrayOffsetZ = new GuiNumberField(id++, id++, id++, fontRenderer, buttons, left + 210, y, 50, 18); textArrayOffsetZ.setNumber(0); textArrayOffsetZ.setTooltip("How much each copy is shifted."); arrayNumberFieldList.add(textArrayOffsetZ); y = top + 50; - textArrayCount = new GuiNumberField(id++, id++, id++, fontRenderer, buttonList, left + 55, y, 50, 18); + textArrayCount = new GuiNumberField(id++, id++, id++, fontRenderer, buttons, left + 55, y, 50, 18); textArrayCount.setNumber(5); textArrayCount.setTooltip("How many copies should be made."); arrayNumberFieldList.add(textArrayCount); @@ -73,48 +82,44 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry { return id; } - @Override public void updateScreen() { - super.updateScreen(); arrayNumberFieldList.forEach(GuiNumberField::update); } @Override public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partialTicks) { - super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partialTicks); - int yy = y; int offset = 8; - buttonArrayEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks); + buttonArrayEnabled.render(mouseX, mouseY, partialTicks); if (buttonArrayEnabled.isChecked()) { buttonArrayEnabled.y = yy; - fontRenderer.drawString("Array enabled", left + offset, yy + 2, 0xFFFFFF, true); + fontRenderer.drawString("Array enabled", left + offset, yy + 2, 0xFFFFFF); yy = y + 20; - fontRenderer.drawString("Offset", left + offset, yy + 5, 0xFFFFFF, true); - fontRenderer.drawString("X", left + 50 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Offset", left + offset, yy + 5, 0xFFFFFF); + fontRenderer.drawString("X", left + 50 + offset, yy + 5, 0xFFFFFF); textArrayOffsetX.y = yy; - fontRenderer.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF); textArrayOffsetY.y = yy; - fontRenderer.drawString("Z", left + 190 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Z", left + 190 + offset, yy + 5, 0xFFFFFF); textArrayOffsetZ.y = yy; yy = y + 50; - fontRenderer.drawString("Count", left + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Count", left + offset, yy + 5, 0xFFFFFF); textArrayCount.y = yy; int currentReach = Math.max(-1, getArrayReach()); int maxReach = ReachHelper.getMaxReach(mc.player); TextFormatting reachColor = isCurrentReachValid(currentReach, maxReach) ? TextFormatting.GRAY : TextFormatting.RED; String reachText = "Reach: " + reachColor + currentReach + TextFormatting.GRAY + "/" + TextFormatting.GRAY + maxReach; - fontRenderer.drawString(reachText, left + 176 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString(reachText, left + 176 + offset, yy + 5, 0xFFFFFF); - arrayNumberFieldList.forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks)); + arrayNumberFieldList.forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks)); } else { buttonArrayEnabled.y = yy; - fontRenderer.drawString("Array disabled", left + offset, yy + 2, 0x999999, true); + fontRenderer.drawString("Array disabled", left + offset, yy + 2, 0x999999); } } @@ -128,43 +133,28 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry { } @Override - public void updatePosition(int slotIndex, int x, int y, float partialTicks) { - super.updatePosition(slotIndex, x, y, partialTicks); - } - - @Override - public void keyTyped(char typedChar, int keyCode) throws IOException { - super.keyTyped(typedChar, keyCode); + public boolean charTyped(char typedChar, int keyCode) { + super.charTyped(typedChar, keyCode); for (GuiNumberField numberField : arrayNumberFieldList) { - numberField.keyTyped(typedChar, keyCode); + numberField.charTyped(typedChar, keyCode); } + return true; } @Override public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { - super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY); arrayNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent)); boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; if (insideArrayEnabledLabel) { - buttonArrayEnabled.setIsChecked(!buttonArrayEnabled.isChecked()); buttonArrayEnabled.playPressSound(this.mc.getSoundHandler()); - actionPerformed(buttonArrayEnabled); + buttonArrayEnabled.onClick(mouseX, mouseY); } return true; } - @Override - public void actionPerformed(GuiButton button) { - super.actionPerformed(button); - if (button == buttonArrayEnabled) { - setCollapsed(!buttonArrayEnabled.isChecked()); - } - arrayNumberFieldList.forEach(numberField -> numberField.actionPerformed(button)); - } - public Array.ArraySettings getArraySettings() { boolean arrayEnabled = buttonArrayEnabled.isChecked(); BlockPos arrayOffset = new BlockPos(0, 0, 0); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorSettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorSettingsGui.java index fb76219..865fdf2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorSettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorSettingsGui.java @@ -5,6 +5,8 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.client.config.GuiCheckBox; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.Mirror; @@ -20,6 +22,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +@SuppressWarnings("Duplicates") +@OnlyIn(Dist.CLIENT) public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png"); @@ -42,7 +46,13 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { id = super.initGui(id, buttonList); int y = top - 2; - buttonMirrorEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false); + buttonMirrorEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + setCollapsed(!buttonMirrorEnabled.isChecked()); + } + }; buttonList.add(buttonMirrorEnabled); y = top + 18; @@ -82,19 +92,62 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { mirrorNumberFieldList.add(textMirrorRadius); y = top + 72; - buttonCurrentPosition = new GuiIconButton(id++, left + 5, y, 0, 0, BUILDING_ICONS); + buttonCurrentPosition = new GuiIconButton(id++, left + 5, y, 0, 0, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5); + textMirrorPosX.setNumber(pos.x); + textMirrorPosY.setNumber(pos.y); + textMirrorPosZ.setNumber(pos.z); + } + }; buttonCurrentPosition.setTooltip("Set mirror position to current player position"); mirrorIconButtonList.add(buttonCurrentPosition); - buttonToggleOdd = new GuiIconButton(id++, left + 35, y, 0, 20, BUILDING_ICONS); + buttonToggleOdd = new GuiIconButton(id++, left + 35, y, 0, 20, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + toggleOdd = !toggleOdd; + buttonToggleOdd.setUseAlternateIcon(toggleOdd); + if (toggleOdd) { + buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds")); + textMirrorPosX.setNumber(textMirrorPosX.getNumber() + 0.5); + textMirrorPosY.setNumber(textMirrorPosY.getNumber() + 0.5); + textMirrorPosZ.setNumber(textMirrorPosZ.getNumber() + 0.5); + } else { + buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); + textMirrorPosX.setNumber(Math.floor(textMirrorPosX.getNumber())); + textMirrorPosY.setNumber(Math.floor(textMirrorPosY.getNumber())); + textMirrorPosZ.setNumber(Math.floor(textMirrorPosZ.getNumber())); + } + } + }; buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); mirrorIconButtonList.add(buttonToggleOdd); - buttonDrawLines = new GuiIconButton(id++, left + 65, y, 0, 40, BUILDING_ICONS); + buttonDrawLines = new GuiIconButton(id++, left + 65, y, 0, 40, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + drawLines = !drawLines; + buttonDrawLines.setUseAlternateIcon(drawLines); + buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); + } + }; buttonDrawLines.setTooltip("Show lines"); mirrorIconButtonList.add(buttonDrawLines); - buttonDrawPlanes = new GuiIconButton(id++, left + 95, y, 0, 60, BUILDING_ICONS); + buttonDrawPlanes = new GuiIconButton(id++, left + 95, y, 0, 60, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + drawPlanes = !drawPlanes; + buttonDrawPlanes.setUseAlternateIcon(drawPlanes); + buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); + } + }; buttonDrawPlanes.setTooltip("Show area"); mirrorIconButtonList.add(buttonDrawPlanes); @@ -142,31 +195,30 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { @Override public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partialTicks) { - super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partialTicks); - + int yy = y; int offset = 8; - buttonMirrorEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks); + buttonMirrorEnabled.render(mouseX, mouseY, partialTicks); if (buttonMirrorEnabled.isChecked()) { buttonMirrorEnabled.y = yy; - fontRenderer.drawString("Mirror enabled", left + offset, yy + 2, 0xFFFFFF, true); + fontRenderer.drawString("Mirror enabled", left + offset, yy + 2, 0xFFFFFF); yy = y + 18; - fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF, true); - fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF); + fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF); textMirrorPosX.y = yy; - fontRenderer.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF); textMirrorPosY.y = yy; - fontRenderer.drawString("Z", left + 200 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Z", left + 200 + offset, yy + 5, 0xFFFFFF); textMirrorPosZ.y = yy; yy = y + 50; - fontRenderer.drawString("Direction", left + offset, yy + 2, 0xFFFFFF, true); + fontRenderer.drawString("Direction", left + offset, yy + 2, 0xFFFFFF); buttonMirrorX.y = yy; buttonMirrorY.y = yy; buttonMirrorZ.y = yy; - fontRenderer.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF, true); + fontRenderer.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF); textMirrorRadius.y = yy - 3; yy = y + 72; @@ -175,12 +227,12 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { buttonDrawLines.y = yy; buttonDrawPlanes.y = yy; - mirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); - mirrorIconButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); - mirrorNumberFieldList.forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks)); + mirrorButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); + mirrorIconButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); + mirrorNumberFieldList.forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks)); } else { buttonMirrorEnabled.y = yy; - fontRenderer.drawString("Mirror disabled", left + offset, yy + 2, 0x999999, true); + fontRenderer.drawString("Mirror disabled", left + offset, yy + 2, 0x999999); } } @@ -195,74 +247,28 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { } @Override - public void updatePosition(int slotIndex, int x, int y, float partialTicks) { - super.updatePosition(slotIndex, x, y, partialTicks); - } - - @Override - public void keyTyped(char typedChar, int keyCode) throws IOException { - super.keyTyped(typedChar, keyCode); + public boolean charTyped(char typedChar, int keyCode) { + super.charTyped(typedChar, keyCode); for (GuiNumberField numberField : mirrorNumberFieldList) { - numberField.keyTyped(typedChar, keyCode); + numberField.charTyped(typedChar, keyCode); } + return true; } @Override public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { - super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY); mirrorNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent)); boolean insideMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; if (insideMirrorEnabledLabel) { - buttonMirrorEnabled.setIsChecked(!buttonMirrorEnabled.isChecked()); buttonMirrorEnabled.playPressSound(this.mc.getSoundHandler()); - actionPerformed(buttonMirrorEnabled); + buttonMirrorEnabled.onClick(mouseX, mouseY); } return true; } - @Override - public void actionPerformed(GuiButton button) { - super.actionPerformed(button); - if (button == buttonMirrorEnabled) { - setCollapsed(!buttonMirrorEnabled.isChecked()); - } - if (button == buttonCurrentPosition) { - Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5); - textMirrorPosX.setNumber(pos.x); - textMirrorPosY.setNumber(pos.y); - textMirrorPosZ.setNumber(pos.z); - } - if (button == buttonToggleOdd) { - toggleOdd = !toggleOdd; - buttonToggleOdd.setUseAlternateIcon(toggleOdd); - if (toggleOdd) { - buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds")); - textMirrorPosX.setNumber(textMirrorPosX.getNumber() + 0.5); - textMirrorPosY.setNumber(textMirrorPosY.getNumber() + 0.5); - textMirrorPosZ.setNumber(textMirrorPosZ.getNumber() + 0.5); - } else { - buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); - textMirrorPosX.setNumber(Math.floor(textMirrorPosX.getNumber())); - textMirrorPosY.setNumber(Math.floor(textMirrorPosY.getNumber())); - textMirrorPosZ.setNumber(Math.floor(textMirrorPosZ.getNumber())); - } - } - if (button == buttonDrawLines) { - drawLines = !drawLines; - buttonDrawLines.setUseAlternateIcon(drawLines); - buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); - } - if (button == buttonDrawPlanes) { - drawPlanes = !drawPlanes; - buttonDrawPlanes.setUseAlternateIcon(drawPlanes); - buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); - } - mirrorNumberFieldList.forEach(numberField -> numberField.actionPerformed(button)); - } - public Mirror.MirrorSettings getMirrorSettings() { boolean mirrorEnabled = buttonMirrorEnabled.isChecked(); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java index b317b4c..66fe6a6 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java @@ -1,7 +1,10 @@ package nl.requios.effortlessbuilding.gui.buildmodifier; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.Mirror; @@ -9,10 +12,12 @@ import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import nl.requios.effortlessbuilding.gui.elements.GuiScrollPane; import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; +import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.proxy.ClientProxy; import java.io.IOException; +@OnlyIn(Dist.CLIENT) public class ModifierSettingsGui extends GuiScreen { private GuiScrollPane scrollPane; @@ -30,68 +35,79 @@ public class ModifierSettingsGui extends GuiScreen { scrollPane = new GuiScrollPane(this, fontRenderer, 8, height - 30); mirrorSettingsGui = new MirrorSettingsGui(scrollPane); - scrollPane.listEntries.add(mirrorSettingsGui); + scrollPane.AddListEntry(mirrorSettingsGui); arraySettingsGui = new ArraySettingsGui(scrollPane); - scrollPane.listEntries.add(arraySettingsGui); + scrollPane.AddListEntry(arraySettingsGui); radialMirrorSettingsGui = new RadialMirrorSettingsGui(scrollPane); - scrollPane.listEntries.add(radialMirrorSettingsGui); + scrollPane.AddListEntry(radialMirrorSettingsGui); - id = scrollPane.initGui(id, buttonList); + id = scrollPane.initGui(id, buttons); //Close button int y = height - 26; - buttonClose = new GuiButton(id++, width / 2 - 100, y, "Close"); - buttonList.add(buttonClose); + buttonClose = new GuiButton(id++, width / 2 - 100, y, "Close") { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + mc.player.closeScreen(); + } + }; + buttons.add(buttonClose); } @Override //Process general logic, i.e. hide buttons - public void updateScreen() { + public void tick() { scrollPane.updateScreen(); + + handleMouseInput(); } @Override //Set colors using GL11, use the fontRendererObj field to display text //Use drawTexturedModalRect() to transfers areas of a texture resource to the screen - public void drawScreen(int mouseX, int mouseY, float partialTicks) { + public void render(int mouseX, int mouseY, float partialTicks) { this.drawDefaultBackground(); scrollPane.drawScreen(mouseX, mouseY, partialTicks); - buttonClose.drawButton(this.mc, mouseX, mouseY, partialTicks); + buttonClose.render(mouseX, mouseY, partialTicks); scrollPane.drawTooltip(this, mouseX, mouseY); } + @Override - protected void keyTyped(char typedChar, int keyCode) throws IOException { - super.keyTyped(typedChar, keyCode); - scrollPane.keyTyped(typedChar, keyCode); - if (keyCode == ClientProxy.keyBindings[0].getKeyCode()) { + public boolean charTyped(char typedChar, int keyCode) { + super.charTyped(typedChar, keyCode); + scrollPane.charTyped(typedChar, keyCode); + if (keyCode == ClientProxy.keyBindings[0].getKey().getKeyCode()) { mc.player.closeScreen(); } + return false; } @Override - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { super.mouseClicked(mouseX, mouseY, mouseButton); - scrollPane.mouseClicked(mouseX, mouseY, mouseButton); + buttons.forEach(button -> button.mouseClicked(mouseX, mouseY, mouseButton)); + return scrollPane.mouseClicked(mouseX, mouseY, mouseButton); } @Override - protected void mouseReleased(int mouseX, int mouseY, int state) { + public boolean mouseReleased(double mouseX, double mouseY, int state) { if (state != 0 || !scrollPane.mouseReleased(mouseX, mouseY, state)) { - super.mouseReleased(mouseX, mouseY, state); + return super.mouseReleased(mouseX, mouseY, state); } + return false; } - @Override - public void handleMouseInput() throws IOException { - super.handleMouseInput(); + public void handleMouseInput() { + //super.handleMouseInput(); scrollPane.handleMouseInput(); //Scrolling numbers @@ -100,15 +116,6 @@ public class ModifierSettingsGui extends GuiScreen { // numberFieldList.forEach(numberField -> numberField.handleMouseInput(mouseX, mouseY)); } - @Override - protected void actionPerformed(GuiButton button) { - //check what button and action type (left/right click) - if (button == buttonClose) { - mc.player.closeScreen(); - } - scrollPane.actionPerformed(button); - } - @Override public void onGuiClosed() { scrollPane.onGuiClosed(); @@ -131,7 +138,10 @@ public class ModifierSettingsGui extends GuiScreen { ModifierSettingsManager.setModifierSettings(mc.player, modifierSettings); //Send to server - EffortlessBuilding.packetHandler.sendToServer(new ModifierSettingsMessage(modifierSettings)); + PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings)); + + //TODO fix not being able to scroll after this gui has opened + Minecraft.getInstance().mouseHelper.grabMouse(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorSettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorSettingsGui.java index 0e01414..7c73c5b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorSettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorSettingsGui.java @@ -5,6 +5,8 @@ import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.client.config.GuiCheckBox; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; @@ -20,6 +22,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +@SuppressWarnings("Duplicates") +@OnlyIn(Dist.CLIENT) public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png"); @@ -42,7 +46,13 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { id = super.initGui(id, buttonList); int y = top - 2; - buttonRadialMirrorEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false); + buttonRadialMirrorEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + setCollapsed(!buttonRadialMirrorEnabled.isChecked()); + } + }; buttonList.add(buttonRadialMirrorEnabled); y = top + 18; @@ -76,21 +86,63 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { TextFormatting.GRAY + "Upgradeable in survival with reach upgrades.")); radialMirrorNumberFieldList.add(textRadialMirrorRadius); - y = top + 72; - buttonCurrentPosition = new GuiIconButton(id++, left + 5, y, 0, 0, BUILDING_ICONS); + buttonCurrentPosition = new GuiIconButton(id++, left + 5, y, 0, 0, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5); + textRadialMirrorPosX.setNumber(pos.x); + textRadialMirrorPosY.setNumber(pos.y); + textRadialMirrorPosZ.setNumber(pos.z); + } + }; buttonCurrentPosition.setTooltip("Set radial mirror position to current player position"); radialMirrorIconButtonList.add(buttonCurrentPosition); - buttonToggleOdd = new GuiIconButton(id++, left + 35, y, 0, 20, BUILDING_ICONS); + buttonToggleOdd = new GuiIconButton(id++, left + 35, y, 0, 20, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + toggleOdd = !toggleOdd; + buttonToggleOdd.setUseAlternateIcon(toggleOdd); + if (toggleOdd) { + buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds")); + textRadialMirrorPosX.setNumber(textRadialMirrorPosX.getNumber() + 0.5); + textRadialMirrorPosY.setNumber(textRadialMirrorPosY.getNumber() + 0.5); + textRadialMirrorPosZ.setNumber(textRadialMirrorPosZ.getNumber() + 0.5); + } else { + buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); + textRadialMirrorPosX.setNumber(Math.floor(textRadialMirrorPosX.getNumber())); + textRadialMirrorPosY.setNumber(Math.floor(textRadialMirrorPosY.getNumber())); + textRadialMirrorPosZ.setNumber(Math.floor(textRadialMirrorPosZ.getNumber())); + } + } + }; buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to middle of block", "for odd numbered builds")); radialMirrorIconButtonList.add(buttonToggleOdd); - buttonDrawLines = new GuiIconButton(id++, left + 65, y, 0, 40, BUILDING_ICONS); + buttonDrawLines = new GuiIconButton(id++, left + 65, y, 0, 40, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + drawLines = !drawLines; + buttonDrawLines.setUseAlternateIcon(drawLines); + buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); + } + }; buttonDrawLines.setTooltip("Show lines"); radialMirrorIconButtonList.add(buttonDrawLines); - buttonDrawPlanes = new GuiIconButton(id++, left + 95, y, 0, 60, BUILDING_ICONS); + buttonDrawPlanes = new GuiIconButton(id++, left + 95, y, 0, 60, BUILDING_ICONS) { + @Override + public void onClick(double mouseX, double mouseY) { + super.onClick(mouseX, mouseY); + drawPlanes = !drawPlanes; + buttonDrawPlanes.setUseAlternateIcon(drawPlanes); + buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); + } + }; buttonDrawPlanes.setTooltip("Show area"); radialMirrorIconButtonList.add(buttonDrawPlanes); @@ -132,38 +184,36 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { return id; } - @Override public void updateScreen() { - super.updateScreen(); radialMirrorNumberFieldList.forEach(GuiNumberField::update); } + @Override public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partialTicks) { - super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partialTicks); int yy = y; int offset = 8; - buttonRadialMirrorEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks); + buttonRadialMirrorEnabled.render(mouseX, mouseY, partialTicks); if (buttonRadialMirrorEnabled.isChecked()) { buttonRadialMirrorEnabled.y = yy; - fontRenderer.drawString("Radial mirror enabled", left + offset, yy + 2, 0xFFFFFF, true); + fontRenderer.drawString("Radial mirror enabled", left + offset, yy + 2, 0xFFFFFF); yy = y + 18; - fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF, true); - fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF); + fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF); textRadialMirrorPosX.y = yy; - fontRenderer.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Y", left + 120 + offset, yy + 5, 0xFFFFFF); textRadialMirrorPosY.y = yy; - fontRenderer.drawString("Z", left + 200 + offset, yy + 5, 0xFFFFFF, true); + fontRenderer.drawString("Z", left + 200 + offset, yy + 5, 0xFFFFFF); textRadialMirrorPosZ.y = yy; yy = y + 50; - fontRenderer.drawString("Slices", left + offset, yy + 2, 0xFFFFFF, true); + fontRenderer.drawString("Slices", left + offset, yy + 2, 0xFFFFFF); textRadialMirrorSlices.y = yy - 3; - fontRenderer.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF, true); + fontRenderer.drawString("Radius", left + 176 + offset, yy + 2, 0xFFFFFF); textRadialMirrorRadius.y = yy - 3; yy = y + 72; @@ -175,13 +225,13 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { yy = y + 76; buttonRadialMirrorAlternate.y = yy; - radialMirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); - radialMirrorIconButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); + radialMirrorButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); + radialMirrorIconButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks)); radialMirrorNumberFieldList - .forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks)); + .forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks)); } else { buttonRadialMirrorEnabled.y = yy; - fontRenderer.drawString("Radial mirror disabled", left + offset, yy + 2, 0x999999, true); + fontRenderer.drawString("Radial mirror disabled", left + offset, yy + 2, 0x999999); } } @@ -196,74 +246,28 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { } @Override - public void updatePosition(int slotIndex, int x, int y, float partialTicks) { - super.updatePosition(slotIndex, x, y, partialTicks); - } - - @Override - public void keyTyped(char typedChar, int keyCode) throws IOException { - super.keyTyped(typedChar, keyCode); + public boolean charTyped(char typedChar, int keyCode) { + super.charTyped(typedChar, keyCode); for (GuiNumberField numberField : radialMirrorNumberFieldList) { - numberField.keyTyped(typedChar, keyCode); + numberField.charTyped(typedChar, keyCode); } + return true; } @Override public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { - super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY); radialMirrorNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent)); boolean insideRadialMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; if (insideRadialMirrorEnabledLabel) { - buttonRadialMirrorEnabled.setIsChecked(!buttonRadialMirrorEnabled.isChecked()); buttonRadialMirrorEnabled.playPressSound(this.mc.getSoundHandler()); - actionPerformed(buttonRadialMirrorEnabled); + buttonRadialMirrorEnabled.onClick(mouseX, mouseY); } return true; } - @Override - public void actionPerformed(GuiButton button) { - super.actionPerformed(button); - if (button == buttonRadialMirrorEnabled) { - setCollapsed(!buttonRadialMirrorEnabled.isChecked()); - } - if (button == buttonCurrentPosition) { - Vec3d pos = new Vec3d(Math.floor(mc.player.posX) + 0.5, Math.floor(mc.player.posY) + 0.5, Math.floor(mc.player.posZ) + 0.5); - textRadialMirrorPosX.setNumber(pos.x); - textRadialMirrorPosY.setNumber(pos.y); - textRadialMirrorPosZ.setNumber(pos.z); - } - if (button == buttonToggleOdd) { - toggleOdd = !toggleOdd; - buttonToggleOdd.setUseAlternateIcon(toggleOdd); - if (toggleOdd) { - buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to corner of block", "for even numbered builds")); - textRadialMirrorPosX.setNumber(textRadialMirrorPosX.getNumber() + 0.5); - textRadialMirrorPosY.setNumber(textRadialMirrorPosY.getNumber() + 0.5); - textRadialMirrorPosZ.setNumber(textRadialMirrorPosZ.getNumber() + 0.5); - } else { - buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds")); - textRadialMirrorPosX.setNumber(Math.floor(textRadialMirrorPosX.getNumber())); - textRadialMirrorPosY.setNumber(Math.floor(textRadialMirrorPosY.getNumber())); - textRadialMirrorPosZ.setNumber(Math.floor(textRadialMirrorPosZ.getNumber())); - } - } - if (button == buttonDrawLines) { - drawLines = !drawLines; - buttonDrawLines.setUseAlternateIcon(drawLines); - buttonDrawLines.setTooltip(drawLines ? "Hide lines" : "Show lines"); - } - if (button == buttonDrawPlanes) { - drawPlanes = !drawPlanes; - buttonDrawPlanes.setUseAlternateIcon(drawPlanes); - buttonDrawPlanes.setTooltip(drawPlanes ? "Hide area" : "Show area"); - } - radialMirrorNumberFieldList.forEach(numberField -> numberField.actionPerformed(button)); - } - public RadialMirror.RadialMirrorSettings getRadialMirrorSettings() { boolean radialMirrorEnabled = buttonRadialMirrorEnabled.isChecked(); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiCollapsibleScrollEntry.java b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiCollapsibleScrollEntry.java index a123163..c67fa33 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiCollapsibleScrollEntry.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiCollapsibleScrollEntry.java @@ -4,10 +4,14 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.IGuiEventListener; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import java.io.IOException; import java.util.List; +@OnlyIn(Dist.CLIENT) public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScrollEntry { public GuiScrollPane scrollPane; @@ -36,18 +40,10 @@ public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScroll @Override public void updateScreen() { - - } - - @Override - public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, - boolean isSelected, float partialTicks) { - } @Override public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) { - } @Override @@ -56,8 +52,8 @@ public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScroll } @Override - public void keyTyped(char eventChar, int eventKey) throws IOException { - + public boolean charTyped(char eventChar, int eventKey) { + return false; } @Override @@ -70,14 +66,8 @@ public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScroll } - @Override - public void actionPerformed(GuiButton button) { - - } - @Override public void onGuiClosed() { - } @Override diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiIconButton.java b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiIconButton.java index 9dbd0dc..5d8f5f9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiIconButton.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiIconButton.java @@ -4,11 +4,14 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.util.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +@OnlyIn(Dist.CLIENT) public class GuiIconButton extends GuiButton { private final ResourceLocation resourceLocation; @@ -44,12 +47,12 @@ public class GuiIconButton extends GuiButton { } @Override - public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { - super.drawButton(mc, mouseX, mouseY, partialTicks); + public void render(int mouseX, int mouseY, float partialTicks) { + super.render(mouseX, mouseY, partialTicks); if (this.visible) { this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; - mc.getTextureManager().bindTexture(this.resourceLocation); + Minecraft.getInstance().getTextureManager().bindTexture(this.resourceLocation); int currentIconX = this.iconX; int currentIconY = this.iconY; diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiNumberField.java b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiNumberField.java index 6f87587..55cb69b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiNumberField.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiNumberField.java @@ -3,13 +3,17 @@ package nl.requios.effortlessbuilding.gui.elements; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.*; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import java.io.IOException; import java.text.DecimalFormat; +import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +@OnlyIn(Dist.CLIENT) public class GuiNumberField extends Gui { public int x, y, width, height; @@ -28,21 +32,42 @@ public class GuiNumberField extends Gui { this.height = height; textField = new GuiTextField(id1, fontRenderer, x + buttonWidth + 1, y + 1, width - 2 * buttonWidth - 2, height - 2); - minusButton = new GuiButton(id2, x, y - 1, buttonWidth, height + 2, "-"); - plusButton = new GuiButton(id3, x + width - buttonWidth, y - 1, buttonWidth, height + 2, "+"); + minusButton = new GuiButton(id2, x, y - 1, buttonWidth, height + 2, "-") { + @Override + public void onClick(double mouseX, double mouseY) { + float valueChanged = 1f; + if (GuiScreen.isCtrlKeyDown()) valueChanged = 5f; + if (GuiScreen.isShiftKeyDown()) valueChanged = 10f; + + setNumber(getNumber() - valueChanged); + } + }; + plusButton = new GuiButton(id3, x + width - buttonWidth, y - 1, buttonWidth, height + 2, "+") { + @Override + public void onClick(double mouseX, double mouseY) { + float valueChanged = 1f; + if (GuiScreen.isCtrlKeyDown()) valueChanged = 5f; + if (GuiScreen.isShiftKeyDown()) valueChanged = 10f; + + setNumber(getNumber() + valueChanged); + } + }; buttonList.add(minusButton); buttonList.add(plusButton); } public void setNumber(double number) { - DecimalFormat format = new DecimalFormat("0.#"); - textField.setText(format.format(number)); + textField.setText(DecimalFormat.getInstance().format(number)); } public double getNumber() { if (textField.getText().isEmpty()) return 0; - return Double.parseDouble(textField.getText()); + try { + return DecimalFormat.getInstance().parse(textField.getText()).doubleValue(); + } catch (ParseException e) { + return 0; + } } public void setTooltip(String tooltip) { @@ -53,7 +78,7 @@ public class GuiNumberField extends Gui { this.tooltip = tooltip; } - public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) { + public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { boolean result = textField.mouseClicked(mouseX, mouseY, mouseButton); //Check if clicked inside textfield @@ -69,14 +94,14 @@ public class GuiNumberField extends Gui { return result; } - public void drawNumberField(Minecraft mc, int mouseX, int mouseY, float partialTicks) { + public void drawNumberField(int mouseX, int mouseY, float partialTicks) { textField.y = y + 1; minusButton.y = y - 1; plusButton.y = y - 1; - textField.drawTextBox(); - minusButton.drawButton(mc, mouseX, mouseY, partialTicks); - plusButton.drawButton(mc, mouseX, mouseY, partialTicks); + textField.drawTextField(mouseX, mouseY, partialTicks); + minusButton.render(mouseX, mouseY, partialTicks); + plusButton.render(mouseX, mouseY, partialTicks); } public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) { @@ -106,33 +131,21 @@ public class GuiNumberField extends Gui { } - public void actionPerformed(GuiButton button) { - float valueChanged = 1f; - if (GuiScreen.isCtrlKeyDown()) valueChanged = 5f; - if (GuiScreen.isShiftKeyDown()) valueChanged = 10f; - - if (button == minusButton) { - setNumber(getNumber() - valueChanged); - } - if (button == plusButton) { - setNumber(getNumber() + valueChanged); - } - } - public void update() { - textField.updateCursorCounter(); + textField.tick(); } - public void keyTyped(char typedChar, int keyCode) throws IOException { - if (!textField.isFocused()) return; + public boolean charTyped(char typedChar, int keyCode) { + if (!textField.isFocused()) return false; // if (Character.isDigit(typedChar) || typedChar == '.' || typedChar == '-' || keyCode == Keyboard.KEY_BACK // || keyCode == Keyboard.KEY_DELETE || keyCode == Keyboard.KEY_LEFT || keyCode == Keyboard.KEY_RIGHT // || keyCode == Keyboard.KEY_UP || keyCode == Keyboard.KEY_DOWN) { - textField.textboxKeyTyped(typedChar, keyCode); + return textField.charTyped(typedChar, keyCode); // } } //Scroll inside textfield to change number + //Disabled because entire screen can be scrolled // public void handleMouseInput(int mouseX, int mouseY) { // boolean insideTextField = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height; // diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java index 2c26729..e046993 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java @@ -1,30 +1,37 @@ package nl.requios.effortlessbuilding.gui.elements; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiListExtended; -import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.MouseHelper; +import net.minecraft.client.gui.*; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.lwjgl.input.Mouse; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.glfw.GLFW; +import sun.security.ssl.Debug; import java.io.IOException; import java.util.ArrayList; import java.util.List; -@SideOnly(Side.CLIENT) -public class GuiScrollPane extends GuiListExtended { +@OnlyIn(Dist.CLIENT) +public class GuiScrollPane extends GuiSlot { public GuiScreen parent; public FontRenderer fontRenderer; - public List listEntries; + private List listEntries; + private float scrollMultiplier = 1f; + + private int mouseX; + private int mouseY; public GuiScrollPane(GuiScreen parent, FontRenderer fontRenderer, int top, int bottom) { super(parent.mc, parent.width, parent.height, top, bottom, 100); @@ -32,18 +39,27 @@ public class GuiScrollPane extends GuiListExtended { this.fontRenderer = fontRenderer; this.setShowSelectionBox(false); listEntries = new ArrayList<>(); + MinecraftForge.EVENT_BUS.register(this); } - @Override - public IGuiListEntry getListEntry(int index) { + public IScrollEntry getListEntry(int index) { return listEntries.get(index); } + public void AddListEntry(IScrollEntry listEntry){ + listEntries.add(listEntry); + } + @Override protected int getSize() { return listEntries.size(); } + @Override + protected boolean isSelected(int slotIndex) { + return false; + } + @Override protected int getScrollBarX() { //return width / 2 + 140 + 10; @@ -80,15 +96,15 @@ public class GuiScrollPane extends GuiListExtended { //All entries this.drawSelectionBox(insideLeft, insideTop, mouseXIn, mouseYIn, partialTicks); - GlStateManager.disableDepth(); + GlStateManager.disableDepthTest(); //Dirt overlays on top and bottom // this.overlayBackground(0, this.top, 255, 255); // this.overlayBackground(this.bottom, this.height, 255, 255); GlStateManager.enableBlend(); - GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); - GlStateManager.disableAlpha(); + GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); + GlStateManager.disableAlphaTest(); GlStateManager.shadeModel(7425); GlStateManager.disableTexture2D(); @@ -161,7 +177,7 @@ public class GuiScrollPane extends GuiListExtended { GlStateManager.enableTexture2D(); GlStateManager.shadeModel(7424); - GlStateManager.enableAlpha(); + GlStateManager.enableAlphaTest(); GlStateManager.disableBlend(); } } @@ -178,6 +194,17 @@ public class GuiScrollPane extends GuiListExtended { return height; } + @Override + protected void drawBackground() { + + } + + @Override + protected void drawSlot(int slotIndex, int xPos, int yPos, int heightIn, int mouseXIn, int mouseYIn, float partialTicks) { + this.getListEntry(slotIndex).drawEntry(slotIndex, xPos, yPos, this.getListWidth(), heightIn, mouseXIn, mouseYIn, + this.getSlotIndexFromScreenCoords(mouseXIn, mouseYIn) == slotIndex, partialTicks); + } + public int getContentHeight(int count) { //Add all count entry heights int height = this.headerPadding; @@ -188,11 +215,10 @@ public class GuiScrollPane extends GuiListExtended { return height; } - @Override - public int getSlotIndexFromScreenCoords(int posX, int posY) { + public int getSlotIndexFromScreenCoords(double posX, double posY) { int left = this.left + (this.width - this.getListWidth()) / 2; int right = this.left + (this.width + this.getListWidth()) / 2; - int relativeMouseY = getRelativeMouseY(mouseY, 0); + double relativeMouseY = getRelativeMouseY(mouseY, 0); //Iterate over every entry until relativeMouseY falls within its height for (int i = 0; i < listEntries.size(); i++) { @@ -206,15 +232,14 @@ public class GuiScrollPane extends GuiListExtended { } @Override - public boolean mouseClicked(int mouseX, int mouseY, int mouseEvent) - { + protected boolean mouseClicked(int index, int button, double mouseX, double mouseY) { int selectedSlot = this.getSlotIndexFromScreenCoords(mouseX, mouseY); - int relativeX = getRelativeMouseX(mouseX); + double relativeX = getRelativeMouseX(mouseX); //Always pass through mouseclicked, to be able to unfocus textfields for (int i = 0; i < this.listEntries.size(); i++) { - int relativeY = getRelativeMouseY(mouseY, i); - this.getListEntry(i).mousePressed(selectedSlot, mouseX, mouseY, mouseEvent, relativeX, relativeY); + double relativeY = getRelativeMouseY(mouseY, i); + this.getListEntry(i).mousePressed(selectedSlot, (int) mouseX, (int) mouseY, button, (int) relativeX, (int) relativeY); } @@ -239,38 +264,36 @@ public class GuiScrollPane extends GuiListExtended { } @Override - public boolean mouseReleased(int x, int y, int mouseEvent) - { + public boolean mouseReleased(double p_mouseReleased_1_, double p_mouseReleased_3_, int p_mouseReleased_5_) { for (int i = 0; i < this.getSize(); ++i) { - int relativeX = getRelativeMouseX(mouseX); - int relativeY = getRelativeMouseY(mouseY, i); - this.getListEntry(i).mouseReleased(i, x, y, mouseEvent, relativeX, relativeY); + double relativeX = getRelativeMouseX(mouseX); + double relativeY = getRelativeMouseY(mouseY, i); + this.getListEntry(i).mouseReleased(i, (int) p_mouseReleased_1_, (int) p_mouseReleased_3_, p_mouseReleased_5_, (int) relativeX, (int) relativeY); } - this.setEnabled(true); + this.visible = true; return false; } - @Override public void handleMouseInput() { - if (this.isMouseYWithinSlotBounds(this.mouseY)) { - if (Mouse.getEventButton() == 0 && Mouse.getEventButtonState() && this.mouseY >= this.top && + if (this.isMouseInList(this.mouseX, this.mouseY)) { + if (mc.mouseHelper.isLeftDown() && this.mouseY >= this.top && this.mouseY <= this.bottom) { int i = this.left + (this.width - this.getListWidth()) / 2; int j = this.left + (this.width + this.getListWidth()) / 2; int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY); - int relativeMouseY = getRelativeMouseY(mouseY, slotIndex); + double relativeMouseY = getRelativeMouseY(mouseY, slotIndex); if (slotIndex > -1) { - this.elementClicked(slotIndex, false, this.mouseX, this.mouseY); + this.mouseClicked(slotIndex, 0, this.mouseX, this.mouseY); this.selectedElement = slotIndex; } else if (this.mouseX >= i && this.mouseX <= j && relativeMouseY < 0) { this.clickedHeader(this.mouseX - i, this.mouseY - this.top + (int) this.amountScrolled - 4); } } - if (Mouse.isButtonDown(0) && this.getEnabled()) { + if (mc.mouseHelper.isLeftDown() && this.isVisible()) { if (this.initialClickY == -1) { boolean flag1 = true; @@ -278,14 +301,15 @@ public class GuiScrollPane extends GuiListExtended { int i2 = this.left + (this.width - this.getListWidth()) / 2; int j2 = this.left + (this.width + this.getListWidth()) / 2; int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY); - int relativeMouseY = getRelativeMouseY(mouseY, slotIndex); + double relativeMouseY = getRelativeMouseY(mouseY, slotIndex); if (slotIndex > -1) { + //TODO 1.13 use flag boolean flag = slotIndex == this.selectedElement && - Minecraft.getSystemTime() - this.lastClicked < 250L; - this.elementClicked(slotIndex, flag, this.mouseX, this.mouseY); + Util.milliTime() - this.lastClicked < 250L; + this.mouseClicked(slotIndex, this.mouseX, this.mouseY); this.selectedElement = slotIndex; - this.lastClicked = Minecraft.getSystemTime(); + this.lastClicked = Util.milliTime(); } else if (this.mouseX >= i2 && this.mouseX <= j2 && relativeMouseY < 0) { this.clickedHeader(this.mouseX - i2, this.mouseY - this.top + (int) this.amountScrolled - 4); @@ -327,17 +351,21 @@ public class GuiScrollPane extends GuiListExtended { this.initialClickY = -1; } - int i2 = Mouse.getEventDWheel(); + } + } - if (i2 != 0) { - if (i2 > 0) { - i2 = -1; - } else if (i2 < 0) { - i2 = 1; - } - - this.amountScrolled += (float) (i2 * this.slotHeight / 2); + //Through forge event instead of through the parent, because the parent no longer has scroll functionality in 1.13 + @SubscribeEvent + public void mouseScrolled(GuiScreenEvent.MouseScrollEvent.Pre event) { + double scrollDelta = event.getScrollDelta(); + if (scrollDelta != 0) { + if (scrollDelta > 0) { + scrollDelta = -1; + } else if (scrollDelta < 0) { + scrollDelta = 1; } + + this.amountScrolled += (float) (scrollDelta * this.slotHeight / 2); } } @@ -374,7 +402,7 @@ public class GuiScrollPane extends GuiListExtended { { int i1 = this.left + this.width / 2 - this.getListWidth() / 2; int j1 = this.left + this.width / 2 + this.getListWidth() / 2; - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.disableTexture2D(); bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); bufferbuilder.pos((double)i1, (double)(y + entryHeight2 + 2), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex(); @@ -394,14 +422,14 @@ public class GuiScrollPane extends GuiListExtended { } } - private int getRelativeMouseX(int mouseX) { + private double getRelativeMouseX(double mouseX) { int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; return mouseX - j; } - private int getRelativeMouseY(int mouseY, int contentIndex) { + private double getRelativeMouseY(double mouseY, int contentIndex) { int k = this.top + 4 - this.getAmountScrolled() + getContentHeight(contentIndex) + this.headerPadding; - int relativeMouseY = mouseY - k; + double relativeMouseY = mouseY - k; //Content might be centered, adjust relative mouse y accordingly int contentHeight = getContentHeight(); @@ -419,7 +447,6 @@ public class GuiScrollPane extends GuiListExtended { for (IScrollEntry entry : this.listEntries) { id = entry.initGui(id, buttonList); } - registerScrollButtons(id++, id++); return id; } @@ -433,14 +460,11 @@ public class GuiScrollPane extends GuiListExtended { entry.drawTooltip(guiScreen, mouseX, mouseY); } - public void keyTyped(char eventChar, int eventKey) throws IOException { + @Override + public boolean charTyped(char eventChar, int eventKey) { for (IScrollEntry entry : this.listEntries) - entry.keyTyped(eventChar, eventKey); - } - - public void actionPerformed(GuiButton button) { - for (IScrollEntry entry : this.listEntries) - entry.actionPerformed(button); + entry.charTyped(eventChar, eventKey); + return false; } public void onGuiClosed() { @@ -448,19 +472,32 @@ public class GuiScrollPane extends GuiListExtended { entry.onGuiClosed(); } - public interface IScrollEntry extends GuiListExtended.IGuiListEntry { + public interface IScrollEntry { int initGui(int id, List buttonList); void updateScreen(); void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY); - void keyTyped(char eventChar, int eventKey) throws IOException; - - void actionPerformed(GuiButton button); + boolean charTyped(char eventChar, int eventKey); void onGuiClosed(); int getHeight(); + + void updatePosition(int slotIndex, int x, int y, float partialTicks); + + void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected, float partialTicks); + + /** + * Called when the mouse is clicked within this entry. Returning true means that something within this entry was + * clicked and the list should not be dragged. + */ + boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY); + + /** + * Fired when the mouse button is released. Arguments: index, x, y, mouseEvent, relativeX, relativeY + */ + void mouseReleased(int slotIndex, int x, int y, int mouseEvent, int relativeX, int relativeY); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/ReachConditionFactory.java b/src/main/java/nl/requios/effortlessbuilding/helper/ReachConditionFactory.java index e33949b..a5cef28 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/ReachConditionFactory.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/ReachConditionFactory.java @@ -1,15 +1,14 @@ package nl.requios.effortlessbuilding.helper; import com.google.gson.JsonObject; -import net.minecraftforge.common.crafting.IConditionFactory; -import net.minecraftforge.common.crafting.JsonContext; +import net.minecraftforge.common.crafting.IConditionSerializer; import nl.requios.effortlessbuilding.BuildConfig; import java.util.function.BooleanSupplier; -public class ReachConditionFactory implements IConditionFactory { +public class ReachConditionFactory implements IConditionSerializer { @Override - public BooleanSupplier parse(JsonContext context, JsonObject json) { - return () -> BuildConfig.reach.enableReachUpgrades; + public BooleanSupplier parse(JsonObject json) { + return () -> BuildConfig.reach.enableReachUpgrades.get(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java b/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java index e5e6f14..73525db 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java @@ -7,19 +7,19 @@ import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; public class ReachHelper { public static int getMaxReach(EntityPlayer player) { - if (player.isCreative()) return BuildConfig.reach.maxReachCreative; + if (player.isCreative()) return BuildConfig.reach.maxReachCreative.get(); - if (!BuildConfig.reach.enableReachUpgrades) return BuildConfig.reach.maxReachLevel3; + if (!BuildConfig.reach.enableReachUpgrades.get()) return BuildConfig.reach.maxReachLevel3.get(); //Check buildsettings for reachUpgrade int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade(); switch (reachUpgrade) { - case 0: return BuildConfig.reach.maxReachLevel0; - case 1: return BuildConfig.reach.maxReachLevel1; - case 2: return BuildConfig.reach.maxReachLevel2; - case 3: return BuildConfig.reach.maxReachLevel3; + case 0: return BuildConfig.reach.maxReachLevel0.get(); + case 1: return BuildConfig.reach.maxReachLevel1.get(); + case 2: return BuildConfig.reach.maxReachLevel2.get(); + case 3: return BuildConfig.reach.maxReachLevel3.get(); } - return BuildConfig.reach.maxReachLevel0; + return BuildConfig.reach.maxReachLevel0.get(); } public static int getPlacementReach(EntityPlayer player) { @@ -45,6 +45,6 @@ public class ReachHelper { } public static boolean canBreakFar(EntityPlayer player) { - return player.isCreative() || BuildConfig.survivalBalancers.breakFar; + return player.isCreative() || BuildConfig.survivalBalancers.breakFar.get(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java index 0d6baea..6c97c97 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java @@ -1,27 +1,28 @@ package nl.requios.effortlessbuilding.helper; import net.minecraft.block.Block; -import net.minecraft.block.BlockLiquid; import net.minecraft.block.BlockSlab; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.BlockWorldState; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; +import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemSlab; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.World; +import net.minecraftforge.common.ToolType; import nl.requios.effortlessbuilding.BuildConfig; +import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.compatibility.CompatHelper; @@ -41,7 +42,7 @@ public class SurvivalHelper { if (blockState.getBlock().isAir(blockState, world, pos) || itemstack.isEmpty()) { dropBlock(world, player, pos); - world.setBlockToAir(pos); + world.removeBlock(pos); return true; } @@ -60,8 +61,21 @@ public class SurvivalHelper { //Drop existing block dropBlock(world, player, pos); - boolean placed = ((ItemBlock) itemstack.getItem()).placeBlockAt(itemstack, player, world, pos, facing, (float) hitVec.x, (float) hitVec.y, (float) hitVec.z, blockState); - if (!placed) return false; + //TryPlace sets block with offset, so we only do world.setBlockState now + //Remember count of itemstack before tryPlace, and set it back after. + //TryPlace reduces stack even in creative so it is not usable here. +// int origCount = itemstack.getCount(); +// BlockItemUseContext blockItemUseContext = new BlockItemUseContext(world, player, itemstack, pos, facing, (float) hitVec.x, (float) hitVec.y, (float) hitVec.z); +// EnumActionResult result = ((ItemBlock) itemstack.getItem()).tryPlace(blockItemUseContext); +// itemstack.setCount(origCount); + + //Set our (rotated) blockstate + world.setBlockState(pos, blockState, 3); +// blockState.onBlockAdded(world, pos, blockState); +// block.onBlockPlacedBy(world, pos, blockState, player, itemstack); +// world.notifyBlockUpdate(pos, blockState, world.getBlockState(pos), 3); + +// if (result != EnumActionResult.SUCCESS) return false; IBlockState afterState = world.getBlockState(pos); @@ -119,7 +133,7 @@ public class SurvivalHelper { //Damage tool player.getHeldItemMainhand().onBlockDestroyed(world, world.getBlockState(pos), pos, player); - world.setBlockToAir(pos); + world.removeBlock(pos); return true; } return false; @@ -198,9 +212,8 @@ public class SurvivalHelper { if (player.isCreative()) return true; IBlockState state = world.getBlockState(pos); - state = state.getBlock().getActualState(state, world, pos); - switch (BuildConfig.survivalBalancers.quickReplaceMiningLevel) { + switch (BuildConfig.survivalBalancers.quickReplaceMiningLevel.get()) { case -1: return state.getMaterial().isToolNotRequired(); case 0: return state.getBlock().getHarvestLevel(state) <= 0; case 1: return state.getBlock().getHarvestLevel(state) <= 1; @@ -214,7 +227,9 @@ public class SurvivalHelper { //From EntityPlayer#canPlayerEdit private static boolean canPlayerEdit(EntityPlayer player, World world, BlockPos pos, ItemStack stack) { - if (player.capabilities.allowEdit) + if (!world.isBlockModifiable(player, pos)) return false; + + if (player.abilities.allowEdit) { //True in creative and survival mode return true; @@ -222,8 +237,9 @@ public class SurvivalHelper { else { //Adventure mode - Block block = world.getBlockState(pos).getBlock(); - return stack.canPlaceOn(block) || stack.canEditBlocks(); + BlockWorldState blockworldstate = new BlockWorldState(world, pos, false); + return stack.canPlaceOn(world.getTags(), blockworldstate); + } } @@ -231,9 +247,9 @@ public class SurvivalHelper { private static boolean mayPlace(World world, Block blockIn, IBlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) { IBlockState iblockstate1 = world.getBlockState(pos); - AxisAlignedBB axisalignedbb = skipCollisionCheck ? Block.NULL_AABB : blockIn.getDefaultState().getCollisionBoundingBox(world, pos); + VoxelShape voxelShape = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionShape(world, pos); - if (axisalignedbb != Block.NULL_AABB && !world.checkNoEntityCollision(axisalignedbb.offset(pos))) + if (voxelShape != null && !world.checkNoEntityCollision(iblockstate1, pos)) { return false; } @@ -259,7 +275,8 @@ public class SurvivalHelper { return true; } - return iblockstate1.getBlock().isReplaceable(world, pos) && blockIn.canPlaceBlockOnSide(world, pos, sidePlacedOn); + //TODO 1.13 replaceable + return iblockstate1.getMaterial().isReplaceable() /*&& canPlaceBlockOnSide(world, pos, sidePlacedOn)*/; } @@ -267,7 +284,7 @@ public class SurvivalHelper { //Can break using held tool? (or in creative) public static boolean canBreak(World world, EntityPlayer player, BlockPos pos) { IBlockState blockState = world.getBlockState(pos); - if (blockState.getBlock() instanceof BlockLiquid) return false; + if (!world.getFluidState(pos).isEmpty()) return false; if (player.isCreative()) return true; @@ -275,13 +292,12 @@ public class SurvivalHelper { } //From ForgeHooks#canHarvestBlock - public static boolean canHarvestBlock(@Nonnull Block block, @Nonnull EntityPlayer player, @Nonnull IBlockAccess world, @Nonnull BlockPos pos) + public static boolean canHarvestBlock(@Nonnull Block block, @Nonnull EntityPlayer player, @Nonnull World world, @Nonnull BlockPos pos) { IBlockState state = world.getBlockState(pos); - state = state.getBlock().getActualState(state, world, pos); //Dont break bedrock - if (state.getBlockHardness((World) world, pos) < 0) { + if (state.getBlockHardness(world, pos) < 0) { return false; } @@ -291,13 +307,13 @@ public class SurvivalHelper { } ItemStack stack = player.getHeldItemMainhand(); - String tool = block.getHarvestTool(state); + ToolType tool = block.getHarvestTool(state); if (stack.isEmpty() || tool == null) { return player.canHarvestBlock(state); } - if (stack.getItemDamage() >= stack.getMaxDamage()) return false; + if (stack.getDamage() >= stack.getMaxDamage()) return false; int toolLevel = stack.getItem().getHarvestLevel(stack, tool, player, state); if (toolLevel < 0) @@ -315,20 +331,21 @@ public class SurvivalHelper { if (CompatHelper.isItemBlockProxy(itemstack)) itemstack = CompatHelper.getItemBlockFromStack(itemstack); - if (itemstack.isEmpty() || !(itemstack.getItem() instanceof ItemSlab)) return false; - BlockSlab heldSlab = (BlockSlab) ((ItemSlab) itemstack.getItem()).getBlock(); + if (itemstack.isEmpty() || !(itemstack.getItem() instanceof ItemBlock) || !(((ItemBlock) itemstack.getItem()).getBlock() instanceof BlockSlab)) return false; + BlockSlab heldSlab = (BlockSlab) ((ItemBlock) itemstack.getItem()).getBlock(); if (placedBlockState.getBlock() == heldSlab) { - IProperty variantProperty = heldSlab.getVariantProperty(); - Comparable placedVariant = placedBlockState.getValue(variantProperty); - BlockSlab.EnumBlockHalf placedHalf = placedBlockState.getValue(BlockSlab.HALF); - - Comparable heldVariant = heldSlab.getTypeForItem(itemstack); - - if ((facing == EnumFacing.UP && placedHalf == BlockSlab.EnumBlockHalf.BOTTOM || facing == EnumFacing.DOWN && placedHalf == BlockSlab.EnumBlockHalf.TOP) && placedVariant == heldVariant) - { - return true; - } + //TODO 1.13 +// IProperty variantProperty = heldSlab.getVariantProperty(); +// Comparable placedVariant = placedBlockState.getValue(variantProperty); +// BlockSlab.EnumBlockHalf placedHalf = placedBlockState.getValue(BlockSlab.HALF); +// +// Comparable heldVariant = heldSlab.getTypeForItem(itemstack); +// +// if ((facing == EnumFacing.UP && placedHalf == BlockSlab.EnumBlockHalf.BOTTOM || facing == EnumFacing.DOWN && placedHalf == BlockSlab.EnumBlockHalf.TOP) && placedVariant == heldVariant) +// { +// return true; +// } } return false; } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java b/src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java index f548606..6ec8b6d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ItemRandomizerBag.java @@ -3,10 +3,9 @@ package nl.requios.effortlessbuilding.item; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.*; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; @@ -14,9 +13,12 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.EffortlessBuilding; @@ -24,6 +26,8 @@ import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; +import nl.requios.effortlessbuilding.gui.RandomizerBagContainer; +import nl.requios.effortlessbuilding.gui.RandomizerBagGuiHandler; import nl.requios.effortlessbuilding.helper.SurvivalHelper; import javax.annotation.Nullable; @@ -39,20 +43,25 @@ public class ItemRandomizerBag extends Item { private static Random rand = new Random(currentSeed); public ItemRandomizerBag() { - this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag"); - this.setTranslationKey(this.getRegistryName().toString()); + super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1)); - this.maxStackSize = 1; - this.setCreativeTab(CreativeTabs.TOOLS); + this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag"); } @Override - public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { + public EnumActionResult onItemUse(ItemUseContext ctx) { + EntityPlayer player = ctx.getPlayer(); + World world = ctx.getWorld(); + BlockPos pos = ctx.getPos(); + EnumFacing facing = ctx.getFace(); + ItemStack item = ctx.getItem(); - if (player.isSneaking()) { + if (player == null) return EnumActionResult.FAIL; + + if (ctx.isPlacerSneaking()) { if (world.isRemote) return EnumActionResult.SUCCESS; //Open inventory - player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0); + NetworkHooks.openGui((EntityPlayerMP) player, new RandomizerBagGuiHandler()); } else { if (world.isRemote) return EnumActionResult.SUCCESS; @@ -65,7 +74,8 @@ public class ItemRandomizerBag extends Item { //Use item //Get bag inventory - ItemStack bag = player.getHeldItem(hand); + //TODO offhand support + ItemStack bag = player.getHeldItem(EnumHand.MAIN_HAND); IItemHandler bagInventory = getBagInventory(bag); if (bagInventory == null) return EnumActionResult.FAIL; @@ -77,14 +87,15 @@ public class ItemRandomizerBag extends Item { //bag.setItemDamage(toPlace.getMetadata()); //toPlace.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); - if (!world.getBlockState(pos).getBlock().isReplaceable(world, pos)) { + //TODO replaceable + if (!world.getBlockState(pos).getBlock().getMaterial(world.getBlockState(pos)).isReplaceable()) { pos = pos.offset(facing); } - IBlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(world, pos, facing, - hitX, hitY, hitZ, toPlace.getMetadata(), player, hand); + BlockItemUseContext blockItemUseContext = new BlockItemUseContext(world, player, item, pos, facing, ctx.getHitX(), ctx.getHitY(), ctx.getHitZ()); + IBlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(blockItemUseContext); - SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, new Vec3d(hitX, hitY, hitZ), false, false, true); + SurvivalHelper.placeBlock(world, player, pos, blockState, toPlace, facing, new Vec3d(ctx.getHitX(), ctx.getHitY(), ctx.getHitZ()), false, false, true); //Synergy //Works without calling @@ -103,7 +114,7 @@ public class ItemRandomizerBag extends Item { if (player.isSneaking()) { if (world.isRemote) return new ActionResult<>(EnumActionResult.SUCCESS, bag); //Open inventory - player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0); + NetworkHooks.openGui((EntityPlayerMP) player, new RandomizerBagGuiHandler()); } else { //Use item //Get bag inventory @@ -126,8 +137,7 @@ public class ItemRandomizerBag extends Item { * @return */ public static IItemHandler getBagInventory(ItemStack bag) { - if (!bag.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)) return null; - return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); + return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null); } /** @@ -176,7 +186,7 @@ public class ItemRandomizerBag extends Item { } @Override - public int getMaxItemUseDuration(ItemStack stack) { + public int getUseDuration(ItemStack p_77626_1_) { return 1; } @@ -187,14 +197,14 @@ public class ItemRandomizerBag extends Item { } @Override - public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { - tooltip.add(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block"); - tooltip.add(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory"); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + tooltip.add(new TextComponentString(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block")); + tooltip.add(new TextComponentString(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory")); } @Override public String getTranslationKey() { - return super.getTranslationKey(); + return this.getRegistryName().toString(); } public static void resetRandomness() { diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade1.java b/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade1.java index 10a823e..badad7d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade1.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade1.java @@ -1,12 +1,13 @@ package nl.requios.effortlessbuilding.item; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.util.*; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import nl.requios.effortlessbuilding.BuildConfig; @@ -20,11 +21,8 @@ import java.util.List; public class ItemReachUpgrade1 extends Item { public ItemReachUpgrade1() { + super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1)); this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade1"); - this.setTranslationKey(this.getRegistryName().toString()); - - this.maxStackSize = 1; - this.setCreativeTab(CreativeTabs.TOOLS); } @Override @@ -56,12 +54,12 @@ public class ItemReachUpgrade1 extends Item { } @Override - public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { - tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + tooltip.add(new TextComponentString(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1.get())); } @Override public String getTranslationKey() { - return super.getTranslationKey(); + return this.getRegistryName().toString(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade2.java b/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade2.java index c4fd156..6d74fc2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade2.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade2.java @@ -1,11 +1,13 @@ package nl.requios.effortlessbuilding.item; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.util.*; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import nl.requios.effortlessbuilding.BuildConfig; @@ -19,11 +21,8 @@ import java.util.List; public class ItemReachUpgrade2 extends Item { public ItemReachUpgrade2() { + super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1)); this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade2"); - this.setTranslationKey(this.getRegistryName().toString()); - - this.maxStackSize = 1; - this.setCreativeTab(CreativeTabs.TOOLS); } @Override @@ -59,13 +58,13 @@ public class ItemReachUpgrade2 extends Item { } @Override - public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { - tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel2); - tooltip.add(TextFormatting.GRAY + "Previous upgrades need to be consumed first"); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + tooltip.add(new TextComponentString(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel2.get())); + tooltip.add(new TextComponentString(TextFormatting.GRAY + "Previous upgrades need to be consumed first")); } @Override public String getTranslationKey() { - return super.getTranslationKey(); + return this.getRegistryName().toString(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade3.java b/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade3.java index 47bc9e8..d773777 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade3.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ItemReachUpgrade3.java @@ -1,11 +1,13 @@ package nl.requios.effortlessbuilding.item; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.util.*; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import nl.requios.effortlessbuilding.BuildConfig; @@ -19,11 +21,8 @@ import java.util.List; public class ItemReachUpgrade3 extends Item { public ItemReachUpgrade3() { + super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1)); this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade3"); - this.setTranslationKey(this.getRegistryName().toString()); - - this.maxStackSize = 1; - this.setCreativeTab(CreativeTabs.TOOLS); } @Override @@ -62,13 +61,13 @@ public class ItemReachUpgrade3 extends Item { } @Override - public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { - tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel3); - tooltip.add(TextFormatting.GRAY + "Previous upgrades need to be consumed first"); + public void addInformation(ItemStack stack, @Nullable World world, List tooltip, ITooltipFlag flag) { + tooltip.add(new TextComponentString(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel3.get())); + tooltip.add(new TextComponentString(TextFormatting.GRAY + "Previous upgrades need to be consumed first")); } @Override public String getTranslationKey() { - return super.getTranslationKey(); + return this.getRegistryName().toString(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/AddUndoMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/AddUndoMessage.java index 4bb82f6..596c116 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/AddUndoMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/AddUndoMessage.java @@ -1,26 +1,24 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.BlockSet; import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; -import nl.requios.effortlessbuilding.proxy.ClientProxy; import java.util.ArrayList; +import java.util.function.Supplier; /*** * Sends a message to the client asking to add a block to the undo stack. */ -public class AddUndoMessage implements IMessage { +public class AddUndoMessage { private BlockPos coordinate; private IBlockState previousBlockState; private IBlockState newBlockState; @@ -49,46 +47,42 @@ public class AddUndoMessage implements IMessage { return newBlockState; } - @Override - public void toBytes(ByteBuf buf) { - buf.writeInt(this.coordinate.getX()); - buf.writeInt(this.coordinate.getY()); - buf.writeInt(this.coordinate.getZ()); - buf.writeInt(Block.getStateId(this.previousBlockState)); - buf.writeInt(Block.getStateId(this.newBlockState)); + public static void encode(AddUndoMessage message, PacketBuffer buf) { + buf.writeInt(message.coordinate.getX()); + buf.writeInt(message.coordinate.getY()); + buf.writeInt(message.coordinate.getZ()); + buf.writeInt(Block.getStateId(message.previousBlockState)); + buf.writeInt(Block.getStateId(message.newBlockState)); } - @Override - public void fromBytes(ByteBuf buf) { - coordinate = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); - previousBlockState = Block.getStateById(buf.readInt()); - newBlockState = Block.getStateById(buf.readInt()); + public static AddUndoMessage decode(PacketBuffer buf) { + BlockPos coordinate = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); + IBlockState previousBlockState = Block.getStateById(buf.readInt()); + IBlockState newBlockState = Block.getStateById(buf.readInt()); + return new AddUndoMessage(coordinate, previousBlockState, newBlockState); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(AddUndoMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("AddUndoMessage"); - @Override - public IMessage onMessage(AddUndoMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); + if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { + //Received clientside - if (ctx.side == Side.CLIENT){ - //Received clientside - - EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); - //Add to undo stack clientside - UndoRedo.addUndo(player, new BlockSet( + UndoRedo.addUndo(ctx.get().getSender(), new BlockSet( new ArrayList() {{add(message.getCoordinate());}}, new ArrayList() {{add(message.getPreviousBlockState());}}, new ArrayList() {{add(message.getNewBlockState());}}, new Vec3d(0,0,0), message.getCoordinate(), message.getCoordinate())); - }); - } - return null; + } + }); + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/BlockBrokenMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/BlockBrokenMessage.java index ea2242b..76acf99 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/BlockBrokenMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/BlockBrokenMessage.java @@ -1,22 +1,21 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.BuildModes; -import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; + +import java.util.function.Supplier; /*** * Sends a message to the server indicating that a player wants to break a block */ -public class BlockBrokenMessage implements IMessage { +public class BlockBrokenMessage { private boolean blockHit; private BlockPos blockPos; @@ -31,12 +30,19 @@ public class BlockBrokenMessage implements IMessage { } public BlockBrokenMessage(RayTraceResult result) { - this.blockHit = result.typeOfHit == RayTraceResult.Type.BLOCK; + this.blockHit = result.type == RayTraceResult.Type.BLOCK; this.blockPos = result.getBlockPos(); this.sideHit = result.sideHit; this.hitVec = result.hitVec; } + public BlockBrokenMessage(boolean blockHit, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + this.blockHit = blockHit; + this.blockPos = blockPos; + this.sideHit = sideHit; + this.hitVec = hitVec; + } + public boolean isBlockHit() { return blockHit; } @@ -53,43 +59,37 @@ public class BlockBrokenMessage implements IMessage { return hitVec; } - @Override - public void toBytes(ByteBuf buf) { - buf.writeBoolean(blockHit); - buf.writeInt(blockPos.getX()); - buf.writeInt(blockPos.getY()); - buf.writeInt(blockPos.getZ()); - buf.writeInt(sideHit.getIndex()); - buf.writeDouble(hitVec.x); - buf.writeDouble(hitVec.y); - buf.writeDouble(hitVec.z); + public static void encode(BlockBrokenMessage message, PacketBuffer buf) { + buf.writeBoolean(message.blockHit); + buf.writeInt(message.blockPos.getX()); + buf.writeInt(message.blockPos.getY()); + buf.writeInt(message.blockPos.getZ()); + buf.writeInt(message.sideHit.getIndex()); + buf.writeDouble(message.hitVec.x); + buf.writeDouble(message.hitVec.y); + buf.writeDouble(message.hitVec.z); } - @Override - public void fromBytes(ByteBuf buf) { - blockHit = buf.readBoolean(); - blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); - sideHit = EnumFacing.byIndex(buf.readInt()); - hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); + public static BlockBrokenMessage decode(PacketBuffer buf) { + boolean blockHit = buf.readBoolean(); + BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); + EnumFacing sideHit = EnumFacing.byIndex(buf.readInt()); + Vec3d hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); + return new BlockBrokenMessage(blockHit, blockPos, sideHit, hitVec); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case - - @Override - public IMessage onMessage(BlockBrokenMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); - - if (ctx.side == Side.SERVER) { - //Received serverside - EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { - BuildModes.onBlockBrokenMessage(ctx.getServerHandler().player, message); - }); - } - // No response packet - return null; + public static class Handler + { + public static void handle(BlockBrokenMessage message, Supplier ctx) + { + EffortlessBuilding.log("BlockBrokenMessage"); + ctx.get().enqueueWork(() -> { + if (ctx.get().getDirection().getReceptionSide() == LogicalSide.SERVER) { + //Received serverside + BuildModes.onBlockBrokenMessage(ctx.get().getSender(), message); + } + }); + ctx.get().setPacketHandled(true); } } - } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java index a7ef5b2..5390f43 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java @@ -1,25 +1,23 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -import net.minecraftforge.fml.relauncher.Side; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.BuildModes; -import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; -import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.render.BlockPreviewRenderer; +import java.util.function.Supplier; + /*** * Sends a message to the server indicating that a player wants to place a block. * Received clientside: server has placed blocks and its letting the client know. */ -public class BlockPlacedMessage implements IMessage { +public class BlockPlacedMessage { private boolean blockHit; private BlockPos blockPos; @@ -36,13 +34,21 @@ public class BlockPlacedMessage implements IMessage { } public BlockPlacedMessage(RayTraceResult result, boolean placeStartPos) { - this.blockHit = result.typeOfHit == RayTraceResult.Type.BLOCK; + this.blockHit = result.type == RayTraceResult.Type.BLOCK; this.blockPos = result.getBlockPos(); this.sideHit = result.sideHit; this.hitVec = result.hitVec; this.placeStartPos = placeStartPos; } + public BlockPlacedMessage(boolean blockHit, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean placeStartPos) { + this.blockHit = blockHit; + this.blockPos = blockPos; + this.sideHit = sideHit; + this.hitVec = hitVec; + this.placeStartPos = placeStartPos; + } + public boolean isBlockHit() { return blockHit; } @@ -63,51 +69,44 @@ public class BlockPlacedMessage implements IMessage { return placeStartPos; } - @Override - public void toBytes(ByteBuf buf) { - buf.writeBoolean(blockHit); - buf.writeInt(blockPos.getX()); - buf.writeInt(blockPos.getY()); - buf.writeInt(blockPos.getZ()); - buf.writeInt(sideHit.getIndex()); - buf.writeDouble(hitVec.x); - buf.writeDouble(hitVec.y); - buf.writeDouble(hitVec.z); - buf.writeBoolean(placeStartPos); + public static void encode(BlockPlacedMessage message, PacketBuffer buf) { + buf.writeBoolean(message.blockHit); + buf.writeInt(message.blockPos.getX()); + buf.writeInt(message.blockPos.getY()); + buf.writeInt(message.blockPos.getZ()); + buf.writeInt(message.sideHit.getIndex()); + buf.writeDouble(message.hitVec.x); + buf.writeDouble(message.hitVec.y); + buf.writeDouble(message.hitVec.z); + buf.writeBoolean(message.placeStartPos); } - @Override - public void fromBytes(ByteBuf buf) { - blockHit = buf.readBoolean(); - blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); - sideHit = EnumFacing.byIndex(buf.readInt()); - hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); - placeStartPos = buf.readBoolean(); + public static BlockPlacedMessage decode(PacketBuffer buf) { + boolean blockHit = buf.readBoolean(); + BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); + EnumFacing sideHit = EnumFacing.byIndex(buf.readInt()); + Vec3d hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); + boolean placeStartPos = buf.readBoolean(); + return new BlockPlacedMessage(blockHit, blockPos, sideHit, hitVec, placeStartPos); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(BlockPlacedMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("BlockPlacedMessage"); - @Override - public IMessage onMessage(BlockPlacedMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); - - if (ctx.side == Side.CLIENT){ - //Received clientside - EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { + if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { + //Received clientside //Nod RenderHandler to do the dissolve shader effect BlockPreviewRenderer.onBlocksPlaced(); - }); - return null; - } else { - //Received serverside - EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { - BuildModes.onBlockPlacedMessage(ctx.getServerHandler().player, message); - }); - // No response packet - return null; - } + } else { + //Received serverside + BuildModes.onBlockPlacedMessage(ctx.get().getSender(), message); + } + }); + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/CancelModeMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/CancelModeMessage.java index 9308c43..4206822 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/CancelModeMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/CancelModeMessage.java @@ -1,45 +1,37 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.IThreadListener; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.BuildModes; +import java.util.function.Supplier; + /** * Sends a message to the server indicating that a buildmode needs to be canceled for a player */ -public class CancelModeMessage implements IMessage { - - @Override - public void toBytes(ByteBuf buf) { +public class CancelModeMessage { + public static void encode(CancelModeMessage message, PacketBuffer buf) { } - @Override - public void fromBytes(ByteBuf buf) { - + public static CancelModeMessage decode(PacketBuffer buf) { + return new CancelModeMessage(); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(CancelModeMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("CancelModeMessage"); - @Override - public IMessage onMessage(CancelModeMessage message, MessageContext ctx) { - - // Execute the action on the main server thread by adding it as a scheduled task - IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx); - threadListener.addScheduledTask(() -> { EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); BuildModes.initializeMode(player); }); - // No response packet - return null; + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ClearUndoMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/ClearUndoMessage.java index 5e205c9..dcd9ce0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/ClearUndoMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/ClearUndoMessage.java @@ -1,57 +1,46 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -import net.minecraftforge.fml.relauncher.Side; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmodifier.BlockSet; import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; -import nl.requios.effortlessbuilding.proxy.ClientProxy; -import java.util.ArrayList; +import java.util.function.Supplier; /*** * Sends a message to the client asking to clear the undo and redo stacks. */ -public class ClearUndoMessage implements IMessage { +public class ClearUndoMessage { public ClearUndoMessage() { } - @Override - public void toBytes(ByteBuf buf) { + public static void encode(ClearUndoMessage message, PacketBuffer buf) { + } - @Override - public void fromBytes(ByteBuf buf) { + public static ClearUndoMessage decode(PacketBuffer buf) { + return new ClearUndoMessage(); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(ClearUndoMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("ClearUndoMessage"); - @Override - public IMessage onMessage(ClearUndoMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); - - if (ctx.side == Side.CLIENT){ - //Received clientside - - EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { + if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { + //Received clientside EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); //Add to undo stack clientside UndoRedo.clear(player); - }); - } - return null; + } + }); + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ModeActionMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/ModeActionMessage.java index bbd9955..6317f93 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/ModeActionMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/ModeActionMessage.java @@ -1,22 +1,17 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.IThreadListener; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeOptions; -import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; -import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.*; +import java.util.function.Supplier; /** * Shares mode settings (see ModeSettingsManager) between server and client */ -public class ModeActionMessage implements IMessage { +public class ModeActionMessage { private ModeOptions.ActionEnum action; @@ -27,36 +22,27 @@ public class ModeActionMessage implements IMessage { this.action = action; } - @Override - public void toBytes(ByteBuf buf) { - buf.writeInt(action.ordinal()); + public static void encode(ModeActionMessage message, PacketBuffer buf) { + buf.writeInt(message.action.ordinal()); } - @Override - public void fromBytes(ByteBuf buf) { - action = ModeOptions.ActionEnum.values()[buf.readInt()]; + public static ModeActionMessage decode(PacketBuffer buf) { + ModeOptions.ActionEnum action = ModeOptions.ActionEnum.values()[buf.readInt()]; + return new ModeActionMessage(action); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(ModeActionMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("ModeActionMessage"); - @Override - public IMessage onMessage(ModeActionMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); - - // The value that was sent - ModeOptions.ActionEnum action = message.action; - - // Execute the action on the main server thread by adding it as a scheduled task - IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx); - threadListener.addScheduledTask(() -> { EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); - ModeOptions.performAction(player, action); + ModeOptions.performAction(player, message.action); }); - // No response packet - return null; + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java index 89d7a04..cd3a450 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java @@ -2,20 +2,20 @@ package nl.requios.effortlessbuilding.network; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.IThreadListener; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; +import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.ModeSettings; -import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.*; +import java.util.function.Supplier; /** * Shares mode settings (see ModeSettingsManager) between server and client */ -public class ModeSettingsMessage implements IMessage { +public class ModeSettingsMessage { private ModeSettings modeSettings; @@ -26,41 +26,31 @@ public class ModeSettingsMessage implements IMessage { this.modeSettings = modeSettings; } - @Override - public void toBytes(ByteBuf buf) { - buf.writeInt(modeSettings.getBuildMode().ordinal()); + public static void encode(ModeSettingsMessage message, PacketBuffer buf) { + buf.writeInt(message.modeSettings.getBuildMode().ordinal()); } - @Override - public void fromBytes(ByteBuf buf) { + public static ModeSettingsMessage decode(PacketBuffer buf) { BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.values()[buf.readInt()]; - modeSettings = new ModeSettings(buildMode); + return new ModeSettingsMessage(new ModeSettings(buildMode)); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(ModeSettingsMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("ModeSettingsMessage"); - @Override - public IMessage onMessage(ModeSettingsMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); - - // The value that was sent - ModeSettings modeSettings = message.modeSettings; - - // Execute the action on the main server thread by adding it as a scheduled task - IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx); - threadListener.addScheduledTask(() -> { EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); // Sanitize - ModeSettingsManager.sanitize(modeSettings, player); + ModeSettingsManager.sanitize(message.modeSettings, player); - ModeSettingsManager.setModeSettings(player, modeSettings); + ModeSettingsManager.setModeSettings(player, message.modeSettings); }); - // No response packet - return null; + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsMessage.java index f3aa54e..5c20111 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsMessage.java @@ -1,25 +1,24 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.IThreadListener; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; -import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.*; +import java.util.function.Supplier; + +import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings; /** * Shares modifier settings (see ModifierSettingsManager) between server and client */ -public class ModifierSettingsMessage implements IMessage { +public class ModifierSettingsMessage { private ModifierSettings modifierSettings; @@ -30,10 +29,9 @@ public class ModifierSettingsMessage implements IMessage { this.modifierSettings = modifierSettings; } - @Override - public void toBytes(ByteBuf buf) { + public static void encode(ModifierSettingsMessage message, PacketBuffer buf) { //MIRROR - Mirror.MirrorSettings m = modifierSettings.getMirrorSettings(); + Mirror.MirrorSettings m = message.modifierSettings.getMirrorSettings(); buf.writeBoolean(m != null); if (m != null) { buf.writeBoolean(m.enabled); @@ -49,7 +47,7 @@ public class ModifierSettingsMessage implements IMessage { } //ARRAY - Array.ArraySettings a = modifierSettings.getArraySettings(); + Array.ArraySettings a = message.modifierSettings.getArraySettings(); buf.writeBoolean(a != null); if (a != null) { buf.writeBoolean(a.enabled); @@ -59,12 +57,12 @@ public class ModifierSettingsMessage implements IMessage { buf.writeInt(a.count); } - buf.writeBoolean(modifierSettings.doQuickReplace()); + buf.writeBoolean(message.modifierSettings.doQuickReplace()); - buf.writeInt(modifierSettings.getReachUpgrade()); + buf.writeInt(message.modifierSettings.getReachUpgrade()); //RADIAL MIRROR - RadialMirror.RadialMirrorSettings r = modifierSettings.getRadialMirrorSettings(); + RadialMirror.RadialMirrorSettings r = message.modifierSettings.getRadialMirrorSettings(); buf.writeBoolean(r != null); if (r != null) { buf.writeBoolean(r.enabled); @@ -79,8 +77,7 @@ public class ModifierSettingsMessage implements IMessage { } } - @Override - public void fromBytes(ByteBuf buf) { + public static ModifierSettingsMessage decode(PacketBuffer buf) { //MIRROR Mirror.MirrorSettings m = new Mirror.MirrorSettings(); if (buf.readBoolean()) { @@ -93,7 +90,7 @@ public class ModifierSettingsMessage implements IMessage { boolean mirrorDrawLines = buf.readBoolean(); boolean mirrorDrawPlanes = buf.readBoolean(); m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, - mirrorDrawLines, mirrorDrawPlanes); + mirrorDrawLines, mirrorDrawPlanes); } //ARRAY @@ -120,35 +117,28 @@ public class ModifierSettingsMessage implements IMessage { boolean radialMirrorDrawLines = buf.readBoolean(); boolean radialMirrorDrawPlanes = buf.readBoolean(); r = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, radialMirrorSlices, - radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes); + radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes); } - modifierSettings = new ModifierSettings(m, a, r, quickReplace, reachUpgrade); + ModifierSettings modifierSettings = new ModifierSettings(m, a, r, quickReplace, reachUpgrade); + return new ModifierSettingsMessage(modifierSettings); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(ModifierSettingsMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("ModifierSettingsMessage"); - @Override - public IMessage onMessage(ModifierSettingsMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); - - // The value that was sent - ModifierSettings modifierSettings = message.modifierSettings; - - // Execute the action on the main server thread by adding it as a scheduled task - IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx); - threadListener.addScheduledTask(() -> { EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); // Sanitize - ModifierSettingsManager.sanitize(modifierSettings, player); + ModifierSettingsManager.sanitize(message.modifierSettings, player); - ModifierSettingsManager.setModifierSettings(player, modifierSettings); + ModifierSettingsManager.setModifierSettings(player, message.modifierSettings); }); - // No response packet - return null; + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java new file mode 100644 index 0000000..f0ca33d --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java @@ -0,0 +1,32 @@ +package nl.requios.effortlessbuilding.network; + +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.network.NetworkRegistry; +import net.minecraftforge.fml.network.simple.SimpleChannel; +import nl.requios.effortlessbuilding.EffortlessBuilding; + +public class PacketHandler { + private static final String PROTOCOL_VERSION = "1"; + public static final SimpleChannel INSTANCE = NetworkRegistry.ChannelBuilder + .named(new ResourceLocation(EffortlessBuilding.MODID, "main_channel")) + .clientAcceptedVersions(PROTOCOL_VERSION::equals) + .serverAcceptedVersions(PROTOCOL_VERSION::equals) + .networkProtocolVersion(() -> PROTOCOL_VERSION) + .simpleChannel(); + + public static void register() { + int id = 0; + + INSTANCE.registerMessage(id++, ModifierSettingsMessage.class, ModifierSettingsMessage::encode, ModifierSettingsMessage::decode, ModifierSettingsMessage.Handler::handle); + INSTANCE.registerMessage(id++, ModeSettingsMessage.class, ModeSettingsMessage::encode, ModeSettingsMessage::decode, ModeSettingsMessage.Handler::handle); + INSTANCE.registerMessage(id++, ModeActionMessage.class, ModeActionMessage::encode, ModeActionMessage::decode, ModeActionMessage.Handler::handle); + INSTANCE.registerMessage(id++, BlockPlacedMessage.class, BlockPlacedMessage::encode, BlockPlacedMessage::decode, BlockPlacedMessage.Handler::handle); + INSTANCE.registerMessage(id++, BlockBrokenMessage.class, BlockBrokenMessage::encode, BlockBrokenMessage::decode, BlockBrokenMessage.Handler::handle); + INSTANCE.registerMessage(id++, CancelModeMessage.class, CancelModeMessage::encode, CancelModeMessage::decode, CancelModeMessage.Handler::handle); + INSTANCE.registerMessage(id++, RequestLookAtMessage.class, RequestLookAtMessage::encode, RequestLookAtMessage::decode, RequestLookAtMessage.Handler::handle); + INSTANCE.registerMessage(id++, AddUndoMessage.class, AddUndoMessage::encode, AddUndoMessage::decode, AddUndoMessage.Handler::handle); + INSTANCE.registerMessage(id++, ClearUndoMessage.class, ClearUndoMessage::encode, ClearUndoMessage::decode, ClearUndoMessage.Handler::handle); + + } + +} diff --git a/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java index 81286f0..226ab9c 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java @@ -1,27 +1,26 @@ package nl.requios.effortlessbuilding.network; -import io.netty.buffer.ByteBuf; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.BlockSet; import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; import nl.requios.effortlessbuilding.proxy.ClientProxy; import java.util.ArrayList; +import java.util.function.Supplier; /*** * Sends a message to the client asking for its lookat (objectmouseover) data. * This is then sent back with a BlockPlacedMessage. */ -public class RequestLookAtMessage implements IMessage { +public class RequestLookAtMessage { private boolean placeStartPos; public RequestLookAtMessage() { @@ -36,38 +35,33 @@ public class RequestLookAtMessage implements IMessage { return placeStartPos; } - @Override - public void toBytes(ByteBuf buf) { - buf.writeBoolean(this.placeStartPos); + public static void encode(RequestLookAtMessage message, PacketBuffer buf) { + buf.writeBoolean(message.placeStartPos); } - @Override - public void fromBytes(ByteBuf buf) { - placeStartPos = buf.readBoolean(); + public static RequestLookAtMessage decode(PacketBuffer buf) { + boolean placeStartPos = buf.readBoolean(); + return new RequestLookAtMessage(placeStartPos); } - // The params of the IMessageHandler are - public static class MessageHandler implements IMessageHandler { - // Do note that the default constructor is required, but implicitly defined in this case + public static class Handler + { + public static void handle(RequestLookAtMessage message, Supplier ctx) + { + ctx.get().enqueueWork(() -> { + EffortlessBuilding.log("RequestLookAtMessage"); - @Override - public IMessage onMessage(RequestLookAtMessage message, MessageContext ctx) { - //EffortlessBuilding.log("message received on " + ctx.side + " side"); + if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) { + //Received clientside + //Send back your info + EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); - if (ctx.side == Side.CLIENT){ - //Received clientside - //Send back your info - -// EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { -// EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); -// -// }); - - //Prevent double placing in normal mode with placeStartPos false. - //Unless QuickReplace is on, then we do need to place start pos. - return new BlockPlacedMessage(ClientProxy.previousLookAt, message.getPlaceStartPos()); - } - return null; + //Prevent double placing in normal mode with placeStartPos false + //Unless QuickReplace is on, then we do need to place start pos. + PacketHandler.INSTANCE.sendToServer(new BlockPlacedMessage(ClientProxy.previousLookAt, message.getPlaceStartPos())); + } + }); + ctx.get().setPacketHandled(true); } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java index 8c1fc0c..557634e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java @@ -1,144 +1,116 @@ package nl.requios.effortlessbuilding.proxy; -import net.minecraft.block.Block; import net.minecraft.block.SoundType; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.KeyboardListener; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.resources.I18n; import net.minecraft.client.settings.KeyBinding; +import net.minecraft.client.util.InputMappings; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; -import net.minecraft.util.IThreadListener; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceFluidMode; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.GuiOpenEvent; +import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.event.TextureStitchEvent; -import net.minecraftforge.client.model.ModelLoader; -import net.minecraftforge.client.settings.IKeyConflictContext; import net.minecraftforge.client.settings.KeyConflictContext; import net.minecraftforge.client.settings.KeyModifier; import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.event.FMLServerStartingEvent; -import net.minecraftforge.fml.common.eventhandler.EventPriority; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.InputEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.network.NetworkEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; +import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui; -import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.ReachHelper; +import nl.requios.effortlessbuilding.network.*; import nl.requios.effortlessbuilding.render.RenderHandler; import nl.requios.effortlessbuilding.render.ShaderHandler; -import nl.requios.effortlessbuilding.network.*; -import org.lwjgl.input.Keyboard; +import org.lwjgl.glfw.GLFW; import javax.annotation.Nullable; import java.util.HashMap; +import java.util.function.Supplier; -@Mod.EventBusSubscriber(Side.CLIENT) +@Mod.EventBusSubscriber(value = {Dist.CLIENT}) public class ClientProxy implements IProxy { public static KeyBinding[] keyBindings; public static RayTraceResult previousLookAt; public static RayTraceResult currentLookAt; private static int placeCooldown = 0; private static int breakCooldown = 0; + private static boolean shadersInitialized = false; public static int ticksInGame = 0; - private static final HashMap buildModeIcons = new HashMap<>(); - private static final HashMap modeOptionIcons = new HashMap<>(); + private static final HashMap buildModeIcons = new HashMap<>(); + private static final HashMap modeOptionIcons = new HashMap<>(); @Override - public void preInit(FMLPreInitializationEvent event) { - ShaderHandler.init(); - } + public void setup(FMLCommonSetupEvent event) {} @Override - public void init(FMLInitializationEvent event) { + public void clientSetup(FMLClientSetupEvent event) { + //Crashes in 1.13, do it elsewhere +// ShaderHandler.init(); + // register key bindings - keyBindings = new KeyBinding[6]; + keyBindings = new KeyBinding[7]; // instantiate the key bindings - keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, Keyboard.KEY_ADD, "key.effortlessbuilding.category"); - keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", KeyConflictContext.IN_GAME, Keyboard.KEY_SUBTRACT, "key.effortlessbuilding.category"); - keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", KeyConflictContext.IN_GAME, Keyboard.KEY_NONE, "key.effortlessbuilding.category"); - keyBindings[3] = new KeyBinding("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, Keyboard.KEY_LMENU, "key.effortlessbuilding.category") { + keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, InputMappings.getInputByCode(GLFW.GLFW_KEY_KP_ADD, 0), "key.effortlessbuilding.category"); + keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_KP_SUBTRACT, 0), "key.effortlessbuilding.category"); + keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_F4, 0), "key.effortlessbuilding.category"); + keyBindings[3] = new KeyBinding("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_LEFT_ALT, 0), "key.effortlessbuilding.category") { @Override - public boolean conflicts(KeyBinding other) { + public boolean func_197983_b(KeyBinding other) { //Does not conflict with Chisels and Bits radial menu - if (other.getKeyCode() == getKeyCode() && other.getKeyDescription().equals("mod.chiselsandbits.other.mode")) return false; - return super.conflicts(other); + if (other.getKey().getKeyCode() == getKey().getKeyCode() && other.getKeyDescription().equals("mod.chiselsandbits.other.mode")) return false; + return super.func_197983_b(other); } }; - keyBindings[4] = new KeyBinding("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, Keyboard.KEY_Z, "key.effortlessbuilding.category"); - keyBindings[5] = new KeyBinding("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, Keyboard.KEY_Y, "key.effortlessbuilding.category"); -// keyBindings[6] = new KeyBinding("Reload shaders", Keyboard.KEY_TAB, "key.effortlessbuilding.category"); + keyBindings[4] = new KeyBinding("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getInputByCode(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category"); + keyBindings[5] = new KeyBinding("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputMappings.getInputByCode(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category"); + keyBindings[6] = new KeyBinding("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputMappings.getInputByCode(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category"); + //keyBindings[7] = new KeyBinding("Reload shaders", KeyConflictContext.UNIVERSAL, InputMappings.getInputByCode(GLFW.GLFW_KEY_TAB, 0), "key.effortlessbuilding.category"); // register all the key bindings for (int i = 0; i < keyBindings.length; ++i) { ClientRegistry.registerKeyBinding(keyBindings[i]); } - } - - @Override - public void postInit(FMLPostInitializationEvent event) { } - @Override - public EntityPlayer getPlayerEntityFromContext(MessageContext ctx) { - return (ctx.side.isClient() ? Minecraft.getMinecraft().player : ctx.getServerHandler().player); - } - - @Override - public IThreadListener getThreadListenerFromContext(MessageContext ctx) { - return (ctx.side.isClient() ? Minecraft.getMinecraft() : ((EntityPlayerMP) getPlayerEntityFromContext(ctx)).getServerWorld()); - } - - @Override - public void serverStarting(FMLServerStartingEvent event) { - //This will get called clientside - } - - @SubscribeEvent - public static void registerModels(ModelRegistryEvent event) { - for (Block block : EffortlessBuilding.BLOCKS) { - ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), "inventory")); - } - - for (Item item : EffortlessBuilding.ITEMS) { - ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory")); - } + public EntityPlayer getPlayerEntityFromContext(Supplier ctx){ + return (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT ? Minecraft.getInstance().player : ctx.get().getSender()); } @SubscribeEvent public static void onEntityJoinWorld(EntityJoinWorldEvent event) { - if (event.getEntity() == Minecraft.getMinecraft().player) { + if (event.getEntity() == Minecraft.getInstance().player) { event.getWorld().addEventListener(new RenderHandler()); } } @@ -150,23 +122,25 @@ public class ClientProxy implements IProxy { for ( final BuildModes.BuildModeEnum mode : BuildModes.BuildModeEnum.values() ) { - final ResourceLocation sprite = new ResourceLocation("effortlessbuilding", "icons/" + mode.name().toLowerCase()); - buildModeIcons.put( mode, map.registerSprite(sprite)); + final ResourceLocation sprite = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + mode.name().toLowerCase()); + map.registerSprite(Minecraft.getInstance().getResourceManager(), sprite); + buildModeIcons.put(mode, sprite); } for ( final ModeOptions.ActionEnum action : ModeOptions.ActionEnum.values() ) { - final ResourceLocation sprite = new ResourceLocation("effortlessbuilding", "icons/" + action.name().toLowerCase()); - modeOptionIcons.put( action, map.registerSprite(sprite)); + final ResourceLocation sprite = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + action.name().toLowerCase()); + map.registerSprite(Minecraft.getInstance().getResourceManager(), sprite); + modeOptionIcons.put(action, sprite); } } public static TextureAtlasSprite getBuildModeIcon(BuildModes.BuildModeEnum mode) { - return buildModeIcons.get(mode); + return Minecraft.getInstance().getTextureMap().getSprite(buildModeIcons.get(mode)); } public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) { - return modeOptionIcons.get(action); + return Minecraft.getInstance().getTextureMap().getSprite(modeOptionIcons.get(action)); } @SubscribeEvent @@ -176,7 +150,7 @@ public class ClientProxy implements IProxy { onMouseInput(); //Update previousLookAt - RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver; + RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver; //Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS) if (objectMouseOver == null) return; @@ -186,8 +160,8 @@ public class ClientProxy implements IProxy { return; } - if (objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { - if (currentLookAt.typeOfHit != RayTraceResult.Type.BLOCK) { + if (objectMouseOver.type == RayTraceResult.Type.BLOCK) { + if (currentLookAt.type != RayTraceResult.Type.BLOCK) { currentLookAt = objectMouseOver; previousLookAt = objectMouseOver; } else { @@ -197,28 +171,36 @@ public class ClientProxy implements IProxy { } } } + } else if (event.phase == TickEvent.Phase.END){ - GuiScreen gui = Minecraft.getMinecraft().currentScreen; + GuiScreen gui = Minecraft.getInstance().currentScreen; if(gui == null || !gui.doesGuiPauseGame()) { ticksInGame++; } + + //Init shaders in the first tick. Doing it anywhere before this seems to crash the game. + if (!shadersInitialized) { + ShaderHandler.init(); + shadersInitialized = true; + } } } private static void onMouseInput() { - Minecraft mc = Minecraft.getMinecraft(); + Minecraft mc = Minecraft.getInstance(); EntityPlayerSP player = mc.player; if (player == null) return; BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); - if (Minecraft.getMinecraft().currentScreen != null || + if (Minecraft.getInstance().currentScreen != null || buildMode == BuildModes.BuildModeEnum.NORMAL || RadialMenu.instance.isVisible()) { return; } if (mc.gameSettings.keyBindUseItem.isKeyDown()) { + //KeyBinding.setKeyBindState(mc.gameSettings.keyBindUseItem.getKeyCode(), false); if (placeCooldown <= 0) { @@ -233,11 +215,11 @@ public class ClientProxy implements IProxy { //find position in distance RayTraceResult lookingAt = getLookingAt(player); BuildModes.onBlockPlacedMessage(player, lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt, true)); - EffortlessBuilding.packetHandler.sendToServer(lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt, true)); + PacketHandler.INSTANCE.sendToServer(lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt, true)); //play sound if further than normal - if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK && - (lookingAt.hitVec.subtract(player.getPositionEyes(1f))).lengthSquared() > 25f && + if (lookingAt != null && lookingAt.type == RayTraceResult.Type.BLOCK && + (lookingAt.hitVec.subtract(player.getEyePosition(1f))).lengthSquared() > 25f && itemStack.getItem() instanceof ItemBlock) { IBlockState state = ((ItemBlock) itemStack.getItem()).getBlock().getDefaultState(); @@ -248,7 +230,8 @@ public class ClientProxy implements IProxy { player.swingArm(EnumHand.MAIN_HAND); } } - } else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { + } + else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { placeCooldown--; if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) placeCooldown = 0; } @@ -270,11 +253,11 @@ public class ClientProxy implements IProxy { RayTraceResult lookingAt = getLookingAt(player); BuildModes.onBlockBrokenMessage(player, lookingAt == null ? new BlockBrokenMessage() : new BlockBrokenMessage(lookingAt)); - EffortlessBuilding.packetHandler.sendToServer(lookingAt == null ? new BlockBrokenMessage() : new BlockBrokenMessage(lookingAt)); + PacketHandler.INSTANCE.sendToServer(lookingAt == null ? new BlockBrokenMessage() : new BlockBrokenMessage(lookingAt)); //play sound if further than normal - if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK && - (lookingAt.hitVec.subtract(player.getPositionEyes(1f))).lengthSquared() > 25f) { + if (lookingAt != null && lookingAt.type == RayTraceResult.Type.BLOCK && + (lookingAt.hitVec.subtract(player.getEyePosition(1f))).lengthSquared() > 25f) { BlockPos blockPos = lookingAt.getBlockPos(); IBlockState state = player.world.getBlockState(blockPos); @@ -283,7 +266,8 @@ public class ClientProxy implements IProxy { 0.4f, soundtype.getPitch() * 1f); player.swingArm(EnumHand.MAIN_HAND); } - } else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { + } + else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { breakCooldown--; if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) breakCooldown = 0; } @@ -293,18 +277,11 @@ public class ClientProxy implements IProxy { } else { breakCooldown = 0; } - - if (mc.gameSettings.keyBindAttack.isPressed()) { - if (RadialMenu.instance.isVisible()) { - EffortlessBuilding.log(player, "mouse click"); - } - } - } - @SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true) + @SubscribeEvent(receiveCanceled = true) public static void onKeyPress(InputEvent.KeyInputEvent event) { - EntityPlayerSP player = Minecraft.getMinecraft().player; + EntityPlayerSP player = Minecraft.getInstance().player; //Remember to send packet to server if necessary //Show Modifier Settings GUI @@ -316,17 +293,17 @@ public class ClientProxy implements IProxy { if (keyBindings[1].isPressed()) { ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); modifierSettings.setQuickReplace(!modifierSettings.doQuickReplace()); - EffortlessBuilding.log(player, "Set "+ TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + ( + EffortlessBuilding.log(player, "Set " + TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + ( modifierSettings.doQuickReplace() ? "on" : "off")); - EffortlessBuilding.packetHandler.sendToServer(new ModifierSettingsMessage(modifierSettings)); + PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings)); } //Creative/survival mode toggle if (keyBindings[2].isPressed()) { if (player.isCreative()) { - player.sendChatMessage("/gamemode 0"); + player.sendChatMessage("/gamemode survival"); } else { - player.sendChatMessage("/gamemode 1"); + player.sendChatMessage("/gamemode creative"); } } @@ -334,18 +311,36 @@ public class ClientProxy implements IProxy { if (keyBindings[4].isPressed()) { ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO; ModeOptions.performAction(player, action); - EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action)); + PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); } //Redo (Ctrl+Y) if (keyBindings[5].isPressed()) { ModeOptions.ActionEnum action = ModeOptions.ActionEnum.REDO; ModeOptions.performAction(player, action); - EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action)); + PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); + } + + //Change placement mode + if (keyBindings[6].isPressed()) { + //Toggle between first two actions of the first option of the current build mode + BuildModes.BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); + if (currentBuildMode.options.length > 0) { + ModeOptions.OptionEnum option = currentBuildMode.options[0]; + if (option.actions.length >= 2) { + if (ModeOptions.getOptionSetting(option) == option.actions[0]) { + ModeOptions.performAction(player, option.actions[1]); + PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(option.actions[1])); + } else { + ModeOptions.performAction(player, option.actions[0]); + PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(option.actions[0])); + } + } + } } //For shader development - if (keyBindings.length >= 7 && keyBindings[6].isPressed()) { + if (keyBindings.length >= 8 && keyBindings[7].isPressed()) { ShaderHandler.init(); EffortlessBuilding.log(player, "Reloaded shaders"); } @@ -353,7 +348,7 @@ public class ClientProxy implements IProxy { } public static void openModifierSettings() { - Minecraft mc = Minecraft.getMinecraft(); + Minecraft mc = Minecraft.getInstance(); EntityPlayerSP player = mc.player; RadialMenu.instance.setVisibility(0f); @@ -372,7 +367,7 @@ public class ClientProxy implements IProxy { @SubscribeEvent public static void onGuiOpen(GuiOpenEvent event) { - EntityPlayer player = Minecraft.getMinecraft().player; + EntityPlayer player = Minecraft.getInstance().player; if (player != null) { BuildModes.initializeMode(player); } @@ -388,11 +383,11 @@ public class ClientProxy implements IProxy { // Vec3d look = player.getLookVec(); // Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); // Vec3d end = new Vec3d(player.posX + look.x * raytraceRange, player.posY + player.getEyeHeight() + look.y * raytraceRange, player.posZ + look.z * raytraceRange); - return player.rayTrace(raytraceRange, 1f); + return player.rayTrace(raytraceRange, 1f, RayTraceFluidMode.NEVER); // return world.rayTraceBlocks(start, end, false, false, false); } public static void logTranslate(String key) { - EffortlessBuilding.log(Minecraft.getMinecraft().player, I18n.format(key), true); + EffortlessBuilding.log(Minecraft.getInstance().player, I18n.format(key), true); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java index 4877d9f..472c199 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/IProxy.java @@ -1,43 +1,16 @@ package nl.requios.effortlessbuilding.proxy; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.IThreadListener; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.event.FMLServerStartingEvent; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.network.NetworkEvent; -public interface IProxy -{ - /** - * Register entities and networking. - */ - void preInit(FMLPreInitializationEvent event); +import java.util.function.Supplier; - /** - * Register event listeners, recipes and advancements. - */ - void init(FMLInitializationEvent event); +public interface IProxy { + void setup(final FMLCommonSetupEvent event); - /** - * For doing inter-mod stuff like checking which mods are loaded or if you want a complete view of things across - * mods like having a list of all registered items to aid random item generation. - */ - void postInit(FMLPostInitializationEvent event); + void clientSetup(final FMLClientSetupEvent event); - /** - * Server commands should be registered here. - */ - void serverStarting(FMLServerStartingEvent event); - - /** - * Returns a side-appropriate EntityPlayer for use during message handling. - * - * @param ctx the context - * @return the player entity from context - */ - EntityPlayer getPlayerEntityFromContext(MessageContext ctx); - - IThreadListener getThreadListenerFromContext(MessageContext ctx); + EntityPlayer getPlayerEntityFromContext(Supplier ctx); } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java index ada60ea..29e3e0d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ServerProxy.java @@ -1,45 +1,23 @@ package nl.requios.effortlessbuilding.proxy; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.IThreadListener; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.event.FMLServerStartingEvent; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.network.NetworkEvent; -public class ServerProxy implements IProxy -{ +import java.util.function.Supplier; + +public class ServerProxy implements IProxy { //Only physical server! Singleplayer server is seen as clientproxy @Override - public void preInit(FMLPreInitializationEvent event) - { + public void setup(FMLCommonSetupEvent event) { + } @Override - public void init(FMLInitializationEvent event) - { - } + public void clientSetup(FMLClientSetupEvent event) {} - @Override - public void postInit(FMLPostInitializationEvent event) - { - } - - @Override - public void serverStarting(FMLServerStartingEvent event) - { - } - - @Override - public EntityPlayer getPlayerEntityFromContext(MessageContext ctx) - { - return ctx.getServerHandler().player; - } - - @Override - public IThreadListener getThreadListenerFromContext(MessageContext ctx) { - return ((EntityPlayerMP) getPlayerEntityFromContext(ctx)).getServerWorld(); + public EntityPlayer getPlayerEntityFromContext(Supplier ctx){ + return ctx.get().getSender(); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java index da251c6..8432bd1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java @@ -11,11 +11,14 @@ import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; -import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.*; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.BuildModes; @@ -26,7 +29,6 @@ import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings; import nl.requios.effortlessbuilding.compatibility.CompatHelper; -import nl.requios.effortlessbuilding.helper.InventoryHelper; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.item.ItemRandomizerBag; @@ -40,7 +42,7 @@ import java.util.Collections; import java.util.List; import java.util.function.Consumer; -@SideOnly(Side.CLIENT) +@OnlyIn(Dist.CLIENT) public class BlockPreviewRenderer { private static List previousCoordinates; private static List previousBlockStates; @@ -79,13 +81,13 @@ public class BlockPreviewRenderer { //Render placed blocks with dissolve effect //Use fancy shader if config allows, otherwise no dissolve - if (BuildConfig.visuals.useShaders) { + if (BuildConfig.visuals.useShaders.get()) { RenderHandler.beginBlockPreviews(); for (int i = 0; i < placedDataList.size(); i++) { PlacedData placed = placedDataList.get(i); if (placed.coordinates != null && !placed.coordinates.isEmpty()) { - double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distanceSq(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier; + double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distanceSq(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier.get(); float dissolve = (ClientProxy.ticksInGame - placed.time) / (float) totalTime; renderBlockPreviews(placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking); } @@ -94,13 +96,13 @@ public class BlockPreviewRenderer { } //Expire placedDataList.removeIf(placed -> { - double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distanceSq(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier; + double totalTime = MathHelper.clampedLerp(30, 60, placed.firstPos.distanceSq(placed.secondPos) / 100.0) * BuildConfig.visuals.dissolveTimeMultiplier.get(); return placed.time + totalTime < ClientProxy.ticksInGame; }); //Render block previews RayTraceResult lookingAt = ClientProxy.getLookingAt(player); - if (modeSettings.getBuildMode() == BuildModes.BuildModeEnum.NORMAL) lookingAt = Minecraft.getMinecraft().objectMouseOver; + if (modeSettings.getBuildMode() == BuildModes.BuildModeEnum.NORMAL) lookingAt = Minecraft.getInstance().objectMouseOver; ItemStack mainhand = player.getHeldItemMainhand(); boolean toolInHand = !(!mainhand.isEmpty() && CompatHelper.isItemBlockProxy(mainhand)); @@ -110,11 +112,12 @@ public class BlockPreviewRenderer { Vec3d hitVec = null; //Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS) - if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK) { + if (lookingAt != null && lookingAt.type == RayTraceResult.Type.BLOCK) { startPos = lookingAt.getBlockPos(); //Check if tool (or none) in hand - boolean replaceable = player.world.getBlockState(startPos).getBlock().isReplaceable(player.world, startPos); + //TODO 1.13 replaceable + boolean replaceable = player.world.getBlockState(startPos).getBlock().getMaterial(player.world.getBlockState(startPos)).isReplaceable(); boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, lookingAt.sideHit); if (!modifierSettings.doQuickReplace() && !toolInHand && !replaceable && !becomesDoubleSlab) { startPos = startPos.offset(lookingAt.sideHit); @@ -149,8 +152,8 @@ public class BlockPreviewRenderer { //get coordinates List startCoordinates = BuildModes.findCoordinates(player, startPos, breaking || modifierSettings.doQuickReplace()); + //Remember first and last point for the shader BlockPos firstPos = BlockPos.ORIGIN, secondPos = BlockPos.ORIGIN; - //Remember first and last pos for the shader if (!startCoordinates.isEmpty()) { firstPos = startCoordinates.get(0); secondPos = startCoordinates.get(startCoordinates.size() - 1); @@ -210,7 +213,7 @@ public class BlockPreviewRenderer { int blockCount; //Use fancy shader if config allows, otherwise outlines - if (BuildConfig.visuals.useShaders && newCoordinates.size() < BuildConfig.visuals.shaderTreshold) { + if (BuildConfig.visuals.useShaders.get() && newCoordinates.size() < BuildConfig.visuals.shaderTreshold.get()) { RenderHandler.beginBlockPreviews(); @@ -225,8 +228,8 @@ public class BlockPreviewRenderer { if (breaking) color = new Vec3d(1f, 0f, 0f); for (int i = newCoordinates.size() - 1; i >= 0; i--) { - AxisAlignedBB boundingBox = blockStates.get(i).getBoundingBox(player.world, newCoordinates.get(i)); - RenderHandler.renderBlockOutline(newCoordinates.get(i), boundingBox, color); + VoxelShape collisionShape = blockStates.get(i).getCollisionShape(player.world, newCoordinates.get(i)); + RenderHandler.renderBlockOutline(newCoordinates.get(i), collisionShape, color); } RenderHandler.endLines(); @@ -236,8 +239,20 @@ public class BlockPreviewRenderer { //Display block count and dimensions in actionbar if (BuildModes.isActive(player)) { - BlockPos dim = secondPos.subtract(firstPos); - dim = new BlockPos(Math.abs(dim.getX()) + 1, Math.abs(dim.getY()) + 1, Math.abs(dim.getZ()) + 1); + + //Find min and max values (not simply firstPos and secondPos because that doesn't work with circles) + int minX = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE; + int minY = Integer.MAX_VALUE, maxY = Integer.MIN_VALUE; + int minZ = Integer.MAX_VALUE, maxZ = Integer.MIN_VALUE; + for (BlockPos pos : startCoordinates) { + if (pos.getX() < minX) minX = pos.getX(); + if (pos.getX() > maxX) maxX = pos.getX(); + if (pos.getY() < minY) minY = pos.getY(); + if (pos.getY() > maxY) maxY = pos.getY(); + if (pos.getZ() < minZ) minZ = pos.getZ(); + if (pos.getZ() > maxZ) maxZ = pos.getZ(); + } + BlockPos dim = new BlockPos(maxX - minX + 1, maxY - minY + 1, maxZ - minZ + 1); String dimensions = "("; if (dim.getX() > 1) dimensions += dim.getX() + "x"; @@ -256,21 +271,21 @@ public class BlockPreviewRenderer { RenderHandler.beginLines(); //Draw outlines if tool in hand //Find proper raytrace: either normal range or increased range depending on canBreakFar - RayTraceResult objectMouseOver = Minecraft.getMinecraft().objectMouseOver; + RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver; RayTraceResult breakingRaytrace = ReachHelper.canBreakFar(player) ? lookingAt : objectMouseOver; - if (toolInHand && breakingRaytrace != null && breakingRaytrace.typeOfHit == RayTraceResult.Type.BLOCK) { + if (toolInHand && breakingRaytrace != null && breakingRaytrace.type == RayTraceResult.Type.BLOCK) { List breakCoordinates = BuildModifiers.findCoordinates(player, breakingRaytrace.getBlockPos()); //Only render first outline if further than normal reach - boolean excludeFirst = objectMouseOver != null && objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK; + boolean excludeFirst = objectMouseOver != null && objectMouseOver.type == RayTraceResult.Type.BLOCK; for (int i = excludeFirst ? 1 : 0; i < breakCoordinates.size(); i++) { BlockPos coordinate = breakCoordinates.get(i); IBlockState blockState = player.world.getBlockState(coordinate); if (!blockState.getBlock().isAir(blockState, player.world, coordinate)) { if (SurvivalHelper.canBreak(player.world, player, coordinate) || i == 0) { - AxisAlignedBB boundingBox = blockState.getBoundingBox(player.world, coordinate); - RenderHandler.renderBlockOutline(coordinate, boundingBox, new Vec3d(0f, 0f, 0f)); + VoxelShape collisionShape = blockState.getCollisionShape(player.world, coordinate); + RenderHandler.renderBlockOutline(coordinate, collisionShape, new Vec3d(0f, 0f, 0f)); } } } @@ -283,15 +298,15 @@ public class BlockPreviewRenderer { public static boolean doRenderBlockPreviews(ModifierSettings modifierSettings, ModeSettings modeSettings, BlockPos startPos) { return modeSettings.getBuildMode() != BuildModes.BuildModeEnum.NORMAL || (startPos != null && BuildModifiers.isEnabled(modifierSettings, startPos)) || - BuildConfig.visuals.alwaysShowBlockPreview; + BuildConfig.visuals.alwaysShowBlockPreview.get(); } protected static int renderBlockPreviews(List coordinates, List blockStates, List itemStacks, float dissolve, BlockPos firstPos, BlockPos secondPos, boolean checkCanPlace, boolean red) { - EntityPlayer player = Minecraft.getMinecraft().player; + EntityPlayer player = Minecraft.getInstance().player; ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); - BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); + BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher(); int blocksValid = 0; if (coordinates.isEmpty()) return blocksValid; @@ -324,7 +339,7 @@ public class BlockPreviewRenderer { public static void onBlocksPlaced(List coordinates, List itemStacks, List blockStates, BlockPos firstPos, BlockPos secondPos) { - EntityPlayerSP player = Minecraft.getMinecraft().player; + EntityPlayerSP player = Minecraft.getInstance().player; ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); @@ -333,7 +348,7 @@ public class BlockPreviewRenderer { //Save current coordinates, blockstates and itemstacks if (!coordinates.isEmpty() && blockStates.size() == coordinates.size() && - coordinates.size() > 1 && coordinates.size() < BuildConfig.visuals.shaderTreshold) { + coordinates.size() > 1 && coordinates.size() < BuildConfig.visuals.shaderTreshold.get()) { placedDataList.add(new PlacedData(ClientProxy.ticksInGame, coordinates, blockStates, itemStacks, firstPos, secondPos, false)); @@ -348,7 +363,7 @@ public class BlockPreviewRenderer { public static void onBlocksBroken(List coordinates, List itemStacks, List blockStates, BlockPos firstPos, BlockPos secondPos) { - EntityPlayerSP player = Minecraft.getMinecraft().player; + EntityPlayerSP player = Minecraft.getInstance().player; ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); @@ -357,7 +372,7 @@ public class BlockPreviewRenderer { //Save current coordinates, blockstates and itemstacks if (!coordinates.isEmpty() && blockStates.size() == coordinates.size() && - coordinates.size() > 1 && coordinates.size() < BuildConfig.visuals.shaderTreshold) { + coordinates.size() > 1 && coordinates.size() < BuildConfig.visuals.shaderTreshold.get()) { sortOnDistanceToPlayer(coordinates, player); @@ -371,7 +386,7 @@ public class BlockPreviewRenderer { private static Consumer generateShaderCallback(final float dissolve, final Vec3d blockpos, final Vec3d firstpos, final Vec3d secondpos, final boolean highlight, final boolean red) { - Minecraft mc = Minecraft.getMinecraft(); + Minecraft mc = Minecraft.getInstance(); return (Integer shader) -> { int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve"); int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight"); @@ -387,13 +402,13 @@ public class BlockPreviewRenderer { //mask ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit); - OpenGlHelper.setActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.renderEngine.getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId()); + OpenGlHelper.glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId()); //image ARBShaderObjects.glUniform1iARB(imageUniform, primaryTextureUnit); - OpenGlHelper.setActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit); - GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.renderEngine.getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).getGlTextureId()); + OpenGlHelper.glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit); + GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).getGlTextureId()); //blockpos ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z); @@ -413,8 +428,8 @@ public class BlockPreviewRenderer { Collections.sort(coordinates, (lhs, rhs) -> { // -1 - less than, 1 - greater than, 0 - equal - double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getPositionEyes(1f)).lengthSquared(); - double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getPositionEyes(1f)).lengthSquared(); + double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getEyePosition(1f)).lengthSquared(); + double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getEyePosition(1f)).lengthSquared(); return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer); }); diff --git a/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java index 7f99656..b6f409f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java @@ -4,15 +4,16 @@ import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import org.lwjgl.opengl.GL11; -import org.lwjgl.util.Color; -@SideOnly(Side.CLIENT) +import java.awt.*; + +@OnlyIn(Dist.CLIENT) public class ModifierRenderer { protected static final Color colorX = new Color(255, 72, 52); diff --git a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java index 8386d7e..89cabaa 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java @@ -2,45 +2,42 @@ package nl.requios.effortlessbuilding.render; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; -import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.audio.SimpleSound; import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.RenderGlobal; -import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.resources.I18n; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumHand; -import net.minecraft.util.ResourceLocation; +import net.minecraft.particles.IParticleData; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldEventListener; -import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; -import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.network.ModeActionMessage; import nl.requios.effortlessbuilding.network.ModeSettingsMessage; +import nl.requios.effortlessbuilding.network.PacketHandler; import nl.requios.effortlessbuilding.proxy.ClientProxy; -import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL14; @@ -50,12 +47,12 @@ import java.util.List; /*** * Main render class for Effortless Building */ -@Mod.EventBusSubscriber(Side.CLIENT) +@Mod.EventBusSubscriber(value = Dist.CLIENT) public class RenderHandler implements IWorldEventListener { @SubscribeEvent public static void onRender(RenderWorldLastEvent event) { - EntityPlayer player = Minecraft.getMinecraft().player; + EntityPlayer player = Minecraft.getInstance().player; ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); @@ -72,15 +69,16 @@ public class RenderHandler implements IWorldEventListener { @SubscribeEvent //Display Radial Menu - public static void onRenderGameOverlay(final RenderGameOverlayEvent.Post event ) { - Minecraft mc = Minecraft.getMinecraft(); + public static void onRenderGameOverlay(final RenderGameOverlayEvent.Post event) { + Minecraft mc = Minecraft.getInstance(); EntityPlayerSP player = mc.player; //check if chisel and bits tool in hand (and has menu) - final boolean hasChiselInHand = CompatHelper.chiselsAndBitsProxy.isHoldingChiselTool(EnumHand.MAIN_HAND); +// final boolean hasChiselInHand = CompatHelper.chiselsAndBitsProxy.isHoldingChiselTool(EnumHand.MAIN_HAND); final RenderGameOverlayEvent.ElementType type = event.getType(); - if (type == RenderGameOverlayEvent.ElementType.ALL && !hasChiselInHand) { + //TODO 1.13 compatibility + if (type == RenderGameOverlayEvent.ElementType.ALL /*&& !hasChiselInHand*/) { final boolean wasVisible = RadialMenu.instance.isVisible(); if (ClientProxy.keyBindings[3].isKeyDown()) { @@ -98,7 +96,7 @@ public class RenderHandler implements IWorldEventListener { playRadialMenuSound(); modeSettings.setBuildMode(RadialMenu.instance.switchTo); ModeSettingsManager.setModeSettings(player, modeSettings); - EffortlessBuilding.packetHandler.sendToServer(new ModeSettingsMessage(modeSettings)); + PacketHandler.INSTANCE.sendToServer(new ModeSettingsMessage(modeSettings)); EffortlessBuilding.log(player, I18n.format(modeSettings.getBuildMode().name), true); } @@ -107,7 +105,7 @@ public class RenderHandler implements IWorldEventListener { ModeOptions.ActionEnum action = RadialMenu.instance.doAction; if (action != null) { ModeOptions.performAction(player, action); - EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action)); + PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action)); } playRadialMenuSound(); @@ -119,25 +117,25 @@ public class RenderHandler implements IWorldEventListener { if (RadialMenu.instance.isVisible()) { - final ScaledResolution res = event.getResolution(); - RadialMenu.instance.configure(res.getScaledWidth(), res.getScaledHeight()); + int scaledWidth = mc.mainWindow.getScaledWidth(); + int scaledHeight = mc.mainWindow.getScaledHeight(); + RadialMenu.instance.configure(scaledWidth, scaledHeight); if (!wasVisible) { - mc.inGameHasFocus = false; - mc.mouseHelper.ungrabMouseCursor(); + mc.mouseHelper.ungrabMouse(); } - if (mc.inGameHasFocus) { + if (mc.mouseHelper.isMouseGrabbed()) { KeyBinding.unPressAllKeys(); } - final int mouseX = Mouse.getX() * res.getScaledWidth() / mc.displayWidth; - final int mouseY = res.getScaledHeight() - Mouse.getY() * res.getScaledHeight() / mc.displayHeight - 1; + final int mouseX = ((int) mc.mouseHelper.getMouseX()) * scaledWidth / mc.mainWindow.getFramebufferWidth(); + final int mouseY = scaledHeight - ((int) mc.mouseHelper.getMouseY()) * scaledHeight / mc.mainWindow.getFramebufferHeight() - 1; net.minecraftforge.client.ForgeHooksClient.drawScreen(RadialMenu.instance, mouseX, mouseY, event.getPartialTicks()); } else { if (wasVisible && RadialMenu.instance.doAction != ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) { - mc.setIngameFocus(); + mc.mouseHelper.grabMouse(); } } } @@ -146,14 +144,13 @@ public class RenderHandler implements IWorldEventListener { public static void playRadialMenuSound() { final float volume = 0.1f; if (volume >= 0.0001f) { - final PositionedSoundRecord psr = new PositionedSoundRecord(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, - volume, 1.0f, Minecraft.getMinecraft().player.getPosition()); - Minecraft.getMinecraft().getSoundHandler().playSound(psr); + SimpleSound sound = new SimpleSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, volume, 1.0f, Minecraft.getInstance().player.getPosition()); + Minecraft.getInstance().getSoundHandler().play(sound); } } private static void begin(float partialTicks) { - EntityPlayer player = Minecraft.getMinecraft().player; + EntityPlayer player = Minecraft.getInstance().player; double playerX = player.prevPosX + (player.posX - player.prevPosX) * partialTicks; double playerY = player.prevPosY + (player.posY - player.prevPosY) * partialTicks; double playerZ = player.prevPosZ + (player.posZ - player.prevPosZ) * partialTicks; @@ -186,7 +183,7 @@ public class RenderHandler implements IWorldEventListener { GL11.glEnable(GL11.GL_CULL_FACE); GL11.glEnable(GL11.GL_TEXTURE_2D); // Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - Minecraft.getMinecraft().renderEngine.bindTexture(ShaderHandler.shaderMaskTextureLocation); + Minecraft.getInstance().textureManager.bindTexture(ShaderHandler.shaderMaskTextureLocation); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); @@ -207,10 +204,10 @@ public class RenderHandler implements IWorldEventListener { protected static void renderBlockPreview(BlockRendererDispatcher dispatcher, BlockPos blockPos, IBlockState blockState) { GlStateManager.pushMatrix(); - GlStateManager.translate(blockPos.getX(), blockPos.getY(), blockPos.getZ()); - GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); - GlStateManager.translate(-0.01f, -0.01f, 0.01f); - GlStateManager.scale(1.02f, 1.02f, 1.02f); + GlStateManager.translatef(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + GlStateManager.rotatef(-90.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.translatef(-0.01f, -0.01f, 0.01f); + GlStateManager.scalef(1.02f, 1.02f, 1.02f); try { dispatcher.renderBlockBrightness(blockState, 0.85f); @@ -239,23 +236,23 @@ public class RenderHandler implements IWorldEventListener { AxisAlignedBB aabb = new AxisAlignedBB(pos1, pos2.add(1, 1, 1)).grow(0.0020000000949949026); - RenderGlobal.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f); + WorldRenderer.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f); } //Renders outline with given bounding box - protected static void renderBlockOutline(BlockPos pos, AxisAlignedBB boundingBox, Vec3d color) { + protected static void renderBlockOutline(BlockPos pos, VoxelShape collisionShape, Vec3d color) { GL11.glLineWidth(2); - AxisAlignedBB aabb = boundingBox.offset(pos).grow(0.0020000000949949026); +// AxisAlignedBB aabb = boundingBox.offset(pos).grow(0.0020000000949949026); +// VoxelShape voxelShape = collisionShape.withOffset(pos.getX(), pos.getY(), pos.getZ()); - RenderGlobal.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f); +// WorldRenderer.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f); + WorldRenderer.drawShape(collisionShape, pos.getX(), pos.getY(), pos.getZ(), (float) color.x, (float) color.y, (float) color.z, 0.4f); } - - //IWORLDEVENTLISTENER IMPLEMENTATION @Override - public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) { + public void notifyBlockUpdate(IBlockReader worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) { } @@ -281,14 +278,12 @@ public class RenderHandler implements IWorldEventListener { } @Override - public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, - double xSpeed, double ySpeed, double zSpeed, int... parameters) { + public void addParticle(IParticleData particleData, boolean alwaysRender, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { } @Override - public void spawnParticle(int id, boolean ignoreRange, boolean p_190570_3_, double x, double y, double z, - double xSpeed, double ySpeed, double zSpeed, int... parameters) { + public void addParticle(IParticleData particleData, boolean ignoreRange, boolean minimizeLevel, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) { } @@ -315,7 +310,7 @@ public class RenderHandler implements IWorldEventListener { //Sends breaking progress for all coordinates to renderglobal, so all blocks get visually broken @Override public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { - Minecraft mc = Minecraft.getMinecraft(); + Minecraft mc = Minecraft.getInstance(); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(mc.player); if (!BuildModifiers.isEnabled(modifierSettings, pos)) return; diff --git a/src/main/java/nl/requios/effortlessbuilding/render/ShaderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/ShaderHandler.java index 1d2bace..a3f1484 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/ShaderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/ShaderHandler.java @@ -46,7 +46,7 @@ public final class ShaderHandler { if(!doUseShaders()) return; - rawColor = createProgram("/assets/effortlessbuilding/shaders/raw_color", FRAG); +// rawColor = createProgram("/assets/effortlessbuilding/shaders/raw_color", FRAG); dissolve = createProgram("/assets/effortlessbuilding/shaders/dissolve", VERT + FRAG); } @@ -74,7 +74,7 @@ public final class ShaderHandler { } public static boolean doUseShaders() { - return BuildConfig.visuals.useShaders && OpenGlHelper.shadersSupported; + return BuildConfig.visuals.useShaders.get() && OpenGlHelper.shadersSupported; } private static int createProgram(String s, int sides) { diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..8add64c --- /dev/null +++ b/src/main/resources/META-INF/mods.toml @@ -0,0 +1,52 @@ +# This is an example mods.toml file. It contains the data relating to the loading mods. +# There are several mandatory fields (#mandatory), and many more that are optional (#optional). +# The overall format is standard TOML format, v0.5.0. +# Note that there are a couple of TOML lists in this file. +# Find more information on toml format here: https://github.com/toml-lang/toml +# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml +modLoader="javafml" #mandatory +# A version range to match for said mod loader - for regular FML @Mod it will be the forge version +loaderVersion="[25,)" #mandatory (24 is current forge version) +# A URL to refer people to when problems occur with this mod +issueTrackerURL="https://bitbucket.org/Requios/effortless-building/issues?status=new&status=open" #optional +# A list of mods - how many allowed here is determined by the individual mod loader +[[mods]] #mandatory +# The modid of the mod +modId="effortlessbuilding" #mandatory +# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it +version="${file.jarVersion}" #mandatory + # A display name for the mod +displayName="Effortless Building" #mandatory +# A URL to query for updates for this mod. See the JSON update specification +updateJSONURL="http://myurl.me/" #optional +# A URL for the "homepage" for this mod, displayed in the mod UI +displayURL="https://minecraft.curseforge.com/projects/effortless-building" #optional +# A file name (in the root of the mod JAR) containing a logo for display +logoFile="logo.png" #optional +# A text field displayed in the mod UI +credits="" #optional +# A text field displayed in the mod UI +authors="Requios" #optional +# The description text for the mod (multi line!) (#mandatory) +description=''' +Makes building easier by providing tools like mirrors, arrays, QuickReplace and a block randomizer. For survival and creative mode. +''' +# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. +#[[dependencies.examplemod]] #optional +# # the modid of the dependency +# modId="forge" #mandatory +# # Does this dependency have to exist - if not, ordering below must be specified +# mandatory=true #mandatory +# # The version range of the dependency +# versionRange="[25,)" #mandatory +# # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory +# ordering="NONE" +# # Side this dependency is applied on - BOTH, CLIENT or SERVER +# side="BOTH" +## Here's another dependency +#[[dependencies.examplemod]] +# modId="minecraft" +# mandatory=true +# versionRange="[1.13.2]" +# ordering="NONE" +# side="BOTH" \ No newline at end of file diff --git a/src/main/resources/assets/effortlessbuilding/lang/en_us.json b/src/main/resources/assets/effortlessbuilding/lang/en_us.json new file mode 100644 index 0000000..0fb188e --- /dev/null +++ b/src/main/resources/assets/effortlessbuilding/lang/en_us.json @@ -0,0 +1,54 @@ +{ + "key.effortlessbuilding.category": "Effortless Building", + "key.effortlessbuilding.hud.desc": "Modifier Menu", + "key.effortlessbuilding.replace.desc": "Toggle QuickReplace", + "key.effortlessbuilding.creative.desc": "Toggle Survival/Creative Mode", + "key.effortlessbuilding.mode.desc": "Radial Menu", + "key.effortlessbuilding.undo.desc": "Undo", + "key.effortlessbuilding.redo.desc": "Redo", + "key.effortlessbuilding.altplacement.desc": "Alternative placement", + + "effortlessbuilding:randomizer_bag": "Randomizer Bag", + "effortlessbuilding:reach_upgrade1": "Reach Upgrade 1", + "effortlessbuilding:reach_upgrade2": "Reach Upgrade 2", + "effortlessbuilding:reach_upgrade3": "Reach Upgrade 3", + + "effortlessbuilding.mode.normal": "Normal", + "effortlessbuilding.mode.normal_plus": "Normal+", + "effortlessbuilding.mode.line": "Line", + "effortlessbuilding.mode.wall": "Wall", + "effortlessbuilding.mode.floor": "Floor", + "effortlessbuilding.mode.diagonal_line": "Diagonal Line", + "effortlessbuilding.mode.diagonal_wall": "Diagonal Wall", + "effortlessbuilding.mode.slope_floor": "Slope Floor", + "effortlessbuilding.mode.cube": "Cube", + "effortlessbuilding.mode.circle": "Circle", + "effortlessbuilding.mode.cylinder": "Cylinder", + "effortlessbuilding.mode.sphere": "Sphere", + + "effortlessbuilding.action.undo": "Undo", + "effortlessbuilding.action.redo": "Redo", + "effortlessbuilding.action.replace": "Replace", + "effortlessbuilding.action.open_modifier_settings": "Open Modifier Settings", + + "effortlessbuilding.action.build_speed": "Build Speed", + "effortlessbuilding.action.filling": "Filling", + "effortlessbuilding.action.raised_edge": "Raised Edge", + "effortlessbuilding.action.thickness": "Line Thickness", + "effortlessbuilding.action.circle_start": "Start Point", + + "effortlessbuilding.action.normal_speed": "Normal", + "effortlessbuilding.action.fast_speed": "Fast", + "effortlessbuilding.action.full": "Filled", + "effortlessbuilding.action.hollow": "Hollow", + "effortlessbuilding.action.skeleton": "Skeleton", + "effortlessbuilding.action.short_edge": "Short Edge", + "effortlessbuilding.action.long_edge": "Long Edge", + "effortlessbuilding.action.thickness_1": "1 Block Thick", + "effortlessbuilding.action.thickness_3": "3 Blocks Thick", + "effortlessbuilding.action.thickness_5": "5 Blocks Thick", + "effortlessbuilding.action.start_center": "Middle", + "effortlessbuilding.action.start_corner": "Corner", + + "commands.reach.usage": "/reach " +} \ No newline at end of file diff --git a/src/main/resources/assets/effortlessbuilding/lang/en_us.lang b/src/main/resources/assets/effortlessbuilding/lang/en_us.lang deleted file mode 100644 index f292005..0000000 --- a/src/main/resources/assets/effortlessbuilding/lang/en_us.lang +++ /dev/null @@ -1,45 +0,0 @@ -key.effortlessbuilding.category=Effortless Building -key.effortlessbuilding.hud.desc=Modifier Menu -key.effortlessbuilding.replace.desc=Toggle QuickReplace -key.effortlessbuilding.creative.desc=Toggle Survival/Creative Mode -key.effortlessbuilding.mode.desc=Radial Menu (C&B compatible) -key.effortlessbuilding.undo.desc=Undo -key.effortlessbuilding.redo.desc=Redo - -item.effortlessbuilding:randomizer_bag.name=Randomizer Bag -item.effortlessbuilding:reach_upgrade1.name=Reach Upgrade 1 -item.effortlessbuilding:reach_upgrade2.name=Reach Upgrade 2 -item.effortlessbuilding:reach_upgrade3.name=Reach Upgrade 3 - -effortlessbuilding.mode.normal=Normal -effortlessbuilding.mode.normal_plus=Normal+ -effortlessbuilding.mode.line=Line -effortlessbuilding.mode.wall=Wall -effortlessbuilding.mode.floor=Floor -effortlessbuilding.mode.diagonal_line=Diagonal Line -effortlessbuilding.mode.diagonal_wall=Diagonal Wall -effortlessbuilding.mode.slope_floor=Slope Floor -effortlessbuilding.mode.cube=Cube - -effortlessbuilding.action.undo=Undo -effortlessbuilding.action.redo=Redo -effortlessbuilding.action.replace=Replace -effortlessbuilding.action.open_modifier_settings=Open Modifier Settings - -effortlessbuilding.action.build_speed=Build Speed -effortlessbuilding.action.filling=Filling -effortlessbuilding.action.raised_edge=Raised Edge -effortlessbuilding.action.thickness=Line Thickness - -effortlessbuilding.action.normal_speed=Normal -effortlessbuilding.action.fast_speed=Fast -effortlessbuilding.action.full=Filled -effortlessbuilding.action.hollow=Hollow -effortlessbuilding.action.skeleton=Skeleton -effortlessbuilding.action.short_edge=Short Edge -effortlessbuilding.action.long_edge=Long Edge -effortlessbuilding.action.thickness_1=1 Block Thick -effortlessbuilding.action.thickness_3=3 Blocks Thick -effortlessbuilding.action.thickness_5=5 Blocks Thick - -commands.reach.usage=/reach \ No newline at end of file diff --git a/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag b/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag index dd0cae8..d322425 100644 --- a/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag +++ b/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag @@ -101,4 +101,4 @@ void main() { if (maskgs * 0.3 + place * 0.7 <= dissolve) gl_FragColor = vec4(texcolor.rgb, 0.0); else gl_FragColor = color; -} \ No newline at end of file +} diff --git a/src/main/resources/assets/effortlessbuilding/recipes/_factories.json b/src/main/resources/data/effortlessbuilding/recipes/_factories.json similarity index 100% rename from src/main/resources/assets/effortlessbuilding/recipes/_factories.json rename to src/main/resources/data/effortlessbuilding/recipes/_factories.json diff --git a/src/main/resources/assets/effortlessbuilding/recipes/randomizer_bag.json b/src/main/resources/data/effortlessbuilding/recipes/randomizer_bag.json similarity index 83% rename from src/main/resources/assets/effortlessbuilding/recipes/randomizer_bag.json rename to src/main/resources/data/effortlessbuilding/recipes/randomizer_bag.json index e27597b..b43fc1d 100644 --- a/src/main/resources/assets/effortlessbuilding/recipes/randomizer_bag.json +++ b/src/main/resources/data/effortlessbuilding/recipes/randomizer_bag.json @@ -10,8 +10,7 @@ "item": "minecraft:leather" }, "O": { - "item": "minecraft:planks", - "data": 32767 + "tag": "minecraft:planks" } }, "result": { diff --git a/src/main/resources/assets/effortlessbuilding/recipes/reach_upgrade1.json b/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade1.json similarity index 100% rename from src/main/resources/assets/effortlessbuilding/recipes/reach_upgrade1.json rename to src/main/resources/data/effortlessbuilding/recipes/reach_upgrade1.json diff --git a/src/main/resources/assets/effortlessbuilding/recipes/reach_upgrade2.json b/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade2.json similarity index 100% rename from src/main/resources/assets/effortlessbuilding/recipes/reach_upgrade2.json rename to src/main/resources/data/effortlessbuilding/recipes/reach_upgrade2.json diff --git a/src/main/resources/assets/effortlessbuilding/recipes/reach_upgrade3.json b/src/main/resources/data/effortlessbuilding/recipes/reach_upgrade3.json similarity index 100% rename from src/main/resources/assets/effortlessbuilding/recipes/reach_upgrade3.json rename to src/main/resources/data/effortlessbuilding/recipes/reach_upgrade3.json diff --git a/src/main/resources/logo.png b/src/main/resources/logo.png new file mode 100644 index 0000000..0a4f217 Binary files /dev/null and b/src/main/resources/logo.png differ diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info deleted file mode 100644 index 52c95fc..0000000 --- a/src/main/resources/mcmod.info +++ /dev/null @@ -1,16 +0,0 @@ -[ -{ - "modid": "effortlessbuilding", - "name": "Effortless Building", - "description": "Makes building easier by providing tools like mirrors, arrays, QuickReplace and a block randomizer. For survival and creative mode.", - "version": "${version}", - "mcversion": "${mcversion}", - "url": "https://minecraft.curseforge.com/projects/effortless-building", - "updateUrl": "", - "authorList": ["Requios"], - "credits": "", - "logoFile": "", - "screenshots": [], - "dependencies": [] -} -] diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index 4018267..cc7b4d0 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,7 +1,7 @@ { "pack": { "description": "examplemod resources", - "pack_format": 3, - "_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)." + "pack_format": 4, + "_comment": "A pack_format of 4 requires json lang files. Note: we require v4 pack meta for all mods." } -} +} \ No newline at end of file