1.13 branch commit, taken from 1.13 repository commit 491113040c350791a403f18752d98c0faa966e6b. For rest of history see repository at https://bitbucket.org/Requios/effortless-building-1.13/src/master/

This commit is contained in:
Christian Knaapen
2019-12-04 15:40:52 +01:00
parent 3718492495
commit 6c34b09223
96 changed files with 3012 additions and 2825 deletions

62
.gitignore vendored
View File

@@ -1,43 +1,25 @@
## Based on GitHub's Eclipse .gitignore # eclipse
bin
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"
*.launch *.launch
.settings
.metadata
.classpath
.project
# CDT-specific # idea
.cproject out
*.ipr
*.iws
*.iml
.idea
# PDT-specific # gradle
.buildpath build
.gradle
# other
eclipse
run
# Files from Forge MDK
forge*changelog.txt

View File

@@ -1,3 +1 @@
This is the version for Minecraft 1.12. The 1.12 repository can be found here: https://bitbucket.org/Requios/effortless-building/src/master/
1.13 can be found here: https://bitbucket.org/Requios/effortless-building-1.13/src/master/

53
README.txt Normal file
View File

@@ -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

View File

@@ -1,82 +1,131 @@
buildscript { buildscript {
repositories { repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter() jcenter()
maven { url = "http://files.minecraftforge.net/maven" } mavenCentral()
} }
dependencies { 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' apply plugin: 'net.minecraftforge.gradle'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. // 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" sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
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'
}
minecraft { minecraft {
version = "1.12.2-14.23.5.2825" // The mappings can be changed at any time, and must be in the following format.
runDir = "run" // 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. // 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. // Simply re-run your setup task after changing the mappings to update your workspace.
mappings = "stable_39" mappings channel: 'snapshot', version: '20180921-1.13'
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}
repositories { // accessTransformer = file('build/resources/main/META-INF/accesstransformer.cfg')
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 { dependencies {
// you may put jars on which you depend on in ./libs // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// or you may define them like so.. // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
//compile "some.group:artifact:version:classifier" // The userdev artifact is a special name and will get all sorts of transformations applied to it.
//compile "some.group:artifact:version" minecraft 'net.minecraftforge:forge:1.13.2-25.0.219'
// real examples // You may put jars on which you depend on in ./libs or you may define them like so..
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env // compile "some.group:artifact:version:classifier"
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env // compile "some.group:artifact:version"
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. // Real examples
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' // 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
// the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided, // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
// except that these dependencies get remapped to your current MCP mappings // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
//deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
provided 'mod.chiselsandbits:chiselsandbits:14.30'
// for more info... // 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/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html // http://www.gradle.org/docs/current/userguide/dependency_management.html
} }
processResources { // Example for how to get properties into the manifest for reading by the runtime..
// this will ensure that this task is redone when the versions change. jar {
inputs.property "version", project.version manifest {
inputs.property "mcversion", project.minecraft.version attributes([
"Specification-Title": "effortlessbuilding",
// replace stuff in mcmod.info, nothing else "Specification-Vendor": "requios",
from(sourceSets.main.resources.srcDirs) { "Specification-Version": "1", // We are version 1 of ourselves
include 'mcmod.info' "Implementation-Title": project.name,
"Implementation-Version": "${version}",
// replace version and mcversion "Implementation-Vendor" :"requios",
expand 'version':project.version, 'mcversion':project.minecraft.version "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
} ])
}
// copy everything else except the mcmod.info }
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info' // 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"
}
} }
} }

4
gradle.properties Normal file
View File

@@ -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

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip

Binary file not shown.

View File

@@ -1,89 +1,134 @@
package nl.requios.effortlessbuilding; 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 class BuildConfig {
public static Reach reach = new Reach(); private static final ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder();
public static SurvivalBalancers survivalBalancers = new SurvivalBalancers(); public static final Reach reach = new Reach(builder);
public static Visuals visuals = new Visuals(); 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 { public static class Reach {
@Comment({"Reach: how far away the player can place blocks using mirror/array etc.", public final ForgeConfigSpec.ConfigValue<Boolean> enableReachUpgrades;
public final ForgeConfigSpec.ConfigValue<Integer> maxReachCreative;
public final ForgeConfigSpec.ConfigValue<Integer> maxReachLevel0;
public final ForgeConfigSpec.ConfigValue<Integer> maxReachLevel1;
public final ForgeConfigSpec.ConfigValue<Integer> maxReachLevel2;
public final ForgeConfigSpec.ConfigValue<Integer> maxReachLevel3;
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.", "Enable the crafting of reach upgrades to increase reach.",
"If disabled, reach is set to level 3 for survival players."}) "If disabled, reach is set to level 3 for survival players.")
public boolean enableReachUpgrades = true; .define("enableReachUpgrades", true);
@Comment({"Maximum reach in creative", maxReachCreative = builder
"Keep in mind that chunks need to be loaded to be able to place blocks inside."}) .comment("Maximum reach in creative",
public int maxReachCreative = 200; "Keep in mind that chunks need to be loaded to be able to place blocks inside.")
.define("maxReachCreative", 200);
@Comment({"Maximum reach in survival without upgrades", maxReachLevel0 = builder
.comment("Maximum reach in survival without upgrades",
"Reach upgrades are craftable consumables that permanently increase reach.", "Reach upgrades are craftable consumables that permanently increase reach.",
"Set to 0 to disable Effortless Building until the player has consumed a reach upgrade."}) "Set to 0 to disable Effortless Building until the player has consumed a reach upgrade.")
public int maxReachLevel0 = 20; .define("maxReachLevel0", 20);
@Comment("Maximum reach in survival with one upgrade") maxReachLevel1 = builder
public int maxReachLevel1 = 50; .comment("Maximum reach in survival with one upgrade")
.define("maxReachLevel1", 50);
@Comment("Maximum reach in survival with two upgrades") maxReachLevel2 = builder
public int maxReachLevel2 = 100; .comment("Maximum reach in survival with two upgrades")
.define("maxReachLevel2", 100);
@Comment("Maximum reach in survival with three upgrades") maxReachLevel3 = builder
public int maxReachLevel3 = 200; .comment("Maximum reach in survival with three upgrades")
.define("maxReachLevel3", 200);
builder.pop();
}
} }
public static class SurvivalBalancers { public static class SurvivalBalancers {
@Comment({"Allows a survival player to break blocks that are far away, in addition to placing blocks.", public final ForgeConfigSpec.ConfigValue<Boolean> breakFar;
"Note: this allows insta-breaking of blocks in survival."}) public final ForgeConfigSpec.ConfigValue<Boolean> increasedMiningTime;
public boolean breakFar = false; public final ForgeConfigSpec.ConfigValue<Integer> miningTimePercentage;
public final ForgeConfigSpec.ConfigValue<Integer> quickReplaceMiningLevel;
public final ForgeConfigSpec.ConfigValue<Integer> undoStackSize;
@Comment({"Increases the time to mine a block when breaking multiple at once.", public SurvivalBalancers(ForgeConfigSpec.Builder builder) {
builder.push("SurvivalBalancers");
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);
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.", "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."}) "Example: breaking 1 dirt + 1 obsidian takes the time of breaking 1 dirt + 1 obsidian.")
public boolean increasedMiningTime = true; .define("increasedMiningTime", true);
@Comment({"How much the mining time of each additional block counts towards an increased mining time.", 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,", "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.", "and 100% takes as much time as breaking each block individually.",
"The block in front of you always counts as 100%."}) "The block in front of you always counts as 100%.")
@RangeInt(min = 0, max = 200) .defineInRange("miningTimePercentage", 50, 0, 200);
public int miningTimePercentage = 50;
@Comment({"Determines what blocks can be replaced in survival.", quickReplaceMiningLevel = builder
.comment("Determines what blocks can be replaced in survival.",
"-1: only blocks that can be harvested by hand (default)", "-1: only blocks that can be harvested by hand (default)",
"0: blocks that can be harvested with wooden or gold tools", "0: blocks that can be harvested with wooden or gold tools",
"1: blocks that can be harvested with stone tools", "1: blocks that can be harvested with stone tools",
"2: blocks that can be harvested with iron tools", "2: blocks that can be harvested with iron tools",
"3: blocks that can be harvested with diamond tools", "3: blocks that can be harvested with diamond tools")
}) .defineInRange("quickReplaceMiningLevel", -1, -1, 3);
@RangeInt(min = -1, max = 3)
public int quickReplaceMiningLevel = -1;
@Comment({"How many placements are remembered for the undo functionality."}) undoStackSize = builder
@RequiresMcRestart .comment("How many placements are remembered for the undo functionality.")
public int undoStackSize = 10; .worldRestart()
.define("undoStackSize", 10);
builder.pop();
}
} }
public static class Visuals { public static class Visuals {
@Comment({"Show a block preview if you have a block in hand on build mode NORMAL"}) public final ForgeConfigSpec.ConfigValue<Boolean> alwaysShowBlockPreview;
public boolean alwaysShowBlockPreview = false; public final ForgeConfigSpec.ConfigValue<Double> dissolveTimeMultiplier;
public final ForgeConfigSpec.ConfigValue<Integer> shaderTreshold;
public final ForgeConfigSpec.ConfigValue<Boolean> useShaders;
@Comment({"How long the dissolve effect takes when placing blocks.", public Visuals(ForgeConfigSpec.Builder builder) {
builder.push("Visuals");
alwaysShowBlockPreview = builder
.comment("Show a block preview if you have a block in hand even in the 'Normal' build mode")
.define("alwaysShowBlockPreview", false);
dissolveTimeMultiplier = builder
.comment("How long the dissolve effect takes when placing blocks.",
"Default between 30 and 60 ticks, you can multiply that here.", "Default between 30 and 60 ticks, you can multiply that here.",
"Recommended values:", "Recommended values:",
"Snappy: 0.7", "Snappy: 0.7",
"Relaxing: 1.5"}) "Relaxing: 1.5")
public double dissolveTimeMultiplier = 1.0; .define("dissolveTimeMultiplier", 1.0);
@Comment({"Switch to using the simple performance shader when placing more than this many blocks."}) shaderTreshold = builder
public int shaderTreshold = 1500; .comment("Switch to using the simple performance shader when placing more than this many blocks.")
.define("shaderTreshold", 1500);
@Comment({"Use fancy shaders while placing blocks"}) useShaders = builder
public boolean useShaders = true; .comment("Use fancy shaders while placing blocks")
.define("useShaders", true);
builder.pop();
}
} }
} }

View File

@@ -4,55 +4,55 @@ import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.config.Config; import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.common.config.ConfigManager; 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;
import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.config.ModConfig;
import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; import net.minecraftforge.fml.network.NetworkRegistry;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager;
import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager;
import nl.requios.effortlessbuilding.command.CommandReach; import nl.requios.effortlessbuilding.command.CommandReach;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.gui.RandomizerBagGuiHandler; import nl.requios.effortlessbuilding.gui.RandomizerBagGuiHandler;
import nl.requios.effortlessbuilding.helper.ReachConditionFactory;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade1; import nl.requios.effortlessbuilding.item.ItemReachUpgrade1;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade2; import nl.requios.effortlessbuilding.item.ItemReachUpgrade2;
import nl.requios.effortlessbuilding.item.ItemReachUpgrade3; 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.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; import org.apache.logging.log4j.Logger;
@Mod(modid = EffortlessBuilding.MODID, name = EffortlessBuilding.NAME, version = EffortlessBuilding.VERSION) // The value here should match an entry in the META-INF/mods.toml file
@Mod.EventBusSubscriber @Mod(EffortlessBuilding.MODID)
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public class EffortlessBuilding public class EffortlessBuilding
{ {
public static final String MODID = "effortlessbuilding"; public static final String MODID = "effortlessbuilding";
public static final String NAME = "Effortless Building"; 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 EffortlessBuilding instance;
public static Logger logger; public static final Logger logger = LogManager.getLogger();
@SidedProxy( public static IProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> ServerProxy::new);
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 final ItemRandomizerBag ITEM_RANDOMIZER_BAG = new ItemRandomizerBag(); public static final ItemRandomizerBag ITEM_RANDOMIZER_BAG = new ItemRandomizerBag();
public static final ItemReachUpgrade1 ITEM_REACH_UPGRADE_1 = new ItemReachUpgrade1(); public static final ItemReachUpgrade1 ITEM_REACH_UPGRADE_1 = new ItemReachUpgrade1();
@@ -69,73 +69,76 @@ public class EffortlessBuilding
ITEM_REACH_UPGRADE_3 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 public EffortlessBuilding() {
// preInit "Run before anything else. Read your config, create blocks, items, etc, and register them with the GameRegistry." instance = this;
public void preInit(FMLPreInitializationEvent event)
{
logger = event.getModLog();
CapabilityManager.INSTANCE.register(ModifierCapabilityManager.IModifierCapability.class, new ModifierCapabilityManager.Storage(), ModifierCapabilityManager.ModifierCapability.class); // Register the setup method for modloading
CapabilityManager.INSTANCE.register(ModeCapabilityManager.IModeCapability.class, new ModeCapabilityManager.Storage(), ModeCapabilityManager.ModeCapability.class); 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); //Register config
EffortlessBuilding.packetHandler.registerMessage(ModifierSettingsMessage.MessageHandler.class, ModifierSettingsMessage.class, 0, Side.CLIENT); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, BuildConfig.spec);
EffortlessBuilding.packetHandler.registerMessage(ModeSettingsMessage.MessageHandler.class, ModeSettingsMessage.class, 1, Side.SERVER); // Register ourselves for server and other game events we are interested in
EffortlessBuilding.packetHandler.registerMessage(ModeSettingsMessage.MessageHandler.class, ModeSettingsMessage.class, 1, Side.CLIENT); MinecraftForge.EVENT_BUS.register(this);
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);
} }
@EventHandler @SubscribeEvent
// Do your mod setup. Build whatever data structures you care about. public void setup(final FMLCommonSetupEvent event)
// Register network handlers
public void init(FMLInitializationEvent event)
{ {
ConfigManager.sync(MODID, Config.Type.INSTANCE); CapabilityManager.INSTANCE.register(ModifierCapabilityManager.IModifierCapability.class, new ModifierCapabilityManager.Storage(), ModifierCapabilityManager.ModifierCapability::new);
NetworkRegistry.INSTANCE.registerGuiHandler(EffortlessBuilding.instance, new RandomizerBagGuiHandler()); 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 @SubscribeEvent
// postInit "Handle interaction with other mods, complete your setup based on this." public void clientSetup(final FMLClientSetupEvent event) {
public void postInit(FMLPostInitializationEvent event)
{ proxy.clientSetup(event);
proxy.postInit(event);
CompatHelper.postInit();
} }
@EventHandler @SubscribeEvent
public void serverStarting(FMLServerStartingEvent event) public void enqueueIMC(final InterModEnqueueEvent event) {
{
event.registerServerCommand(new CommandReach()); // some example code to dispatch IMC to another mod
proxy.serverStarting(event); // 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){ public static void log(String msg){
logger.info(msg); logger.info(msg);
} }

View File

@@ -1,29 +1,24 @@
package nl.requios.effortlessbuilding; package nl.requios.effortlessbuilding;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.Item; import net.minecraft.stats.Stat;
import net.minecraft.item.ItemBlock; import net.minecraft.stats.StatList;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.config.Config; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.world.BlockEvent; 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.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.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.BlockSet;
import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; 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.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.network.AddUndoMessage; import nl.requios.effortlessbuilding.network.AddUndoMessage;
import nl.requios.effortlessbuilding.network.BlockBrokenMessage;
import nl.requios.effortlessbuilding.network.ClearUndoMessage; import nl.requios.effortlessbuilding.network.ClearUndoMessage;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.network.RequestLookAtMessage; import nl.requios.effortlessbuilding.network.RequestLookAtMessage;
import scala.actors.threadpool.Arrays;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.minecraftforge.fml.common.gameevent.PlayerEvent.*; import static net.minecraftforge.fml.common.gameevent.PlayerEvent.*;
@@ -46,39 +39,23 @@ import static net.minecraftforge.fml.common.gameevent.PlayerEvent.*;
public class EventHandler public class EventHandler
{ {
@SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event)
{
event.getRegistry().registerAll(EffortlessBuilding.BLOCKS);
}
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event)
{
event.getRegistry().registerAll(EffortlessBuilding.ITEMS);
for (Block block : EffortlessBuilding.BLOCKS)
{
event.getRegistry().register(new ItemBlock(block).setRegistryName(block.getRegistryName()));
}
}
@SubscribeEvent @SubscribeEvent
public static void attachCapabilities(AttachCapabilitiesEvent<Entity> event) { public static void attachCapabilities(AttachCapabilitiesEvent<Entity> event) {
if (event.getObject() instanceof EntityPlayer) { if (event.getObject() instanceof EntityPlayer) {
event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "BuildModifier"), new ModifierCapabilityManager.Provider()); event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_modifier"), new ModifierCapabilityManager.Provider());
event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "BuildMode"), new ModeCapabilityManager.Provider()); event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_mode"), new ModeCapabilityManager.Provider());
} }
} }
@SubscribeEvent //TODO 1.13 config
public static void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event) // @SubscribeEvent
{ // public static void onConfigChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event)
if (event.getModID().equals(EffortlessBuilding.MODID)) // {
{ // if (event.getModID().equals(EffortlessBuilding.MODID))
ConfigManager.sync(EffortlessBuilding.MODID, Config.Type.INSTANCE); // {
} // ConfigManager.sync(EffortlessBuilding.MODID, Config.Type.INSTANCE);
} // }
// }
// @SubscribeEvent // @SubscribeEvent
// public static void onServerTick(TickEvent.ServerTickEvent event) { // public static void onServerTick(TickEvent.ServerTickEvent event) {
@@ -87,11 +64,13 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
//Only called serverside (except with lilypads...) //Only called serverside (except with lilypads...)
public static void onBlockPlaced(BlockEvent.PlaceEvent event) { public static void onBlockPlaced(BlockEvent.EntityPlaceEvent event) {
if (event.getWorld().isRemote) return; if (event.getWorld().isRemote()) return;
if (!(event.getEntity() instanceof EntityPlayer)) return;
//Cancel event if necessary //Cancel event if necessary
EntityPlayer player = event.getPlayer(); EntityPlayerMP player = ((EntityPlayerMP) event.getEntity());
BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode();
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
@@ -100,21 +79,26 @@ public class EventHandler
} else if (modifierSettings.doQuickReplace()) { } else if (modifierSettings.doQuickReplace()) {
//Cancel event and send message if QuickReplace //Cancel event and send message if QuickReplace
event.setCanceled(true); event.setCanceled(true);
EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(true), (EntityPlayerMP) player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new RequestLookAtMessage(true));
EffortlessBuilding.packetHandler.sendTo(new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState()), (EntityPlayerMP) player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState()));
} else { } else {
//NORMAL mode, let vanilla handle block placing //NORMAL mode, let vanilla handle block placing
//But modifiers should still work //But modifiers should still work
//Send message to client, which sends message back with raytrace info //Send message to client, which sends message back with raytrace info
EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(false), (EntityPlayerMP) player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new RequestLookAtMessage(false));
EffortlessBuilding.packetHandler.sendTo(new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState()), (EntityPlayerMP) player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new AddUndoMessage(event.getPos(), event.getBlockSnapshot().getReplacedBlock(), event.getState()));
} }
// Stat<ResourceLocation> blocksPlacedStat = StatList.CUSTOM.get(new ResourceLocation(EffortlessBuilding.MODID, "blocks_placed"));
// player.getStats().increment(player, blocksPlacedStat, 1);
//
// System.out.println(player.getStats().getValue(blocksPlacedStat));
} }
@SubscribeEvent @SubscribeEvent
public static void onBlockBroken(BlockEvent.BreakEvent event) { public static void onBlockBroken(BlockEvent.BreakEvent event) {
if (event.getWorld().isRemote) return; if (event.getWorld().isRemote()) return;
//Cancel event if necessary //Cancel event if necessary
//If cant break far then dont cancel event ever //If cant break far then dont cancel event ever
@@ -123,19 +107,19 @@ public class EventHandler
event.setCanceled(true); event.setCanceled(true);
} else { } else {
//NORMAL mode, let vanilla handle block breaking //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 //Dont break the original block yourself, otherwise Tinkers Hammer and Veinminer won't work
BuildModes.onBlockBroken(event.getPlayer(), event.getPos(), false); BuildModes.onBlockBroken(event.getPlayer(), event.getPos(), false);
//Add to undo stack in client //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 @SubscribeEvent
public static void breakSpeed(PlayerEvent.BreakSpeed event) { public static void breakSpeed(PlayerEvent.BreakSpeed event) {
//Disable if config says so //Disable if config says so
if (!BuildConfig.survivalBalancers.increasedMiningTime) return; if (!BuildConfig.survivalBalancers.increasedMiningTime.get()) return;
EntityPlayer player = event.getEntityPlayer(); EntityPlayer player = event.getEntityPlayer();
World world = player.world; World world = player.world;
@@ -158,7 +142,7 @@ public class EventHandler
} }
//Grabbing percentage from config //Grabbing percentage from config
float percentage = (float) BuildConfig.survivalBalancers.miningTimePercentage / 100; float percentage = (float) BuildConfig.survivalBalancers.miningTimePercentage.get() / 100;
totalBlockHardness *= percentage; totalBlockHardness *= percentage;
totalBlockHardness += originalBlockHardness; totalBlockHardness += originalBlockHardness;
@@ -171,36 +155,59 @@ public class EventHandler
@SubscribeEvent @SubscribeEvent
public static void onPlayerLoggedIn(PlayerLoggedInEvent event) { public static void onPlayerLoggedIn(PlayerLoggedInEvent event) {
EntityPlayer player = event.player; EntityPlayer player = event.getPlayer();
ModifierSettingsManager.handleNewPlayer(player); ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player);
} }
@SubscribeEvent @SubscribeEvent
public static void onPlayerLoggedOut(PlayerLoggedOutEvent event) { public static void onPlayerLoggedOut(PlayerLoggedOutEvent event) {
EntityPlayer player = event.player; EntityPlayer player = event.getPlayer();
if (player.getEntityWorld().isRemote) return; if (player.getEntityWorld().isRemote) return;
UndoRedo.clear(player); UndoRedo.clear(player);
EffortlessBuilding.packetHandler.sendTo(new ClearUndoMessage(), (EntityPlayerMP) player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) player), new ClearUndoMessage());
} }
@SubscribeEvent @SubscribeEvent
public static void onPlayerRespawn(PlayerRespawnEvent event) { public static void onPlayerRespawn(PlayerRespawnEvent event) {
EntityPlayer player = event.player; EntityPlayer player = event.getPlayer();
ModifierSettingsManager.handleNewPlayer(player); ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player);
} }
@SubscribeEvent @SubscribeEvent
public static void onPlayerChangedDimension(PlayerChangedDimensionEvent event) { public static void onPlayerChangedDimension(PlayerChangedDimensionEvent event) {
EntityPlayer player = event.player; EntityPlayer player = event.getPlayer();
if (player.getEntityWorld().isRemote) return; 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); ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player); ModeSettingsManager.handleNewPlayer(player);
UndoRedo.clear(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));
} }
} }

View File

@@ -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<Block> event) {
event.getRegistry().registerAll(EffortlessBuilding.BLOCKS);
}
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event)
{
event.getRegistry().registerAll(EffortlessBuilding.ITEMS);
for (Block block : EffortlessBuilding.BLOCKS)
{
event.getRegistry().register(new ItemBlock(block, new Item.Properties()).setRegistryName(block.getRegistryName()));
}
}
}

View File

@@ -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<UUID, Integer> rightClickClientTable = new Hashtable<>();
protected Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
protected Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
protected Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
protected Dictionary<UUID, Vec3d> 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());
}
}

View File

