diff --git a/README.md b/README.md index fb9841e..9cc8930 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Scott's Tweaks -**LATEST OFFICIAL VERSION**: [Scott's Tweaks 1.1.0 for MC 1.7.10][latest] ([changelog][changelog.md]) ([all releases][releases])
-*DEPENDS ON*: [Kore Sample 1.2.2 (or later) for MC 1.7.10][koresample] +**LATEST OFFICIAL VERSION**: [Scott's Tweaks 1.2.0 for MC 1.7.10][latest] ([changelog][changelog.md]) ([all releases][releases])
+*DEPENDS ON*: [Kore Sample 1.2.5 (or later) for MC 1.7.10][koresample] [latest]: https://github.com/MinecraftModArchive/ScottsTweaks/releases/latest [releases]: https://github.com/MinecraftModArchive/ScottsTweaks/releases [changelog.md]: https://github.com/MinecraftModArchive/ScottsTweaks/blob/develop/src/main/resources/CHANGELOG.md @@ -13,6 +13,7 @@ Scott's Tweaks adds several of my favorite gameplay tweaks to the game. - Live chickens drop feathers as they go about their lives. - Growables (saplings, etc.) plant themselves if possible. - Clay generates in the overworld (not just in lake bottoms). +- Squid and bat spawning can be reduced or disabled. [Contributing](#contributing) diff --git a/api/KoreSample/.gitignore b/api/KoreSample/.gitignore new file mode 100644 index 0000000..a91a1cd --- /dev/null +++ b/api/KoreSample/.gitignore @@ -0,0 +1,135 @@ +# Adapted from http://www.gitignote.io + +### Windows ### +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + + +### OSX ### +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + + + +### Linux ### +*~ + +# KDE directory preferences +.directory + + +### Java ### +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + + +### Eclipse ### +*.pydevproject +.metadata +.gradle +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + +# sbteclipse plugin +.target + +# TeXlipse plugin +.texlipse + + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm + +## Directory-based project format +.idea/ +/*.iml + +## File-based project format +*.ipr +*.iws + +## Additional for IntelliJ +out/ + +# generated by mpeltonen/sbt-idea plugin +.idea_modules/ + +# generated by JIRA plugin +atlassian-ide-plugin.xml + +# generated by Crashlytics plugin (for Android Studio and Intellij) +com_crashlytics_export_strings.xml + + +### Project ### +.classpath +.project +run/ + +### Gradle ### +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting diff --git a/api/KoreSample/CONTRIBUTING.md b/api/KoreSample/CONTRIBUTING.md new file mode 100644 index 0000000..2bbb036 --- /dev/null +++ b/api/KoreSample/CONTRIBUTING.md @@ -0,0 +1,43 @@ +#Contributing + +We love pull requests. Here is a quick guide: + +To get started, [sign the Contributor License Agreement][cla]. This project is in the public domain and we need you to agree that your submissions will also be in the public domain. See [unlicense.org](http://unlicense.org/). + +[cla]: https://www.clahub.com/agreements/MinecraftModArchive/KoreSample + +Fork, then clone the repo: + + git clone git@github.com:your-username/KoreSample.git + +Check out the development branch: + + git checkout develop + +Set up your development environment: + + gradlew setupDecompWorkspace + +Setup your integrated development environment: + + gradlew idea + +-or- + + gradlew eclipse + +Make your changes. + +Push to your fork and [submit a pull request][pr]. + +[pr]: https://github.com/MinecraftModArchive/KoreSample/compare/ + +At this point, things are waiting on us. We may merge your code as is. We may suggest some changes or improvements or alternatives. + +###Some things that will increase the chance thate your pull request is accepted: + +* Write logical, thought out code. +* Reuse your code. +* Write a [good commit message][commit]. + +[commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html diff --git a/api/KoreSample/README.md b/api/KoreSample/README.md new file mode 100644 index 0000000..4560e9b --- /dev/null +++ b/api/KoreSample/README.md @@ -0,0 +1,67 @@ +## Kore Sample +**LATEST OFFICIAL VERSION**: [Kore Sample 1.2.5 for MC 1.7.10][latest] ([changelog][changelog.md]) ([all releases][releases]) +[latest]: https://github.com/MinecraftModArchive/KoreSample/releases/latest +[releases]: https://github.com/MinecraftModArchive/KoreSample/releases +[changelog.md]: https://github.com/MinecraftModArchive/KoreSample/blob/develop/src/main/resources/CHANGELOG.md + +![KoreSample](https://raw.githubusercontent.com/MinecraftModArchive/KoreSample/develop/src/main/resources/assets/logo.png) + +Kore Sample provides a set of tools and base classes for other Minecraft mods that depend on it. + +[Contributing](#contributing) + +[Support](#support) + +[Mod Packs](#mod-packs) + +[Licensing](#licensing) + +### Contributing + +Please see [CONTRIBUTING.md](CONTRIBUTING.md). + +### Support +Something not quite right? Have a suggestion? Found a bug? Create an issue now! + +1. Make sure your issue hasn't already been answered or fixed. Also think about whether your issue is a valid one +before submitting it. +2. Go to [the issues page][issues]. +3. Click [`New Issue`][new] right below `Star` and `Fork`. +4. Enter your Issue's title (something that summarizes your issue), and then create a detailed description ("Hey, could +you add/change xxx?" or "Hey, I found an exploit.", etc.). +5. Click `Submit new issue`, and wait for feedback! + +[issues]: /MinecraftModArchive/KoreSample/issues +[new]: /MinecraftModArchive/KoreSample/issues/new + +* * * + +#### Mod Packs + +This mod is released to the public domain. (*See [below](#licensing).*) The authors have disclaimed all rights and +anyone can use this software and source code as they wish. This means that anyone has permission to distribute this +compiled mod in any form, including bundled with other mods in a "mod pack." In fact, this mod was written with that +purpose in mind. + +* * * + +#### Licensing + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or +as a compiled binary, for any purpose, commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright +interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the +detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of +all present and future rights to this software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to [unlicense.org](http://unlicense.org/). + +![Public Domain](https://raw.githubusercontent.com/MinecraftModArchive/assets/master/pd-icon.png) diff --git a/api/KoreSample/UNLICENSE b/api/KoreSample/UNLICENSE new file mode 100644 index 0000000..a84c395 --- /dev/null +++ b/api/KoreSample/UNLICENSE @@ -0,0 +1,25 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + diff --git a/api/KoreSample/build.gradle b/api/KoreSample/build.gradle new file mode 100644 index 0000000..f642d64 --- /dev/null +++ b/api/KoreSample/build.gradle @@ -0,0 +1,110 @@ +evaluationDependsOn(':version') + +buildscript { + repositories { + mavenCentral() + maven { + name = "forge" + url = "http://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + } + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + } +} + +apply plugin: 'forge' +apply plugin: 'maven' + +group = "com.scottkillen.mod" +archivesBaseName = "KoreSample" + +minecraft { + version = project.mcversion + "-" + project.forgeversion + runDir = "run" + + replace '${mod_version}', project.version +} + +processResources +{ + // this will ensure that this task is redone when the versions change. + inputs.property "version", project.version + inputs.property "mcversion", project.minecraft.version + inputs.property "forgeversion", project.ext.forgeversion + + // replace stuff in the files we want. + from(sourceSets.main.resources.srcDirs) { + include '**/*.info' + include '**/version.properties' + + expand 'mod_version': project.version, 'minecraft_version': project.minecraft.version, 'forge_version': project + .ext.forgeversion + } + + // copy everything else, that we didn't do before + from(sourceSets.main.resources.srcDirs) { + exclude '**/*.info' + exclude '**/version.properties' + } +} + +jar { + includeEmptyDirs = false +} + +task sourcesJar(type: Jar, dependsOn: classes) { + from(sourceSets.main.output) { + include '**/*.info' + include '**/version.properties' + + expand 'mod_version': project.version, 'minecraft_version': project.minecraft.version, 'forge_version': project + .ext.forgeversion + } + + from(sourceSets.main.allSource) { + include '**/TheMod.java' + + expand 'mod_version': project.version + } + + from(sourceSets.main.allSource) { + exclude '**/*.info' + exclude '**/version.properties' + exclude '**/TheMod.java' + } + + classifier = 'sources' +} + +task deobfJar(type: Jar) { + from(sourceSets.main.output) { + include '**/*.info' + include '**/version.properties' + + expand 'mod_version': project.version, 'minecraft_version': project.minecraft.version, 'forge_version': project + .ext.forgeversion + } + + from(sourceSets.main.output) { + exclude '**/*.info' + exclude '**/version.properties' + } + + classifier = 'deobf' +} + +artifacts { + archives sourcesJar + archives deobfJar +} + +uploadArchives { + repositories.mavenDeployer { + repository (url:"file://" + projectDir + "/build/maven") + } +} diff --git a/api/KoreSample/gradle/wrapper/gradle-wrapper.jar b/api/KoreSample/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..b761216 Binary files /dev/null and b/api/KoreSample/gradle/wrapper/gradle-wrapper.jar differ diff --git a/api/KoreSample/gradle/wrapper/gradle-wrapper.properties b/api/KoreSample/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..dc4c2ff --- /dev/null +++ b/api/KoreSample/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Oct 07 22:55:33 EDT 2014 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-all.zip diff --git a/api/KoreSample/gradlew b/api/KoreSample/gradlew new file mode 100644 index 0000000..91a7e26 --- /dev/null +++ b/api/KoreSample/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/api/KoreSample/gradlew.bat b/api/KoreSample/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/api/KoreSample/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/api/KoreSample/settings.gradle b/api/KoreSample/settings.gradle new file mode 100644 index 0000000..d6855b7 --- /dev/null +++ b/api/KoreSample/settings.gradle @@ -0,0 +1 @@ +include 'version' \ No newline at end of file diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/TheMod.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/TheMod.java new file mode 100644 index 0000000..6cf81da --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/TheMod.java @@ -0,0 +1,45 @@ +package com.scottkillen.mod.koresample; + +import com.scottkillen.mod.koresample.compat.versionchecker.Versioned; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Mod.EventHandler; +import cpw.mods.fml.common.Mod.Instance; +import cpw.mods.fml.common.event.FMLInterModComms; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; + +@SuppressWarnings({ + "StaticNonFinalField", + "WeakerAccess", + "StaticVariableMayNotBeInitialized", + "NonConstantFieldWithUpperCaseName", + "MethodMayBeStatic" +}) +@Mod(modid = TheMod.MOD_ID, name = TheMod.MOD_NAME, version = TheMod.MOD_VERSION, useMetadata = true) +public final class TheMod implements Versioned +{ + static final String MOD_ID = "koresample"; + static final String MOD_NAME = "Kore Sample"; + static final String MOD_VERSION = "${mod_version}"; + private static final String RESOURCE_PREFIX = MOD_ID.toLowerCase() + ':'; + private static final String VERSIONCHECK_URL = + "https://raw.githubusercontent.com/ScottKillen/glowing-ninja/master/KoreSample.json"; + @Instance(MOD_ID) + public static TheMod INSTANCE; + + public static String resourcePrefix() { return RESOURCE_PREFIX; } + + @EventHandler + public void onFMLPreInitialization(FMLPreInitializationEvent event) { addVersionCheck(this); } + + public void addVersionCheck(Versioned versionCheck) + { + FMLInterModComms.sendRuntimeMessage(versionCheck.modID(), "VersionChecker", "addVersionCheck", + versionCheck.versionInfoURL()); + } + + @Override + public String modID() { return MOD_ID; } + + @Override + public String versionInfoURL() { return VERSIONCHECK_URL; } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/block/SlabBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/block/SlabBlock.java new file mode 100644 index 0000000..7853a93 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/block/SlabBlock.java @@ -0,0 +1,129 @@ +package com.scottkillen.mod.koresample.common.block; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; +import com.scottkillen.mod.koresample.common.util.slab.TheSingleSlabRegistry; +import com.scottkillen.mod.koresample.tree.DefinesSlab; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.block.BlockSlab; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import static com.google.common.base.Preconditions.*; + +@SuppressWarnings("AbstractClassNeverImplemented") +public abstract class SlabBlock extends BlockSlab +{ + public static final int CAPACITY = 8; + private static final int METADATA_MASK = CAPACITY - 1; + private static final TheSingleSlabRegistry slabRegistry = TheSingleSlabRegistry.REFERENCE; + private final ImmutableList subBlocks; + + protected SlabBlock(boolean isDouble, Collection subBlocks) + { + super(isDouble, Material.wood); + + checkArgument(!subBlocks.isEmpty()); + checkArgument(subBlocks.size() <= CAPACITY); + this.subBlocks = ImmutableList.copyOf(subBlocks); + setBlockName("slab"); + } + + private static int mask(int metadata) {return metadata & METADATA_MASK;} + + public static boolean isSingleSlab(Item item) + { + return slabRegistry.isSingleSlab(item); + } + + @SuppressWarnings("WeakerAccess") + protected static String getUnwrappedUnlocalizedName(String unlocalizedName) + { + return unlocalizedName.substring(unlocalizedName.indexOf('.') + 1); + } + + @SideOnly(Side.CLIENT) + @Override + public final IIcon getIcon(int side, int metadata) + { + final DefinesSlab subBlock = subBlocks.get(mask(metadata)); + final Block modelBlock = subBlock.slabModelBlock(); + final int modelBlockMetadata = subBlock.slabModelSubBlockIndex(); + return modelBlock.getIcon(side, modelBlockMetadata); + } + + @Override + public final Item getItemDropped(int metadata, Random unused, int unused2) + { + final DefinesSlab subBlock = subBlocks.get(mask(metadata)); + return Item.getItemFromBlock(subBlock.singleSlabBlock()); + } + + @Override + public boolean getUseNeighborBrightness() + { + // Fix lighting bugs + return true; + } + + @Override + protected final ItemStack createStackedBlock(int metadata) + { + final DefinesSlab subBlock = subBlocks.get(mask(metadata)); + return new ItemStack(Item.getItemFromBlock(subBlock.singleSlabBlock()), 2, subBlock.slabSubBlockIndex()); + } + + @Override + public final String getUnlocalizedName() + { + return String.format("tile.%s%s", resourcePrefix(), getUnwrappedUnlocalizedName(super.getUnlocalizedName())); + } + + @SuppressWarnings("unchecked") + @SideOnly(Side.CLIENT) + @Override + public final void getSubBlocks(Item item, CreativeTabs unused, List subblocks) + { + if (isSingleSlab(item)) + { + for (int i = 0; i < subBlocks.size(); ++i) + { + //noinspection ObjectAllocationInLoop + subblocks.add(new ItemStack(item, 1, i)); + } + } + } + + @SideOnly(Side.CLIENT) + @Override + public final void registerBlockIcons(IIconRegister unused) {} + + @Override + public final String func_150002_b(int metadata) + { + int metadata1 = metadata; + if (metadata1 < 0 || metadata1 >= subBlocks.size()) + { + metadata1 = 0; + } + + return getUnlocalizedName() + '.' + subBlocks.get(metadata1).slabName(); + } + + protected abstract String resourcePrefix(); + + protected final List subBlocks() { return Collections.unmodifiableList(subBlocks); } + + @Override + public String toString() { return Objects.toStringHelper(this).add("subBlocks", subBlocks).toString(); } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/block/StairsBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/block/StairsBlock.java new file mode 100644 index 0000000..0601ef6 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/block/StairsBlock.java @@ -0,0 +1,35 @@ +package com.scottkillen.mod.koresample.common.block; + +import com.scottkillen.mod.koresample.tree.DefinesStairs; +import net.minecraft.block.BlockStairs; + +@SuppressWarnings("AbstractClassNeverImplemented") +public abstract class StairsBlock extends BlockStairs +{ + protected StairsBlock(DefinesStairs model) + { + super(model.stairsModelBlock(), model.stairsModelSubBlockIndex()); + } + + @Override + public boolean getUseNeighborBrightness() + { + // Fix lighting bugs + return true; + } + + @SuppressWarnings("WeakerAccess") + protected static String getUnwrappedUnlocalizedName(String unlocalizedName) + { + return unlocalizedName.substring(unlocalizedName.indexOf('.') + 1); + } + + @Override + public final String getUnlocalizedName() + { + //noinspection StringConcatenationMissingWhitespace + return "tile." + resourcePrefix() + getUnwrappedUnlocalizedName(super.getUnlocalizedName()); + } + + protected abstract String resourcePrefix(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/event/ForgeEventListener.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/event/ForgeEventListener.java new file mode 100644 index 0000000..c955a8e --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/event/ForgeEventListener.java @@ -0,0 +1,12 @@ +package com.scottkillen.mod.koresample.common.util.event; + +import cpw.mods.fml.common.eventhandler.EventBus; + +@SuppressWarnings({ "AbstractClassNeverImplemented", "WeakerAccess" }) +public abstract class ForgeEventListener +{ + public void listen(EventBus eventBus) + { + eventBus.register(this); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/log/Logger.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/log/Logger.java new file mode 100644 index 0000000..d3d4900 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/log/Logger.java @@ -0,0 +1,42 @@ +package com.scottkillen.mod.koresample.common.util.log; + +import com.google.common.base.Objects; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; + +public final class Logger +{ + private final org.apache.logging.log4j.Logger logger; + + private Logger(String modID) + { + logger = LogManager.getLogger(modID); + } + + public static Logger forMod(String modID) + { + return new Logger(modID); + } + + public void info(final String format, final Object... args) { log(Level.INFO, format, args); } + + public void log(final Level level, final Throwable exception, final String format, final Object... args) + { + logger.log(level, String.format(format, args), exception); + } + + private void log(final Level level, final String format, final Object... data) + { + logger.log(level, String.format(format, data)); + } + + public void severe(final String format, final Object... args) { log(Level.ERROR, format, args); } + + public void warning(final String format, final Object... args) { log(Level.WARN, format, args); } + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("logger", logger).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/slab/SingleDoubleSlab.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/slab/SingleDoubleSlab.java new file mode 100644 index 0000000..b01b860 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/slab/SingleDoubleSlab.java @@ -0,0 +1,31 @@ +package com.scottkillen.mod.koresample.common.util.slab; + +import com.google.common.base.Objects; +import com.scottkillen.mod.koresample.common.block.SlabBlock; +import org.apache.commons.lang3.tuple.ImmutablePair; + +public final class SingleDoubleSlab +{ + private final ImmutablePair pair; + + public SingleDoubleSlab(SlabBlock singleSlab, SlabBlock doubleSlab) + { + pair = ImmutablePair.of(singleSlab, doubleSlab); + } + + public SlabBlock singleSlab() + { + return pair.left; + } + + public SlabBlock doubleSlab() + { + return pair.right; + } + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("pair", pair).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/slab/TheSingleSlabRegistry.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/slab/TheSingleSlabRegistry.java new file mode 100644 index 0000000..863a7d3 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/common/util/slab/TheSingleSlabRegistry.java @@ -0,0 +1,30 @@ +package com.scottkillen.mod.koresample.common.util.slab; + +import com.google.common.base.Objects; +import com.google.common.collect.Sets; +import com.scottkillen.mod.koresample.common.block.SlabBlock; +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import java.util.Set; + +import static com.google.common.base.Preconditions.*; + +@SuppressWarnings({ "NonSerializableFieldInSerializableClass", "WeakerAccess" }) +public enum TheSingleSlabRegistry +{ + REFERENCE; + + private final Set slabBlocks = Sets.newHashSet(); + + public void add(SlabBlock slabBlock) { slabBlocks.add(checkNotNull(slabBlock)); } + + public boolean isSingleSlab(Block block) { return slabBlocks.contains(block); } + + public boolean isSingleSlab(Item item) { return isSingleSlab(Block.getBlockFromItem(item)); } + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("slabBlocks", slabBlocks).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/Integrates.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/Integrates.java new file mode 100644 index 0000000..e56523b --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/Integrates.java @@ -0,0 +1,8 @@ +package com.scottkillen.mod.koresample.compat; + +import cpw.mods.fml.common.LoaderState.ModState; + +public interface Integrates +{ + void integrate(ModState modState); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/Integrator.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/Integrator.java new file mode 100644 index 0000000..f26ead6 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/Integrator.java @@ -0,0 +1,24 @@ +package com.scottkillen.mod.koresample.compat; + +import com.scottkillen.mod.koresample.common.util.log.Logger; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.LoaderState.ModState; + +public abstract class Integrator implements Integrates +{ + + protected abstract void doIntegration(ModState modState); + + @Override + public final void integrate(ModState modState) + { + if (Loader.isModLoaded(modID())) + { + doIntegration(modState); + } else Logger.forMod(modID()).info("%s not present. %s state integration skipped.", modName(), modState); + } + + protected abstract String modID(); + + protected abstract String modName(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/versionchecker/Versioned.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/versionchecker/Versioned.java new file mode 100644 index 0000000..bbbe5e5 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/compat/versionchecker/Versioned.java @@ -0,0 +1,8 @@ +package com.scottkillen.mod.koresample.compat.versionchecker; + +public interface Versioned +{ + String modID(); + + String versionInfoURL(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/config/ConfigEventHandler.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/config/ConfigEventHandler.java new file mode 100644 index 0000000..f03f728 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/config/ConfigEventHandler.java @@ -0,0 +1,153 @@ +package com.scottkillen.mod.koresample.config; + +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import com.scottkillen.mod.koresample.common.util.log.Logger; +import cpw.mods.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.common.config.Configuration; +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; +import java.util.Set; + +public final class ConfigEventHandler +{ + private final File configFile; + private final ConfigSyncable sync; + private final Configuration configuration; + private final String configVersion; + private final String modID; + private final Logger logger; + + public ConfigEventHandler(String modID, File configFile, ConfigSyncable sync, String configVersion) + { + this.modID = modID; + logger = Logger.forMod(modID); + this.configFile = configFile; + this.sync = sync; + + final Configuration localConfiguration = new Configuration(configFile, configVersion); + final Optional oldConfig; + if (isConfigVersionMismatch(localConfiguration)) + { + backup(configFile); + oldConfig = Optional.of(localConfiguration); + configuration = new Configuration(configFile, configVersion); + } else + { + oldConfig = Optional.absent(); + configuration = localConfiguration; + } + + this.configVersion = configVersion; + + syncConfig(false, oldConfig); + } + + private static String getModName(String modID) + { + final Map mods = Loader.instance().getIndexedModList(); + final ModContainer mod = mods.get(modID); + return mod == null ? "Unknown" : mod.getName(); + } + + private static boolean isConfigVersionMismatch(Configuration configuration) + { + return !configuration.getLoadedConfigVersion().equals(configuration.getDefinedConfigVersion()); + } + + public void activate() + { + FMLCommonHandler.instance().bus().register(this); + } + + private void backup(File fileRef) + { + final File fileBak = new File( + fileRef.getAbsolutePath() + '_' + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".old"); + logger.warning( + "Your %s config file is out of date and could cause issues. The existing file will be renamed to %s and a new one will be generated.", + getModName(modID), fileBak.getName()); + logger.warning( + "%s will attempt to copy your old settings.", + getModName(modID)); + + final boolean success = fileRef.renameTo(fileBak); + logger.warning("Rename %s successful.", success ? "was" : "was not"); + } + + public Configuration configuration() { return configuration; } + + private void loadConfig() + { + try + { + configuration.load(); + } catch (final RuntimeException e) + { + final File fileBak = new File( + configFile.getAbsolutePath() + '_' + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + + ".errored"); + logger.severe( + "An exception occurred while loading your config file. This file will be renamed to %s and a new config file will be generated.", + fileBak.getName()); + logger.severe("Exception encountered: %s", e.getLocalizedMessage()); + + final boolean success = configFile.renameTo(fileBak); + logger.warning("Rename %s successful.", success ? "was" : "was not"); + + final Configuration newConfig = new Configuration(configFile, configVersion); + final Set categoryNames = configuration.getCategoryNames(); + newConfig.copyCategoryProps(configuration, categoryNames.toArray(new String[categoryNames.size()])); + sync.syncConfig(newConfig); + newConfig.save(); + } + } + + @SubscribeEvent + public void onConfigChanged(OnConfigChangedEvent event) + { + if (event.modID.equalsIgnoreCase(modID)) + { + saveConfig(); + syncConfig(); + } + } + + private void saveConfig() + { + if (configuration.hasChanged()) + { + configuration.save(); + } + } + + void syncConfig() + { + syncConfig(true, Optional.absent()); + } + + private void syncConfig(boolean doLoad, Optional oldConfig) + { + if (doLoad) loadConfig(); + + sync.syncConfig(configuration); + + if (oldConfig.isPresent()) sync.convertOldConfig(oldConfig.get()); + + saveConfig(); + } + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("configFile", configFile).add("sync", sync) + .add("configuration", configuration).add("configVersion", configVersion).add("modID", modID) + .add("logger", logger).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/config/ConfigSyncable.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/config/ConfigSyncable.java new file mode 100644 index 0000000..3485a26 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/config/ConfigSyncable.java @@ -0,0 +1,10 @@ +package com.scottkillen.mod.koresample.config; + +import net.minecraftforge.common.config.Configuration; + +public interface ConfigSyncable +{ + void convertOldConfig(Configuration oldConfig); + + void syncConfig(Configuration config); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesLeaves.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesLeaves.java new file mode 100644 index 0000000..47a236f --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesLeaves.java @@ -0,0 +1,18 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.tree.block.LeavesBlock; + +public interface DefinesLeaves extends ProvidesColor +{ + void assignLeavesBlock(LeavesBlock block); + + void assignLeavesSubBlockIndex(int index); + + LeavesBlock leavesBlock(); + + int leavesSubBlockIndex(); + + DefinesSapling saplingDefinition(); + + String speciesName(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesLog.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesLog.java new file mode 100644 index 0000000..661fb81 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesLog.java @@ -0,0 +1,21 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.tree.block.LogBlock; +import net.minecraft.block.Block; + +public interface DefinesLog +{ + void assignLogBlock(LogBlock block); + + void assignLogSubBlockIndex(int index); + + Block logBlock(); + + int logSubBlockIndex(); + + String speciesName(); + + Block woodBlock(); + + int woodSubBlockIndex(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesSapling.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesSapling.java new file mode 100644 index 0000000..46e5201 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesSapling.java @@ -0,0 +1,23 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.tree.block.SaplingBlock; +import net.minecraft.world.gen.feature.WorldGenerator; + +@SuppressWarnings("InterfaceNeverImplemented") +public interface DefinesSapling +{ + void assignSaplingBlock(SaplingBlock block); + + void assignSaplingSubBlockIndex(int index); + + SaplingBlock saplingBlock(); + + int saplingSubBlockIndex(); + + String speciesName(); + + @Deprecated + WorldGenerator treeGenerator(); + + WorldGenerator saplingTreeGenerator(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesSlab.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesSlab.java new file mode 100644 index 0000000..185444d --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesSlab.java @@ -0,0 +1,26 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.common.block.SlabBlock; +import net.minecraft.block.Block; + +public interface DefinesSlab +{ + + void assignDoubleSlabBlock(SlabBlock doubleSlabBlock); + + void assignSingleSlabBlock(SlabBlock block); + + void assignSlabSubBlockIndex(int index); + + SlabBlock doubleSlabBlock(); + + SlabBlock singleSlabBlock(); + + int slabSubBlockIndex(); + + Block slabModelBlock(); + + int slabModelSubBlockIndex(); + + String slabName(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesStairs.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesStairs.java new file mode 100644 index 0000000..ed4af15 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesStairs.java @@ -0,0 +1,17 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.common.block.StairsBlock; +import net.minecraft.block.Block; + +public interface DefinesStairs +{ + void assignStairsBlock(StairsBlock block); + + StairsBlock stairsBlock(); + + Block stairsModelBlock(); + + int stairsModelSubBlockIndex(); + + String stairsName(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesTree.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesTree.java new file mode 100644 index 0000000..66f77f7 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesTree.java @@ -0,0 +1,26 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.tree.block.LeavesBlock; +import com.scottkillen.mod.koresample.tree.block.LogBlock; +import com.scottkillen.mod.koresample.tree.block.SaplingBlock; +import net.minecraft.world.gen.feature.WorldGenerator; + +@SuppressWarnings("InterfaceNeverImplemented") +public interface DefinesTree +{ + LeavesBlock leavesBlock(); + + int leavesSubBlockIndex(); + + LogBlock logBlock(); + + int logSubBlockIndex(); + + SaplingBlock saplingBlock(); + + int saplingSubBlockIndex(); + + WorldGenerator saplingTreeGenerator(); + + WorldGenerator worldTreeGenerator(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesWood.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesWood.java new file mode 100644 index 0000000..f99740f --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/DefinesWood.java @@ -0,0 +1,16 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.tree.block.WoodBlock; + +public interface DefinesWood +{ + void assignWoodBlock(WoodBlock block); + + void assignWoodSubBlockIndex(int index); + + WoodBlock woodBlock(); + + int woodSubBlockIndex(); + + String speciesName(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/ProvidesColor.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/ProvidesColor.java new file mode 100644 index 0000000..bb849b1 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/ProvidesColor.java @@ -0,0 +1,14 @@ +package com.scottkillen.mod.koresample.tree; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.world.IBlockAccess; + +public interface ProvidesColor +{ + @SideOnly(Side.CLIENT) + int getLeavesInventoryColor(); + + @SideOnly(Side.CLIENT) + int getLeavesColor(IBlockAccess blockAccess, int x, int y, int z); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/TreeBlockFactory.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/TreeBlockFactory.java new file mode 100644 index 0000000..288bd1f --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/TreeBlockFactory.java @@ -0,0 +1,23 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.common.util.slab.SingleDoubleSlab; +import com.scottkillen.mod.koresample.tree.block.LeavesBlock; +import com.scottkillen.mod.koresample.tree.block.LogBlock; +import com.scottkillen.mod.koresample.tree.block.SaplingBlock; +import com.scottkillen.mod.koresample.common.block.StairsBlock; +import com.scottkillen.mod.koresample.tree.block.WoodBlock; + +public interface TreeBlockFactory +{ + LeavesBlock createLeavesBlock(Iterable subBlocks); + + LogBlock createLogBlock(Iterable subBlocks); + + SaplingBlock createSaplingBlock(Iterable subBlocks); + + SingleDoubleSlab createSlabBlocks(Iterable subBlocks); + + StairsBlock createStairsBlock(DefinesStairs definition); + + WoodBlock createWoodBlock(Iterable subBlocks); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/TreeTaxonomy.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/TreeTaxonomy.java new file mode 100644 index 0000000..54e1875 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/TreeTaxonomy.java @@ -0,0 +1,18 @@ +package com.scottkillen.mod.koresample.tree; + +import com.scottkillen.mod.koresample.tree.DefinesLeaves; + +public interface TreeTaxonomy +{ + Iterable leavesDefinitions(); + + Iterable logDefinitions(); + + Iterable saplingDefinitions(); + + Iterable slabDefinitions(); + + Iterable stairsDefinitions(); + + Iterable woodDefinitions(); +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/LeavesBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/LeavesBlock.java new file mode 100644 index 0000000..7946f3e --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/LeavesBlock.java @@ -0,0 +1,151 @@ +package com.scottkillen.mod.koresample.tree.block; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.scottkillen.mod.koresample.tree.DefinesLeaves; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.block.BlockLeaves; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import static com.google.common.base.Preconditions.*; + +public abstract class LeavesBlock extends BlockLeaves +{ + public static final int CAPACITY = 4; + private static final int METADATA_MASK = CAPACITY - 1; + private final ImmutableList subBlocks; + + protected LeavesBlock(Collection subBlocks) + { + checkArgument(!subBlocks.isEmpty()); + checkArgument(subBlocks.size() <= CAPACITY); + this.subBlocks = ImmutableList.copyOf(subBlocks); + setBlockName("leaves"); + } + + private static int mask(int metadata) {return metadata & METADATA_MASK;} + + @SuppressWarnings("WeakerAccess") + protected static String getUnwrappedUnlocalizedName(String unlocalizedName) + { + return unlocalizedName.substring(unlocalizedName.indexOf('.') + 1); + } + + @SideOnly(Side.CLIENT) + private static boolean isFancyGraphics() {return Minecraft.getMinecraft().gameSettings.fancyGraphics;} + + protected final List subBlocks() { return Collections.unmodifiableList(subBlocks); } + + @SideOnly(Side.CLIENT) + @Override + public final int getRenderColor(int metadata) { return subBlocks.get(mask(metadata)).getLeavesInventoryColor(); } + + @SideOnly(Side.CLIENT) + @Override + public final int colorMultiplier(IBlockAccess blockAccess, int x, int y, int z) + { + final int metadata = mask(blockAccess.getBlockMetadata(x, y, z)); + return subBlocks.get(metadata).getLeavesColor(blockAccess, x, y, z); + } + + @Override + public final Item getItemDropped(int metadata, Random unused, int unused2) + { + return Item.getItemFromBlock(subBlocks.get(mask(metadata)).saplingDefinition().saplingBlock()); + } + + @Override + public final int damageDropped(int metadata) + { + return subBlocks.get(mask(metadata)).saplingDefinition().saplingSubBlockIndex(); + } + + @SideOnly(Side.CLIENT) + @Override + public final boolean isOpaqueCube() { return !isFancyGraphics(); } + + @SideOnly(Side.CLIENT) + @Override + public final IIcon getIcon(int unused, int metadata) + { + return field_150129_M[isFancyGraphics() ? 0 : 1][mask(metadata)]; + } + + @Override + public final String[] func_150125_e() + { + final List names = Lists.newArrayList(); + for (final DefinesLeaves subBlock : subBlocks) + names.add(subBlock.speciesName()); + return names.toArray(new String[names.size()]); + } + + @Override + public final String getUnlocalizedName() + { + return String.format("tile.%s%s", resourcePrefix(), getUnwrappedUnlocalizedName(super.getUnlocalizedName())); + } + + @Override + public final int getDamageValue(World world, int x, int y, int z) { return world.getBlockMetadata(x, y, z) & 3; } + + @SuppressWarnings("unchecked") + @SideOnly(Side.CLIENT) + @Override + public final void getSubBlocks(Item item, CreativeTabs unused, List subBlocks) + { + for (int i = 0; i < this.subBlocks.size(); i++) + //noinspection ObjectAllocationInLoop + subBlocks.add(new ItemStack(item, 1, i)); + } + + @SideOnly(Side.CLIENT) + @Override + public final void registerBlockIcons(IIconRegister iconRegister) + { + field_150129_M[0] = new IIcon[subBlocks.size()]; + field_150129_M[1] = new IIcon[subBlocks.size()]; + + for (int i = 0; i < subBlocks.size(); i++) + { + final String iconName = + String.format("%sleaves_%s", resourcePrefix(), subBlocks.get(i).speciesName().replace('.', '_')); + field_150129_M[0][i] = iconRegister.registerIcon(iconName); + field_150129_M[1][i] = iconRegister.registerIcon(iconName + "_opaque"); + } + } + + protected abstract String resourcePrefix(); + + @SuppressWarnings("OverlyComplexBooleanExpression") + @SideOnly(Side.CLIENT) + @Override + public final boolean shouldSideBeRendered(IBlockAccess blockAccess, int x, int y, int z, int side) + { + final Block block = blockAccess.getBlock(x, y, z); + return !(!isFancyGraphics() && block.equals(this)) && + (side == 0 && minY > 0.0D || side == 1 && maxY < 1.0D || side == 2 && minZ > 0.0D || + side == 3 && maxZ < 1.0D || side == 4 && minX > 0.0D || side == 5 && maxX < 1.0D || + !blockAccess.getBlock(x, y, z).isOpaqueCube()); + } + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("subBlocks", subBlocks).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/LogBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/LogBlock.java new file mode 100644 index 0000000..8fcfb6c --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/LogBlock.java @@ -0,0 +1,88 @@ +package com.scottkillen.mod.koresample.tree.block; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.scottkillen.mod.koresample.tree.DefinesLog; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.BlockLog; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import static com.google.common.base.Preconditions.*; + +public abstract class LogBlock extends BlockLog +{ + public static final int CAPACITY = 4; + private final ImmutableList subBlocks; + + protected LogBlock(Collection subBlocks) + { + checkArgument(!subBlocks.isEmpty()); + checkArgument(subBlocks.size() <= CAPACITY); + this.subBlocks = ImmutableList.copyOf(subBlocks); + setBlockName("log"); + } + + @SuppressWarnings("WeakerAccess") + protected static String getUnwrappedUnlocalizedName(String unlocalizedName) + { + return unlocalizedName.substring(unlocalizedName.indexOf('.') + 1); + } + + protected final List subBlocks() { return Collections.unmodifiableList(subBlocks); } + + public final ImmutableList getSubBlockNames() + { + final List names = Lists.newArrayList(); + for (final DefinesLog subBlock : subBlocks) + names.add(subBlock.speciesName()); + return ImmutableList.copyOf(names); + } + + @Override + public final String getUnlocalizedName() + { + return String.format("tile.%s%s", resourcePrefix(), getUnwrappedUnlocalizedName(super.getUnlocalizedName())); + } + + @SuppressWarnings("unchecked") + @SideOnly(Side.CLIENT) + @Override + public final void getSubBlocks(Item item, CreativeTabs unused, List subblocks) + { + for (int i = 0; i < subBlocks.size(); i++) + //noinspection ObjectAllocationInLoop + subblocks.add(new ItemStack(item, 1, i)); + } + + @Override + @SideOnly(Side.CLIENT) + public final void registerBlockIcons(IIconRegister iconRegister) + { + field_150167_a = new IIcon[subBlocks.size()]; + field_150166_b = new IIcon[subBlocks.size()]; + + for (int i = 0; i < subBlocks.size(); i++) + { + final String iconName = String.format("%slog_%s", resourcePrefix(), subBlocks.get(i).speciesName()); + field_150167_a[i] = iconRegister.registerIcon(iconName); + field_150166_b[i] = iconRegister.registerIcon(iconName + "_top"); + } + } + + protected abstract String resourcePrefix(); + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("subBlocks", subBlocks).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/SaplingBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/SaplingBlock.java new file mode 100644 index 0000000..4a587e7 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/SaplingBlock.java @@ -0,0 +1,119 @@ +package com.scottkillen.mod.koresample.tree.block; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.scottkillen.mod.koresample.tree.DefinesSapling; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.BlockSapling; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraft.world.gen.feature.WorldGenerator; +import net.minecraftforge.event.terraingen.TerrainGen; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import static com.google.common.base.Preconditions.*; + +@SuppressWarnings("AbstractClassNeverImplemented") +public abstract class SaplingBlock extends BlockSapling +{ + public static final int CAPACITY = 8; + private static final int METADATA_MASK = CAPACITY - 1; + private final ImmutableList subBlocks; + private final List subblockIcons; + + protected SaplingBlock(Collection subBlocks) + { + checkArgument(!subBlocks.isEmpty()); + checkArgument(subBlocks.size() <= CAPACITY); + this.subBlocks = ImmutableList.copyOf(subBlocks); + + subblockIcons = Lists.newArrayListWithCapacity(subBlocks.size()); + + setBlockName("sapling"); + } + + @SuppressWarnings("WeakerAccess") + protected static String getUnwrappedUnlocalizedName(String unlocalizedName) + { + return unlocalizedName.substring(unlocalizedName.indexOf('.') + 1); + } + + private static int mask(int metadata) { return metadata & METADATA_MASK; } + + protected final List subBlocks() { return Collections.unmodifiableList(subBlocks); } + + public final List subBlockNames() + { + final List names = Lists.newArrayListWithCapacity(subBlocks.size()); + for (final DefinesSapling subBlock : subBlocks) + names.add(subBlock.speciesName()); + return ImmutableList.copyOf(names); + } + + @SideOnly(Side.CLIENT) + @Override + public final IIcon getIcon(int unused, int metadata) { return subblockIcons.get(mask(metadata)); } + + @Override + public final void func_149878_d(World world, int x, int y, int z, Random rand) + { + if (!TerrainGen.saplingGrowTree(world, rand, x, y, z)) return; + + final int metadata = mask(world.getBlockMetadata(x, y, z)); + final WorldGenerator treeGen = subBlocks.get(metadata).saplingTreeGenerator(); + world.setBlock(x, y, z, Blocks.air, 0, 4); + if (!treeGen.generate(world, rand, x, y, z)) world.setBlock(x, y, z, this, metadata, 4); + } + + @Override + public final int damageDropped(int metadata) + { + return mask(metadata); + } + + @SuppressWarnings("unchecked") + @SideOnly(Side.CLIENT) + @Override + public final void getSubBlocks(Item item, CreativeTabs unused, List subBlocks) + { + for (int i = 0; i < this.subBlocks.size(); i++) + //noinspection ObjectAllocationInLoop + subBlocks.add(new ItemStack(item, 1, i)); + } + + @Override + public final void registerBlockIcons(IIconRegister iconRegister) + { + subblockIcons.clear(); + + for (int i = 0; i < subBlocks.size(); i++) + { + final String iconName = String.format("%ssapling_%s", resourcePrefix(), subBlocks.get(i).speciesName()); + subblockIcons.add(i, iconRegister.registerIcon(iconName)); + } + } + + @Override + public final String getUnlocalizedName() + { + return String.format("tile.%s%s", resourcePrefix(), getUnwrappedUnlocalizedName(super.getUnlocalizedName())); + } + + protected abstract String resourcePrefix(); + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("subBlocks", subBlocks).add("subblockIcons", subblockIcons).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/SlabBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/SlabBlock.java new file mode 100644 index 0000000..4fad2ff --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/SlabBlock.java @@ -0,0 +1,15 @@ +package com.scottkillen.mod.koresample.tree.block; + +import com.scottkillen.mod.koresample.tree.DefinesSlab; +import java.util.Collection; + +// Use com.scottkillen.mod.koresample.common.block.SlabBlock instead +// This is left to honor the api contract +@Deprecated +public abstract class SlabBlock extends com.scottkillen.mod.koresample.common.block.SlabBlock +{ + protected SlabBlock(boolean isDouble, Collection subBlocks) + { + super(isDouble, subBlocks); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/StairsBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/StairsBlock.java new file mode 100644 index 0000000..b49192f --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/StairsBlock.java @@ -0,0 +1,14 @@ +package com.scottkillen.mod.koresample.tree.block; + +import com.scottkillen.mod.koresample.tree.DefinesStairs; + +// Use com.scottkillen.mod.koresample.common.block.StairsBlock instead +// This is left to honor the api contract +@Deprecated +public abstract class StairsBlock extends com.scottkillen.mod.koresample.common.block.StairsBlock +{ + protected StairsBlock(DefinesStairs model) + { + super(model); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/WoodBlock.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/WoodBlock.java new file mode 100644 index 0000000..09a5bab --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/block/WoodBlock.java @@ -0,0 +1,93 @@ +package com.scottkillen.mod.koresample.tree.block; + +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.scottkillen.mod.koresample.tree.DefinesWood; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.BlockWood; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public abstract class WoodBlock extends BlockWood +{ + public static final int CAPACITY = 16; + private final ImmutableList subBlocks; + private final List icons = Lists.newArrayList(); + + protected WoodBlock(Collection subBlocks) + { + Preconditions.checkArgument(!subBlocks.isEmpty()); + Preconditions.checkArgument(subBlocks.size() <= CAPACITY); + this.subBlocks = ImmutableList.copyOf(subBlocks); + setBlockName("wood"); + } + + @SuppressWarnings("WeakerAccess") + protected static String getUnwrappedUnlocalizedName(String unlocalizedName) + { + return unlocalizedName.substring(unlocalizedName.indexOf('.') + 1); + } + + protected final List subBlocks() { return Collections.unmodifiableList(subBlocks); } + + public final ImmutableList getSubBlockNames() + { + final List names = Lists.newArrayList(); + for (final DefinesWood subBlock : subBlocks) + names.add(subBlock.speciesName()); + return ImmutableList.copyOf(names); + } + + @Override + public final String getUnlocalizedName() + { + return String.format("tile.%s%s", resourcePrefix(), getUnwrappedUnlocalizedName(super.getUnlocalizedName())); + } + + @SideOnly(Side.CLIENT) + @Override + public final IIcon getIcon(int unused, int meta) + { + final int meta1 = meta < 0 || meta >= icons.size() ? 0 : meta; + return icons.get(meta1); + } + + @SuppressWarnings("unchecked") + @SideOnly(Side.CLIENT) + @Override + public final void getSubBlocks(Item item, CreativeTabs unused, List subblocks) + { + for (int i = 0; i < subBlocks.size(); i++) + //noinspection ObjectAllocationInLoop + subblocks.add(new ItemStack(item, 1, i)); + } + + @Override + public final void registerBlockIcons(IIconRegister iconRegister) + { + icons.clear(); + + for (int i = 0; i < subBlocks.size(); i++) + { + final String iconName = String.format("%splanks_%s", resourcePrefix(), subBlocks.get(i).speciesName()); + icons.add(i, iconRegister.registerIcon(iconName)); + } + } + + protected abstract String resourcePrefix(); + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("subBlocks", subBlocks).add("icons", icons).toString(); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/LeavesItem.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/LeavesItem.java new file mode 100644 index 0000000..3ad3620 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/LeavesItem.java @@ -0,0 +1,10 @@ +package com.scottkillen.mod.koresample.tree.item; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockLeaves; +import net.minecraft.item.ItemLeaves; + +public final class LeavesItem extends ItemLeaves +{ + public LeavesItem(Block block) { super((BlockLeaves) block); } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/LogItem.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/LogItem.java new file mode 100644 index 0000000..fbd6d53 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/LogItem.java @@ -0,0 +1,13 @@ +package com.scottkillen.mod.koresample.tree.item; + +import com.scottkillen.mod.koresample.tree.block.LogBlock; +import net.minecraft.block.Block; +import net.minecraft.item.ItemMultiTexture; + +public abstract class LogItem extends ItemMultiTexture +{ + // This provides a reminder that you must extend this class and change the constructor to accept your extension of + // LogBlock in the second parameter + + protected LogItem(Block block, LogBlock log, String[] names) { super(block, log, names); } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/SaplingItem.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/SaplingItem.java new file mode 100644 index 0000000..8d02419 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/SaplingItem.java @@ -0,0 +1,13 @@ +package com.scottkillen.mod.koresample.tree.item; + +import com.scottkillen.mod.koresample.tree.block.SaplingBlock; +import net.minecraft.block.Block; +import net.minecraft.item.ItemMultiTexture; + +public abstract class SaplingItem extends ItemMultiTexture +{ + // This provides a reminder that you must extend this class and change the constructor to accept your extension of + // SaplingBlock in the second parameter + + protected SaplingItem(Block block, SaplingBlock sapling, String[] names) { super(block, sapling, names); } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/SlabItem.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/SlabItem.java new file mode 100644 index 0000000..992ddc0 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/SlabItem.java @@ -0,0 +1,15 @@ +package com.scottkillen.mod.koresample.tree.item; + +import com.scottkillen.mod.koresample.common.block.SlabBlock; +import net.minecraft.block.Block; +import net.minecraft.item.ItemSlab; + +public abstract class SlabItem extends ItemSlab +{ + // This provides a reminder that you must extend this class and change the constructor to accept your extension of + // SlabBlock in the second and third parameters + protected SlabItem(Block block, SlabBlock singleSlab, SlabBlock doubleSlab, Boolean isDouble) + { + super(block, singleSlab, doubleSlab, isDouble); + } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/WoodItem.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/WoodItem.java new file mode 100644 index 0000000..4f94b3a --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/item/WoodItem.java @@ -0,0 +1,13 @@ +package com.scottkillen.mod.koresample.tree.item; + +import com.scottkillen.mod.koresample.tree.block.WoodBlock; +import net.minecraft.block.Block; +import net.minecraft.item.ItemMultiTexture; + +public abstract class WoodItem extends ItemMultiTexture +{ + // This provides a reminder that you must extend this class and change the constructor to accept your extension of + // WoodBlock in the second parameter + + protected WoodItem(Block block, WoodBlock log, String[] names) { super(block, log, names); } +} diff --git a/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/loader/TreeSpeciesLoader.java b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/loader/TreeSpeciesLoader.java new file mode 100644 index 0000000..84d4093 --- /dev/null +++ b/api/KoreSample/src/main/java/com/scottkillen/mod/koresample/tree/loader/TreeSpeciesLoader.java @@ -0,0 +1,146 @@ +package com.scottkillen.mod.koresample.tree.loader; + +import com.google.common.base.Objects; +import com.google.common.collect.Lists; +import com.scottkillen.mod.koresample.common.util.slab.SingleDoubleSlab; +import com.scottkillen.mod.koresample.common.util.slab.TheSingleSlabRegistry; +import com.scottkillen.mod.koresample.tree.DefinesLeaves; +import com.scottkillen.mod.koresample.tree.DefinesLog; +import com.scottkillen.mod.koresample.tree.DefinesSapling; +import com.scottkillen.mod.koresample.tree.DefinesSlab; +import com.scottkillen.mod.koresample.tree.DefinesStairs; +import com.scottkillen.mod.koresample.tree.DefinesWood; +import com.scottkillen.mod.koresample.tree.TreeBlockFactory; +import com.scottkillen.mod.koresample.tree.TreeTaxonomy; +import com.scottkillen.mod.koresample.tree.block.LeavesBlock; +import com.scottkillen.mod.koresample.tree.block.LogBlock; +import com.scottkillen.mod.koresample.tree.block.SaplingBlock; +import com.scottkillen.mod.koresample.common.block.SlabBlock; +import com.scottkillen.mod.koresample.tree.block.WoodBlock; +import java.util.List; + +public class TreeSpeciesLoader +{ + private final TreeTaxonomy taxonomy; + private final TheSingleSlabRegistry slabRegistry = TheSingleSlabRegistry.REFERENCE; + + public TreeSpeciesLoader(TreeTaxonomy taxonomy) + { + this.taxonomy = taxonomy; + } + + public void load(TreeBlockFactory factory) + { + loadLogBlocks(factory); + loadLeavesBlocks(factory); + loadWoodBlocks(factory); + loadSaplingBlocks(factory); + loadSlabBlocks(factory); + loadStairsBlocks(factory); + } + + private void loadLeavesBlocks(TreeBlockFactory factory) + { + final List subBlocks = Lists.newArrayListWithCapacity(LeavesBlock.CAPACITY); + for (final DefinesLeaves definition : taxonomy.leavesDefinitions()) + { + definition.assignLeavesSubBlockIndex(subBlocks.size()); + + subBlocks.add(definition); + if (subBlocks.size() == LeavesBlock.CAPACITY) + { + factory.createLeavesBlock(subBlocks); + subBlocks.clear(); + } + } + if (!subBlocks.isEmpty()) factory.createLeavesBlock(subBlocks); + } + + private void loadLogBlocks(TreeBlockFactory factory) + { + final List subBlocks = Lists.newArrayListWithCapacity(LogBlock.CAPACITY); + for (final DefinesLog definition : taxonomy.logDefinitions()) + { + definition.assignLogSubBlockIndex(subBlocks.size()); + + subBlocks.add(definition); + if (subBlocks.size() == LogBlock.CAPACITY) + { + factory.createLogBlock(subBlocks); + subBlocks.clear(); + } + } + if (!subBlocks.isEmpty()) factory.createLogBlock(subBlocks); + } + + private void loadSaplingBlocks(TreeBlockFactory factory) + { + final List subBlocks = Lists.newArrayListWithCapacity(SaplingBlock.CAPACITY); + for (final DefinesSapling definition : taxonomy.saplingDefinitions()) + { + definition.assignSaplingSubBlockIndex(subBlocks.size()); + + subBlocks.add(definition); + if (subBlocks.size() == SaplingBlock.CAPACITY) + { + factory.createSaplingBlock(subBlocks); + subBlocks.clear(); + } + } + if (!subBlocks.isEmpty()) factory.createSaplingBlock(subBlocks); + } + + private void loadSlabBlocks(TreeBlockFactory factory) + { + final List subBlocks = Lists.newArrayList(); + for (final DefinesSlab definition : taxonomy.slabDefinitions()) + { + definition.assignSlabSubBlockIndex(subBlocks.size()); + + subBlocks.add(definition); + if (subBlocks.size() == SlabBlock.CAPACITY) + { + final SingleDoubleSlab slabs = factory.createSlabBlocks(subBlocks); + slabRegistry.add(slabs.singleSlab()); + + subBlocks.clear(); + } + } + if (!subBlocks.isEmpty()) + { + final SingleDoubleSlab slabs = factory.createSlabBlocks(subBlocks); + slabRegistry.add(slabs.singleSlab()); + } + } + + private void loadStairsBlocks(TreeBlockFactory factory) + { + for (final DefinesStairs definition : taxonomy.stairsDefinitions()) + { + factory.createStairsBlock(definition); + } + } + + private void loadWoodBlocks(TreeBlockFactory factory) + { + final List subBlocks = Lists.newArrayListWithCapacity(WoodBlock.CAPACITY); + for (final DefinesWood definition : taxonomy.woodDefinitions()) + { + definition.assignWoodSubBlockIndex(subBlocks.size()); + + subBlocks.add(definition); + if (subBlocks.size() == WoodBlock.CAPACITY) + { + factory.createWoodBlock(subBlocks); + subBlocks.clear(); + } + } + if (!subBlocks.isEmpty()) factory.createWoodBlock(subBlocks); + } + + @Override + public String toString() + { + return Objects.toStringHelper(this).add("taxonomy", taxonomy).add("slabRegistry", slabRegistry).toString(); + } +} diff --git a/api/KoreSample/src/main/resources/CHANGELOG.md b/api/KoreSample/src/main/resources/CHANGELOG.md new file mode 100644 index 0000000..690ae51 --- /dev/null +++ b/api/KoreSample/src/main/resources/CHANGELOG.md @@ -0,0 +1,31 @@ +# Kore Sample Changelog + +## 1.2.5 +- Fixed lighting bug for slabs and stairs. +- Fixed slabs showing wrong textures. + +## 1.2.4 +- Corrected incorrect log message. + +## 1.2.3 +- Fixed failure to detect config version mismatch. +- Update build environment to Minecraft Forge 10.13.2.1291 + +## 1.2.2 +- Refactored Version Checker integration to be reused by client mods. + +## 1.2.1 +- Add support for [Version Checker][vc_url]. +[vc_url]: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2091981-version-checker-auto-update-mods-and-clean + +## 1.2.0 +- Added boilerplate for forge event listeners + +## 1.1.0 +- Added logo made by [CyanideX][cyanidex_twitter] +- Expand tree definition to include worldGen spawns +- Enhance epic awesomeness +[cyanidex_twitter]: https://twitter.com/electrodynamix + +## 1.0.0 +- Initial release diff --git a/api/KoreSample/src/main/resources/UNLICENSE b/api/KoreSample/src/main/resources/UNLICENSE new file mode 100644 index 0000000..a84c395 --- /dev/null +++ b/api/KoreSample/src/main/resources/UNLICENSE @@ -0,0 +1,25 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + diff --git a/api/KoreSample/src/main/resources/assets/logo.png b/api/KoreSample/src/main/resources/assets/logo.png new file mode 100644 index 0000000..e90b1cf Binary files /dev/null and b/api/KoreSample/src/main/resources/assets/logo.png differ diff --git a/api/KoreSample/src/main/resources/mcmod.info b/api/KoreSample/src/main/resources/mcmod.info new file mode 100644 index 0000000..f34d532 --- /dev/null +++ b/api/KoreSample/src/main/resources/mcmod.info @@ -0,0 +1,21 @@ +[ +{ + "modid": "koresample", + "name": "Kore Sample", + "description": "Kore Sample provides a set of tools and base classes for other Minecraft mods that depend on it.", + "version": "${mod_version}", + "mcversion": "${minecraft_version}", + "url": "", + "updateUrl": "", + "authorList": [ + "ScottKillen" + ], + "credits": "", + "logoFile": "assets/logo.png", + "screenshots": [ + ], + "parent":"", + "dependencies": [ + ] +} +] diff --git a/api/KoreSample/src/main/resources/version.properties b/api/KoreSample/src/main/resources/version.properties new file mode 100644 index 0000000..c204bf4 --- /dev/null +++ b/api/KoreSample/src/main/resources/version.properties @@ -0,0 +1,3 @@ +version.mod=${mod_version} +version.forge=${forge_version} +version.minecraft=${minecraft_version} diff --git a/api/KoreSample/version/.gitignore b/api/KoreSample/version/.gitignore new file mode 100644 index 0000000..89654b7 --- /dev/null +++ b/api/KoreSample/version/.gitignore @@ -0,0 +1 @@ +version.iml diff --git a/api/KoreSample/version/build.gradle b/api/KoreSample/version/build.gradle new file mode 100644 index 0000000..9977553 --- /dev/null +++ b/api/KoreSample/version/build.gradle @@ -0,0 +1,42 @@ +rootProject.version = "$mcversion-$version_major.$version_series.$version_revision" +rootProject.ext.mcversion = mcversion +rootProject.ext.forgeversion = forgeversion + +task echoVersion << { + printNextVersion() +} + +def saveVersion() { + ant.propertyfile( + file: "gradle.properties") { + entry( key:"version_major", type:"int", value: version_major) + entry( key:"version_series", type:"int", value: version_series) + entry( key:"version_revision", type:"int", value: version_revision) + } + rootProject.version = "$mcversion-$version_major.$version_series.$version_revision" + printNextVersion() +} + +def printNextVersion(){ + println '*************************************************************' + println 'The next build will be version: ' + rootProject.version + println '*************************************************************' +} + +task bumpMajor << { + project.version_major = Integer.parseInt(project.version_major) + 1 + project.version_series = "0" + project.version_revision = "0" + saveVersion() +} + +task bumpSeries << { + project.version_series = Integer.parseInt(project.version_series) + 1 + project.version_revision = "0" + saveVersion() +} + +task bumpRevision << { + project.version_revision = Integer.parseInt(project.version_revision) + 1 + saveVersion() +} diff --git a/api/KoreSample/version/gradle.properties b/api/KoreSample/version/gradle.properties new file mode 100644 index 0000000..b8fce11 --- /dev/null +++ b/api/KoreSample/version/gradle.properties @@ -0,0 +1,6 @@ +#Mon, 16 Feb 2015 00:21:40 -0500 +mcversion=1.7.10 +forgeversion=10.13.2.1291 +version_major=1 +version_series=2 +version_revision=5 diff --git a/build.gradle b/build.gradle index 6700e31..0bd8761 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,8 @@ apply plugin: 'maven' group = "com.scottkillen.mod" archivesBaseName = "ScottsTweaks" +ext.apiKore = "./api/KoreSample/src/main/java" + minecraft { version = project.mcversion + "-" + project.forgeversion runDir = "run" @@ -30,17 +32,14 @@ minecraft { replace '${mod_version}', project.version } -repositories { - mavenLocal() - maven { - url = 'http://maven.scottkillen.com/' +sourceSets { + api { + java { + srcDir project.apiKore + } } } -dependencies { - compile "com.scottkillen.mod:KoreSample:${project.ext.koreversion}:deobf" -} - processResources { // this will ensure that this task is redone when the versions change. diff --git a/src/main/java/com/scottkillen/mod/scottstweaks/TheMod.java b/src/main/java/com/scottkillen/mod/scottstweaks/TheMod.java index 23151e1..a3961cf 100644 --- a/src/main/java/com/scottkillen/mod/scottstweaks/TheMod.java +++ b/src/main/java/com/scottkillen/mod/scottstweaks/TheMod.java @@ -7,9 +7,10 @@ import com.scottkillen.mod.koresample.compat.versionchecker.Versioned; import com.scottkillen.mod.koresample.config.ConfigEventHandler; import com.scottkillen.mod.scottstweaks.config.Settings; -import com.scottkillen.mod.scottstweaks.tweaks.ClayGenerator; import com.scottkillen.mod.scottstweaks.tweaks.chicken.ChickenPlucker; import com.scottkillen.mod.scottstweaks.tweaks.planting.Planter; +import com.scottkillen.mod.scottstweaks.tweaks.spawncontrol.SpawnGovernor; +import com.scottkillen.mod.scottstweaks.tweaks.worldgen.ClayGenerator; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; @@ -57,6 +58,7 @@ public void onFMLInitialization(FMLInitializationEvent unused) new ChickenPlucker().listen(MinecraftForge.EVENT_BUS); new Planter().listen(MinecraftForge.EVENT_BUS); new ClayGenerator().install(); + new SpawnGovernor().listen(MinecraftForge.EVENT_BUS); } @Override diff --git a/src/main/java/com/scottkillen/mod/scottstweaks/config/Settings.java b/src/main/java/com/scottkillen/mod/scottstweaks/config/Settings.java index ba788c2..de9cbaf 100644 --- a/src/main/java/com/scottkillen/mod/scottstweaks/config/Settings.java +++ b/src/main/java/com/scottkillen/mod/scottstweaks/config/Settings.java @@ -16,6 +16,8 @@ public enum Settings implements ConfigSyncable String.format("%s%sfeather_drop", Configuration.CATEGORY_GENERAL, Configuration.CATEGORY_SPLITTER); private static final String CATEGORY_PLANTING = String.format("%s%splanting", Configuration.CATEGORY_GENERAL, Configuration.CATEGORY_SPLITTER); + private static final String CATEGORY_SPAWN_CONTROL = + String.format("%s%sspawn_control", Configuration.CATEGORY_GENERAL, Configuration.CATEGORY_SPLITTER); private int chickFeatherQuantity = 1; @@ -27,6 +29,8 @@ public enum Settings implements ConfigSyncable private int clayVeinSizeMin = 12; private int claySpawnYMin = 50; private int claySpawnYMax = 60; + private int batSpawnPercent = 100; + private int squidSpawnPercent = 100; private boolean doChicksDropFeathers = true; private boolean doHensDropFeathers = true; private boolean doPlantGrowable = true; @@ -75,6 +79,9 @@ public void syncConfig(Configuration config) clayVeinSizeMin = get(config, "clayVeinSizeMin", CATEGORY_CLAY_SPAWN, clayVeinSizeMin, 0, clayVeinSizeMax); claySpawnYMax = get(config, "claySpawnYMax", CATEGORY_CLAY_SPAWN, claySpawnYMax, 1, 255); claySpawnYMin = get(config, "claySpawnYMin", CATEGORY_CLAY_SPAWN, claySpawnYMin, 1, claySpawnYMax); + + batSpawnPercent = get(config, "batSpawnPercent", CATEGORY_SPAWN_CONTROL, batSpawnPercent, 0, 100); + squidSpawnPercent = get(config, "squidSpawnPercent", CATEGORY_SPAWN_CONTROL, squidSpawnPercent, 0, 100); } public int chickFeatherQuantity() { return chickFeatherQuantity; } @@ -101,6 +108,10 @@ public void syncConfig(Configuration config) public int henFeatherRarity() { return henFeatherRarity; } + public int batSpawnPercent() { return batSpawnPercent; } + + public int squidSpawnPercent() { return squidSpawnPercent; } + @Override public String toString() { @@ -109,6 +120,7 @@ public String toString() .add("henFeatherRarity", henFeatherRarity).add("clayVeinQuantity", clayVeinQuantity) .add("clayVeinSizeMax", clayVeinSizeMax).add("clayVeinSizeMin", clayVeinSizeMin) .add("claySpawnYMin", claySpawnYMin).add("claySpawnYMax", claySpawnYMax) + .add("batSpawnPercent", batSpawnPercent).add("squidSpawnPercent", squidSpawnPercent) .add("doChicksDropFeathers", doChicksDropFeathers).add("doHensDropFeathers", doHensDropFeathers) .add("doPlantGrowable", doPlantGrowable).toString(); } diff --git a/src/main/java/com/scottkillen/mod/scottstweaks/tweaks/spawncontrol/SpawnGovernor.java b/src/main/java/com/scottkillen/mod/scottstweaks/tweaks/spawncontrol/SpawnGovernor.java new file mode 100644 index 0000000..a0c0760 --- /dev/null +++ b/src/main/java/com/scottkillen/mod/scottstweaks/tweaks/spawncontrol/SpawnGovernor.java @@ -0,0 +1,36 @@ +package com.scottkillen.mod.scottstweaks.tweaks.spawncontrol; + +import com.scottkillen.mod.koresample.common.util.event.ForgeEventListener; +import com.scottkillen.mod.scottstweaks.config.Settings; +import cpw.mods.fml.common.eventhandler.Event.Result; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.EntityBat; +import net.minecraft.entity.passive.EntitySquid; +import net.minecraftforge.event.entity.living.LivingSpawnEvent.CheckSpawn; + +public final class SpawnGovernor extends ForgeEventListener +{ + @SuppressWarnings("MethodMayBeStatic") + @SubscribeEvent + public void onCheckSpawn(CheckSpawn event) + { + if (event.entity.worldObj.isRemote) return; + + if (event.entity instanceof EntityBat || event.entity instanceof EntitySquid) + { + event.setResult(limitSpawn(event.entity)); + } + } + + private Result limitSpawn(Entity entity) + { + final Settings settings = Settings.INSTANCE; + final int successChance = + entity instanceof EntityBat ? settings.batSpawnPercent() : settings.squidSpawnPercent(); + if (successChance == 0) return Result.DENY; + if (successChance == 100) return Result.DEFAULT; + + return entity.worldObj.rand.nextInt(100) < successChance ? Result.DEFAULT : Result.DENY; + } +} diff --git a/src/main/java/com/scottkillen/mod/scottstweaks/tweaks/ClayGenerator.java b/src/main/java/com/scottkillen/mod/scottstweaks/tweaks/worldgen/ClayGenerator.java similarity index 96% rename from src/main/java/com/scottkillen/mod/scottstweaks/tweaks/ClayGenerator.java rename to src/main/java/com/scottkillen/mod/scottstweaks/tweaks/worldgen/ClayGenerator.java index 53e8c63..41f9e96 100644 --- a/src/main/java/com/scottkillen/mod/scottstweaks/tweaks/ClayGenerator.java +++ b/src/main/java/com/scottkillen/mod/scottstweaks/tweaks/worldgen/ClayGenerator.java @@ -1,4 +1,4 @@ -package com.scottkillen.mod.scottstweaks.tweaks; +package com.scottkillen.mod.scottstweaks.tweaks.worldgen; import com.scottkillen.mod.scottstweaks.config.Settings; import cpw.mods.fml.common.IWorldGenerator; diff --git a/src/main/resources/CHANGELOG.md b/src/main/resources/CHANGELOG.md index 83750a7..b9f83c7 100644 --- a/src/main/resources/CHANGELOG.md +++ b/src/main/resources/CHANGELOG.md @@ -1,3 +1,9 @@ +# Scott's Tweaks Changelog + +## 1.2.0 +- Update build environment to minecraft Forge 10.13.2.1291 +- Added bat and squid spawn control. + ## 1.1.0 - Added clay generation to overworld. diff --git a/src/main/resources/assets/scottstweaks/lang/en_US.lang b/src/main/resources/assets/scottstweaks/lang/en_US.lang index e626703..be074d5 100644 --- a/src/main/resources/assets/scottstweaks/lang/en_US.lang +++ b/src/main/resources/assets/scottstweaks/lang/en_US.lang @@ -12,3 +12,5 @@ config.scottstweaks:doChicksDropFeathers='True' enables feather drops from live config.scottstweaks:doHensDropFeathers='True' enables feather drops from live adult chickens. config.scottstweaks:henFeatherQuantity=The number of feathers dropped by live adult chickens. config.scottstweaks:henFeatherRarity=The rarity of an adult chicken dropping feathers. Higher values are more rare. +config.scottstweaks:batSpawnPercent=Limit bat spawning to this percentage of vanilla rate. (0 disables spawns; 100 preserves vanilla rate) +config.scottstweaks:squidSpawnPercent=Limit squid spawning to this percentage of vanilla rate. (0 disables spawns; 100 preserves vanilla rate) diff --git a/version/gradle.properties b/version/gradle.properties index d3bf69a..ad1d6f7 100644 --- a/version/gradle.properties +++ b/version/gradle.properties @@ -1,7 +1,7 @@ -#Sun, 08 Feb 2015 23:28:27 -0500 +#Sat, 21 Feb 2015 01:35:30 -0500 mcversion=1.7.10 -forgeversion=10.13.2.1235 -koreversion=1.2.2 +forgeversion=10.13.2.1291 +koreversion=1.2.5 version_major=1 -version_series=1 +version_series=2 version_revision=0