@@ -2,13 +2,14 @@ package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; 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 net.minecraft.util.math.Vec3d;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.ModeOptions.ActionEnum; import nl.requios.effortlessbuilding.buildmode.buildmodes.*;
import nl.requios.effortlessbuilding.buildmodifier.*; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.network.BlockBrokenMessage; import nl.requios.effortlessbuilding.network.BlockBrokenMessage;
@@ -19,6 +20,8 @@ import java.util.Dictionary;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*;
public class BuildModes { public class BuildModes {
//Static variables are shared between client and server in singleplayer //Static variables are shared between client and server in singleplayer
@@ -27,21 +30,24 @@ public class BuildModes {
public static Dictionary<EntityPlayer, Boolean> currentlyBreakingServer = new Hashtable<>(); public static Dictionary<EntityPlayer, Boolean> currentlyBreakingServer = new Hashtable<>();
public enum BuildModeEnum { public enum BuildModeEnum {
NORMAL("effortlessbuilding.mode.normal", new Normal(), new ActionEnum[]{}), NORMAL("effortlessbuilding.mode.normal", new Normal()),
NORMAL_PLUS("effortlessbuilding.mode.normal_plus", new NormalPlus(), new ActionEnum[]{ActionEnum.NORMAL_SPEED, ActionEnum.FAST_SPEED}), NORMAL_PLUS("effortlessbuilding.mode.normal_plus", new NormalPlus(), OptionEnum.BUILD_SPEED),
LINE("effortlessbuilding.mode.line", new Line(), new ActionEnum[]{/*ActionEnum.THICKNESS_1, ActionEnum.THICKNESS_3, ActionEnum.THICKNESS_5*/}), LINE("effortlessbuilding.mode.line", new Line() /*, OptionEnum.THICKNESS*/),
WALL("effortlessbuilding.mode.wall", new Wall(), new ActionEnum[]{ActionEnum.FULL, ActionEnum.HOLLOW}), WALL("effortlessbuilding.mode.wall", new Wall(), OptionEnum.FILL),
FLOOR("effortlessbuilding.mode.floor", new Floor(), new ActionEnum[]{ActionEnum.FULL, ActionEnum.HOLLOW}), FLOOR("effortlessbuilding.mode.floor", new Floor(), OptionEnum.FILL),
DIAGONAL_LINE("effortlessbuilding.mode.diagonal_line", new DiagonalLine(), new ActionEnum[]{/*ActionEnum.THICKNESS_1, ActionEnum.THICKNESS_3, ActionEnum.THICKNESS_5*/}), DIAGONAL_LINE("effortlessbuilding.mode.diagonal_line", new DiagonalLine() /*, OptionEnum.THICKNESS*/),
DIAGONAL_WALL("effortlessbuilding.mode.diagonal_wall", new DiagonalWall(), new ActionEnum[]{/*ActionEnum.FULL, ActionEnum.HOLLOW*/}), DIAGONAL_WALL("effortlessbuilding.mode.diagonal_wall", new DiagonalWall() /*, OptionEnum.FILL*/),
SLOPE_FLOOR("effortlessbuilding.mode.slope_floor", new SlopeFloor(), new ActionEnum[]{ActionEnum.SHORT_EDGE, ActionEnum.LONG_EDGE}), SLOPE_FLOOR("effortlessbuilding.mode.slope_floor", new SlopeFloor(), OptionEnum.RAISED_EDGE),
CUBE("effortlessbuilding.mode.cube", new Cube(), new ActionEnum[]{ActionEnum.CUBE_FULL, ActionEnum.CUBE_HOLLOW, ActionEnum.CUBE_SKELETON}); 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 String name;
public IBuildMode instance; 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.name = name;
this.instance = instance; this.instance = instance;
this.options = options; this.options = options;
@@ -71,7 +77,8 @@ public class BuildModes {
startPos = message.getBlockPos(); startPos = message.getBlockPos();
//Offset in direction of sidehit if not quickreplace and not replaceable //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()); boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, message.getSideHit());
if (!modifierSettings.doQuickReplace() && !replaceable && !becomesDoubleSlab) { if (!modifierSettings.doQuickReplace() && !replaceable && !becomesDoubleSlab) {
startPos = startPos.offset(message.getSideHit()); 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 //Find coordinates on a line bound by a plane
public static Vec3d findXBound(double x, Vec3d start, Vec3d look) { public static Vec3d findXBound(double x, Vec3d start, Vec3d look) {
//then y and z are //then y and z are
@@ -220,4 +229,17 @@ public class BuildModes {
return new Vec3d(x, y, z); 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;
}
} }

View File

@@ -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<UUID, Integer> rightClickClientTable = new Hashtable<>();
private Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> secondPosTable = new Hashtable<>();
private Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
private Dictionary<UUID, Vec3d> 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<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> 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<BlockPos> 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<BlockPos> 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());
}
}

View File

@@ -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<UUID, Integer> rightClickClientTable = new Hashtable<>();
private Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> secondPosTable = new Hashtable<>();
private Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
private Dictionary<UUID, Vec3d> 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<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> getDiagonalWallBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, BlockPos thirdPos) {
List<BlockPos> list = new ArrayList<>();
int axisLimit = ReachHelper.getMaxBlocksPerAxis(player);
//Get diagonal line blocks
List<BlockPos> 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());
}
}

View File

@@ -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<UUID, Integer> rightClickClientTable = new Hashtable<>();
private Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
private Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
private Dictionary<UUID, Vec3d> 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<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<Criteria> 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<BlockPos> getFloorBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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());
}
}

View File

@@ -30,7 +30,10 @@ public class ModeOptions {
THICKNESS_1("effortlessbuilding.action.thickness_1"), THICKNESS_1("effortlessbuilding.action.thickness_1"),
THICKNESS_3("effortlessbuilding.action.thickness_3"), 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; 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 buildSpeed = ActionEnum.NORMAL_SPEED;
private static ActionEnum fill = ActionEnum.FULL; private static ActionEnum fill = ActionEnum.FULL;
private static ActionEnum cubeFill = ActionEnum.CUBE_FULL; private static ActionEnum cubeFill = ActionEnum.CUBE_FULL;
private static ActionEnum raisedEdge = ActionEnum.SHORT_EDGE; private static ActionEnum raisedEdge = ActionEnum.SHORT_EDGE;
private static ActionEnum lineThickness = ActionEnum.THICKNESS_1; 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() { public static ActionEnum getBuildSpeed() {
return buildSpeed; return buildSpeed;
@@ -65,6 +105,10 @@ public class ModeOptions {
return lineThickness; return lineThickness;
} }
public static ActionEnum getCircleStart() {
return circleStart;
}
//Called on both client and server //Called on both client and server
public static void performAction(EntityPlayer player, ActionEnum action) { public static void performAction(EntityPlayer player, ActionEnum action) {
if (action == null) return; if (action == null) return;
@@ -123,6 +167,12 @@ public class ModeOptions {
case THICKNESS_5: case THICKNESS_5:
lineThickness = ActionEnum.THICKNESS_5; lineThickness = ActionEnum.THICKNESS_5;
break; 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) { if (player.world.isRemote && action != ActionEnum.REPLACE && action != ActionEnum.OPEN_MODIFIER_SETTINGS) {

View File

@@ -2,44 +2,57 @@ package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.network.PacketDistributor;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.network.ModeSettingsMessage; import nl.requios.effortlessbuilding.network.ModeSettingsMessage;
import nl.requios.effortlessbuilding.network.PacketHandler;
import javax.annotation.Nonnull;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class ModeSettingsManager { public class ModeSettingsManager {
//Retrieves the buildsettings of a player through the modifierCapability capability //Retrieves the buildsettings of a player through the modifierCapability capability
//Never returns null //Never returns null
@Nonnull
public static ModeSettings getModeSettings(EntityPlayer player) { public static ModeSettings getModeSettings(EntityPlayer player) {
if (player.hasCapability(ModeCapabilityManager.modeCapability, null)) { LazyOptional<ModeCapabilityManager.IModeCapability> modeCapability =
ModeCapabilityManager.IModeCapability capability = player.getCapability( player.getCapability(ModeCapabilityManager.modeCapability, null);
ModeCapabilityManager.modeCapability, null);
if (modeCapability.isPresent()) {
ModeCapabilityManager.IModeCapability capability = modeCapability.orElse(null);
if (capability.getModeData() == null) { if (capability.getModeData() == null) {
capability.setModeData(new ModeSettings()); capability.setModeData(new ModeSettings());
} }
return capability.getModeData(); 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) { public static void setModeSettings(EntityPlayer player, ModeSettings modeSettings) {
if (player == null) { if (player == null) {
EffortlessBuilding.log("Cannot set buildsettings, player is null"); EffortlessBuilding.log("Cannot set buildmode settings, player is null");
return; return;
} }
if (player.hasCapability(ModeCapabilityManager.modeCapability, null)) { LazyOptional<ModeCapabilityManager.IModeCapability> modeCapability =
ModeCapabilityManager.IModeCapability capability = player.getCapability( player.getCapability(ModeCapabilityManager.modeCapability, null);
ModeCapabilityManager.modeCapability, null);
modeCapability.ifPresent((capability) -> {
capability.setModeData(modeSettings); capability.setModeData(modeSettings);
//Initialize new mode
BuildModes.initializeMode(player); 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){ public static void handleNewPlayer(EntityPlayer player){
if (getModeSettings(player) == null) { //Makes sure player has mode settings (if it doesnt it will create it)
setModeSettings(player, new ModeSettings()); getModeSettings(player);
}
//Only on server //Only on server
if (!player.world.isRemote) { if (!player.world.isRemote) {
//Send to client //Send to client
ModeSettingsMessage msg = new ModeSettingsMessage(getModeSettings(player)); ModeSettingsMessage msg = new ModeSettingsMessage(getModeSettings(player));
EffortlessBuilding.packetHandler.sendTo(msg, (EntityPlayerMP) player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) player), msg);
} }
} }
} }

View File

@@ -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<UUID, Integer> rightClickClientTable = new Hashtable<>();
private Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> secondPosTable = new Hashtable<>();
private Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
private Dictionary<UUID, Vec3d> 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<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> getSlopeFloorBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, BlockPos thirdPos) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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());
}
}

View File

@@ -3,21 +3,15 @@ package nl.requios.effortlessbuilding.buildmode;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; 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 nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.*; import java.util.*;
public class DiagonalLine implements IBuildMode { public abstract class ThreeClicksBuildMode extends BaseBuildMode {
//In singleplayer client and server variables are shared protected Dictionary<UUID, BlockPos> secondPosTable = new Hashtable<>();
//Split everything that needs separate values and may not be called twice in one click
private Dictionary<UUID, Integer> rightClickClientTable = new Hashtable<>();
private Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> secondPosTable = new Hashtable<>();
private Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
private Dictionary<UUID, Vec3d> hitVecTable = new Hashtable<>();
static class HeightCriteria { static class HeightCriteria {
Vec3d planeBound; Vec3d planeBound;
@@ -42,27 +36,14 @@ public class DiagonalLine implements IBuildMode {
//also check if raytrace from player to block does not intersect blocks //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) { public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) {
boolean intersects = false; return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq);
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;
} }
} }
@Override @Override
public void initialize(EntityPlayer player) { public void initialize(EntityPlayer player) {
rightClickClientTable.put(player.getUniqueID(), 0); super.initialize(player);
rightClickServerTable.put(player.getUniqueID(), 0); secondPosTable.put(player.getUniqueID(), BlockPos.ORIGIN);
firstPosTable.put(player.getUniqueID(), BlockPos.ORIGIN);
sideHitTable.put(player.getUniqueID(), EnumFacing.UP);
hitVecTable.put(player.getUniqueID(), Vec3d.ZERO);
} }
@Override @Override
@@ -89,7 +70,7 @@ public class DiagonalLine implements IBuildMode {
} else if (rightClickNr == 2) { } else if (rightClickNr == 2) {
//Second click, find other floor point //Second click, find other floor point
BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos firstPos = firstPosTable.get(player.getUniqueID());
BlockPos secondPos = Floor.findFloor(player, firstPos, true); BlockPos secondPos = findSecondPos(player, firstPos, true);
if (secondPos == null) { if (secondPos == null) {
rightClickTable.put(player.getUniqueID(), 1); rightClickTable.put(player.getUniqueID(), 1);
@@ -99,7 +80,7 @@ public class DiagonalLine implements IBuildMode {
secondPosTable.put(player.getUniqueID(), secondPos); secondPosTable.put(player.getUniqueID(), secondPos);
} else { } else {
//Third click, place diagonal line with height //Third click, place diagonal wall with height
list = findCoordinates(player, blockPos, skipRaytrace); list = findCoordinates(player, blockPos, skipRaytrace);
rightClickTable.put(player.getUniqueID(), 0); rightClickTable.put(player.getUniqueID(), 0);
} }
@@ -119,26 +100,75 @@ public class DiagonalLine implements IBuildMode {
} else if (rightClickNr == 1) { } else if (rightClickNr == 1) {
BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos firstPos = firstPosTable.get(player.getUniqueID());
BlockPos secondPos = Floor.findFloor(player, firstPos, true); BlockPos secondPos = findSecondPos(player, firstPos, true);
if (secondPos == null) return list; 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 //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 { } else {
BlockPos firstPos = firstPosTable.get(player.getUniqueID()); BlockPos firstPos = firstPosTable.get(player.getUniqueID());
BlockPos secondPos = secondPosTable.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; 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 //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; 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<BlockPos> 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<BlockPos> 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 //Finds height after floor has been chosen in buildmodes with 3 clicks
public static BlockPos findHeight(EntityPlayer player, BlockPos secondPos, boolean skipRaytrace) { public static BlockPos findHeight(EntityPlayer player, BlockPos secondPos, boolean skipRaytrace) {
Vec3d look = player.getLookVec(); Vec3d look = player.getLookVec();
@@ -182,47 +212,4 @@ public class DiagonalLine implements IBuildMode {
} }
return new BlockPos(selected.lineBound); return new BlockPos(selected.lineBound);
} }
//Add diagonal line from first to second
public static List<BlockPos> getDiagonalLineBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos, float sampleMultiplier) {
List<BlockPos> 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());
}
} }

View File

@@ -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<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> getAllBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2);
}

View File

@@ -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<UUID, Integer> rightClickClientTable = new Hashtable<>();
private Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
private Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
private Dictionary<UUID, Vec3d> 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<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<Criteria> 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<BlockPos> getWallBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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<BlockPos> 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<BlockPos> 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());
}
}

View File

@@ -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<BlockPos> 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<BlockPos> getCircleBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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);
}
}

View File

@@ -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<BlockPos> 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<BlockPos> 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<BlockPos> getFloorBlocksUsingCubeFill(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> 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<BlockPos> getCubeBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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<BlockPos> 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);
}
}

View File

@@ -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<BlockPos> 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<BlockPos> 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<BlockPos> getCylinderBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>();
//Get circle blocks (using CIRCLE_START and FILL options built-in)
List<BlockPos> 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;
}
}

View File

@@ -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<BlockPos> 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<BlockPos> 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<BlockPos> getDiagonalLineBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, float sampleMultiplier) {
List<BlockPos> 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;
}
}

View File

@@ -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<BlockPos> 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<BlockPos> 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<BlockPos> getDiagonalWallBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> list = new ArrayList<>();
//Get diagonal line blocks
List<BlockPos> 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;
}
}

View File

@@ -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<Criteria> 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<BlockPos> 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<BlockPos> getFloorBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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);
}
}

View File

@@ -1,22 +1,16 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; 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 nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.*; import java.util.ArrayList;
import java.util.List;
public class Line implements IBuildMode { public class Line extends TwoClicksBuildMode {
//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<UUID, Integer> rightClickClientTable = new Hashtable<>();
private Dictionary<UUID, Integer> rightClickServerTable = new Hashtable<>();
private Dictionary<UUID, BlockPos> firstPosTable = new Hashtable<>();
private Dictionary<UUID, EnumFacing> sideHitTable = new Hashtable<>();
private Dictionary<UUID, Vec3d> hitVecTable = new Hashtable<>();
static class Criteria { static class Criteria {
Vec3d planeBound; Vec3d planeBound;
@@ -55,78 +49,14 @@ public class Line implements IBuildMode {
//also check if raytrace from player to block does not intersect blocks //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) { public boolean isValid(Vec3d start, Vec3d look, int reach, EntityPlayer player, boolean skipRaytrace) {
boolean intersects = false; return BuildModes.isCriteriaValid(start, look, reach, player, skipRaytrace, lineBound, planeBound, distToPlayerSq);
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;
}
} }
@Override @Override
public void initialize(EntityPlayer player) { protected BlockPos findSecondPos(EntityPlayer player, BlockPos firstPos, boolean skipRaytrace) {
rightClickClientTable.put(player.getUniqueID(), 0); return findLine(player, firstPos, skipRaytrace);
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<BlockPos> onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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<BlockPos> findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) {
List<BlockPos> list = new ArrayList<>();
Dictionary<UUID, Integer> 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;
} }
public static BlockPos findLine(EntityPlayer player, BlockPos firstPos, boolean 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); return new BlockPos(selected.lineBound);
} }
public static List<BlockPos> getLineBlocks(EntityPlayer player, BlockPos firstPos, BlockPos secondPos) { @Override
protected List<BlockPos> 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<BlockPos> getLineBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> list = new ArrayList<>(); List<BlockPos> 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) { if (x1 != x2) {
addXLineBlocks(list, x1, x2, y1, z1); addXLineBlocks(list, x1, x2, y1, z1);
} else if (y1 != y2) { } else if (y1 != y2) {
@@ -225,15 +144,4 @@ public class Line implements IBuildMode {
list.add(new BlockPos(x, y, z)); 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());
}
} }

View File

@@ -1,9 +1,10 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import nl.requios.effortlessbuilding.buildmode.IBuildMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -1,9 +1,10 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode.buildmodes;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import nl.requios.effortlessbuilding.buildmode.IBuildMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@@ -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<BlockPos> 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<BlockPos> 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<BlockPos> getSlopeFloorBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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;
}
}

View File

@@ -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<BlockPos> 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<BlockPos> 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<BlockPos> getSphereBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3) {
List<BlockPos> 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;
}
}

View File

@@ -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<Criteria> 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<BlockPos> 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<BlockPos> getWallBlocks(EntityPlayer player, int x1, int y1, int z1, int x2, int y2, int z2) {
List<BlockPos> 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<BlockPos> 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<BlockPos> 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<BlockPos> 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<BlockPos> 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);
}
}

View File

@@ -4,6 +4,7 @@ import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; 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.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.helper.InventoryHelper; import nl.requios.effortlessbuilding.helper.InventoryHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
@@ -87,7 +89,6 @@ public class BuildModifiers {
BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1); BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1);
UndoRedo.addUndo(player, new BlockSet(coordinates, previousBlockStates, newBlockStates, hitVec, firstPos, secondPos)); UndoRedo.addUndo(player, new BlockSet(coordinates, previousBlockStates, newBlockStates, hitVec, firstPos, secondPos));
} }
} }
public static void onBlockBroken(EntityPlayer player, List<BlockPos> startCoordinates, boolean breakStartPos) { public static void onBlockBroken(EntityPlayer player, List<BlockPos> startCoordinates, boolean breakStartPos) {
@@ -108,7 +109,7 @@ public class BuildModifiers {
BlockPreviewRenderer.onBlocksBroken(); BlockPreviewRenderer.onBlocksBroken();
//list of air blockstates //list of air blockstates
for (BlockPos coordinate : coordinates) { for (int i = 0; i < coordinates.size(); i++) {
newBlockStates.add(Blocks.AIR.getDefaultState()); 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) { 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, return Block.getBlockFromItem(itemStack.getItem()).getStateForPlacement(new BlockItemUseContext(player.world, player, itemStack, blockPos, facing,
((float) hitVec.x), ((float) hitVec.y), ((float) hitVec.z), itemStack.getMetadata(), player, hand); ((float) hitVec.x), ((float) hitVec.y), ((float) hitVec.z)));
} }
//Returns true if equal (or both null) //Returns true if equal (or both null)

View File

@@ -7,6 +7,8 @@ import net.minecraft.block.BlockStairs;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; 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.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -118,7 +120,7 @@ public class Mirror {
} }
//Find blockstate //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 //Store blockstate and itemstack
blockStates.add(newBlockState); blockStates.add(newBlockState);
@@ -163,7 +165,7 @@ public class Mirror {
} }
//Find blockstate //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 //Store blockstate and itemstack
blockStates.add(newBlockState); blockStates.add(newBlockState);
@@ -185,38 +187,39 @@ public class Mirror {
private static IBlockState getVerticalMirror(IBlockState blockState) { private static IBlockState getVerticalMirror(IBlockState blockState) {
//Stairs //Stairs
if (blockState.getBlock() instanceof BlockStairs) { if (blockState.getBlock() instanceof BlockStairs) {
if (blockState.getValue(BlockStairs.HALF) == BlockStairs.EnumHalf.BOTTOM) { if (blockState.get(BlockStairs.HALF) == Half.BOTTOM) {
return blockState.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.TOP); return blockState.with(BlockStairs.HALF, Half.TOP);
} else { } else {
return blockState.withProperty(BlockStairs.HALF, BlockStairs.EnumHalf.BOTTOM); return blockState.with(BlockStairs.HALF, Half.BOTTOM);
} }
} }
//Slabs //Slabs
if (blockState.getBlock() instanceof BlockSlab) { if (blockState.getBlock() instanceof BlockSlab) {
if (((BlockSlab) blockState.getBlock()).isDouble()) return blockState; if (blockState.get(BlockSlab.TYPE) == SlabType.DOUBLE) {
if (blockState.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) { return blockState;
return blockState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP); } else if (blockState.get(BlockSlab.TYPE) == SlabType.BOTTOM) {
return blockState.with(BlockSlab.TYPE, SlabType.TOP);
} else { } else {
return blockState.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.BOTTOM); return blockState.with(BlockSlab.TYPE, SlabType.BOTTOM);
} }
} }
//Buttons, endrod, observer, piston //Buttons, endrod, observer, piston
if (blockState.getBlock() instanceof BlockDirectional) { if (blockState.getBlock() instanceof BlockDirectional) {
if (blockState.getValue(BlockDirectional.FACING) == EnumFacing.DOWN) { if (blockState.get(BlockDirectional.FACING) == EnumFacing.DOWN) {
return blockState.withProperty(BlockDirectional.FACING, EnumFacing.UP); return blockState.with(BlockDirectional.FACING, EnumFacing.UP);
} else if (blockState.getValue(BlockDirectional.FACING) == EnumFacing.UP) { } else if (blockState.get(BlockDirectional.FACING) == EnumFacing.UP) {
return blockState.withProperty(BlockDirectional.FACING, EnumFacing.DOWN); return blockState.with(BlockDirectional.FACING, EnumFacing.DOWN);
} }
} }
//Dispenser, dropper //Dispenser, dropper
if (blockState.getBlock() instanceof BlockDispenser) { if (blockState.getBlock() instanceof BlockDispenser) {
if (blockState.getValue(BlockDispenser.FACING) == EnumFacing.DOWN) { if (blockState.get(BlockDispenser.FACING) == EnumFacing.DOWN) {
return blockState.withProperty(BlockDispenser.FACING, EnumFacing.UP); return blockState.with(BlockDispenser.FACING, EnumFacing.UP);
} else if (blockState.getValue(BlockDispenser.FACING) == EnumFacing.UP) { } else if (blockState.get(BlockDispenser.FACING) == EnumFacing.UP) {
return blockState.withProperty(BlockDispenser.FACING, EnumFacing.DOWN); return blockState.with(BlockDispenser.FACING, EnumFacing.DOWN);
} }
} }

View File

@@ -2,28 +2,42 @@ package nl.requios.effortlessbuilding.buildmodifier;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.network.PacketDistributor;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; 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 @Mod.EventBusSubscriber
public class ModifierSettingsManager { public class ModifierSettingsManager {
//Retrieves the buildsettings of a player through the modifierCapability capability //Retrieves the buildsettings of a player through the modifierCapability capability
//Never returns null //Never returns null
@Nonnull
public static ModifierSettings getModifierSettings(EntityPlayer player){ public static ModifierSettings getModifierSettings(EntityPlayer player){
if (player.hasCapability(ModifierCapabilityManager.modifierCapability, null)) { LazyOptional<ModifierCapabilityManager.IModifierCapability> modifierCapability =
ModifierCapabilityManager.IModifierCapability capability = player.getCapability( player.getCapability(ModifierCapabilityManager.modifierCapability, null);
ModifierCapabilityManager.modifierCapability, null);
if (modifierCapability.isPresent()) {
ModifierCapabilityManager.IModifierCapability capability = modifierCapability.orElse(null);
if (capability.getModifierData() == null) { if (capability.getModifierData() == null) {
capability.setModifierData(new ModifierSettings()); capability.setModifierData(new ModifierSettings());
} }
return capability.getModifierData(); 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) { public static void setModifierSettings(EntityPlayer player, ModifierSettings modifierSettings) {
@@ -31,11 +45,15 @@ public class ModifierSettingsManager {
EffortlessBuilding.log("Cannot set buildsettings, player is null"); EffortlessBuilding.log("Cannot set buildsettings, player is null");
return; return;
} }
if (player.hasCapability(ModifierCapabilityManager.modifierCapability, null)) {
ModifierCapabilityManager.IModifierCapability capability = player.getCapability( LazyOptional<ModifierCapabilityManager.IModifierCapability> modifierCapability =
ModifierCapabilityManager.modifierCapability, null); player.getCapability(ModifierCapabilityManager.modifierCapability, null);
modifierCapability.ifPresent((capability) -> {
capability.setModifierData(modifierSettings); capability.setModifierData(modifierSettings);
} else { });
if (!modifierCapability.isPresent()) {
EffortlessBuilding.log(player, "Saving buildsettings failed."); EffortlessBuilding.log(player, "Saving buildsettings failed.");
} }
} }
@@ -163,33 +181,28 @@ public class ModifierSettingsManager {
//Set mirror radius to max //Set mirror radius to max
int reach = 10; int reach = 10;
switch (reachUpgrade) { switch (reachUpgrade) {
case 0: reach = BuildConfig.reach.maxReachLevel0; break; case 0: reach = BuildConfig.reach.maxReachLevel0.get(); break;
case 1: reach = BuildConfig.reach.maxReachLevel1; break; case 1: reach = BuildConfig.reach.maxReachLevel1.get(); break;
case 2: reach = BuildConfig.reach.maxReachLevel2; break; case 2: reach = BuildConfig.reach.maxReachLevel2.get(); break;
case 3: reach = BuildConfig.reach.maxReachLevel3; break; case 3: reach = BuildConfig.reach.maxReachLevel3.get(); break;
} }
EffortlessBuilding.log("before "+this.mirrorSettings.radius);
if (this.mirrorSettings != null) if (this.mirrorSettings != null)
this.mirrorSettings.radius = reach / 2; this.mirrorSettings.radius = reach / 2;
if (this.radialMirrorSettings != null) if (this.radialMirrorSettings != null)
this.radialMirrorSettings.radius = reach / 2; this.radialMirrorSettings.radius = reach / 2;
EffortlessBuilding.log("after "+this.mirrorSettings.radius);
} }
} }
public static void handleNewPlayer(EntityPlayer player){ public static void handleNewPlayer(EntityPlayer player){
if (getModifierSettings(player) == null) { //Makes sure player has modifier settings (if it doesnt it will create it)
setModifierSettings(player, new ModifierSettings()); getModifierSettings(player);
}
//Only on server //Only on server
if (!player.world.isRemote) { if (!player.world.isRemote) {
//Send to client //Send to client
ModifierSettingsMessage msg = new ModifierSettingsMessage(getModifierSettings(player)); ModifierSettingsMessage msg = new ModifierSettingsMessage(getModifierSettings(player));
EffortlessBuilding.packetHandler.sendTo(msg, (EntityPlayerMP) player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (EntityPlayerMP) player), msg);
} }
} }
} }

View File

@@ -143,11 +143,11 @@ public class RadialMirror {
IBlockState newBlockState = blockState; IBlockState newBlockState = blockState;
if (startAngleToCenter < -0.751 * Math.PI || startAngleToCenter > 0.749 * Math.PI) { 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) { } 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) { } else if (startAngleToCenter > 0.249 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.CLOCKWISE_90); newBlockState = blockState.rotate(Rotation.CLOCKWISE_90);
} }
return newBlockState; return newBlockState;
@@ -158,24 +158,24 @@ public class RadialMirror {
double angleToCenter = MathHelper.atan2(relVec.x, relVec.z); //between -PI and PI double angleToCenter = MathHelper.atan2(relVec.x, relVec.z); //between -PI and PI
if (angleToCenter < -0.751 * Math.PI || angleToCenter > 0.749 * Math.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) { if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK); newBlockState = newBlockState.mirror(Mirror.FRONT_BACK);
} }
} else if (angleToCenter < -0.251 * Math.PI) { } else if (angleToCenter < -0.251 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.CLOCKWISE_90); newBlockState = blockState.rotate(Rotation.CLOCKWISE_90);
if (alternate) { if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT); newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT);
} }
} else if (angleToCenter > 0.249 * Math.PI) { } else if (angleToCenter > 0.249 * Math.PI) {
newBlockState = blockState.withRotation(Rotation.COUNTERCLOCKWISE_90); newBlockState = blockState.rotate(Rotation.COUNTERCLOCKWISE_90);
if (alternate) { if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.LEFT_RIGHT); newBlockState = newBlockState.mirror(Mirror.LEFT_RIGHT);
} }
} else { } else {
newBlockState = blockState; newBlockState = blockState;
if (alternate) { if (alternate) {
newBlockState = newBlockState.withMirror(Mirror.FRONT_BACK); newBlockState = newBlockState.mirror(Mirror.FRONT_BACK);
} }
} }

View File

@@ -50,10 +50,9 @@ public class UndoRedo {
//If no stack exists, make one //If no stack exists, make one
if (!undoStacks.containsKey(player.getUniqueID())) { 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); undoStacks.get(player.getUniqueID()).push(blockSet);
} }
@@ -64,7 +63,7 @@ public class UndoRedo {
//If no stack exists, make one //If no stack exists, make one
if (!redoStacks.containsKey(player.getUniqueID())) { 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); redoStacks.get(player.getUniqueID()).push(blockSet);
@@ -214,7 +213,7 @@ public class UndoRedo {
//then anything it drops //then anything it drops
if (itemStack.isEmpty()) { 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) { if (itemDropped instanceof ItemBlock) {
Block block = ((ItemBlock) itemDropped).getBlock(); Block block = ((ItemBlock) itemDropped).getBlock();
itemStack = InventoryHelper.findItemStackInInventory(player, block); itemStack = InventoryHelper.findItemStackInInventory(player, block);

View File

@@ -3,7 +3,9 @@ package nl.requios.effortlessbuilding.capability;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
@@ -15,19 +17,10 @@ import javax.annotation.Nullable;
public class ItemHandlerCapabilityProvider implements ICapabilitySerializable<NBTTagCompound> { public class ItemHandlerCapabilityProvider implements ICapabilitySerializable<NBTTagCompound> {
IItemHandler itemHandler = new ItemStackHandler(ItemRandomizerBag.INV_SIZE); IItemHandler itemHandler = new ItemStackHandler(ItemRandomizerBag.INV_SIZE);
@Nonnull
@Override @Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) { public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing side) {
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.orEmpty(cap, LazyOptional.of(() -> itemHandler));
return true;
return false;
}
@Nullable
@Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return (T) itemHandler;
return null;
} }
@Override @Override

View File

@@ -1,20 +1,21 @@
package nl.requios.effortlessbuilding.capability; package nl.requios.effortlessbuilding.capability;
import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.INBTBase;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.*; import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.ModeSettings;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class ModeCapabilityManager { public class ModeCapabilityManager {
@@ -44,7 +45,7 @@ public class ModeCapabilityManager {
public static class Storage implements Capability.IStorage<IModeCapability> { public static class Storage implements Capability.IStorage<IModeCapability> {
@Override @Override
public NBTBase writeNBT(Capability<IModeCapability> capability, IModeCapability instance, EnumFacing side) { public INBTBase writeNBT(Capability<IModeCapability> capability, IModeCapability instance, EnumFacing side) {
NBTTagCompound compound = new NBTTagCompound(); NBTTagCompound compound = new NBTTagCompound();
ModeSettings modeSettings = instance.getModeData(); ModeSettings modeSettings = instance.getModeData();
if (modeSettings == null) modeSettings = new ModeSettings(); if (modeSettings == null) modeSettings = new ModeSettings();
@@ -57,7 +58,7 @@ public class ModeCapabilityManager {
} }
@Override @Override
public void readNBT(Capability<IModeCapability> capability, IModeCapability instance, EnumFacing side, NBTBase nbt) { public void readNBT(Capability<IModeCapability> capability, IModeCapability instance, EnumFacing side, INBTBase nbt) {
NBTTagCompound compound = (NBTTagCompound) nbt; NBTTagCompound compound = (NBTTagCompound) nbt;
//BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.values()[compound.getInteger("buildMode")]; //BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.values()[compound.getInteger("buildMode")];
@@ -69,36 +70,34 @@ public class ModeCapabilityManager {
} }
} }
public static class Provider implements ICapabilitySerializable<NBTBase> { public static class Provider implements ICapabilitySerializable<INBTBase> {
IModeCapability inst = modeCapability.getDefaultInstance(); IModeCapability inst = modeCapability.getDefaultInstance();
@Nonnull
@Override @Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) { public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing side) {
return capability == modeCapability; return modeCapability.orEmpty(cap, LazyOptional.of(() -> inst));
} }
@Override @Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) { public INBTBase serializeNBT() {
if (capability == modeCapability) return modeCapability.<T>cast(inst);
return null;
}
@Override
public NBTBase serializeNBT() {
return modeCapability.getStorage().writeNBT(modeCapability, inst, null); return modeCapability.getStorage().writeNBT(modeCapability, inst, null);
} }
@Override @Override
public void deserializeNBT(NBTBase nbt) { public void deserializeNBT(INBTBase nbt) {
modeCapability.getStorage().readNBT(modeCapability, inst, null, nbt); modeCapability.getStorage().readNBT(modeCapability, inst, null, nbt);
} }
} }
// Allows for the capability to persist after death. // Allows for the capability to persist after death.
@SubscribeEvent @SubscribeEvent
public static void clonePlayer(PlayerEvent.Clone event) { public static void clonePlayer(PlayerEvent.Clone event) {
IModeCapability original = event.getOriginal().getCapability(modeCapability, null); LazyOptional<IModeCapability> original = event.getOriginal().getCapability(modeCapability, null);
IModeCapability clone = event.getEntity().getCapability(modeCapability, null); LazyOptional<IModeCapability> clone = event.getEntity().getCapability(modeCapability, null);
clone.setModeData(original.getModeData()); clone.ifPresent(cloneModeCapability ->
original.ifPresent(originalModeCapability ->
cloneModeCapability.setModeData(originalModeCapability.getModeData())));
} }
} }

View File

@@ -1,6 +1,6 @@
package nl.requios.effortlessbuilding.capability; package nl.requios.effortlessbuilding.capability;
import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.INBTBase;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; 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.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; 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.Array;
import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.Mirror;
import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror;
@@ -18,6 +20,8 @@ import nl.requios.effortlessbuilding.buildmodifier.RadialMirror;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.concurrent.Callable;
import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.*; import static nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.*;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
@@ -48,7 +52,7 @@ public class ModifierCapabilityManager {
public static class Storage implements Capability.IStorage<IModifierCapability> { public static class Storage implements Capability.IStorage<IModifierCapability> {
@Override @Override
public NBTBase writeNBT(Capability<IModifierCapability> capability, IModifierCapability instance, EnumFacing side) { public INBTBase writeNBT(Capability<IModifierCapability> capability, IModifierCapability instance, EnumFacing side) {
NBTTagCompound compound = new NBTTagCompound(); NBTTagCompound compound = new NBTTagCompound();
ModifierSettings modifierSettings = instance.getModifierData(); ModifierSettings modifierSettings = instance.getModifierData();
if (modifierSettings == null) modifierSettings = new ModifierSettings(); if (modifierSettings == null) modifierSettings = new ModifierSettings();
@@ -63,7 +67,7 @@ public class ModifierCapabilityManager {
compound.setBoolean("mirrorX", m.mirrorX); compound.setBoolean("mirrorX", m.mirrorX);
compound.setBoolean("mirrorY", m.mirrorY); compound.setBoolean("mirrorY", m.mirrorY);
compound.setBoolean("mirrorZ", m.mirrorZ); compound.setBoolean("mirrorZ", m.mirrorZ);
compound.setInteger("mirrorRadius", m.radius); compound.setInt("mirrorRadius", m.radius);
compound.setBoolean("mirrorDrawLines", m.drawLines); compound.setBoolean("mirrorDrawLines", m.drawLines);
compound.setBoolean("mirrorDrawPlanes", m.drawPlanes); compound.setBoolean("mirrorDrawPlanes", m.drawPlanes);
@@ -71,12 +75,12 @@ public class ModifierCapabilityManager {
Array.ArraySettings a = modifierSettings.getArraySettings(); Array.ArraySettings a = modifierSettings.getArraySettings();
if (a == null) a = new Array.ArraySettings(); if (a == null) a = new Array.ArraySettings();
compound.setBoolean("arrayEnabled", a.enabled); compound.setBoolean("arrayEnabled", a.enabled);
compound.setInteger("arrayOffsetX", a.offset.getX()); compound.setInt("arrayOffsetX", a.offset.getX());
compound.setInteger("arrayOffsetY", a.offset.getY()); compound.setInt("arrayOffsetY", a.offset.getY());
compound.setInteger("arrayOffsetZ", a.offset.getZ()); compound.setInt("arrayOffsetZ", a.offset.getZ());
compound.setInteger("arrayCount", a.count); compound.setInt("arrayCount", a.count);
compound.setInteger("reachUpgrade", modifierSettings.getReachUpgrade()); compound.setInt("reachUpgrade", modifierSettings.getReachUpgrade());
//compound.setBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace //compound.setBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace
@@ -87,9 +91,9 @@ public class ModifierCapabilityManager {
compound.setDouble("radialMirrorPosX", r.position.x); compound.setDouble("radialMirrorPosX", r.position.x);
compound.setDouble("radialMirrorPosY", r.position.y); compound.setDouble("radialMirrorPosY", r.position.y);
compound.setDouble("radialMirrorPosZ", r.position.z); compound.setDouble("radialMirrorPosZ", r.position.z);
compound.setInteger("radialMirrorSlices", r.slices); compound.setInt("radialMirrorSlices", r.slices);
compound.setBoolean("radialMirrorAlternate", r.alternate); compound.setBoolean("radialMirrorAlternate", r.alternate);
compound.setInteger("radialMirrorRadius", r.radius); compound.setInt("radialMirrorRadius", r.radius);
compound.setBoolean("radialMirrorDrawLines", r.drawLines); compound.setBoolean("radialMirrorDrawLines", r.drawLines);
compound.setBoolean("radialMirrorDrawPlanes", r.drawPlanes); compound.setBoolean("radialMirrorDrawPlanes", r.drawPlanes);
@@ -97,7 +101,7 @@ public class ModifierCapabilityManager {
} }
@Override @Override
public void readNBT(Capability<IModifierCapability> capability, IModifierCapability instance, EnumFacing side, NBTBase nbt) { public void readNBT(Capability<IModifierCapability> capability, IModifierCapability instance, EnumFacing side, INBTBase nbt) {
NBTTagCompound compound = (NBTTagCompound) nbt; NBTTagCompound compound = (NBTTagCompound) nbt;
//MIRROR //MIRROR
@@ -109,7 +113,7 @@ public class ModifierCapabilityManager {
boolean mirrorX = compound.getBoolean("mirrorX"); boolean mirrorX = compound.getBoolean("mirrorX");
boolean mirrorY = compound.getBoolean("mirrorY"); boolean mirrorY = compound.getBoolean("mirrorY");
boolean mirrorZ = compound.getBoolean("mirrorZ"); boolean mirrorZ = compound.getBoolean("mirrorZ");
int mirrorRadius = compound.getInteger("mirrorRadius"); int mirrorRadius = compound.getInt("mirrorRadius");
boolean mirrorDrawLines = compound.getBoolean("mirrorDrawLines"); boolean mirrorDrawLines = compound.getBoolean("mirrorDrawLines");
boolean mirrorDrawPlanes = compound.getBoolean("mirrorDrawPlanes"); boolean mirrorDrawPlanes = compound.getBoolean("mirrorDrawPlanes");
Mirror.MirrorSettings mirrorSettings = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes); Mirror.MirrorSettings mirrorSettings = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes);
@@ -117,13 +121,13 @@ public class ModifierCapabilityManager {
//ARRAY //ARRAY
boolean arrayEnabled = compound.getBoolean("arrayEnabled"); boolean arrayEnabled = compound.getBoolean("arrayEnabled");
BlockPos arrayOffset = new BlockPos( BlockPos arrayOffset = new BlockPos(
compound.getInteger("arrayOffsetX"), compound.getInt("arrayOffsetX"),
compound.getInteger("arrayOffsetY"), compound.getInt("arrayOffsetY"),
compound.getInteger("arrayOffsetZ")); compound.getInt("arrayOffsetZ"));
int arrayCount = compound.getInteger("arrayCount"); int arrayCount = compound.getInt("arrayCount");
Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, 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 //boolean quickReplace = compound.getBoolean("quickReplace"); //dont load quickreplace
@@ -133,9 +137,9 @@ public class ModifierCapabilityManager {
compound.getDouble("radialMirrorPosX"), compound.getDouble("radialMirrorPosX"),
compound.getDouble("radialMirrorPosY"), compound.getDouble("radialMirrorPosY"),
compound.getDouble("radialMirrorPosZ")); compound.getDouble("radialMirrorPosZ"));
int radialMirrorSlices = compound.getInteger("radialMirrorSlices"); int radialMirrorSlices = compound.getInt("radialMirrorSlices");
boolean radialMirrorAlternate = compound.getBoolean("radialMirrorAlternate"); boolean radialMirrorAlternate = compound.getBoolean("radialMirrorAlternate");
int radialMirrorRadius = compound.getInteger("radialMirrorRadius"); int radialMirrorRadius = compound.getInt("radialMirrorRadius");
boolean radialMirrorDrawLines = compound.getBoolean("radialMirrorDrawLines"); boolean radialMirrorDrawLines = compound.getBoolean("radialMirrorDrawLines");
boolean radialMirrorDrawPlanes = compound.getBoolean("radialMirrorDrawPlanes"); boolean radialMirrorDrawPlanes = compound.getBoolean("radialMirrorDrawPlanes");
RadialMirror.RadialMirrorSettings radialMirrorSettings = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, RadialMirror.RadialMirrorSettings radialMirrorSettings = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition,
@@ -146,36 +150,36 @@ public class ModifierCapabilityManager {
} }
} }
public static class Provider implements ICapabilitySerializable<NBTBase> { public static class Provider implements ICapabilitySerializable<INBTBase> {
IModifierCapability inst = modifierCapability.getDefaultInstance(); IModifierCapability inst = modifierCapability.getDefaultInstance();
@Nonnull
@Override @Override
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) { public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing side) {
return capability == modifierCapability; return modifierCapability.orEmpty(cap, LazyOptional.of(() -> inst));
} }
@Override @Override
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) { public INBTBase serializeNBT() {
if (capability == modifierCapability) return modifierCapability.<T>cast(inst);
return null;
}
@Override
public NBTBase serializeNBT() {
return modifierCapability.getStorage().writeNBT(modifierCapability, inst, null); return modifierCapability.getStorage().writeNBT(modifierCapability, inst, null);
} }
@Override @Override
public void deserializeNBT(NBTBase nbt) { public void deserializeNBT(INBTBase nbt) {
modifierCapability.getStorage().readNBT(modifierCapability, inst, null, nbt); modifierCapability.getStorage().readNBT(modifierCapability, inst, null, nbt);
} }
} }
// Allows for the capability to persist after death. // Allows for the capability to persist after death.
@SubscribeEvent @SubscribeEvent
public static void clonePlayer(PlayerEvent.Clone event) { public static void clonePlayer(PlayerEvent.Clone event) {
IModifierCapability original = event.getOriginal().getCapability(modifierCapability, null); LazyOptional<IModifierCapability> original = event.getOriginal().getCapability(modifierCapability, null);
IModifierCapability clone = event.getEntity().getCapability(modifierCapability, null); LazyOptional<IModifierCapability> clone = event.getEntity().getCapability(modifierCapability, null);
clone.setModifierData(original.getModifierData()); clone.ifPresent(cloneModifierCapability ->
original.ifPresent(originalModifierCapability ->
cloneModifierCapability.setModifierData(originalModifierCapability.getModifierData())));
} }
} }

View File

@@ -1,46 +1,44 @@
package nl.requios.effortlessbuilding.command; package nl.requios.effortlessbuilding.command;
import net.minecraft.command.CommandBase; import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.command.CommandException; import com.mojang.brigadier.arguments.IntegerArgumentType;
import net.minecraft.command.ICommandSender; import net.minecraft.command.CommandSource;
import net.minecraft.command.WrongUsageException; import net.minecraft.command.Commands;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.fml.network.PacketDistributor;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; import nl.requios.effortlessbuilding.network.ModifierSettingsMessage;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.network.RequestLookAtMessage;
public class CommandReach extends CommandBase { public class CommandReach {
@Override
public String getName() { public static void register(CommandDispatcher<CommandSource> dispatcher) {
return "reach"; 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 private static int setReachLevel(EntityPlayerMP player, int level){
public String getUsage(ICommandSender sender) {
return "commands.reach.usage";
}
@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");
}
if (sender instanceof EntityPlayerMP) {
//Set reach level to args[0]
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
modifierSettings.setReachUpgrade(Integer.valueOf(args[0])); modifierSettings.setReachUpgrade(level);
ModifierSettingsManager.setModifierSettings(player, modifierSettings); ModifierSettingsManager.setModifierSettings(player, modifierSettings);
//Send to client //Send to client
EffortlessBuilding.packetHandler.sendTo(new ModifierSettingsMessage(modifierSettings), player); PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new ModifierSettingsMessage(modifierSettings));
sender.sendMessage(new TextComponentString("Reach level of " + sender.getName() + " set to " + modifierSettings player.sendMessage(new TextComponentString("Reach level of " + player.getName().getString() + " set to " + modifierSettings.getReachUpgrade()));
.getReachUpgrade()));
return 1;
} }
private static int getReachLevel(EntityPlayerMP player){
int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade();
EffortlessBuilding.log(player, "Current reach: level "+reachUpgrade);
return 1;
} }
} }

View File

@@ -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();
}
}

View File

@@ -6,31 +6,33 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraftforge.fml.common.Loader; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
public class CompatHelper { public class CompatHelper {
// Get a handle to the dank null item instance. This will remain null if the mod doesn't load //TODO 1.13 compatibility
// and all checks will fail, so it works. // // Get a handle to the dank null item instance. This will remain null if the mod doesn't load
@GameRegistry.ObjectHolder("danknull:dank_null") // // and all checks will fail, so it works.
public static final Item dankNullItem = null; // @GameRegistry.ObjectHolder("danknull:dank_null")
// public static final Item dankNullItem = null;
public static IChiselsAndBitsProxy chiselsAndBitsProxy; //
// public static IChiselsAndBitsProxy chiselsAndBitsProxy;
public static void postInit() { //
if (Loader.isModLoaded("chiselsandbits")) { public static void setup() {
// reflection to avoid hard dependency //TODO 1.13 compatibility
try { // if (Loader.isModLoaded("chiselsandbits")) {
chiselsAndBitsProxy = Class.forName("nl.requios.effortlessbuilding.compatibility.ActiveChiselsAndBitsProxy").asSubclass(ActiveChiselsAndBitsProxy.class).newInstance(); // // reflection to avoid hard dependency
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { // try {
e.printStackTrace(); // chiselsAndBitsProxy = Class.forName("nl.requios.effortlessbuilding.compatibility.ActiveChiselsAndBitsProxy").asSubclass(ActiveChiselsAndBitsProxy.class).newInstance();
} // } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
} else { // e.printStackTrace();
chiselsAndBitsProxy = new DummyChiselsAndBitsProxy(); // }
} // } else {
// chiselsAndBitsProxy = new DummyChiselsAndBitsProxy();
// }
} }
// Check if the item given is a proxy for blocks. For now, we check for the randomizer bag, // 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; return true;
if ((item instanceof ItemRandomizerBag)) if ((item instanceof ItemRandomizerBag))
return true; return true;
if (item == dankNullItem) //TODO 1.13 compatibility
return true; // if (item == dankNullItem)
// return true;
return false; return false;
} }
@@ -64,47 +67,60 @@ public class CompatHelper {
return itemStack; return itemStack;
} }
//TODO 1.13 compatibility
//Dank Null //Dank Null
if (proxyItem == dankNullItem) { // if (proxyItem == dankNullItem) {
int index = 0; // int index = 0;
if (proxy.hasTagCompound() && proxy.getTagCompound().hasKey("selectedIndex")) // if (proxy.hasTagCompound() && proxy.getTagCompound().hasKey("selectedIndex"))
index = proxy.getTagCompound().getInteger("selectedIndex"); // index = proxy.getTagCompound().getInteger("selectedIndex");
return proxy.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index); // return proxy.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).getStackInSlot(index);
} // }
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
public static ItemStack getItemBlockByState(ItemStack stack, IBlockState state) { public static ItemStack getItemBlockByState(ItemStack stack, IBlockState state) {
if (state == null) return ItemStack.EMPTY;
Item blockItem = Item.getItemFromBlock(state.getBlock()); Item blockItem = Item.getItemFromBlock(state.getBlock());
if (stack.getItem() instanceof ItemBlock) if (stack.getItem() instanceof ItemBlock)
return stack; return stack;
else if (stack.getItem() instanceof ItemRandomizerBag) { else if (stack.getItem() instanceof ItemRandomizerBag) {
IItemHandler bagInventory = ItemRandomizerBag.getBagInventory(stack); IItemHandler bagInventory = ItemRandomizerBag.getBagInventory(stack);
return ItemRandomizerBag.findStack(bagInventory, blockItem); 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; return ItemStack.EMPTY;
} }
// Handle IItemHandler slot stacks not being modifiable. We must call IItemHandler#extractItem, // Handle IItemHandler slot stacks not being modifiable. We must call IItemHandler#extractItem,
// because the ItemStack returned by IItemHandler#getStackInSlot isn't modifiable. // because the ItemStack returned by IItemHandler#getStackInSlot isn't modifiable.
public static void shrinkStack(ItemStack origStack, ItemStack curStack, EntityPlayer player) { 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 //TODO 1.13 compatibility, offhand support
origStack = player.getHeldItem(EnumHand.MAIN_HAND); //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) { // if (origStack.getItem() == dankNullItem) {
int index = itemHandlerSlotForItem(origStack, curStack.getItem()); // int index = itemHandlerSlotForItem(origStack, curStack.getItem());
origStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).extractItem(index, 1, false); // origStack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).extractItem(index, 1, false);
} else // } else
curStack.shrink(1); curStack.shrink(1);
} }
private static int itemHandlerSlotForItem(ItemStack stack, Item blockItem) { private static int itemHandlerSlotForItem(ItemStack stack, Item blockItem) {
IItemHandler handler = stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); LazyOptional<IItemHandler> 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++) { for (int i = 0; i < handler.getSlots(); i++) {
ItemStack ref = handler.getStackInSlot(i); ItemStack ref = handler.getStackInSlot(i);
if (ref.getItem() instanceof ItemBlock) if (ref.getItem() instanceof ItemBlock)

View File

@@ -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;
}
}

View File

@@ -1,7 +0,0 @@
package nl.requios.effortlessbuilding.compatibility;
import net.minecraft.util.EnumHand;
public interface IChiselsAndBitsProxy {
boolean isHoldingChiselTool(EnumHand hand);
}

View File

@@ -23,20 +23,20 @@ public class RandomizerBagContainer extends Container {
bagInventory = parIInventory; bagInventory = parIInventory;
sizeInventory = bagInventory.getSlots(); sizeInventory = bagInventory.getSlots();
for (int i = 0; i < sizeInventory; ++i) { 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 // add player inventory slots
int i; int i;
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) { 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 // add hotbar slots
for (i = 0; i < 9; ++i) { for (i = 0; i < 9; ++i) {
addSlotToContainer(new Slot(parInventoryPlayer, i, 8 + i * 18, 109)); addSlot(new Slot(parInventoryPlayer, i, 8 + i * 18, 109));
} }
} }

View File

@@ -4,12 +4,12 @@ import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
@SideOnly(Side.CLIENT) @OnlyIn(Dist.CLIENT)
public class RandomizerBagGuiContainer extends GuiContainer { public class RandomizerBagGuiContainer extends GuiContainer {
private static final ResourceLocation guiTextures = private static final ResourceLocation guiTextures =
new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png"); new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/container/randomizerbag.png");
@@ -25,9 +25,9 @@ public class RandomizerBagGuiContainer extends GuiContainer {
} }
@Override @Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) { public void render(int mouseX, int mouseY, float partialTicks) {
drawDefaultBackground(); drawDefaultBackground();
super.drawScreen(mouseX, mouseY, partialTicks); super.render(mouseX, mouseY, partialTicks);
this.renderHoveredToolTip(mouseX, mouseY); this.renderHoveredToolTip(mouseX, mouseY);
} }
@@ -35,12 +35,12 @@ public class RandomizerBagGuiContainer extends GuiContainer {
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
String s = "Randomizer Bag"; String s = "Randomizer Bag";
fontRenderer.drawString(s, 8, 6, 0x404040); 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 @Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { 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); mc.getTextureManager().bindTexture(guiTextures);
int marginHorizontal = (width - xSize) / 2; int marginHorizontal = (width - xSize) / 2;
int marginVertical = (height - ySize) / 2; int marginVertical = (height - ySize) / 2;

View File

@@ -1,41 +1,112 @@
package nl.requios.effortlessbuilding.gui; 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.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.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.common.network.IGuiHandler;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.network.FMLPlayMessages;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class RandomizerBagGuiHandler implements IGuiHandler { public class RandomizerBagGuiHandler implements /*IGuiHandler, */IInteractionObject {
@Nullable // @Nullable
@Override // @Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { // public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { // if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) {
// Use the player's held item to create the container // // Use the player's held item to create the container
IItemHandler capability = player.getHeldItemMainhand().hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) ? // LazyOptional<IItemHandler> capabilityOptional = player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) : //
player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); // if (!capabilityOptional.isPresent()) {
return new RandomizerBagContainer(player.inventory, capability); // 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<IItemHandler> 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; return null;
} }
@Nullable
@Override @Override
@SideOnly(Side.CLIENT) public Container createContainer(InventoryPlayer inventory, EntityPlayer player) {
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { if (player.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof ItemRandomizerBag) {
if (ID == EffortlessBuilding.RANDOMIZER_BAG_GUI) { IItemHandler itemHandler = player.getHeldItem(EnumHand.MAIN_HAND).getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null);
// Use the player's held item to create the client-side gui container if (itemHandler != null) {
IItemHandler capability = player.getHeldItemMainhand().hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) ? return new RandomizerBagContainer(inventory, itemHandler);
player.getHeldItemMainhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) : }
player.getHeldItemOffhand().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
return new RandomizerBagGuiContainer(player.inventory, capability);
} }
return null; 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;
}
} }

View File

@@ -26,6 +26,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoader;
import static nl.requios.effortlessbuilding.buildmode.BuildModes.*; import static nl.requios.effortlessbuilding.buildmode.BuildModes.*;
import static nl.requios.effortlessbuilding.buildmode.ModeOptions.*;
/** /**
* From Chisels and Bits by AlgorithmX2 * From Chisels and Bits by AlgorithmX2
@@ -39,7 +40,7 @@ public class RadialMenu extends GuiScreen {
private float visibility = 0.0f; private float visibility = 0.0f;
private Stopwatch lastChange = Stopwatch.createStarted(); private Stopwatch lastChange = Stopwatch.createStarted();
public BuildModeEnum switchTo = null; public BuildModeEnum switchTo = null;
public ModeOptions.ActionEnum doAction = null; public ActionEnum doAction = null;
public boolean actionUsed = false; public boolean actionUsed = false;
private float clampVis(final float f) { private float clampVis(final float f) {
@@ -65,7 +66,7 @@ public class RadialMenu extends GuiScreen {
} }
public void configure(final int scaledWidth, final int scaledHeight ) { public void configure(final int scaledWidth, final int scaledHeight ) {
mc = Minecraft.getMinecraft(); mc = Minecraft.getInstance();
fontRenderer = mc.fontRenderer; fontRenderer = mc.fontRenderer;
width = scaledWidth; width = scaledWidth;
height = scaledHeight; height = scaledHeight;
@@ -77,11 +78,11 @@ public class RadialMenu extends GuiScreen {
public double y1, y2; public double y1, y2;
public boolean highlighted; public boolean highlighted;
public final ModeOptions.ActionEnum action; public final ActionEnum action;
public String name; public String name;
public EnumFacing textSide; 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) { final EnumFacing textSide) {
this.name = I18n.format(name); this.name = I18n.format(name);
this.action = action; this.action = action;
@@ -108,13 +109,13 @@ public class RadialMenu extends GuiScreen {
} }
@Override @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; if (!isVisible()) return;
BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(Minecraft.getMinecraft().player).getBuildMode(); BuildModeEnum currentBuildMode = ModeSettingsManager.getModeSettings(Minecraft.getInstance().player).getBuildMode();
GlStateManager.pushMatrix(); 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 startColor = (int) ( visibility * 98 ) << 24;
final int endColor = (int) ( visibility * 128 ) << 24; final int endColor = (int) ( visibility * 128 ) << 24;
@@ -123,8 +124,8 @@ public class RadialMenu extends GuiScreen {
GlStateManager.disableTexture2D(); GlStateManager.disableTexture2D();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.disableAlpha(); GlStateManager.disableAlphaTest();
GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); GlStateManager.blendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0);
GlStateManager.shadeModel(GL11.GL_SMOOTH); GlStateManager.shadeModel(GL11.GL_SMOOTH);
final Tessellator tessellator = Tessellator.getInstance(); final Tessellator tessellator = Tessellator.getInstance();
final BufferBuilder buffer = tessellator.getBuffer(); final BufferBuilder buffer = tessellator.getBuffer();
@@ -135,13 +136,13 @@ public class RadialMenu extends GuiScreen {
final double middleY = height / 2.0; final double middleY = height / 2.0;
final double mouseXCenter = mouseX - middleX; final double mouseXCenter = mouseX - middleX;
final double mouseYCenter = mouseY - middleY; final double mouseYCenter = -mouseY + middleY;
double mouseRadians = Math.atan2(mouseYCenter, mouseXCenter); double mouseRadians = Math.atan2(mouseYCenter, mouseXCenter);
final double ringInnerEdge = 20; final double ringInnerEdge = 30;
final double ringOuterEdge = 50; final double ringOuterEdge = 65;
final double textDistance = 60; final double textDistance = 75;
final double buttonDistance = 90; final double buttonDistance = 105;
final double quarterCircle = Math.PI / 2.0; final double quarterCircle = Math.PI / 2.0;
if ( mouseRadians < -quarterCircle ) { if ( mouseRadians < -quarterCircle ) {
@@ -157,16 +158,18 @@ public class RadialMenu extends GuiScreen {
} }
//Add actions //Add actions
buttons.add(new MenuButton(ModeOptions.ActionEnum.UNDO.name, ModeOptions.ActionEnum.UNDO, -buttonDistance - 26, -13, EnumFacing.UP)); buttons.add(new MenuButton(ActionEnum.UNDO.name, 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(ActionEnum.REDO.name, 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(ActionEnum.OPEN_MODIFIER_SETTINGS.name, 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.REPLACE.name, ActionEnum.REPLACE, -buttonDistance, 13, EnumFacing.DOWN));
//Add buildmode dependent options //Add buildmode dependent options
ModeOptions.ActionEnum[] options = currentBuildMode.options; OptionEnum[] options = currentBuildMode.options;
for (int i = 0; i < options.length; i++) { for (int i = 0; i < options.length; i++) {
ModeOptions.ActionEnum action = options[i]; for (int j = 0; j < options[i].actions.length; j++) {
buttons.add(new MenuButton(action.name, action, buttonDistance + i * 26, -13, EnumFacing.DOWN)); ActionEnum action = options[i].actions[j];
buttons.add(new MenuButton(action.name, action, buttonDistance + j * 26, -13 + i * 39, EnumFacing.DOWN));
}
} }
switchTo = null; switchTo = null;
@@ -245,11 +248,12 @@ public class RadialMenu extends GuiScreen {
float a = 0.5f; float a = 0.5f;
//highlight when active option //highlight when active option
if (btn.action == ModeOptions.getBuildSpeed() || if (btn.action == getBuildSpeed() ||
btn.action == ModeOptions.getFill() || btn.action == getFill() ||
btn.action == ModeOptions.getCubeFill() || btn.action == getCubeFill() ||
btn.action == ModeOptions.getRaisedEdge() || btn.action == getRaisedEdge() ||
btn.action == ModeOptions.getLineThickness()) { btn.action == getLineThickness() ||
btn.action == getCircleStart()) {
r = 0.0f; r = 0.0f;
g = 0.5f; g = 0.5f;
b = 1f; b = 1f;
@@ -276,12 +280,12 @@ public class RadialMenu extends GuiScreen {
GlStateManager.shadeModel(GL11.GL_FLAT); GlStateManager.shadeModel(GL11.GL_FLAT);
GlStateManager.translate(0f, 0f, 5f); GlStateManager.translatef(0f, 0f, 5f);
GlStateManager.enableTexture2D(); GlStateManager.enableTexture2D();
GlStateManager.color(1f, 1f, 1f, 1f); GlStateManager.color3f(1f, 1f, 1f);
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableAlpha(); GlStateManager.enableAlphaTest();
GlStateManager.bindTexture(Minecraft.getMinecraft().getTextureMapBlocks().getGlTextureId()); GlStateManager.bindTexture(Minecraft.getInstance().getTextureMap().getGlTextureId());
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
@@ -342,32 +346,12 @@ public class RadialMenu extends GuiScreen {
//Draw strings //Draw strings
//fontRenderer.drawStringWithShadow("Actions", (int) (middleX - buttonDistance - 13) - fontRenderer.getStringWidth("Actions") * 0.5f, (int) middleY - 38, 0xffffffff); //fontRenderer.drawStringWithShadow("Actions", (int) (middleX - buttonDistance - 13) - fontRenderer.getStringWidth("Actions") * 0.5f, (int) middleY - 38, 0xffffffff);
String title = "";
if (currentBuildMode.options.length > 0) { //Draw option strings
switch (currentBuildMode.options[0]) { for (int i = 0; i < currentBuildMode.options.length; i++) {
case NORMAL_SPEED: OptionEnum option = options[i];
case FAST_SPEED: fontRenderer.drawStringWithShadow(I18n.format(option.name), (int) (middleX + buttonDistance - 9), (int) middleY - 37 + i * 39, 0xeeeeeeff);
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;
} }
}
fontRenderer.drawStringWithShadow(title, (int) (middleX + buttonDistance - 9), (int) middleY - 37, 0xeeeeeeff);
String credits = "Effortless Building"; String credits = "Effortless Building";
fontRenderer.drawStringWithShadow(credits, width - fontRenderer.getStringWidth(credits) - 4, height - 10, 0x88888888); fontRenderer.drawStringWithShadow(credits, width - fontRenderer.getStringWidth(credits) - 4, height - 10, 0x88888888);
@@ -402,17 +386,25 @@ public class RadialMenu extends GuiScreen {
String keybindFormatted = ""; String keybindFormatted = "";
//Add keybind in brackets //Add keybind in brackets
if (button.action == ModeOptions.ActionEnum.UNDO) { if (button.action == ActionEnum.UNDO) {
keybind = ClientProxy.keyBindings[4].getDisplayName(); keybind = ClientProxy.keyBindings[4].getKey().getName();
} }
if (button.action == ModeOptions.ActionEnum.REDO) { if (button.action == ActionEnum.REDO) {
keybind = ClientProxy.keyBindings[5].getDisplayName(); keybind = ClientProxy.keyBindings[5].getKey().getName();
} }
if (button.action == ModeOptions.ActionEnum.REPLACE) { if (button.action == ActionEnum.REPLACE) {
keybind = ClientProxy.keyBindings[1].getDisplayName(); keybind = ClientProxy.keyBindings[1].getKey().getName();
}
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 (button.action == ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) {
keybind = ClientProxy.keyBindings[0].getDisplayName();
} }
if (!keybind.isEmpty()) keybindFormatted = TextFormatting.GRAY + "(" + WordUtils.capitalizeFully(keybind) + ")"; 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 * Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton
*/ */
@Override @Override
protected void mouseClicked(int mouseX, int mouseY, int mouseButton ) { public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
EffortlessBuilding.log("mouse clicked"); EffortlessBuilding.log("mouse clicked");
// KeyBinding.updateKeyBindState(); // KeyBinding.updateKeyBindState();
@@ -479,6 +471,8 @@ public class RadialMenu extends GuiScreen {
// this.mc.setIngameFocus(); // this.mc.setIngameFocus();
// } // }
// } // }
return super.mouseClicked(mouseX, mouseY, mouseButton);
} }
} }

View File

@@ -4,6 +4,8 @@ import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting; 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 net.minecraftforge.fml.client.config.GuiCheckBox;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.Array;
@@ -17,6 +19,7 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@OnlyIn(Dist.CLIENT)
public class ArraySettingsGui extends GuiCollapsibleScrollEntry { public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
protected List<GuiNumberField> arrayNumberFieldList = new ArrayList<>(); protected List<GuiNumberField> arrayNumberFieldList = new ArrayList<>();
@@ -29,31 +32,37 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
} }
@Override @Override
public int initGui(int id, List<GuiButton> buttonList) { public int initGui(int id, List<GuiButton> buttons) {
id = super.initGui(id, buttonList); id = super.initGui(id, buttons);
int y = top; int y = top;
buttonArrayEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false); buttonArrayEnabled = new GuiCheckBox(id++, left - 15 + 8, y, "", false) {
buttonList.add(buttonArrayEnabled); @Override
public void onClick(double mouseX, double mouseY) {
super.onClick(mouseX, mouseY);
setCollapsed(!buttonArrayEnabled.isChecked());
}
};
buttons.add(buttonArrayEnabled);
y = top + 20; 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.setNumber(0);
textArrayOffsetX.setTooltip("How much each copy is shifted."); textArrayOffsetX.setTooltip("How much each copy is shifted.");
arrayNumberFieldList.add(textArrayOffsetX); 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.setNumber(0);
textArrayOffsetY.setTooltip("How much each copy is shifted."); textArrayOffsetY.setTooltip("How much each copy is shifted.");
arrayNumberFieldList.add(textArrayOffsetY); 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.setNumber(0);
textArrayOffsetZ.setTooltip("How much each copy is shifted."); textArrayOffsetZ.setTooltip("How much each copy is shifted.");
arrayNumberFieldList.add(textArrayOffsetZ); arrayNumberFieldList.add(textArrayOffsetZ);
y = top + 50; 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.setNumber(5);
textArrayCount.setTooltip("How many copies should be made."); textArrayCount.setTooltip("How many copies should be made.");
arrayNumberFieldList.add(textArrayCount); arrayNumberFieldList.add(textArrayCount);
@@ -73,48 +82,44 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
return id; return id;
} }
@Override
public void updateScreen() { public void updateScreen() {
super.updateScreen();
arrayNumberFieldList.forEach(GuiNumberField::update); arrayNumberFieldList.forEach(GuiNumberField::update);
} }
@Override @Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks) { boolean isSelected, float partialTicks) {
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partialTicks);
int yy = y; int yy = y;
int offset = 8; int offset = 8;
buttonArrayEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks); buttonArrayEnabled.render(mouseX, mouseY, partialTicks);
if (buttonArrayEnabled.isChecked()) { if (buttonArrayEnabled.isChecked()) {
buttonArrayEnabled.y = yy; 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; yy = y + 20;
fontRenderer.drawString("Offset", left + offset, yy + 5, 0xFFFFFF, true); fontRenderer.drawString("Offset", left + offset, yy + 5, 0xFFFFFF);
fontRenderer.drawString("X", left + 50 + offset, yy + 5, 0xFFFFFF, true); fontRenderer.drawString("X", left + 50 + offset, yy + 5, 0xFFFFFF);
textArrayOffsetX.y = yy; 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; 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; textArrayOffsetZ.y = yy;
yy = y + 50; yy = y + 50;
fontRenderer.drawString("Count", left + offset, yy + 5, 0xFFFFFF, true); fontRenderer.drawString("Count", left + offset, yy + 5, 0xFFFFFF);
textArrayCount.y = yy; textArrayCount.y = yy;
int currentReach = Math.max(-1, getArrayReach()); int currentReach = Math.max(-1, getArrayReach());
int maxReach = ReachHelper.getMaxReach(mc.player); int maxReach = ReachHelper.getMaxReach(mc.player);
TextFormatting reachColor = isCurrentReachValid(currentReach, maxReach) ? TextFormatting.GRAY : TextFormatting.RED; TextFormatting reachColor = isCurrentReachValid(currentReach, maxReach) ? TextFormatting.GRAY : TextFormatting.RED;
String reachText = "Reach: " + reachColor + currentReach + TextFormatting.GRAY + "/" + TextFormatting.GRAY + maxReach; 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 { } else {
buttonArrayEnabled.y = yy; 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 @Override
public void updatePosition(int slotIndex, int x, int y, float partialTicks) { public boolean charTyped(char typedChar, int keyCode) {
super.updatePosition(slotIndex, x, y, partialTicks); super.charTyped(typedChar, keyCode);
}
@Override
public void keyTyped(char typedChar, int keyCode) throws IOException {
super.keyTyped(typedChar, keyCode);
for (GuiNumberField numberField : arrayNumberFieldList) { for (GuiNumberField numberField : arrayNumberFieldList) {
numberField.keyTyped(typedChar, keyCode); numberField.charTyped(typedChar, keyCode);
} }
return true;
} }
@Override @Override
public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { 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)); arrayNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent));
boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
if (insideArrayEnabledLabel) { if (insideArrayEnabledLabel) {
buttonArrayEnabled.setIsChecked(!buttonArrayEnabled.isChecked());
buttonArrayEnabled.playPressSound(this.mc.getSoundHandler()); buttonArrayEnabled.playPressSound(this.mc.getSoundHandler());
actionPerformed(buttonArrayEnabled); buttonArrayEnabled.onClick(mouseX, mouseY);
} }
return true; 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() { public Array.ArraySettings getArraySettings() {
boolean arrayEnabled = buttonArrayEnabled.isChecked(); boolean arrayEnabled = buttonArrayEnabled.isChecked();
BlockPos arrayOffset = new BlockPos(0, 0, 0); BlockPos arrayOffset = new BlockPos(0, 0, 0);

View File

@@ -5,6 +5,8 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting; 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 net.minecraftforge.fml.client.config.GuiCheckBox;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.Mirror;
@@ -20,6 +22,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@SuppressWarnings("Duplicates")
@OnlyIn(Dist.CLIENT)
public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png"); 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); id = super.initGui(id, buttonList);
int y = top - 2; 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); buttonList.add(buttonMirrorEnabled);
y = top + 18; y = top + 18;
@@ -82,19 +92,62 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
mirrorNumberFieldList.add(textMirrorRadius); mirrorNumberFieldList.add(textMirrorRadius);
y = top + 72; 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"); buttonCurrentPosition.setTooltip("Set mirror position to current player position");
mirrorIconButtonList.add(buttonCurrentPosition); 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")); buttonToggleOdd.setTooltip(Arrays.asList("Set mirror position to middle of block", "for odd numbered builds"));
mirrorIconButtonList.add(buttonToggleOdd); 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"); buttonDrawLines.setTooltip("Show lines");
mirrorIconButtonList.add(buttonDrawLines); 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"); buttonDrawPlanes.setTooltip("Show area");
mirrorIconButtonList.add(buttonDrawPlanes); mirrorIconButtonList.add(buttonDrawPlanes);
@@ -142,31 +195,30 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
@Override @Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks) { boolean isSelected, float partialTicks) {
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partialTicks);
int yy = y; int yy = y;
int offset = 8; int offset = 8;
buttonMirrorEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks); buttonMirrorEnabled.render(mouseX, mouseY, partialTicks);
if (buttonMirrorEnabled.isChecked()) { if (buttonMirrorEnabled.isChecked()) {
buttonMirrorEnabled.y = yy; 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; yy = y + 18;
fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF, true); fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF);
fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF, true); fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF);
textMirrorPosX.y = yy; 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; 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; textMirrorPosZ.y = yy;
yy = y + 50; yy = y + 50;
fontRenderer.drawString("Direction", left + offset, yy + 2, 0xFFFFFF, true); fontRenderer.drawString("Direction", left + offset, yy + 2, 0xFFFFFF);
buttonMirrorX.y = yy; buttonMirrorX.y = yy;
buttonMirrorY.y = yy; buttonMirrorY.y = yy;
buttonMirrorZ.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; textMirrorRadius.y = yy - 3;
yy = y + 72; yy = y + 72;
@@ -175,12 +227,12 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry {
buttonDrawLines.y = yy; buttonDrawLines.y = yy;
buttonDrawPlanes.y = yy; buttonDrawPlanes.y = yy;
mirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); mirrorButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks));
mirrorIconButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); mirrorIconButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks));
mirrorNumberFieldList.forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks)); mirrorNumberFieldList.forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks));
} else { } else {
buttonMirrorEnabled.y = yy; 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 @Override
public void updatePosition(int slotIndex, int x, int y, float partialTicks) { public boolean charTyped(char typedChar, int keyCode) {
super.updatePosition(slotIndex, x, y, partialTicks); super.charTyped(typedChar, keyCode);
}
@Override
public void keyTyped(char typedChar, int keyCode) throws IOException {
super.keyTyped(typedChar, keyCode);
for (GuiNumberField numberField : mirrorNumberFieldList) { for (GuiNumberField numberField : mirrorNumberFieldList) {
numberField.keyTyped(typedChar, keyCode); numberField.charTyped(typedChar, keyCode);
} }
return true;
} }
@Override @Override
public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { 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)); mirrorNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent));
boolean insideMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; boolean insideMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
if (insideMirrorEnabledLabel) { if (insideMirrorEnabledLabel) {
buttonMirrorEnabled.setIsChecked(!buttonMirrorEnabled.isChecked());
buttonMirrorEnabled.playPressSound(this.mc.getSoundHandler()); buttonMirrorEnabled.playPressSound(this.mc.getSoundHandler());
actionPerformed(buttonMirrorEnabled); buttonMirrorEnabled.onClick(mouseX, mouseY);
} }
return true; 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() { public Mirror.MirrorSettings getMirrorSettings() {
boolean mirrorEnabled = buttonMirrorEnabled.isChecked(); boolean mirrorEnabled = buttonMirrorEnabled.isChecked();

View File

@@ -1,7 +1,10 @@
package nl.requios.effortlessbuilding.gui.buildmodifier; package nl.requios.effortlessbuilding.gui.buildmodifier;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen; 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.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.Array;
import nl.requios.effortlessbuilding.buildmodifier.Mirror; 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.buildmodifier.RadialMirror;
import nl.requios.effortlessbuilding.gui.elements.GuiScrollPane; import nl.requios.effortlessbuilding.gui.elements.GuiScrollPane;
import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; import nl.requios.effortlessbuilding.network.ModifierSettingsMessage;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import java.io.IOException; import java.io.IOException;
@OnlyIn(Dist.CLIENT)
public class ModifierSettingsGui extends GuiScreen { public class ModifierSettingsGui extends GuiScreen {
private GuiScrollPane scrollPane; private GuiScrollPane scrollPane;
@@ -30,68 +35,79 @@ public class ModifierSettingsGui extends GuiScreen {
scrollPane = new GuiScrollPane(this, fontRenderer, 8, height - 30); scrollPane = new GuiScrollPane(this, fontRenderer, 8, height - 30);
mirrorSettingsGui = new MirrorSettingsGui(scrollPane); mirrorSettingsGui = new MirrorSettingsGui(scrollPane);
scrollPane.listEntries.add(mirrorSettingsGui); scrollPane.AddListEntry(mirrorSettingsGui);
arraySettingsGui = new ArraySettingsGui(scrollPane); arraySettingsGui = new ArraySettingsGui(scrollPane);
scrollPane.listEntries.add(arraySettingsGui); scrollPane.AddListEntry(arraySettingsGui);
radialMirrorSettingsGui = new RadialMirrorSettingsGui(scrollPane); radialMirrorSettingsGui = new RadialMirrorSettingsGui(scrollPane);
scrollPane.listEntries.add(radialMirrorSettingsGui); scrollPane.AddListEntry(radialMirrorSettingsGui);
id = scrollPane.initGui(id, buttonList); id = scrollPane.initGui(id, buttons);
//Close button //Close button
int y = height - 26; int y = height - 26;
buttonClose = new GuiButton(id++, width / 2 - 100, y, "Close"); buttonClose = new GuiButton(id++, width / 2 - 100, y, "Close") {
buttonList.add(buttonClose); @Override
public void onClick(double mouseX, double mouseY) {
super.onClick(mouseX, mouseY);
mc.player.closeScreen();
}
};
buttons.add(buttonClose);
} }
@Override @Override
//Process general logic, i.e. hide buttons //Process general logic, i.e. hide buttons
public void updateScreen() { public void tick() {
scrollPane.updateScreen(); scrollPane.updateScreen();
handleMouseInput();
} }
@Override @Override
//Set colors using GL11, use the fontRendererObj field to display text //Set colors using GL11, use the fontRendererObj field to display text
//Use drawTexturedModalRect() to transfers areas of a texture resource to the screen //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(); this.drawDefaultBackground();
scrollPane.drawScreen(mouseX, mouseY, partialTicks); scrollPane.drawScreen(mouseX, mouseY, partialTicks);
buttonClose.drawButton(this.mc, mouseX, mouseY, partialTicks); buttonClose.render(mouseX, mouseY, partialTicks);
scrollPane.drawTooltip(this, mouseX, mouseY); scrollPane.drawTooltip(this, mouseX, mouseY);
} }
@Override @Override
protected void keyTyped(char typedChar, int keyCode) throws IOException { public boolean charTyped(char typedChar, int keyCode) {
super.keyTyped(typedChar, keyCode); super.charTyped(typedChar, keyCode);
scrollPane.keyTyped(typedChar, keyCode); scrollPane.charTyped(typedChar, keyCode);
if (keyCode == ClientProxy.keyBindings[0].getKeyCode()) { if (keyCode == ClientProxy.keyBindings[0].getKey().getKeyCode()) {
mc.player.closeScreen(); mc.player.closeScreen();
} }
return false;
} }
@Override @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); 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 @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)) 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() {
public void handleMouseInput() throws IOException { //super.handleMouseInput();
super.handleMouseInput();
scrollPane.handleMouseInput(); scrollPane.handleMouseInput();
//Scrolling numbers //Scrolling numbers
@@ -100,15 +116,6 @@ public class ModifierSettingsGui extends GuiScreen {
// numberFieldList.forEach(numberField -> numberField.handleMouseInput(mouseX, mouseY)); // 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 @Override
public void onGuiClosed() { public void onGuiClosed() {
scrollPane.onGuiClosed(); scrollPane.onGuiClosed();
@@ -131,7 +138,10 @@ public class ModifierSettingsGui extends GuiScreen {
ModifierSettingsManager.setModifierSettings(mc.player, modifierSettings); ModifierSettingsManager.setModifierSettings(mc.player, modifierSettings);
//Send to server //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();
} }
} }

View File

@@ -5,6 +5,8 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting; 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 net.minecraftforge.fml.client.config.GuiCheckBox;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
@@ -20,6 +22,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@SuppressWarnings("Duplicates")
@OnlyIn(Dist.CLIENT)
public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png"); 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); id = super.initGui(id, buttonList);
int y = top - 2; 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); buttonList.add(buttonRadialMirrorEnabled);
y = top + 18; y = top + 18;
@@ -76,21 +86,63 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
TextFormatting.GRAY + "Upgradeable in survival with reach upgrades.")); TextFormatting.GRAY + "Upgradeable in survival with reach upgrades."));
radialMirrorNumberFieldList.add(textRadialMirrorRadius); radialMirrorNumberFieldList.add(textRadialMirrorRadius);
y = top + 72; 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"); buttonCurrentPosition.setTooltip("Set radial mirror position to current player position");
radialMirrorIconButtonList.add(buttonCurrentPosition); 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")); buttonToggleOdd.setTooltip(Arrays.asList("Set radial mirror position to middle of block", "for odd numbered builds"));
radialMirrorIconButtonList.add(buttonToggleOdd); 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"); buttonDrawLines.setTooltip("Show lines");
radialMirrorIconButtonList.add(buttonDrawLines); 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"); buttonDrawPlanes.setTooltip("Show area");
radialMirrorIconButtonList.add(buttonDrawPlanes); radialMirrorIconButtonList.add(buttonDrawPlanes);
@@ -132,38 +184,36 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
return id; return id;
} }
@Override
public void updateScreen() { public void updateScreen() {
super.updateScreen();
radialMirrorNumberFieldList.forEach(GuiNumberField::update); radialMirrorNumberFieldList.forEach(GuiNumberField::update);
} }
@Override @Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks) { boolean isSelected, float partialTicks) {
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partialTicks);
int yy = y; int yy = y;
int offset = 8; int offset = 8;
buttonRadialMirrorEnabled.drawButton(this.mc, mouseX, mouseY, partialTicks); buttonRadialMirrorEnabled.render(mouseX, mouseY, partialTicks);
if (buttonRadialMirrorEnabled.isChecked()) { if (buttonRadialMirrorEnabled.isChecked()) {
buttonRadialMirrorEnabled.y = yy; 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; yy = y + 18;
fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF, true); fontRenderer.drawString("Position", left + offset, yy + 5, 0xFFFFFF);
fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF, true); fontRenderer.drawString("X", left + 40 + offset, yy + 5, 0xFFFFFF);
textRadialMirrorPosX.y = yy; 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; 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; textRadialMirrorPosZ.y = yy;
yy = y + 50; yy = y + 50;
fontRenderer.drawString("Slices", left + offset, yy + 2, 0xFFFFFF, true); fontRenderer.drawString("Slices", left + offset, yy + 2, 0xFFFFFF);
textRadialMirrorSlices.y = yy - 3; 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; textRadialMirrorRadius.y = yy - 3;
yy = y + 72; yy = y + 72;
@@ -175,13 +225,13 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry {
yy = y + 76; yy = y + 76;
buttonRadialMirrorAlternate.y = yy; buttonRadialMirrorAlternate.y = yy;
radialMirrorButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); radialMirrorButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks));
radialMirrorIconButtonList.forEach(button -> button.drawButton(this.mc, mouseX, mouseY, partialTicks)); radialMirrorIconButtonList.forEach(button -> button.render(mouseX, mouseY, partialTicks));
radialMirrorNumberFieldList radialMirrorNumberFieldList
.forEach(numberField -> numberField.drawNumberField(this.mc, mouseX, mouseY, partialTicks)); .forEach(numberField -> numberField.drawNumberField(mouseX, mouseY, partialTicks));
} else { } else {
buttonRadialMirrorEnabled.y = yy; 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 @Override
public void updatePosition(int slotIndex, int x, int y, float partialTicks) { public boolean charTyped(char typedChar, int keyCode) {
super.updatePosition(slotIndex, x, y, partialTicks); super.charTyped(typedChar, keyCode);
}
@Override
public void keyTyped(char typedChar, int keyCode) throws IOException {
super.keyTyped(typedChar, keyCode);
for (GuiNumberField numberField : radialMirrorNumberFieldList) { for (GuiNumberField numberField : radialMirrorNumberFieldList) {
numberField.keyTyped(typedChar, keyCode); numberField.charTyped(typedChar, keyCode);
} }
return true;
} }
@Override @Override
public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { 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)); radialMirrorNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent));
boolean insideRadialMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; boolean insideRadialMirrorEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12;
if (insideRadialMirrorEnabledLabel) { if (insideRadialMirrorEnabledLabel) {
buttonRadialMirrorEnabled.setIsChecked(!buttonRadialMirrorEnabled.isChecked());
buttonRadialMirrorEnabled.playPressSound(this.mc.getSoundHandler()); buttonRadialMirrorEnabled.playPressSound(this.mc.getSoundHandler());
actionPerformed(buttonRadialMirrorEnabled); buttonRadialMirrorEnabled.onClick(mouseX, mouseY);
} }
return true; 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() { public RadialMirror.RadialMirrorSettings getRadialMirrorSettings() {
boolean radialMirrorEnabled = buttonRadialMirrorEnabled.isChecked(); boolean radialMirrorEnabled = buttonRadialMirrorEnabled.isChecked();

View File

@@ -4,10 +4,14 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen; 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.io.IOException;
import java.util.List; import java.util.List;
@OnlyIn(Dist.CLIENT)
public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScrollEntry { public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScrollEntry {
public GuiScrollPane scrollPane; public GuiScrollPane scrollPane;
@@ -36,18 +40,10 @@ public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScroll
@Override @Override
public void updateScreen() { 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 @Override
public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) { public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) {
} }
@Override @Override
@@ -56,8 +52,8 @@ public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScroll
} }
@Override @Override
public void keyTyped(char eventChar, int eventKey) throws IOException { public boolean charTyped(char eventChar, int eventKey) {
return false;
} }
@Override @Override
@@ -70,14 +66,8 @@ public abstract class GuiCollapsibleScrollEntry implements GuiScrollPane.IScroll
} }
@Override
public void actionPerformed(GuiButton button) {
}
@Override @Override
public void onGuiClosed() { public void onGuiClosed() {
} }
@Override @Override

View File

@@ -4,11 +4,14 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@OnlyIn(Dist.CLIENT)
public class GuiIconButton extends GuiButton { public class GuiIconButton extends GuiButton {
private final ResourceLocation resourceLocation; private final ResourceLocation resourceLocation;
@@ -44,12 +47,12 @@ public class GuiIconButton extends GuiButton {
} }
@Override @Override
public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { public void render(int mouseX, int mouseY, float partialTicks) {
super.drawButton(mc, mouseX, mouseY, partialTicks); super.render(mouseX, mouseY, partialTicks);
if (this.visible) if (this.visible)
{ {
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; 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 currentIconX = this.iconX;
int currentIconY = this.iconY; int currentIconY = this.iconY;

View File

@@ -3,13 +3,17 @@ package nl.requios.effortlessbuilding.gui.elements;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*; import net.minecraft.client.gui.*;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import java.io.IOException; import java.io.IOException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@OnlyIn(Dist.CLIENT)
public class GuiNumberField extends Gui { public class GuiNumberField extends Gui {
public int x, y, width, height; public int x, y, width, height;
@@ -28,21 +32,42 @@ public class GuiNumberField extends Gui {
this.height = height; this.height = height;
textField = new GuiTextField(id1, fontRenderer, x + buttonWidth + 1, y + 1, width - 2 * buttonWidth - 2, height - 2); 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, "-"); minusButton = new GuiButton(id2, x, y - 1, buttonWidth, height + 2, "-") {
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);
}
};
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(minusButton);
buttonList.add(plusButton); buttonList.add(plusButton);
} }
public void setNumber(double number) { public void setNumber(double number) {
DecimalFormat format = new DecimalFormat("0.#"); textField.setText(DecimalFormat.getInstance().format(number));
textField.setText(format.format(number));
} }
public double getNumber() { public double getNumber() {
if (textField.getText().isEmpty()) return 0; 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) { public void setTooltip(String tooltip) {
@@ -53,7 +78,7 @@ public class GuiNumberField extends Gui {
this.tooltip = tooltip; 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); boolean result = textField.mouseClicked(mouseX, mouseY, mouseButton);
//Check if clicked inside textfield //Check if clicked inside textfield
@@ -69,14 +94,14 @@ public class GuiNumberField extends Gui {
return result; 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; textField.y = y + 1;
minusButton.y = y - 1; minusButton.y = y - 1;
plusButton.y = y - 1; plusButton.y = y - 1;
textField.drawTextBox(); textField.drawTextField(mouseX, mouseY, partialTicks);
minusButton.drawButton(mc, mouseX, mouseY, partialTicks); minusButton.render(mouseX, mouseY, partialTicks);
plusButton.drawButton(mc, mouseX, mouseY, partialTicks); plusButton.render(mouseX, mouseY, partialTicks);
} }
public void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY) { 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() { public void update() {
textField.updateCursorCounter(); textField.tick();
} }
public void keyTyped(char typedChar, int keyCode) throws IOException { public boolean charTyped(char typedChar, int keyCode) {
if (!textField.isFocused()) return; if (!textField.isFocused()) return false;
// if (Character.isDigit(typedChar) || typedChar == '.' || typedChar == '-' || keyCode == Keyboard.KEY_BACK // 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_DELETE || keyCode == Keyboard.KEY_LEFT || keyCode == Keyboard.KEY_RIGHT
// || keyCode == Keyboard.KEY_UP || keyCode == Keyboard.KEY_DOWN) { // || keyCode == Keyboard.KEY_UP || keyCode == Keyboard.KEY_DOWN) {
textField.textboxKeyTyped(typedChar, keyCode); return textField.charTyped(typedChar, keyCode);
// } // }
} }
//Scroll inside textfield to change number //Scroll inside textfield to change number
//Disabled because entire screen can be scrolled
// public void handleMouseInput(int mouseX, int mouseY) { // public void handleMouseInput(int mouseX, int mouseY) {
// boolean insideTextField = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height; // boolean insideTextField = mouseX >= x + buttonWidth && mouseX < x + width - buttonWidth && mouseY >= y && mouseY < y + height;
// //

View File

@@ -1,30 +1,37 @@
package nl.requios.effortlessbuilding.gui.elements; package nl.requios.effortlessbuilding.gui.elements;
import net.minecraft.client.Minecraft; import net.minecraft.client.MouseHelper;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.*;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiListExtended;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper; 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.common.MinecraftForge;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.common.Mod;
import org.lwjgl.input.Mouse; import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.lwjgl.glfw.GLFW;
import sun.security.ssl.Debug;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@SideOnly(Side.CLIENT) @OnlyIn(Dist.CLIENT)
public class GuiScrollPane extends GuiListExtended { public class GuiScrollPane extends GuiSlot {
public GuiScreen parent; public GuiScreen parent;
public FontRenderer fontRenderer; public FontRenderer fontRenderer;
public List<IScrollEntry> listEntries; private List<IScrollEntry> listEntries;
private float scrollMultiplier = 1f;
private int mouseX;
private int mouseY;
public GuiScrollPane(GuiScreen parent, FontRenderer fontRenderer, int top, int bottom) { public GuiScrollPane(GuiScreen parent, FontRenderer fontRenderer, int top, int bottom) {
super(parent.mc, parent.width, parent.height, top, bottom, 100); super(parent.mc, parent.width, parent.height, top, bottom, 100);
@@ -32,18 +39,27 @@ public class GuiScrollPane extends GuiListExtended {
this.fontRenderer = fontRenderer; this.fontRenderer = fontRenderer;
this.setShowSelectionBox(false); this.setShowSelectionBox(false);
listEntries = new ArrayList<>(); listEntries = new ArrayList<>();
MinecraftForge.EVENT_BUS.register(this);
} }
@Override public IScrollEntry getListEntry(int index) {
public IGuiListEntry getListEntry(int index) {
return listEntries.get(index); return listEntries.get(index);
} }
public void AddListEntry(IScrollEntry listEntry){
listEntries.add(listEntry);
}
@Override @Override
protected int getSize() { protected int getSize() {
return listEntries.size(); return listEntries.size();
} }
@Override
protected boolean isSelected(int slotIndex) {
return false;
}
@Override @Override
protected int getScrollBarX() { protected int getScrollBarX() {
//return width / 2 + 140 + 10; //return width / 2 + 140 + 10;
@@ -80,15 +96,15 @@ public class GuiScrollPane extends GuiListExtended {
//All entries //All entries
this.drawSelectionBox(insideLeft, insideTop, mouseXIn, mouseYIn, partialTicks); this.drawSelectionBox(insideLeft, insideTop, mouseXIn, mouseYIn, partialTicks);
GlStateManager.disableDepth(); GlStateManager.disableDepthTest();
//Dirt overlays on top and bottom //Dirt overlays on top and bottom
// this.overlayBackground(0, this.top, 255, 255); // this.overlayBackground(0, this.top, 255, 255);
// this.overlayBackground(this.bottom, this.height, 255, 255); // this.overlayBackground(this.bottom, this.height, 255, 255);
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE);
GlStateManager.disableAlpha(); GlStateManager.disableAlphaTest();
GlStateManager.shadeModel(7425); GlStateManager.shadeModel(7425);
GlStateManager.disableTexture2D(); GlStateManager.disableTexture2D();
@@ -161,7 +177,7 @@ public class GuiScrollPane extends GuiListExtended {
GlStateManager.enableTexture2D(); GlStateManager.enableTexture2D();
GlStateManager.shadeModel(7424); GlStateManager.shadeModel(7424);
GlStateManager.enableAlpha(); GlStateManager.enableAlphaTest();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
} }
} }
@@ -178,6 +194,17 @@ public class GuiScrollPane extends GuiListExtended {
return height; 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) { public int getContentHeight(int count) {
//Add all count entry heights //Add all count entry heights
int height = this.headerPadding; int height = this.headerPadding;
@@ -188,11 +215,10 @@ public class GuiScrollPane extends GuiListExtended {
return height; return height;
} }
@Override public int getSlotIndexFromScreenCoords(double posX, double posY) {
public int getSlotIndexFromScreenCoords(int posX, int posY) {
int left = this.left + (this.width - this.getListWidth()) / 2; int left = this.left + (this.width - this.getListWidth()) / 2;
int right = 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 //Iterate over every entry until relativeMouseY falls within its height
for (int i = 0; i < listEntries.size(); i++) { for (int i = 0; i < listEntries.size(); i++) {
@@ -206,15 +232,14 @@ public class GuiScrollPane extends GuiListExtended {
} }
@Override @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 selectedSlot = this.getSlotIndexFromScreenCoords(mouseX, mouseY);
int relativeX = getRelativeMouseX(mouseX); double relativeX = getRelativeMouseX(mouseX);
//Always pass through mouseclicked, to be able to unfocus textfields //Always pass through mouseclicked, to be able to unfocus textfields
for (int i = 0; i < this.listEntries.size(); i++) { for (int i = 0; i < this.listEntries.size(); i++) {
int relativeY = getRelativeMouseY(mouseY, i); double relativeY = getRelativeMouseY(mouseY, i);
this.getListEntry(i).mousePressed(selectedSlot, mouseX, mouseY, mouseEvent, relativeX, relativeY); this.getListEntry(i).mousePressed(selectedSlot, (int) mouseX, (int) mouseY, button, (int) relativeX, (int) relativeY);
} }
@@ -239,38 +264,36 @@ public class GuiScrollPane extends GuiListExtended {
} }
@Override @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) for (int i = 0; i < this.getSize(); ++i)
{ {
int relativeX = getRelativeMouseX(mouseX); double relativeX = getRelativeMouseX(mouseX);
int relativeY = getRelativeMouseY(mouseY, i); double relativeY = getRelativeMouseY(mouseY, i);
this.getListEntry(i).mouseReleased(i, x, y, mouseEvent, relativeX, relativeY); 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; return false;
} }
@Override
public void handleMouseInput() { public void handleMouseInput() {
if (this.isMouseYWithinSlotBounds(this.mouseY)) { if (this.isMouseInList(this.mouseX, this.mouseY)) {
if (Mouse.getEventButton() == 0 && Mouse.getEventButtonState() && this.mouseY >= this.top && if (mc.mouseHelper.isLeftDown() && this.mouseY >= this.top &&
this.mouseY <= this.bottom) { this.mouseY <= this.bottom) {
int i = this.left + (this.width - this.getListWidth()) / 2; int i = this.left + (this.width - this.getListWidth()) / 2;
int j = this.left + (this.width + this.getListWidth()) / 2; int j = this.left + (this.width + this.getListWidth()) / 2;
int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY); int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY);
int relativeMouseY = getRelativeMouseY(mouseY, slotIndex); double relativeMouseY = getRelativeMouseY(mouseY, slotIndex);
if (slotIndex > -1) { if (slotIndex > -1) {
this.elementClicked(slotIndex, false, this.mouseX, this.mouseY); this.mouseClicked(slotIndex, 0, this.mouseX, this.mouseY);
this.selectedElement = slotIndex; this.selectedElement = slotIndex;
} else if (this.mouseX >= i && this.mouseX <= j && relativeMouseY < 0) { } else if (this.mouseX >= i && this.mouseX <= j && relativeMouseY < 0) {
this.clickedHeader(this.mouseX - i, this.mouseY - this.top + (int) this.amountScrolled - 4); 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) { if (this.initialClickY == -1) {
boolean flag1 = true; boolean flag1 = true;
@@ -278,14 +301,15 @@ public class GuiScrollPane extends GuiListExtended {
int i2 = this.left + (this.width - this.getListWidth()) / 2; int i2 = this.left + (this.width - this.getListWidth()) / 2;
int j2 = this.left + (this.width + this.getListWidth()) / 2; int j2 = this.left + (this.width + this.getListWidth()) / 2;
int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY); int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY);
int relativeMouseY = getRelativeMouseY(mouseY, slotIndex); double relativeMouseY = getRelativeMouseY(mouseY, slotIndex);
if (slotIndex > -1) { if (slotIndex > -1) {
//TODO 1.13 use flag
boolean flag = slotIndex == this.selectedElement && boolean flag = slotIndex == this.selectedElement &&
Minecraft.getSystemTime() - this.lastClicked < 250L; Util.milliTime() - this.lastClicked < 250L;
this.elementClicked(slotIndex, flag, this.mouseX, this.mouseY); this.mouseClicked(slotIndex, this.mouseX, this.mouseY);
this.selectedElement = slotIndex; this.selectedElement = slotIndex;
this.lastClicked = Minecraft.getSystemTime(); this.lastClicked = Util.milliTime();
} else if (this.mouseX >= i2 && this.mouseX <= j2 && relativeMouseY < 0) { } else if (this.mouseX >= i2 && this.mouseX <= j2 && relativeMouseY < 0) {
this.clickedHeader(this.mouseX - i2, this.clickedHeader(this.mouseX - i2,
this.mouseY - this.top + (int) this.amountScrolled - 4); this.mouseY - this.top + (int) this.amountScrolled - 4);
@@ -327,17 +351,21 @@ public class GuiScrollPane extends GuiListExtended {
this.initialClickY = -1; 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 i1 = this.left + this.width / 2 - this.getListWidth() / 2;
int j1 = 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(); GlStateManager.disableTexture2D();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); 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(); 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; int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2;
return mouseX - j; 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 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 //Content might be centered, adjust relative mouse y accordingly
int contentHeight = getContentHeight(); int contentHeight = getContentHeight();
@@ -419,7 +447,6 @@ public class GuiScrollPane extends GuiListExtended {
for (IScrollEntry entry : this.listEntries) { for (IScrollEntry entry : this.listEntries) {
id = entry.initGui(id, buttonList); id = entry.initGui(id, buttonList);
} }
registerScrollButtons(id++, id++);
return id; return id;
} }
@@ -433,14 +460,11 @@ public class GuiScrollPane extends GuiListExtended {
entry.drawTooltip(guiScreen, mouseX, mouseY); 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) for (IScrollEntry entry : this.listEntries)
entry.keyTyped(eventChar, eventKey); entry.charTyped(eventChar, eventKey);
} return false;
public void actionPerformed(GuiButton button) {
for (IScrollEntry entry : this.listEntries)
entry.actionPerformed(button);
} }
public void onGuiClosed() { public void onGuiClosed() {
@@ -448,19 +472,32 @@ public class GuiScrollPane extends GuiListExtended {
entry.onGuiClosed(); entry.onGuiClosed();
} }
public interface IScrollEntry extends GuiListExtended.IGuiListEntry { public interface IScrollEntry {
int initGui(int id, List<GuiButton> buttonList); int initGui(int id, List<GuiButton> buttonList);
void updateScreen(); void updateScreen();
void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY); void drawTooltip(GuiScreen guiScreen, int mouseX, int mouseY);
void keyTyped(char eventChar, int eventKey) throws IOException; boolean charTyped(char eventChar, int eventKey);
void actionPerformed(GuiButton button);
void onGuiClosed(); void onGuiClosed();
int getHeight(); 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);
} }
} }

View File

@@ -1,15 +1,14 @@
package nl.requios.effortlessbuilding.helper; package nl.requios.effortlessbuilding.helper;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraftforge.common.crafting.IConditionFactory; import net.minecraftforge.common.crafting.IConditionSerializer;
import net.minecraftforge.common.crafting.JsonContext;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
public class ReachConditionFactory implements IConditionFactory { public class ReachConditionFactory implements IConditionSerializer {
@Override @Override
public BooleanSupplier parse(JsonContext context, JsonObject json) { public BooleanSupplier parse(JsonObject json) {
return () -> BuildConfig.reach.enableReachUpgrades; return () -> BuildConfig.reach.enableReachUpgrades.get();
} }
} }

View File

@@ -7,19 +7,19 @@ import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
public class ReachHelper { public class ReachHelper {
public static int getMaxReach(EntityPlayer player) { 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 //Check buildsettings for reachUpgrade
int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade(); int reachUpgrade = ModifierSettingsManager.getModifierSettings(player).getReachUpgrade();
switch (reachUpgrade) { switch (reachUpgrade) {
case 0: return BuildConfig.reach.maxReachLevel0; case 0: return BuildConfig.reach.maxReachLevel0.get();
case 1: return BuildConfig.reach.maxReachLevel1; case 1: return BuildConfig.reach.maxReachLevel1.get();
case 2: return BuildConfig.reach.maxReachLevel2; case 2: return BuildConfig.reach.maxReachLevel2.get();
case 3: return BuildConfig.reach.maxReachLevel3; case 3: return BuildConfig.reach.maxReachLevel3.get();
} }
return BuildConfig.reach.maxReachLevel0; return BuildConfig.reach.maxReachLevel0.get();
} }
public static int getPlacementReach(EntityPlayer player) { public static int getPlacementReach(EntityPlayer player) {
@@ -45,6 +45,6 @@ public class ReachHelper {
} }
public static boolean canBreakFar(EntityPlayer player) { public static boolean canBreakFar(EntityPlayer player) {
return player.isCreative() || BuildConfig.survivalBalancers.breakFar; return player.isCreative() || BuildConfig.survivalBalancers.breakFar.get();
} }
} }

View File

@@ -1,27 +1,28 @@
package nl.requios.effortlessbuilding.helper; package nl.requios.effortlessbuilding.helper;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.BlockSlab; import net.minecraft.block.BlockSlab;
import net.minecraft.block.SoundType; import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material; 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.block.state.IBlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemSlab;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; 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.minecraft.world.World;
import net.minecraftforge.common.ToolType;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
@@ -41,7 +42,7 @@ public class SurvivalHelper {
if (blockState.getBlock().isAir(blockState, world, pos) || itemstack.isEmpty()) { if (blockState.getBlock().isAir(blockState, world, pos) || itemstack.isEmpty()) {
dropBlock(world, player, pos); dropBlock(world, player, pos);
world.setBlockToAir(pos); world.removeBlock(pos);
return true; return true;
} }
@@ -60,8 +61,21 @@ public class SurvivalHelper {
//Drop existing block //Drop existing block
dropBlock(world, player, pos); 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); //TryPlace sets block with offset, so we only do world.setBlockState now
if (!placed) return false; //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); IBlockState afterState = world.getBlockState(pos);
@@ -119,7 +133,7 @@ public class SurvivalHelper {
//Damage tool //Damage tool
player.getHeldItemMainhand().onBlockDestroyed(world, world.getBlockState(pos), pos, player); player.getHeldItemMainhand().onBlockDestroyed(world, world.getBlockState(pos), pos, player);
world.setBlockToAir(pos); world.removeBlock(pos);
return true; return true;
} }
return false; return false;
@@ -198,9 +212,8 @@ public class SurvivalHelper {
if (player.isCreative()) return true; if (player.isCreative()) return true;
IBlockState state = world.getBlockState(pos); 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 -1: return state.getMaterial().isToolNotRequired();
case 0: return state.getBlock().getHarvestLevel(state) <= 0; case 0: return state.getBlock().getHarvestLevel(state) <= 0;
case 1: return state.getBlock().getHarvestLevel(state) <= 1; case 1: return state.getBlock().getHarvestLevel(state) <= 1;
@@ -214,7 +227,9 @@ public class SurvivalHelper {
//From EntityPlayer#canPlayerEdit //From EntityPlayer#canPlayerEdit
private static boolean canPlayerEdit(EntityPlayer player, World world, BlockPos pos, ItemStack stack) 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 //True in creative and survival mode
return true; return true;
@@ -222,8 +237,9 @@ public class SurvivalHelper {
else else
{ {
//Adventure mode //Adventure mode
Block block = world.getBlockState(pos).getBlock(); BlockWorldState blockworldstate = new BlockWorldState(world, pos, false);
return stack.canPlaceOn(block) || stack.canEditBlocks(); 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) private static boolean mayPlace(World world, Block blockIn, IBlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer)
{ {
IBlockState iblockstate1 = world.getBlockState(pos); 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; return false;
} }
@@ -259,7 +275,8 @@ public class SurvivalHelper {
return true; 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) //Can break using held tool? (or in creative)
public static boolean canBreak(World world, EntityPlayer player, BlockPos pos) { public static boolean canBreak(World world, EntityPlayer player, BlockPos pos) {
IBlockState blockState = world.getBlockState(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; if (player.isCreative()) return true;
@@ -275,13 +292,12 @@ public class SurvivalHelper {
} }
//From ForgeHooks#canHarvestBlock //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); IBlockState state = world.getBlockState(pos);
state = state.getBlock().getActualState(state, world, pos);
//Dont break bedrock //Dont break bedrock
if (state.getBlockHardness((World) world, pos) < 0) { if (state.getBlockHardness(world, pos) < 0) {
return false; return false;
} }
@@ -291,13 +307,13 @@ public class SurvivalHelper {
} }
ItemStack stack = player.getHeldItemMainhand(); ItemStack stack = player.getHeldItemMainhand();
String tool = block.getHarvestTool(state); ToolType tool = block.getHarvestTool(state);
if (stack.isEmpty() || tool == null) if (stack.isEmpty() || tool == null)
{ {
return player.canHarvestBlock(state); 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); int toolLevel = stack.getItem().getHarvestLevel(stack, tool, player, state);
if (toolLevel < 0) if (toolLevel < 0)
@@ -315,20 +331,21 @@ public class SurvivalHelper {
if (CompatHelper.isItemBlockProxy(itemstack)) if (CompatHelper.isItemBlockProxy(itemstack))
itemstack = CompatHelper.getItemBlockFromStack(itemstack); itemstack = CompatHelper.getItemBlockFromStack(itemstack);
if (itemstack.isEmpty() || !(itemstack.getItem() instanceof ItemSlab)) return false; if (itemstack.isEmpty() || !(itemstack.getItem() instanceof ItemBlock) || !(((ItemBlock) itemstack.getItem()).getBlock() instanceof BlockSlab)) return false;
BlockSlab heldSlab = (BlockSlab) ((ItemSlab) itemstack.getItem()).getBlock(); BlockSlab heldSlab = (BlockSlab) ((ItemBlock) itemstack.getItem()).getBlock();
if (placedBlockState.getBlock() == heldSlab) { if (placedBlockState.getBlock() == heldSlab) {
IProperty<?> variantProperty = heldSlab.getVariantProperty(); //TODO 1.13
Comparable<?> placedVariant = placedBlockState.getValue(variantProperty); // IProperty<?> variantProperty = heldSlab.getVariantProperty();
BlockSlab.EnumBlockHalf placedHalf = placedBlockState.getValue(BlockSlab.HALF); // Comparable<?> placedVariant = placedBlockState.getValue(variantProperty);
// BlockSlab.EnumBlockHalf placedHalf = placedBlockState.getValue(BlockSlab.HALF);
Comparable<?> heldVariant = heldSlab.getTypeForItem(itemstack); //
// Comparable<?> heldVariant = heldSlab.getTypeForItem(itemstack);
if ((facing == EnumFacing.UP && placedHalf == BlockSlab.EnumBlockHalf.BOTTOM || facing == EnumFacing.DOWN && placedHalf == BlockSlab.EnumBlockHalf.TOP) && placedVariant == heldVariant) //
{ // if ((facing == EnumFacing.UP && placedHalf == BlockSlab.EnumBlockHalf.BOTTOM || facing == EnumFacing.DOWN && placedHalf == BlockSlab.EnumBlockHalf.TOP) && placedVariant == heldVariant)
return true; // {
} // return true;
// }
} }
return false; return false;
} }

View File

@@ -3,10 +3,9 @@ package nl.requios.effortlessbuilding.item;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack; import net.minecraft.item.*;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumActionResult;
@@ -14,9 +13,12 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; 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.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import nl.requios.effortlessbuilding.EffortlessBuilding; 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.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; 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 nl.requios.effortlessbuilding.helper.SurvivalHelper;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -39,20 +43,25 @@ public class ItemRandomizerBag extends Item {
private static Random rand = new Random(currentSeed); private static Random rand = new Random(currentSeed);
public ItemRandomizerBag() { public ItemRandomizerBag() {
this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag"); super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1));
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1; this.setRegistryName(EffortlessBuilding.MODID, "randomizer_bag");
this.setCreativeTab(CreativeTabs.TOOLS);
} }
@Override @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; if (world.isRemote) return EnumActionResult.SUCCESS;
//Open inventory //Open inventory
player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0); NetworkHooks.openGui((EntityPlayerMP) player, new RandomizerBagGuiHandler());
} else { } else {
if (world.isRemote) return EnumActionResult.SUCCESS; if (world.isRemote) return EnumActionResult.SUCCESS;
@@ -65,7 +74,8 @@ public class ItemRandomizerBag extends Item {
//Use item //Use item
//Get bag inventory //Get bag inventory
ItemStack bag = player.getHeldItem(hand); //TODO offhand support
ItemStack bag = player.getHeldItem(EnumHand.MAIN_HAND);
IItemHandler bagInventory = getBagInventory(bag); IItemHandler bagInventory = getBagInventory(bag);
if (bagInventory == null) if (bagInventory == null)
return EnumActionResult.FAIL; return EnumActionResult.FAIL;
@@ -77,14 +87,15 @@ public class ItemRandomizerBag extends Item {
//bag.setItemDamage(toPlace.getMetadata()); //bag.setItemDamage(toPlace.getMetadata());
//toPlace.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ); //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); pos = pos.offset(facing);
} }
IBlockState blockState = Block.getBlockFromItem(toPlace.getItem()).getStateForPlacement(world, pos, facing, BlockItemUseContext blockItemUseContext = new BlockItemUseContext(world, player, item, pos, facing, ctx.getHitX(), ctx.getHitY(), ctx.getHitZ());
hitX, hitY, hitZ, toPlace.getMetadata(), player, hand); 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 //Synergy
//Works without calling //Works without calling
@@ -103,7 +114,7 @@ public class ItemRandomizerBag extends Item {
if (player.isSneaking()) { if (player.isSneaking()) {
if (world.isRemote) return new ActionResult<>(EnumActionResult.SUCCESS, bag); if (world.isRemote) return new ActionResult<>(EnumActionResult.SUCCESS, bag);
//Open inventory //Open inventory
player.openGui(EffortlessBuilding.instance, EffortlessBuilding.RANDOMIZER_BAG_GUI, world, 0, 0, 0); NetworkHooks.openGui((EntityPlayerMP) player, new RandomizerBagGuiHandler());
} else { } else {
//Use item //Use item
//Get bag inventory //Get bag inventory
@@ -126,8 +137,7 @@ public class ItemRandomizerBag extends Item {
* @return * @return
*/ */
public static IItemHandler getBagInventory(ItemStack bag) { public static IItemHandler getBagInventory(ItemStack bag) {
if (!bag.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)) return null; return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null);
return bag.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null);
} }
/** /**
@@ -176,7 +186,7 @@ public class ItemRandomizerBag extends Item {
} }
@Override @Override
public int getMaxItemUseDuration(ItemStack stack) { public int getUseDuration(ItemStack p_77626_1_) {
return 1; return 1;
} }
@@ -187,14 +197,14 @@ public class ItemRandomizerBag extends Item {
} }
@Override @Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) { public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block"); tooltip.add(new TextComponentString(TextFormatting.BLUE + "Rightclick" + TextFormatting.GRAY + " to place a random block"));
tooltip.add(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory"); tooltip.add(new TextComponentString(TextFormatting.BLUE + "Sneak + rightclick" + TextFormatting.GRAY + " to open inventory"));
} }
@Override @Override
public String getTranslationKey() { public String getTranslationKey() {
return super.getTranslationKey(); return this.getRegistryName().toString();
} }
public static void resetRandomness() { public static void resetRandomness() {

View File

@@ -1,12 +1,13 @@
package nl.requios.effortlessbuilding.item; package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag; 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.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.*; 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.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
@@ -20,11 +21,8 @@ import java.util.List;
public class ItemReachUpgrade1 extends Item { public class ItemReachUpgrade1 extends Item {
public ItemReachUpgrade1() { public ItemReachUpgrade1() {
super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1));
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade1"); this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade1");
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
} }
@Override @Override
@@ -56,12 +54,12 @@ public class ItemReachUpgrade1 extends Item {
} }
@Override @Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) { public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1); tooltip.add(new TextComponentString(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1.get()));
} }
@Override @Override
public String getTranslationKey() { public String getTranslationKey() {
return super.getTranslationKey(); return this.getRegistryName().toString();
} }
} }

View File

@@ -1,11 +1,13 @@
package nl.requios.effortlessbuilding.item; package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.*; 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.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
@@ -19,11 +21,8 @@ import java.util.List;
public class ItemReachUpgrade2 extends Item { public class ItemReachUpgrade2 extends Item {
public ItemReachUpgrade2() { public ItemReachUpgrade2() {
super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1));
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade2"); this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade2");
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
} }
@Override @Override
@@ -59,13 +58,13 @@ public class ItemReachUpgrade2 extends Item {
} }
@Override @Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) { public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel2); tooltip.add(new TextComponentString(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel2.get()));
tooltip.add(TextFormatting.GRAY + "Previous upgrades need to be consumed first"); tooltip.add(new TextComponentString(TextFormatting.GRAY + "Previous upgrades need to be consumed first"));
} }
@Override @Override
public String getTranslationKey() { public String getTranslationKey() {
return super.getTranslationKey(); return this.getRegistryName().toString();
} }
} }

View File

@@ -1,11 +1,13 @@
package nl.requios.effortlessbuilding.item; package nl.requios.effortlessbuilding.item;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.*; 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.util.text.TextFormatting;
import net.minecraft.world.World; import net.minecraft.world.World;
import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.BuildConfig;
@@ -19,11 +21,8 @@ import java.util.List;
public class ItemReachUpgrade3 extends Item { public class ItemReachUpgrade3 extends Item {
public ItemReachUpgrade3() { public ItemReachUpgrade3() {
super(new Item.Properties().group(ItemGroup.TOOLS).maxStackSize(1));
this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade3"); this.setRegistryName(EffortlessBuilding.MODID, "reach_upgrade3");
this.setTranslationKey(this.getRegistryName().toString());
this.maxStackSize = 1;
this.setCreativeTab(CreativeTabs.TOOLS);
} }
@Override @Override
@@ -62,13 +61,13 @@ public class ItemReachUpgrade3 extends Item {
} }
@Override @Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) { public void addInformation(ItemStack stack, @Nullable World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel3); tooltip.add(new TextComponentString(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel3.get()));
tooltip.add(TextFormatting.GRAY + "Previous upgrades need to be consumed first"); tooltip.add(new TextComponentString(TextFormatting.GRAY + "Previous upgrades need to be consumed first"));
} }
@Override @Override
public String getTranslationKey() { public String getTranslationKey() {
return super.getTranslationKey(); return this.getRegistryName().toString();
} }
} }

View File

@@ -1,26 +1,24 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.BlockSet; import nl.requios.effortlessbuilding.buildmodifier.BlockSet;
import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; import nl.requios.effortlessbuilding.buildmodifier.UndoRedo;
import nl.requios.effortlessbuilding.proxy.ClientProxy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.function.Supplier;
/*** /***
* Sends a message to the client asking to add a block to the undo stack. * 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 BlockPos coordinate;
private IBlockState previousBlockState; private IBlockState previousBlockState;
private IBlockState newBlockState; private IBlockState newBlockState;
@@ -49,46 +47,42 @@ public class AddUndoMessage implements IMessage {
return newBlockState; return newBlockState;
} }
@Override public static void encode(AddUndoMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) { buf.writeInt(message.coordinate.getX());
buf.writeInt(this.coordinate.getX()); buf.writeInt(message.coordinate.getY());
buf.writeInt(this.coordinate.getY()); buf.writeInt(message.coordinate.getZ());
buf.writeInt(this.coordinate.getZ()); buf.writeInt(Block.getStateId(message.previousBlockState));
buf.writeInt(Block.getStateId(this.previousBlockState)); buf.writeInt(Block.getStateId(message.newBlockState));
buf.writeInt(Block.getStateId(this.newBlockState));
} }
@Override public static AddUndoMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) { BlockPos coordinate = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
coordinate = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); IBlockState previousBlockState = Block.getStateById(buf.readInt());
previousBlockState = Block.getStateById(buf.readInt()); IBlockState newBlockState = Block.getStateById(buf.readInt());
newBlockState = Block.getStateById(buf.readInt()); return new AddUndoMessage(coordinate, previousBlockState, newBlockState);
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<AddUndoMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(AddUndoMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
EffortlessBuilding.log("AddUndoMessage");
@Override if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
public IMessage onMessage(AddUndoMessage message, MessageContext ctx) {
//EffortlessBuilding.log("message received on " + ctx.side + " side");
if (ctx.side == Side.CLIENT){
//Received clientside //Received clientside
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> {
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
//Add to undo stack clientside //Add to undo stack clientside
UndoRedo.addUndo(player, new BlockSet( UndoRedo.addUndo(ctx.get().getSender(), new BlockSet(
new ArrayList<BlockPos>() {{add(message.getCoordinate());}}, new ArrayList<BlockPos>() {{add(message.getCoordinate());}},
new ArrayList<IBlockState>() {{add(message.getPreviousBlockState());}}, new ArrayList<IBlockState>() {{add(message.getPreviousBlockState());}},
new ArrayList<IBlockState>() {{add(message.getNewBlockState());}}, new ArrayList<IBlockState>() {{add(message.getNewBlockState());}},
new Vec3d(0,0,0), new Vec3d(0,0,0),
message.getCoordinate(), message.getCoordinate())); message.getCoordinate(), message.getCoordinate()));
});
} }
return null; });
ctx.get().setPacketHandled(true);
} }
} }
} }

View File

@@ -1,22 +1,21 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; 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 * 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 boolean blockHit;
private BlockPos blockPos; private BlockPos blockPos;
@@ -31,12 +30,19 @@ public class BlockBrokenMessage implements IMessage {
} }
public BlockBrokenMessage(RayTraceResult result) { public BlockBrokenMessage(RayTraceResult result) {
this.blockHit = result.typeOfHit == RayTraceResult.Type.BLOCK; this.blockHit = result.type == RayTraceResult.Type.BLOCK;
this.blockPos = result.getBlockPos(); this.blockPos = result.getBlockPos();
this.sideHit = result.sideHit; this.sideHit = result.sideHit;
this.hitVec = result.hitVec; 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() { public boolean isBlockHit() {
return blockHit; return blockHit;
} }
@@ -53,43 +59,37 @@ public class BlockBrokenMessage implements IMessage {
return hitVec; return hitVec;
} }
@Override public static void encode(BlockBrokenMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) { buf.writeBoolean(message.blockHit);
buf.writeBoolean(blockHit); buf.writeInt(message.blockPos.getX());
buf.writeInt(blockPos.getX()); buf.writeInt(message.blockPos.getY());
buf.writeInt(blockPos.getY()); buf.writeInt(message.blockPos.getZ());
buf.writeInt(blockPos.getZ()); buf.writeInt(message.sideHit.getIndex());
buf.writeInt(sideHit.getIndex()); buf.writeDouble(message.hitVec.x);
buf.writeDouble(hitVec.x); buf.writeDouble(message.hitVec.y);
buf.writeDouble(hitVec.y); buf.writeDouble(message.hitVec.z);
buf.writeDouble(hitVec.z);
} }
@Override public static BlockBrokenMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) { boolean blockHit = buf.readBoolean();
blockHit = buf.readBoolean(); BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); EnumFacing sideHit = EnumFacing.byIndex(buf.readInt());
sideHit = EnumFacing.byIndex(buf.readInt()); Vec3d hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); return new BlockBrokenMessage(blockHit, blockPos, sideHit, hitVec);
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<BlockBrokenMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(BlockBrokenMessage message, Supplier<NetworkEvent.Context> ctx)
{
@Override EffortlessBuilding.log("BlockBrokenMessage");
public IMessage onMessage(BlockBrokenMessage message, MessageContext ctx) { ctx.get().enqueueWork(() -> {
//EffortlessBuilding.log("message received on " + ctx.side + " side"); if (ctx.get().getDirection().getReceptionSide() == LogicalSide.SERVER) {
if (ctx.side == Side.SERVER) {
//Received serverside //Received serverside
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { BuildModes.onBlockBrokenMessage(ctx.get().getSender(), message);
BuildModes.onBlockBrokenMessage(ctx.getServerHandler().player, message); }
}); });
} ctx.get().setPacketHandled(true);
// No response packet
return null;
} }
} }
} }

View File

@@ -1,25 +1,23 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; 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 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. * 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. * Received clientside: server has placed blocks and its letting the client know.
*/ */
public class BlockPlacedMessage implements IMessage { public class BlockPlacedMessage {
private boolean blockHit; private boolean blockHit;
private BlockPos blockPos; private BlockPos blockPos;
@@ -36,13 +34,21 @@ public class BlockPlacedMessage implements IMessage {
} }
public BlockPlacedMessage(RayTraceResult result, boolean placeStartPos) { 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.blockPos = result.getBlockPos();
this.sideHit = result.sideHit; this.sideHit = result.sideHit;
this.hitVec = result.hitVec; this.hitVec = result.hitVec;
this.placeStartPos = placeStartPos; 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() { public boolean isBlockHit() {
return blockHit; return blockHit;
} }
@@ -63,51 +69,44 @@ public class BlockPlacedMessage implements IMessage {
return placeStartPos; return placeStartPos;
} }
@Override public static void encode(BlockPlacedMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) { buf.writeBoolean(message.blockHit);
buf.writeBoolean(blockHit); buf.writeInt(message.blockPos.getX());
buf.writeInt(blockPos.getX()); buf.writeInt(message.blockPos.getY());
buf.writeInt(blockPos.getY()); buf.writeInt(message.blockPos.getZ());
buf.writeInt(blockPos.getZ()); buf.writeInt(message.sideHit.getIndex());
buf.writeInt(sideHit.getIndex()); buf.writeDouble(message.hitVec.x);
buf.writeDouble(hitVec.x); buf.writeDouble(message.hitVec.y);
buf.writeDouble(hitVec.y); buf.writeDouble(message.hitVec.z);
buf.writeDouble(hitVec.z); buf.writeBoolean(message.placeStartPos);
buf.writeBoolean(placeStartPos);
} }
@Override public static BlockPlacedMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) { boolean blockHit = buf.readBoolean();
blockHit = buf.readBoolean(); BlockPos blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); EnumFacing sideHit = EnumFacing.byIndex(buf.readInt());
sideHit = EnumFacing.byIndex(buf.readInt()); Vec3d hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); boolean placeStartPos = buf.readBoolean();
placeStartPos = buf.readBoolean(); return new BlockPlacedMessage(blockHit, blockPos, sideHit, hitVec, placeStartPos);
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<BlockPlacedMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(BlockPlacedMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
EffortlessBuilding.log("BlockPlacedMessage");
@Override if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
public IMessage onMessage(BlockPlacedMessage message, MessageContext ctx) {
//EffortlessBuilding.log("message received on " + ctx.side + " side");
if (ctx.side == Side.CLIENT){
//Received clientside //Received clientside
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> {
//Nod RenderHandler to do the dissolve shader effect //Nod RenderHandler to do the dissolve shader effect
BlockPreviewRenderer.onBlocksPlaced(); BlockPreviewRenderer.onBlocksPlaced();
});
return null;
} else { } else {
//Received serverside //Received serverside
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { BuildModes.onBlockPlacedMessage(ctx.get().getSender(), message);
BuildModes.onBlockPlacedMessage(ctx.getServerHandler().player, message);
});
// No response packet
return null;
} }
});
ctx.get().setPacketHandled(true);
} }
} }
} }

View File

@@ -1,45 +1,37 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.IThreadListener; import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; 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 * Sends a message to the server indicating that a buildmode needs to be canceled for a player
*/ */
public class CancelModeMessage implements IMessage { public class CancelModeMessage {
@Override
public void toBytes(ByteBuf buf) {
public static void encode(CancelModeMessage message, PacketBuffer buf) {
} }
@Override public static CancelModeMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) { return new CancelModeMessage();
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<CancelModeMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(CancelModeMessage message, Supplier<NetworkEvent.Context> 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); EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
BuildModes.initializeMode(player); BuildModes.initializeMode(player);
}); });
// No response packet ctx.get().setPacketHandled(true);
return null;
} }
} }
} }

View File

@@ -1,57 +1,46 @@
package nl.requios.effortlessbuilding.network; 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.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.Vec3d; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.BlockSet;
import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; 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. * Sends a message to the client asking to clear the undo and redo stacks.
*/ */
public class ClearUndoMessage implements IMessage { public class ClearUndoMessage {
public ClearUndoMessage() { public ClearUndoMessage() {
} }
@Override public static void encode(ClearUndoMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) {
} }
@Override public static ClearUndoMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) { return new ClearUndoMessage();
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<ClearUndoMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(ClearUndoMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
EffortlessBuilding.log("ClearUndoMessage");
@Override if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
public IMessage onMessage(ClearUndoMessage message, MessageContext ctx) {
//EffortlessBuilding.log("message received on " + ctx.side + " side");
if (ctx.side == Side.CLIENT){
//Received clientside //Received clientside
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> {
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
//Add to undo stack clientside //Add to undo stack clientside
UndoRedo.clear(player); UndoRedo.clear(player);
});
} }
return null; });
ctx.get().setPacketHandled(true);
} }
} }
} }

View File

@@ -1,22 +1,17 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.IThreadListener; import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; 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 * Shares mode settings (see ModeSettingsManager) between server and client
*/ */
public class ModeActionMessage implements IMessage { public class ModeActionMessage {
private ModeOptions.ActionEnum action; private ModeOptions.ActionEnum action;
@@ -27,36 +22,27 @@ public class ModeActionMessage implements IMessage {
this.action = action; this.action = action;
} }
@Override public static void encode(ModeActionMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) { buf.writeInt(message.action.ordinal());
buf.writeInt(action.ordinal());
} }
@Override public static ModeActionMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) { ModeOptions.ActionEnum action = ModeOptions.ActionEnum.values()[buf.readInt()];
action = ModeOptions.ActionEnum.values()[buf.readInt()]; return new ModeActionMessage(action);
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<ModeActionMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(ModeActionMessage message, Supplier<NetworkEvent.Context> 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); EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
ModeOptions.performAction(player, action); ModeOptions.performAction(player, message.action);
}); });
// No response packet ctx.get().setPacketHandled(true);
return null;
} }
} }
} }

View File

@@ -2,20 +2,20 @@ package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.IThreadListener; import net.minecraft.util.IThreadListener;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; 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 * Shares mode settings (see ModeSettingsManager) between server and client
*/ */
public class ModeSettingsMessage implements IMessage { public class ModeSettingsMessage {
private ModeSettings modeSettings; private ModeSettings modeSettings;
@@ -26,41 +26,31 @@ public class ModeSettingsMessage implements IMessage {
this.modeSettings = modeSettings; this.modeSettings = modeSettings;
} }
@Override public static void encode(ModeSettingsMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) { buf.writeInt(message.modeSettings.getBuildMode().ordinal());
buf.writeInt(modeSettings.getBuildMode().ordinal());
} }
@Override public static ModeSettingsMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) {
BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.values()[buf.readInt()]; BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.values()[buf.readInt()];
modeSettings = new ModeSettings(buildMode); return new ModeSettingsMessage(new ModeSettings(buildMode));
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<ModeSettingsMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(ModeSettingsMessage message, Supplier<NetworkEvent.Context> 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); EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
// Sanitize // Sanitize
ModeSettingsManager.sanitize(modeSettings, player); ModeSettingsManager.sanitize(message.modeSettings, player);
ModeSettingsManager.setModeSettings(player, modeSettings); ModeSettingsManager.setModeSettings(player, message.modeSettings);
}); });
// No response packet ctx.get().setPacketHandled(true);
return null;
} }
} }
} }

View File

@@ -1,25 +1,24 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer; 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.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.Array; import nl.requios.effortlessbuilding.buildmodifier.Array;
import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.Mirror;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; 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 * Shares modifier settings (see ModifierSettingsManager) between server and client
*/ */
public class ModifierSettingsMessage implements IMessage { public class ModifierSettingsMessage {
private ModifierSettings modifierSettings; private ModifierSettings modifierSettings;
@@ -30,10 +29,9 @@ public class ModifierSettingsMessage implements IMessage {
this.modifierSettings = modifierSettings; this.modifierSettings = modifierSettings;
} }
@Override public static void encode(ModifierSettingsMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) {
//MIRROR //MIRROR
Mirror.MirrorSettings m = modifierSettings.getMirrorSettings(); Mirror.MirrorSettings m = message.modifierSettings.getMirrorSettings();
buf.writeBoolean(m != null); buf.writeBoolean(m != null);
if (m != null) { if (m != null) {
buf.writeBoolean(m.enabled); buf.writeBoolean(m.enabled);
@@ -49,7 +47,7 @@ public class ModifierSettingsMessage implements IMessage {
} }
//ARRAY //ARRAY
Array.ArraySettings a = modifierSettings.getArraySettings(); Array.ArraySettings a = message.modifierSettings.getArraySettings();
buf.writeBoolean(a != null); buf.writeBoolean(a != null);
if (a != null) { if (a != null) {
buf.writeBoolean(a.enabled); buf.writeBoolean(a.enabled);
@@ -59,12 +57,12 @@ public class ModifierSettingsMessage implements IMessage {
buf.writeInt(a.count); buf.writeInt(a.count);
} }
buf.writeBoolean(modifierSettings.doQuickReplace()); buf.writeBoolean(message.modifierSettings.doQuickReplace());
buf.writeInt(modifierSettings.getReachUpgrade()); buf.writeInt(message.modifierSettings.getReachUpgrade());
//RADIAL MIRROR //RADIAL MIRROR
RadialMirror.RadialMirrorSettings r = modifierSettings.getRadialMirrorSettings(); RadialMirror.RadialMirrorSettings r = message.modifierSettings.getRadialMirrorSettings();
buf.writeBoolean(r != null); buf.writeBoolean(r != null);
if (r != null) { if (r != null) {
buf.writeBoolean(r.enabled); buf.writeBoolean(r.enabled);
@@ -79,8 +77,7 @@ public class ModifierSettingsMessage implements IMessage {
} }
} }
@Override public static ModifierSettingsMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) {
//MIRROR //MIRROR
Mirror.MirrorSettings m = new Mirror.MirrorSettings(); Mirror.MirrorSettings m = new Mirror.MirrorSettings();
if (buf.readBoolean()) { if (buf.readBoolean()) {
@@ -123,32 +120,25 @@ public class ModifierSettingsMessage implements IMessage {
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 <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<ModifierSettingsMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(ModifierSettingsMessage message, Supplier<NetworkEvent.Context> 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); EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
// Sanitize // Sanitize
ModifierSettingsManager.sanitize(modifierSettings, player); ModifierSettingsManager.sanitize(message.modifierSettings, player);
ModifierSettingsManager.setModifierSettings(player, modifierSettings); ModifierSettingsManager.setModifierSettings(player, message.modifierSettings);
}); });
// No response packet ctx.get().setPacketHandled(true);
return null;
} }
} }
} }

View File

@@ -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);
}
}

View File

@@ -1,27 +1,26 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.BlockSet; import nl.requios.effortlessbuilding.buildmodifier.BlockSet;
import nl.requios.effortlessbuilding.buildmodifier.UndoRedo; import nl.requios.effortlessbuilding.buildmodifier.UndoRedo;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.function.Supplier;
/*** /***
* Sends a message to the client asking for its lookat (objectmouseover) data. * Sends a message to the client asking for its lookat (objectmouseover) data.
* This is then sent back with a BlockPlacedMessage. * This is then sent back with a BlockPlacedMessage.
*/ */
public class RequestLookAtMessage implements IMessage { public class RequestLookAtMessage {
private boolean placeStartPos; private boolean placeStartPos;
public RequestLookAtMessage() { public RequestLookAtMessage() {
@@ -36,38 +35,33 @@ public class RequestLookAtMessage implements IMessage {
return placeStartPos; return placeStartPos;
} }
@Override public static void encode(RequestLookAtMessage message, PacketBuffer buf) {
public void toBytes(ByteBuf buf) { buf.writeBoolean(message.placeStartPos);
buf.writeBoolean(this.placeStartPos);
} }
@Override public static RequestLookAtMessage decode(PacketBuffer buf) {
public void fromBytes(ByteBuf buf) { boolean placeStartPos = buf.readBoolean();
placeStartPos = buf.readBoolean(); return new RequestLookAtMessage(placeStartPos);
} }
// The params of the IMessageHandler are <REQ, REPLY> public static class Handler
public static class MessageHandler implements IMessageHandler<RequestLookAtMessage, IMessage> { {
// Do note that the default constructor is required, but implicitly defined in this case public static void handle(RequestLookAtMessage message, Supplier<NetworkEvent.Context> ctx)
{
ctx.get().enqueueWork(() -> {
EffortlessBuilding.log("RequestLookAtMessage");
@Override if (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT) {
public IMessage onMessage(RequestLookAtMessage message, MessageContext ctx) {
//EffortlessBuilding.log("message received on " + ctx.side + " side");
if (ctx.side == Side.CLIENT){
//Received clientside //Received clientside
//Send back your info //Send back your info
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
// EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> { //Prevent double placing in normal mode with placeStartPos false
// 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. //Unless QuickReplace is on, then we do need to place start pos.
return new BlockPlacedMessage(ClientProxy.previousLookAt, message.getPlaceStartPos()); PacketHandler.INSTANCE.sendToServer(new BlockPlacedMessage(ClientProxy.previousLookAt, message.getPlaceStartPos()));
} }
return null; });
ctx.get().setPacketHandled(true);
} }
} }
} }

View File

@@ -1,144 +1,116 @@
package nl.requios.effortlessbuilding.proxy; package nl.requios.effortlessbuilding.proxy;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType; import net.minecraft.block.SoundType;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.KeyboardListener;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen; 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.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.EntityPlayer; 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.ItemBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.IThreadListener;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceFluidMode;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent; 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.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier; import net.minecraftforge.client.settings.KeyModifier;
import net.minecraftforge.event.entity.EntityJoinWorldEvent; 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.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod; 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.gameevent.TickEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.network.NetworkEvent;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui; import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui;
import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.network.*;
import nl.requios.effortlessbuilding.render.RenderHandler; import nl.requios.effortlessbuilding.render.RenderHandler;
import nl.requios.effortlessbuilding.render.ShaderHandler; import nl.requios.effortlessbuilding.render.ShaderHandler;
import nl.requios.effortlessbuilding.network.*; import org.lwjgl.glfw.GLFW;
import org.lwjgl.input.Keyboard;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.HashMap; import java.util.HashMap;
import java.util.function.Supplier;
@Mod.EventBusSubscriber(Side.CLIENT) @Mod.EventBusSubscriber(value = {Dist.CLIENT})
public class ClientProxy implements IProxy { public class ClientProxy implements IProxy {
public static KeyBinding[] keyBindings; public static KeyBinding[] keyBindings;
public static RayTraceResult previousLookAt; public static RayTraceResult previousLookAt;
public static RayTraceResult currentLookAt; public static RayTraceResult currentLookAt;
private static int placeCooldown = 0; private static int placeCooldown = 0;
private static int breakCooldown = 0; private static int breakCooldown = 0;
private static boolean shadersInitialized = false;
public static int ticksInGame = 0; public static int ticksInGame = 0;
private static final HashMap<BuildModes.BuildModeEnum, TextureAtlasSprite> buildModeIcons = new HashMap<>(); private static final HashMap<BuildModes.BuildModeEnum, ResourceLocation> buildModeIcons = new HashMap<>();
private static final HashMap<ModeOptions.ActionEnum, TextureAtlasSprite> modeOptionIcons = new HashMap<>(); private static final HashMap<ModeOptions.ActionEnum, ResourceLocation> modeOptionIcons = new HashMap<>();
@Override @Override
public void preInit(FMLPreInitializationEvent event) { public void setup(FMLCommonSetupEvent event) {}
ShaderHandler.init();
}
@Override @Override
public void init(FMLInitializationEvent event) { public void clientSetup(FMLClientSetupEvent event) {
//Crashes in 1.13, do it elsewhere
// ShaderHandler.init();
// register key bindings // register key bindings
keyBindings = new KeyBinding[6]; keyBindings = new KeyBinding[7];
// instantiate the key bindings // instantiate the key bindings
keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, Keyboard.KEY_ADD, "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, Keyboard.KEY_SUBTRACT, "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, Keyboard.KEY_NONE, "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, Keyboard.KEY_LMENU, "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 @Override
public boolean conflicts(KeyBinding other) { public boolean func_197983_b(KeyBinding other) {
//Does not conflict with Chisels and Bits radial menu //Does not conflict with Chisels and Bits radial menu
if (other.getKeyCode() == getKeyCode() && other.getKeyDescription().equals("mod.chiselsandbits.other.mode")) return false; if (other.getKey().getKeyCode() == getKey().getKeyCode() && other.getKeyDescription().equals("mod.chiselsandbits.other.mode")) return false;
return super.conflicts(other); 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[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, Keyboard.KEY_Y, "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("Reload shaders", Keyboard.KEY_TAB, "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 // register all the key bindings
for (int i = 0; i < keyBindings.length; ++i) { for (int i = 0; i < keyBindings.length; ++i) {
ClientRegistry.registerKeyBinding(keyBindings[i]); ClientRegistry.registerKeyBinding(keyBindings[i]);
} }
}
@Override
public void postInit(FMLPostInitializationEvent event) {
} }
@Override public EntityPlayer getPlayerEntityFromContext(Supplier<NetworkEvent.Context> ctx){
public EntityPlayer getPlayerEntityFromContext(MessageContext ctx) { return (ctx.get().getDirection().getReceptionSide() == LogicalSide.CLIENT ? Minecraft.getInstance().player : ctx.get().getSender());
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"));
}
} }
@SubscribeEvent @SubscribeEvent
public static void onEntityJoinWorld(EntityJoinWorldEvent event) { public static void onEntityJoinWorld(EntityJoinWorldEvent event) {
if (event.getEntity() == Minecraft.getMinecraft().player) { if (event.getEntity() == Minecraft.getInstance().player) {
event.getWorld().addEventListener(new RenderHandler()); event.getWorld().addEventListener(new RenderHandler());
} }
} }
@@ -150,23 +122,25 @@ public class ClientProxy implements IProxy {
for ( final BuildModes.BuildModeEnum mode : BuildModes.BuildModeEnum.values() ) for ( final BuildModes.BuildModeEnum mode : BuildModes.BuildModeEnum.values() )
{ {
final ResourceLocation sprite = new ResourceLocation("effortlessbuilding", "icons/" + mode.name().toLowerCase()); final ResourceLocation sprite = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + mode.name().toLowerCase());
buildModeIcons.put( mode, map.registerSprite(sprite)); map.registerSprite(Minecraft.getInstance().getResourceManager(), sprite);
buildModeIcons.put(mode, sprite);
} }
for ( final ModeOptions.ActionEnum action : ModeOptions.ActionEnum.values() ) for ( final ModeOptions.ActionEnum action : ModeOptions.ActionEnum.values() )
{ {
final ResourceLocation sprite = new ResourceLocation("effortlessbuilding", "icons/" + action.name().toLowerCase()); final ResourceLocation sprite = new ResourceLocation(EffortlessBuilding.MODID, "icons/" + action.name().toLowerCase());
modeOptionIcons.put( action, map.registerSprite(sprite)); map.registerSprite(Minecraft.getInstance().getResourceManager(), sprite);
modeOptionIcons.put(action, sprite);
} }
} }
public static TextureAtlasSprite getBuildModeIcon(BuildModes.BuildModeEnum mode) { 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) { public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) {
return modeOptionIcons.get(action); return Minecraft.getInstance().getTextureMap().getSprite(modeOptionIcons.get(action));
} }
@SubscribeEvent @SubscribeEvent
@@ -176,7 +150,7 @@ public class ClientProxy implements IProxy {
onMouseInput(); onMouseInput();
//Update previousLookAt //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) //Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS)
if (objectMouseOver == null) return; if (objectMouseOver == null) return;
@@ -186,8 +160,8 @@ public class ClientProxy implements IProxy {
return; return;
} }
if (objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) { if (objectMouseOver.type == RayTraceResult.Type.BLOCK) {
if (currentLookAt.typeOfHit != RayTraceResult.Type.BLOCK) { if (currentLookAt.type != RayTraceResult.Type.BLOCK) {
currentLookAt = objectMouseOver; currentLookAt = objectMouseOver;
previousLookAt = objectMouseOver; previousLookAt = objectMouseOver;
} else { } else {
@@ -197,28 +171,36 @@ public class ClientProxy implements IProxy {
} }
} }
} }
} else if (event.phase == TickEvent.Phase.END){ } else if (event.phase == TickEvent.Phase.END){
GuiScreen gui = Minecraft.getMinecraft().currentScreen; GuiScreen gui = Minecraft.getInstance().currentScreen;
if(gui == null || !gui.doesGuiPauseGame()) { if(gui == null || !gui.doesGuiPauseGame()) {
ticksInGame++; 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() { private static void onMouseInput() {
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getInstance();
EntityPlayerSP player = mc.player; EntityPlayerSP player = mc.player;
if (player == null) return; if (player == null) return;
BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode();
if (Minecraft.getMinecraft().currentScreen != null || if (Minecraft.getInstance().currentScreen != null ||
buildMode == BuildModes.BuildModeEnum.NORMAL || buildMode == BuildModes.BuildModeEnum.NORMAL ||
RadialMenu.instance.isVisible()) { RadialMenu.instance.isVisible()) {
return; return;
} }
if (mc.gameSettings.keyBindUseItem.isKeyDown()) { if (mc.gameSettings.keyBindUseItem.isKeyDown()) {
//KeyBinding.setKeyBindState(mc.gameSettings.keyBindUseItem.getKeyCode(), false); //KeyBinding.setKeyBindState(mc.gameSettings.keyBindUseItem.getKeyCode(), false);
if (placeCooldown <= 0) { if (placeCooldown <= 0) {
@@ -233,11 +215,11 @@ public class ClientProxy implements IProxy {
//find position in distance //find position in distance
RayTraceResult lookingAt = getLookingAt(player); RayTraceResult lookingAt = getLookingAt(player);
BuildModes.onBlockPlacedMessage(player, lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt, true)); 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 //play sound if further than normal
if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK && if (lookingAt != null && lookingAt.type == RayTraceResult.Type.BLOCK &&
(lookingAt.hitVec.subtract(player.getPositionEyes(1f))).lengthSquared() > 25f && (lookingAt.hitVec.subtract(player.getEyePosition(1f))).lengthSquared() > 25f &&
itemStack.getItem() instanceof ItemBlock) { itemStack.getItem() instanceof ItemBlock) {
IBlockState state = ((ItemBlock) itemStack.getItem()).getBlock().getDefaultState(); IBlockState state = ((ItemBlock) itemStack.getItem()).getBlock().getDefaultState();
@@ -248,7 +230,8 @@ public class ClientProxy implements IProxy {
player.swingArm(EnumHand.MAIN_HAND); player.swingArm(EnumHand.MAIN_HAND);
} }
} }
} else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { }
else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) {
placeCooldown--; placeCooldown--;
if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) placeCooldown = 0; if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) placeCooldown = 0;
} }
@@ -270,11 +253,11 @@ public class ClientProxy implements IProxy {
RayTraceResult lookingAt = getLookingAt(player); RayTraceResult lookingAt = getLookingAt(player);
BuildModes.onBlockBrokenMessage(player, lookingAt == null ? new BlockBrokenMessage() : new BlockBrokenMessage(lookingAt)); 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 //play sound if further than normal
if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK && if (lookingAt != null && lookingAt.type == RayTraceResult.Type.BLOCK &&
(lookingAt.hitVec.subtract(player.getPositionEyes(1f))).lengthSquared() > 25f) { (lookingAt.hitVec.subtract(player.getEyePosition(1f))).lengthSquared() > 25f) {
BlockPos blockPos = lookingAt.getBlockPos(); BlockPos blockPos = lookingAt.getBlockPos();
IBlockState state = player.world.getBlockState(blockPos); IBlockState state = player.world.getBlockState(blockPos);
@@ -283,7 +266,8 @@ public class ClientProxy implements IProxy {
0.4f, soundtype.getPitch() * 1f); 0.4f, soundtype.getPitch() * 1f);
player.swingArm(EnumHand.MAIN_HAND); player.swingArm(EnumHand.MAIN_HAND);
} }
} else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { }
else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) {
breakCooldown--; breakCooldown--;
if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) breakCooldown = 0; if (ModeOptions.getBuildSpeed() == ModeOptions.ActionEnum.FAST_SPEED) breakCooldown = 0;
} }
@@ -293,18 +277,11 @@ public class ClientProxy implements IProxy {
} else { } else {
breakCooldown = 0; breakCooldown = 0;
} }
if (mc.gameSettings.keyBindAttack.isPressed()) {
if (RadialMenu.instance.isVisible()) {
EffortlessBuilding.log(player, "mouse click");
}
} }
} @SubscribeEvent(receiveCanceled = true)
@SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true)
public static void onKeyPress(InputEvent.KeyInputEvent event) { 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 //Remember to send packet to server if necessary
//Show Modifier Settings GUI //Show Modifier Settings GUI
@@ -316,17 +293,17 @@ public class ClientProxy implements IProxy {
if (keyBindings[1].isPressed()) { if (keyBindings[1].isPressed()) {
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
modifierSettings.setQuickReplace(!modifierSettings.doQuickReplace()); 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")); modifierSettings.doQuickReplace() ? "on" : "off"));
EffortlessBuilding.packetHandler.sendToServer(new ModifierSettingsMessage(modifierSettings)); PacketHandler.INSTANCE.sendToServer(new ModifierSettingsMessage(modifierSettings));
} }
//Creative/survival mode toggle //Creative/survival mode toggle
if (keyBindings[2].isPressed()) { if (keyBindings[2].isPressed()) {
if (player.isCreative()) { if (player.isCreative()) {
player.sendChatMessage("/gamemode 0"); player.sendChatMessage("/gamemode survival");
} else { } else {
player.sendChatMessage("/gamemode 1"); player.sendChatMessage("/gamemode creative");
} }
} }
@@ -334,18 +311,36 @@ public class ClientProxy implements IProxy {
if (keyBindings[4].isPressed()) { if (keyBindings[4].isPressed()) {
ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO; ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO;
ModeOptions.performAction(player, action); ModeOptions.performAction(player, action);
EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action)); PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action));
} }
//Redo (Ctrl+Y) //Redo (Ctrl+Y)
if (keyBindings[5].isPressed()) { if (keyBindings[5].isPressed()) {
ModeOptions.ActionEnum action = ModeOptions.ActionEnum.REDO; ModeOptions.ActionEnum action = ModeOptions.ActionEnum.REDO;
ModeOptions.performAction(player, action); 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 //For shader development
if (keyBindings.length >= 7 && keyBindings[6].isPressed()) { if (keyBindings.length >= 8 && keyBindings[7].isPressed()) {
ShaderHandler.init(); ShaderHandler.init();
EffortlessBuilding.log(player, "Reloaded shaders"); EffortlessBuilding.log(player, "Reloaded shaders");
} }
@@ -353,7 +348,7 @@ public class ClientProxy implements IProxy {
} }
public static void openModifierSettings() { public static void openModifierSettings() {
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getInstance();
EntityPlayerSP player = mc.player; EntityPlayerSP player = mc.player;
RadialMenu.instance.setVisibility(0f); RadialMenu.instance.setVisibility(0f);
@@ -372,7 +367,7 @@ public class ClientProxy implements IProxy {
@SubscribeEvent @SubscribeEvent
public static void onGuiOpen(GuiOpenEvent event) { public static void onGuiOpen(GuiOpenEvent event) {
EntityPlayer player = Minecraft.getMinecraft().player; EntityPlayer player = Minecraft.getInstance().player;
if (player != null) { if (player != null) {
BuildModes.initializeMode(player); BuildModes.initializeMode(player);
} }
@@ -388,11 +383,11 @@ public class ClientProxy implements IProxy {
// Vec3d look = player.getLookVec(); // Vec3d look = player.getLookVec();
// Vec3d start = new Vec3d(player.posX, player.posY + player.getEyeHeight(), player.posZ); // 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); // 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); // return world.rayTraceBlocks(start, end, false, false, false);
} }
public static void logTranslate(String key) { public static void logTranslate(String key) {
EffortlessBuilding.log(Minecraft.getMinecraft().player, I18n.format(key), true); EffortlessBuilding.log(Minecraft.getInstance().player, I18n.format(key), true);
} }
} }

View File

@@ -1,43 +1,16 @@
package nl.requios.effortlessbuilding.proxy; package nl.requios.effortlessbuilding.proxy;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.IThreadListener; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.network.NetworkEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
public interface IProxy import java.util.function.Supplier;
{
/**
* Register entities and networking.
*/
void preInit(FMLPreInitializationEvent event);
/** public interface IProxy {
* Register event listeners, recipes and advancements. void setup(final FMLCommonSetupEvent event);
*/
void init(FMLInitializationEvent event);
/** void clientSetup(final FMLClientSetupEvent 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);
/** EntityPlayer getPlayerEntityFromContext(Supplier<NetworkEvent.Context> ctx);
* 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);
} }

View File

@@ -1,45 +1,23 @@
package nl.requios.effortlessbuilding.proxy; package nl.requios.effortlessbuilding.proxy;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraft.util.IThreadListener; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.network.NetworkEvent;
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;
public class ServerProxy implements IProxy import java.util.function.Supplier;
{
public class ServerProxy implements IProxy {
//Only physical server! Singleplayer server is seen as clientproxy //Only physical server! Singleplayer server is seen as clientproxy
@Override @Override
public void preInit(FMLPreInitializationEvent event) public void setup(FMLCommonSetupEvent event) {
{
} }
@Override @Override
public void init(FMLInitializationEvent event) public void clientSetup(FMLClientSetupEvent event) {}
{
}
@Override public EntityPlayer getPlayerEntityFromContext(Supplier<NetworkEvent.Context> ctx){
public void postInit(FMLPostInitializationEvent event) return ctx.get().getSender();
{
}
@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();
} }
} }

View File

@@ -11,11 +11,14 @@ import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.math.*; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.relauncher.Side; import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.SideOnly; 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.BuildConfig;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; 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;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings;
import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.helper.InventoryHelper;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.item.ItemRandomizerBag; import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
@@ -40,7 +42,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
@SideOnly(Side.CLIENT) @OnlyIn(Dist.CLIENT)
public class BlockPreviewRenderer { public class BlockPreviewRenderer {
private static List<BlockPos> previousCoordinates; private static List<BlockPos> previousCoordinates;
private static List<IBlockState> previousBlockStates; private static List<IBlockState> previousBlockStates;
@@ -79,13 +81,13 @@ public class BlockPreviewRenderer {
//Render placed blocks with dissolve effect //Render placed blocks with dissolve effect
//Use fancy shader if config allows, otherwise no dissolve //Use fancy shader if config allows, otherwise no dissolve
if (BuildConfig.visuals.useShaders) { if (BuildConfig.visuals.useShaders.get()) {
RenderHandler.beginBlockPreviews(); RenderHandler.beginBlockPreviews();
for (int i = 0; i < placedDataList.size(); i++) { for (int i = 0; i < placedDataList.size(); i++) {
PlacedData placed = placedDataList.get(i); PlacedData placed = placedDataList.get(i);
if (placed.coordinates != null && !placed.coordinates.isEmpty()) { 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; float dissolve = (ClientProxy.ticksInGame - placed.time) / (float) totalTime;
renderBlockPreviews(placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking); renderBlockPreviews(placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking);
} }
@@ -94,13 +96,13 @@ public class BlockPreviewRenderer {
} }
//Expire //Expire
placedDataList.removeIf(placed -> { 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; return placed.time + totalTime < ClientProxy.ticksInGame;
}); });
//Render block previews //Render block previews
RayTraceResult lookingAt = ClientProxy.getLookingAt(player); 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(); ItemStack mainhand = player.getHeldItemMainhand();
boolean toolInHand = !(!mainhand.isEmpty() && CompatHelper.isItemBlockProxy(mainhand)); boolean toolInHand = !(!mainhand.isEmpty() && CompatHelper.isItemBlockProxy(mainhand));
@@ -110,11 +112,12 @@ public class BlockPreviewRenderer {
Vec3d hitVec = null; Vec3d hitVec = null;
//Checking for null is necessary! Even in vanilla when looking down ladders it is occasionally null (instead of Type MISS) //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(); startPos = lookingAt.getBlockPos();
//Check if tool (or none) in hand //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); boolean becomesDoubleSlab = SurvivalHelper.doesBecomeDoubleSlab(player, startPos, lookingAt.sideHit);
if (!modifierSettings.doQuickReplace() && !toolInHand && !replaceable && !becomesDoubleSlab) { if (!modifierSettings.doQuickReplace() && !toolInHand && !replaceable && !becomesDoubleSlab) {
startPos = startPos.offset(lookingAt.sideHit); startPos = startPos.offset(lookingAt.sideHit);
@@ -149,8 +152,8 @@ public class BlockPreviewRenderer {
//get coordinates //get coordinates
List<BlockPos> startCoordinates = BuildModes.findCoordinates(player, startPos, breaking || modifierSettings.doQuickReplace()); List<BlockPos> startCoordinates = BuildModes.findCoordinates(player, startPos, breaking || modifierSettings.doQuickReplace());
//Remember first and last point for the shader
BlockPos firstPos = BlockPos.ORIGIN, secondPos = BlockPos.ORIGIN; BlockPos firstPos = BlockPos.ORIGIN, secondPos = BlockPos.ORIGIN;
//Remember first and last pos for the shader
if (!startCoordinates.isEmpty()) { if (!startCoordinates.isEmpty()) {
firstPos = startCoordinates.get(0); firstPos = startCoordinates.get(0);
secondPos = startCoordinates.get(startCoordinates.size() - 1); secondPos = startCoordinates.get(startCoordinates.size() - 1);
@@ -210,7 +213,7 @@ public class BlockPreviewRenderer {
int blockCount; int blockCount;
//Use fancy shader if config allows, otherwise outlines //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(); RenderHandler.beginBlockPreviews();
@@ -225,8 +228,8 @@ public class BlockPreviewRenderer {
if (breaking) color = new Vec3d(1f, 0f, 0f); if (breaking) color = new Vec3d(1f, 0f, 0f);
for (int i = newCoordinates.size() - 1; i >= 0; i--) { for (int i = newCoordinates.size() - 1; i >= 0; i--) {
AxisAlignedBB boundingBox = blockStates.get(i).getBoundingBox(player.world, newCoordinates.get(i)); VoxelShape collisionShape = blockStates.get(i).getCollisionShape(player.world, newCoordinates.get(i));
RenderHandler.renderBlockOutline(newCoordinates.get(i), boundingBox, color); RenderHandler.renderBlockOutline(newCoordinates.get(i), collisionShape, color);
} }
RenderHandler.endLines(); RenderHandler.endLines();
@@ -236,8 +239,20 @@ public class BlockPreviewRenderer {
//Display block count and dimensions in actionbar //Display block count and dimensions in actionbar
if (BuildModes.isActive(player)) { 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 = "("; String dimensions = "(";
if (dim.getX() > 1) dimensions += dim.getX() + "x"; if (dim.getX() > 1) dimensions += dim.getX() + "x";
@@ -256,21 +271,21 @@ public class BlockPreviewRenderer {
RenderHandler.beginLines(); RenderHandler.beginLines();
//Draw outlines if tool in hand //Draw outlines if tool in hand
//Find proper raytrace: either normal range or increased range depending on canBreakFar //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; 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<BlockPos> breakCoordinates = BuildModifiers.findCoordinates(player, breakingRaytrace.getBlockPos()); List<BlockPos> breakCoordinates = BuildModifiers.findCoordinates(player, breakingRaytrace.getBlockPos());
//Only render first outline if further than normal reach //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++) { for (int i = excludeFirst ? 1 : 0; i < breakCoordinates.size(); i++) {
BlockPos coordinate = breakCoordinates.get(i); BlockPos coordinate = breakCoordinates.get(i);
IBlockState blockState = player.world.getBlockState(coordinate); IBlockState blockState = player.world.getBlockState(coordinate);
if (!blockState.getBlock().isAir(blockState, player.world, coordinate)) { if (!blockState.getBlock().isAir(blockState, player.world, coordinate)) {
if (SurvivalHelper.canBreak(player.world, player, coordinate) || i == 0) { if (SurvivalHelper.canBreak(player.world, player, coordinate) || i == 0) {
AxisAlignedBB boundingBox = blockState.getBoundingBox(player.world, coordinate); VoxelShape collisionShape = blockState.getCollisionShape(player.world, coordinate);
RenderHandler.renderBlockOutline(coordinate, boundingBox, new Vec3d(0f, 0f, 0f)); 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) { public static boolean doRenderBlockPreviews(ModifierSettings modifierSettings, ModeSettings modeSettings, BlockPos startPos) {
return modeSettings.getBuildMode() != BuildModes.BuildModeEnum.NORMAL || return modeSettings.getBuildMode() != BuildModes.BuildModeEnum.NORMAL ||
(startPos != null && BuildModifiers.isEnabled(modifierSettings, startPos)) || (startPos != null && BuildModifiers.isEnabled(modifierSettings, startPos)) ||
BuildConfig.visuals.alwaysShowBlockPreview; BuildConfig.visuals.alwaysShowBlockPreview.get();
} }
protected static int renderBlockPreviews(List<BlockPos> coordinates, List<IBlockState> blockStates, protected static int renderBlockPreviews(List<BlockPos> coordinates, List<IBlockState> blockStates,
List<ItemStack> itemStacks, float dissolve, BlockPos firstPos, List<ItemStack> itemStacks, float dissolve, BlockPos firstPos,
BlockPos secondPos, boolean checkCanPlace, boolean red) { BlockPos secondPos, boolean checkCanPlace, boolean red) {
EntityPlayer player = Minecraft.getMinecraft().player; EntityPlayer player = Minecraft.getInstance().player;
ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
int blocksValid = 0; int blocksValid = 0;
if (coordinates.isEmpty()) return blocksValid; if (coordinates.isEmpty()) return blocksValid;
@@ -324,7 +339,7 @@ public class BlockPreviewRenderer {
public static void onBlocksPlaced(List<BlockPos> coordinates, List<ItemStack> itemStacks, List<IBlockState> blockStates, public static void onBlocksPlaced(List<BlockPos> coordinates, List<ItemStack> itemStacks, List<IBlockState> blockStates,
BlockPos firstPos, BlockPos secondPos) { BlockPos firstPos, BlockPos secondPos) {
EntityPlayerSP player = Minecraft.getMinecraft().player; EntityPlayerSP player = Minecraft.getInstance().player;
ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
@@ -333,7 +348,7 @@ public class BlockPreviewRenderer {
//Save current coordinates, blockstates and itemstacks //Save current coordinates, blockstates and itemstacks
if (!coordinates.isEmpty() && blockStates.size() == coordinates.size() && 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, placedDataList.add(new PlacedData(ClientProxy.ticksInGame, coordinates, blockStates,
itemStacks, firstPos, secondPos, false)); itemStacks, firstPos, secondPos, false));
@@ -348,7 +363,7 @@ public class BlockPreviewRenderer {
public static void onBlocksBroken(List<BlockPos> coordinates, List<ItemStack> itemStacks, List<IBlockState> blockStates, public static void onBlocksBroken(List<BlockPos> coordinates, List<ItemStack> itemStacks, List<IBlockState> blockStates,
BlockPos firstPos, BlockPos secondPos) { BlockPos firstPos, BlockPos secondPos) {
EntityPlayerSP player = Minecraft.getMinecraft().player; EntityPlayerSP player = Minecraft.getInstance().player;
ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
@@ -357,7 +372,7 @@ public class BlockPreviewRenderer {
//Save current coordinates, blockstates and itemstacks //Save current coordinates, blockstates and itemstacks
if (!coordinates.isEmpty() && blockStates.size() == coordinates.size() && 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); sortOnDistanceToPlayer(coordinates, player);
@@ -371,7 +386,7 @@ public class BlockPreviewRenderer {
private static Consumer<Integer> generateShaderCallback(final float dissolve, final Vec3d blockpos, private static Consumer<Integer> generateShaderCallback(final float dissolve, final Vec3d blockpos,
final Vec3d firstpos, final Vec3d secondpos, final Vec3d firstpos, final Vec3d secondpos,
final boolean highlight, final boolean red) { final boolean highlight, final boolean red) {
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getInstance();
return (Integer shader) -> { return (Integer shader) -> {
int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve"); int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve");
int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight"); int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight");
@@ -387,13 +402,13 @@ public class BlockPreviewRenderer {
//mask //mask
ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit); ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit);
OpenGlHelper.setActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit); OpenGlHelper.glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.renderEngine.getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId()); GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId());
//image //image
ARBShaderObjects.glUniform1iARB(imageUniform, primaryTextureUnit); ARBShaderObjects.glUniform1iARB(imageUniform, primaryTextureUnit);
OpenGlHelper.setActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit); OpenGlHelper.glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.renderEngine.getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).getGlTextureId()); GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(TextureMap.LOCATION_BLOCKS_TEXTURE).getGlTextureId());
//blockpos //blockpos
ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z); ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
@@ -413,8 +428,8 @@ public class BlockPreviewRenderer {
Collections.sort(coordinates, (lhs, rhs) -> { Collections.sort(coordinates, (lhs, rhs) -> {
// -1 - less than, 1 - greater than, 0 - equal // -1 - less than, 1 - greater than, 0 - equal
double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getPositionEyes(1f)).lengthSquared(); double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getEyePosition(1f)).lengthSquared();
double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getPositionEyes(1f)).lengthSquared(); double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getEyePosition(1f)).lengthSquared();
return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer); return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer);
}); });

View File

@@ -4,15 +4,16 @@ import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.buildmodifier.Mirror; import nl.requios.effortlessbuilding.buildmodifier.Mirror;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Color;
@SideOnly(Side.CLIENT) import java.awt.*;
@OnlyIn(Dist.CLIENT)
public class ModifierRenderer { public class ModifierRenderer {
protected static final Color colorX = new Color(255, 72, 52); protected static final Color colorX = new Color(255, 72, 52);

View File

@@ -2,45 +2,42 @@ package nl.requios.effortlessbuilding.render;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft; 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.entity.EntityPlayerSP;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents; import net.minecraft.init.SoundEvents;
import net.minecraft.util.EnumHand; import net.minecraft.particles.IParticleData;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; 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.IWorldEventListener;
import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; 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.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeOptions;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
import nl.requios.effortlessbuilding.compatibility.CompatHelper;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.network.ModeActionMessage; import nl.requios.effortlessbuilding.network.ModeActionMessage;
import nl.requios.effortlessbuilding.network.ModeSettingsMessage; import nl.requios.effortlessbuilding.network.ModeSettingsMessage;
import nl.requios.effortlessbuilding.network.PacketHandler;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL14; import org.lwjgl.opengl.GL14;
@@ -50,12 +47,12 @@ import java.util.List;
/*** /***
* Main render class for Effortless Building * Main render class for Effortless Building
*/ */
@Mod.EventBusSubscriber(Side.CLIENT) @Mod.EventBusSubscriber(value = Dist.CLIENT)
public class RenderHandler implements IWorldEventListener { public class RenderHandler implements IWorldEventListener {
@SubscribeEvent @SubscribeEvent
public static void onRender(RenderWorldLastEvent event) { public static void onRender(RenderWorldLastEvent event) {
EntityPlayer player = Minecraft.getMinecraft().player; EntityPlayer player = Minecraft.getInstance().player;
ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player);
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
@@ -72,15 +69,16 @@ public class RenderHandler implements IWorldEventListener {
@SubscribeEvent @SubscribeEvent
//Display Radial Menu //Display Radial Menu
public static void onRenderGameOverlay(final RenderGameOverlayEvent.Post event ) { public static void onRenderGameOverlay(final RenderGameOverlayEvent.Post event) {
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getInstance();
EntityPlayerSP player = mc.player; EntityPlayerSP player = mc.player;
//check if chisel and bits tool in hand (and has menu) //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(); 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(); final boolean wasVisible = RadialMenu.instance.isVisible();
if (ClientProxy.keyBindings[3].isKeyDown()) { if (ClientProxy.keyBindings[3].isKeyDown()) {
@@ -98,7 +96,7 @@ public class RenderHandler implements IWorldEventListener {
playRadialMenuSound(); playRadialMenuSound();
modeSettings.setBuildMode(RadialMenu.instance.switchTo); modeSettings.setBuildMode(RadialMenu.instance.switchTo);
ModeSettingsManager.setModeSettings(player, modeSettings); 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); EffortlessBuilding.log(player, I18n.format(modeSettings.getBuildMode().name), true);
} }
@@ -107,7 +105,7 @@ public class RenderHandler implements IWorldEventListener {
ModeOptions.ActionEnum action = RadialMenu.instance.doAction; ModeOptions.ActionEnum action = RadialMenu.instance.doAction;
if (action != null) { if (action != null) {
ModeOptions.performAction(player, action); ModeOptions.performAction(player, action);
EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action)); PacketHandler.INSTANCE.sendToServer(new ModeActionMessage(action));
} }
playRadialMenuSound(); playRadialMenuSound();
@@ -119,25 +117,25 @@ public class RenderHandler implements IWorldEventListener {
if (RadialMenu.instance.isVisible()) { if (RadialMenu.instance.isVisible()) {
final ScaledResolution res = event.getResolution(); int scaledWidth = mc.mainWindow.getScaledWidth();
RadialMenu.instance.configure(res.getScaledWidth(), res.getScaledHeight()); int scaledHeight = mc.mainWindow.getScaledHeight();
RadialMenu.instance.configure(scaledWidth, scaledHeight);
if (!wasVisible) { if (!wasVisible) {
mc.inGameHasFocus = false; mc.mouseHelper.ungrabMouse();
mc.mouseHelper.ungrabMouseCursor();
} }
if (mc.inGameHasFocus) { if (mc.mouseHelper.isMouseGrabbed()) {
KeyBinding.unPressAllKeys(); KeyBinding.unPressAllKeys();
} }
final int mouseX = Mouse.getX() * res.getScaledWidth() / mc.displayWidth; final int mouseX = ((int) mc.mouseHelper.getMouseX()) * scaledWidth / mc.mainWindow.getFramebufferWidth();
final int mouseY = res.getScaledHeight() - Mouse.getY() * res.getScaledHeight() / mc.displayHeight - 1; final int mouseY = scaledHeight - ((int) mc.mouseHelper.getMouseY()) * scaledHeight / mc.mainWindow.getFramebufferHeight() - 1;
net.minecraftforge.client.ForgeHooksClient.drawScreen(RadialMenu.instance, mouseX, mouseY, event.getPartialTicks()); net.minecraftforge.client.ForgeHooksClient.drawScreen(RadialMenu.instance, mouseX, mouseY, event.getPartialTicks());
} else { } else {
if (wasVisible && RadialMenu.instance.doAction != ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) { 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() { public static void playRadialMenuSound() {
final float volume = 0.1f; final float volume = 0.1f;
if (volume >= 0.0001f) { if (volume >= 0.0001f) {
final PositionedSoundRecord psr = new PositionedSoundRecord(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, SimpleSound sound = new SimpleSound(SoundEvents.UI_BUTTON_CLICK, SoundCategory.MASTER, volume, 1.0f, Minecraft.getInstance().player.getPosition());
volume, 1.0f, Minecraft.getMinecraft().player.getPosition()); Minecraft.getInstance().getSoundHandler().play(sound);
Minecraft.getMinecraft().getSoundHandler().playSound(psr);
} }
} }
private static void begin(float partialTicks) { 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 playerX = player.prevPosX + (player.posX - player.prevPosX) * partialTicks;
double playerY = player.prevPosY + (player.posY - player.prevPosY) * partialTicks; double playerY = player.prevPosY + (player.posY - player.prevPosY) * partialTicks;
double playerZ = player.prevPosZ + (player.posZ - player.prevPosZ) * 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_CULL_FACE);
GL11.glEnable(GL11.GL_TEXTURE_2D); GL11.glEnable(GL11.GL_TEXTURE_2D);
// Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); // Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
Minecraft.getMinecraft().renderEngine.bindTexture(ShaderHandler.shaderMaskTextureLocation); Minecraft.getInstance().textureManager.bindTexture(ShaderHandler.shaderMaskTextureLocation);
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 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) { protected static void renderBlockPreview(BlockRendererDispatcher dispatcher, BlockPos blockPos, IBlockState blockState) {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(blockPos.getX(), blockPos.getY(), blockPos.getZ()); GlStateManager.translatef(blockPos.getX(), blockPos.getY(), blockPos.getZ());
GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); GlStateManager.rotatef(-90.0F, 0.0F, 1.0F, 0.0F);
GlStateManager.translate(-0.01f, -0.01f, 0.01f); GlStateManager.translatef(-0.01f, -0.01f, 0.01f);
GlStateManager.scale(1.02f, 1.02f, 1.02f); GlStateManager.scalef(1.02f, 1.02f, 1.02f);
try { try {
dispatcher.renderBlockBrightness(blockState, 0.85f); 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); 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 //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); 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 //IWORLDEVENTLISTENER IMPLEMENTATION
@Override @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 @Override
public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, public void addParticle(IParticleData particleData, boolean alwaysRender, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {
double xSpeed, double ySpeed, double zSpeed, int... parameters) {
} }
@Override @Override
public void spawnParticle(int id, boolean ignoreRange, boolean p_190570_3_, double x, double y, double z, public void addParticle(IParticleData particleData, boolean ignoreRange, boolean minimizeLevel, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {
double xSpeed, double ySpeed, double zSpeed, int... parameters) {
} }
@@ -315,7 +310,7 @@ public class RenderHandler implements IWorldEventListener {
//Sends breaking progress for all coordinates to renderglobal, so all blocks get visually broken //Sends breaking progress for all coordinates to renderglobal, so all blocks get visually broken
@Override @Override
public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getInstance();
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(mc.player); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(mc.player);
if (!BuildModifiers.isEnabled(modifierSettings, pos)) return; if (!BuildModifiers.isEnabled(modifierSettings, pos)) return;

View File

@@ -46,7 +46,7 @@ public final class ShaderHandler {
if(!doUseShaders()) if(!doUseShaders())
return; 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); dissolve = createProgram("/assets/effortlessbuilding/shaders/dissolve", VERT + FRAG);
} }
@@ -74,7 +74,7 @@ public final class ShaderHandler {
} }
public static boolean doUseShaders() { 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) { private static int createProgram(String s, int sides) {

View File

@@ -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 <here>
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"

View File

@@ -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 <level>"
}

View File

@@ -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 <level>

View File

@@ -10,8 +10,7 @@
"item": "minecraft:leather" "item": "minecraft:leather"
}, },
"O": { "O": {
"item": "minecraft:planks", "tag": "minecraft:planks"
"data": 32767
} }
}, },
"result": { "result": {

BIN
src/main/resources/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -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": []
}
]

View File

@@ -1,7 +1,7 @@
{ {
"pack": { "pack": {
"description": "examplemod resources", "description": "examplemod resources",
"pack_format": 3, "pack_format": 4,
"_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)." "_comment": "A pack_format of 4 requires json lang files. Note: we require v4 pack meta for all mods."
} }
} }