mirror of
https://github.com/GTNewHorizons/bdlib.git
synced 2026-10-26 22:33:53 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70e34b9265 | ||
|
|
5599113c05 | ||
|
|
12653d1295 | ||
|
|
57a1192dc0 | ||
|
|
81e051b592 | ||
|
|
a6eb495fe1 | ||
|
|
2d539e8013 | ||
|
|
c44729536c | ||
|
|
35def010a3 | ||
|
|
911f7aa159 | ||
|
|
3aef519c25 | ||
|
|
6c59b25e2c | ||
|
|
014c1c5e6e | ||
|
|
7fd040e65a | ||
|
|
ece84599f9 | ||
|
|
174af254e8 | ||
|
|
71185838f6 | ||
|
|
f2cdba7800 | ||
|
|
89b54300e3 | ||
|
|
9ee12091e6 | ||
|
|
08ccf07dfb | ||
|
|
382c21f732 | ||
|
|
17e4bf3a2f | ||
|
|
ebe2c1f34a | ||
|
|
fae2825e7b | ||
|
|
b2e138f3cd | ||
|
|
9d897d0663 | ||
|
|
497917185c | ||
|
|
9ff7a75604 | ||
|
|
f8bb1e8fbb | ||
|
|
a530c66680 | ||
|
|
26af828491 | ||
|
|
1c0913d674 | ||
|
|
895cfd9cb6 | ||
|
|
f43dd28e03 | ||
|
|
289f8f7120 | ||
|
|
e7787fb9ca | ||
|
|
58e336f8a9 | ||
|
|
bea6a13896 | ||
|
|
793ceb0024 | ||
|
|
66d9be58c8 | ||
|
|
87d64208c8 | ||
|
|
6f6496c1e3 | ||
|
|
934e984abf | ||
|
|
4900537a82 | ||
|
|
31b5ab9d52 | ||
|
|
8a4ccf7d81 | ||
|
|
429107215f | ||
|
|
0c60d596b6 | ||
|
|
da35094895 | ||
|
|
83d30f12c2 | ||
|
|
8d4484ca18 | ||
|
|
624df87299 | ||
|
|
18b4f19dab | ||
|
|
00b32712a0 | ||
|
|
2a008aa093 | ||
|
|
745170415e | ||
|
|
69b8e80c5f | ||
|
|
93ccc42429 | ||
|
|
dc567bd1be | ||
|
|
516133ee0a | ||
|
|
28de3620a2 | ||
|
|
61ba86d451 | ||
|
|
8e65772cae | ||
|
|
284cdfc970 | ||
|
|
bae688c366 | ||
|
|
d3952b69d0 | ||
|
|
399abf1054 | ||
|
|
f66b97d0cc | ||
|
|
13778072c0 | ||
|
|
7dc95fcce1 | ||
|
|
b71db73b11 | ||
|
|
530d5add82 | ||
|
|
3dd917b2a0 | ||
|
|
8f44111b4c | ||
|
|
8415ee7a00 | ||
|
|
6439ef8f08 | ||
|
|
dc59ee3d31 | ||
|
|
9ae4935fd9 | ||
|
|
0929ba9278 | ||
|
|
1003aa1d6a | ||
|
|
64c0484c2d | ||
|
|
8e90643ea1 | ||
|
|
a232ce52f3 | ||
|
|
35b3a77582 | ||
|
|
be3a1cf2aa | ||
|
|
e0f5d0ceda | ||
|
|
e4169f7a5d | ||
|
|
eb75a26c40 | ||
|
|
3431a6910e | ||
|
|
02598183b8 | ||
|
|
70c19bff5b | ||
|
|
6a78467232 | ||
|
|
561833db33 | ||
|
|
0e345e6675 | ||
|
|
e78e565ec8 | ||
|
|
573330efd3 |
No files matched your search
@@ -0,0 +1,9 @@
|
||||
directory="run/crash-reports"
|
||||
if [ -d $directory ]; then
|
||||
echo "Crash reports detected:"
|
||||
cat $directory/*
|
||||
exit 1
|
||||
else
|
||||
echo "No crash reports detected"
|
||||
exit 0
|
||||
fi
|
||||
@@ -0,0 +1,45 @@
|
||||
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Build and test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master, main ]
|
||||
push:
|
||||
branches: [ master, main ]
|
||||
|
||||
jobs:
|
||||
build-and-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Setup the workspace
|
||||
run: ./gradlew setupCIWorkspace
|
||||
|
||||
- name: Build the mod
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Run server for 1 minute
|
||||
run: |
|
||||
mkdir run
|
||||
echo "eula=true" > run/eula.txt
|
||||
timeout 10 ./gradlew runServer || true
|
||||
|
||||
- name: Test no crashes happend
|
||||
run: |
|
||||
chmod +x .github/scripts/test-no-crash-reports.sh
|
||||
.github/scripts/test-no-crash-reports.sh
|
||||
@@ -0,0 +1,51 @@
|
||||
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Release tagged build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set release version
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Setup the workspace
|
||||
run: ./gradlew setupCIWorkspace
|
||||
|
||||
- name: Build the mod
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Release under current tag
|
||||
uses: "marvinpinto/action-automatic-releases@latest"
|
||||
with:
|
||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
automatic_release_tag: "${{ env.RELEASE_VERSION }}"
|
||||
prerelease: false
|
||||
title: "${{ env.RELEASE_VERSION }}"
|
||||
files: build/libs/*.jar
|
||||
|
||||
- name: Publish to Maven
|
||||
run: ./gradlew publish
|
||||
env:
|
||||
MAVEN_USER: ${{ secrets.MAVEN_USER }}
|
||||
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||
+28
-10
@@ -1,10 +1,28 @@
|
||||
/bin
|
||||
/out
|
||||
/build
|
||||
/run
|
||||
/deps/run
|
||||
/eclipse
|
||||
/.gradle
|
||||
/*.iml
|
||||
/*.ipr
|
||||
/.idea
|
||||
.gradle
|
||||
.settings
|
||||
/.idea/
|
||||
/run/
|
||||
/build/
|
||||
/eclipse/
|
||||
.classpath
|
||||
.project
|
||||
/bin/
|
||||
/config/
|
||||
/crash-reports/
|
||||
/logs/
|
||||
options.txt
|
||||
/saves/
|
||||
usernamecache.json
|
||||
banned-ips.json
|
||||
banned-players.json
|
||||
eula.txt
|
||||
ops.json
|
||||
server.properties
|
||||
servers.dat
|
||||
usercache.json
|
||||
whitelist.json
|
||||
/out/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
src/main/resources/mixins.*.json
|
||||
@@ -0,0 +1,3 @@
|
||||
# Any Github changes require admin approval
|
||||
/.github/** @GTNewHorizons/admin
|
||||
|
||||
+541
-49
@@ -1,102 +1,594 @@
|
||||
//version: 1642484596
|
||||
/*
|
||||
DO NOT CHANGE THIS FILE!
|
||||
|
||||
Also, you may replace this file at any time if there is an update available.
|
||||
Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates.
|
||||
*/
|
||||
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
buildscript {
|
||||
configurations.all {
|
||||
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "forge"
|
||||
url = "http://files.minecraftforge.net/maven"
|
||||
url = "https://maven.minecraftforge.net"
|
||||
}
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
}
|
||||
maven {
|
||||
name = "Scala CI dependencies"
|
||||
url = "https://repo1.maven.org/maven2/"
|
||||
}
|
||||
maven {
|
||||
name = "jitpack"
|
||||
url = "https://jitpack.io"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
|
||||
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.5'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'scala'
|
||||
plugins {
|
||||
id 'idea'
|
||||
id 'scala'
|
||||
id("org.ajoberstar.grgit") version("3.1.1")
|
||||
id("com.github.johnrengelman.shadow") version("4.0.4")
|
||||
id("com.palantir.git-version") version("0.12.3")
|
||||
id("maven-publish")
|
||||
}
|
||||
|
||||
apply plugin: 'forge'
|
||||
|
||||
version = "1.6.0"
|
||||
def projectJavaVersion = JavaLanguageVersion.of(8)
|
||||
|
||||
if (project.hasProperty('buildnum')) {
|
||||
project.version = project.version + '.' + project.buildnum
|
||||
} else {
|
||||
project.version = "0-SNAPSHOT"
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(projectJavaVersion)
|
||||
}
|
||||
}
|
||||
|
||||
group = "net.bdew"
|
||||
archivesBaseName = "bdlib"
|
||||
ext.versuffix = "mc1710"
|
||||
idea {
|
||||
module {
|
||||
inheritOutputDirs = true
|
||||
downloadJavadoc = true
|
||||
downloadSources = true
|
||||
}
|
||||
}
|
||||
|
||||
if(JavaVersion.current() != JavaVersion.VERSION_1_8) {
|
||||
throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current())
|
||||
}
|
||||
|
||||
checkPropertyExists("modName")
|
||||
checkPropertyExists("modId")
|
||||
checkPropertyExists("modGroup")
|
||||
checkPropertyExists("autoUpdateBuildScript")
|
||||
checkPropertyExists("minecraftVersion")
|
||||
checkPropertyExists("forgeVersion")
|
||||
checkPropertyExists("replaceGradleTokenInFile")
|
||||
checkPropertyExists("gradleTokenModId")
|
||||
checkPropertyExists("gradleTokenModName")
|
||||
checkPropertyExists("gradleTokenVersion")
|
||||
checkPropertyExists("gradleTokenGroupName")
|
||||
checkPropertyExists("apiPackage")
|
||||
checkPropertyExists("accessTransformersFile")
|
||||
checkPropertyExists("usesMixins")
|
||||
checkPropertyExists("mixinPlugin")
|
||||
checkPropertyExists("mixinsPackage")
|
||||
checkPropertyExists("coreModClass")
|
||||
checkPropertyExists("containsMixinsAndOrCoreModOnly")
|
||||
checkPropertyExists("usesShadowedDependencies")
|
||||
checkPropertyExists("developmentEnvironmentUserName")
|
||||
|
||||
boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
|
||||
|
||||
String javaSourceDir = "src/main/java/"
|
||||
String scalaSourceDir = "src/main/scala/"
|
||||
|
||||
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
|
||||
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
|
||||
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
|
||||
}
|
||||
|
||||
if(apiPackage) {
|
||||
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
|
||||
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
|
||||
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
|
||||
}
|
||||
}
|
||||
|
||||
if(accessTransformersFile) {
|
||||
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
|
||||
if(getFile(targetFile).exists() == false) {
|
||||
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
|
||||
}
|
||||
}
|
||||
|
||||
if(usesMixins.toBoolean()) {
|
||||
if(mixinsPackage.isEmpty() || mixinPlugin.isEmpty()) {
|
||||
throw new GradleException("\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!")
|
||||
}
|
||||
|
||||
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
|
||||
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
|
||||
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
|
||||
}
|
||||
|
||||
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
|
||||
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala"
|
||||
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
|
||||
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
|
||||
}
|
||||
}
|
||||
|
||||
if(coreModClass) {
|
||||
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
|
||||
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala"
|
||||
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
|
||||
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
|
||||
}
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS)
|
||||
|
||||
// Make sure GregTech build won't time out
|
||||
System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String)
|
||||
System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String)
|
||||
}
|
||||
|
||||
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
|
||||
'git config core.fileMode false'.execute()
|
||||
|
||||
// Pulls version first from the VERSION env and then git tag
|
||||
String identifiedVersion
|
||||
try {
|
||||
String versionOverride = System.getenv("VERSION") ?: null
|
||||
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
|
||||
version = minecraftVersion + "-" + identifiedVersion
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException("This mod must be version controlled by Git AND the repository must provide at least one tag, or the VERSION override must be set!");
|
||||
}
|
||||
|
||||
group = modGroup
|
||||
if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
|
||||
archivesBaseName = customArchiveBaseName
|
||||
}
|
||||
else {
|
||||
archivesBaseName = modId
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = "1.7.10-10.13.2.1231"
|
||||
replace("BDLIB_VER", project.version)
|
||||
}
|
||||
version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion
|
||||
runDir = "run"
|
||||
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
scala {
|
||||
srcDir 'src'
|
||||
if (replaceGradleTokenInFile) {
|
||||
replaceIn replaceGradleTokenInFile
|
||||
if(gradleTokenModId) {
|
||||
replace gradleTokenModId, modId
|
||||
}
|
||||
resources {
|
||||
srcDir 'resources'
|
||||
if(gradleTokenModName) {
|
||||
replace gradleTokenModName, modName
|
||||
}
|
||||
if(gradleTokenVersion) {
|
||||
replace gradleTokenVersion, versionDetails().lastTag
|
||||
}
|
||||
if(gradleTokenGroupName) {
|
||||
replace gradleTokenGroupName, modGroup
|
||||
}
|
||||
output.resourcesDir = output.classesDir // Hack for IDEA
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "tokens", minecraft.replacements
|
||||
if(file("addon.gradle").exists()) {
|
||||
apply from: "addon.gradle"
|
||||
}
|
||||
|
||||
apply from: 'repositories.gradle'
|
||||
|
||||
configurations {
|
||||
implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored
|
||||
implementation.extendsFrom(shadowCompile)
|
||||
implementation.extendsFrom(shadeCompile)
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "Overmind forge repo mirror"
|
||||
url = "https://gregtech.overminddl1.com/"
|
||||
}
|
||||
if(usesMixins.toBoolean()) {
|
||||
maven {
|
||||
name = "sponge"
|
||||
url = "https://repo.spongepowered.org/repository/maven-public"
|
||||
}
|
||||
maven {
|
||||
url = "https://jitpack.io"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
if(usesMixins.toBoolean()) {
|
||||
annotationProcessor("org.ow2.asm:asm-debug-all:5.0.3")
|
||||
annotationProcessor("com.google.guava:guava:24.1.1-jre")
|
||||
annotationProcessor("com.google.code.gson:gson:2.8.6")
|
||||
annotationProcessor("org.spongepowered:mixin:0.8-SNAPSHOT")
|
||||
// using 0.8 to workaround a issue in 0.7 which fails mixin application
|
||||
compile("com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH") {
|
||||
// Mixin includes a lot of dependencies that are too up-to-date
|
||||
exclude module: "launchwrapper"
|
||||
exclude module: "guava"
|
||||
exclude module: "gson"
|
||||
exclude module: "commons-io"
|
||||
exclude module: "log4j-core"
|
||||
}
|
||||
compile("com.github.GTNewHorizons:SpongeMixins:1.5.0")
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'dependencies.gradle'
|
||||
|
||||
def mixingConfigRefMap = "mixins." + modId + ".refmap.json"
|
||||
def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap
|
||||
def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg"
|
||||
|
||||
task generateAssets {
|
||||
if(usesMixins.toBoolean()) {
|
||||
getFile("/src/main/resources/mixins." + modId + ".json").text = """{
|
||||
"required": true,
|
||||
"minVersion": "0.7.11",
|
||||
"package": "${modGroup}.${mixinsPackage}",
|
||||
"plugin": "${modGroup}.${mixinPlugin}",
|
||||
"refmap": "${mixingConfigRefMap}",
|
||||
"target": "@env(DEFAULT)",
|
||||
"compatibilityLevel": "JAVA_8"
|
||||
}
|
||||
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
task relocateShadowJar(type: ConfigureShadowRelocation) {
|
||||
target = tasks.shadowJar
|
||||
prefix = modGroup + ".shadow"
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
manifest {
|
||||
attributes(getManifestAttributes())
|
||||
}
|
||||
|
||||
minimize() // This will only allow shading for actually used classes
|
||||
configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile]
|
||||
dependsOn(relocateShadowJar)
|
||||
}
|
||||
|
||||
jar {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
manifest {
|
||||
attributes(getManifestAttributes())
|
||||
}
|
||||
|
||||
if(usesShadowedDependencies.toBoolean()) {
|
||||
dependsOn(shadowJar)
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
reobf {
|
||||
if(usesMixins.toBoolean()) {
|
||||
addExtraSrgFile mixinSrg
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
if(usesMixins.toBoolean()) {
|
||||
tasks.compileJava {
|
||||
options.compilerArgs += [
|
||||
"-AreobfSrgFile=${tasks.reobf.srg}",
|
||||
"-AoutSrgFile=${mixinSrg}",
|
||||
"-AoutRefMapFile=${refMap}",
|
||||
// Elan: from what I understand they are just some linter configs so you get some warning on how to properly code
|
||||
"-XDenableSunApiLintControl",
|
||||
"-XDignore.symbol.file"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runClient {
|
||||
def arguments = []
|
||||
|
||||
if(usesMixins.toBoolean()) {
|
||||
arguments += [
|
||||
"--mods=../build/libs/$modId-${version}.jar",
|
||||
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
|
||||
]
|
||||
}
|
||||
|
||||
if(developmentEnvironmentUserName) {
|
||||
arguments += [
|
||||
"--username",
|
||||
developmentEnvironmentUserName
|
||||
]
|
||||
}
|
||||
|
||||
args(arguments)
|
||||
}
|
||||
|
||||
runServer {
|
||||
def arguments = []
|
||||
|
||||
if (usesMixins.toBoolean()) {
|
||||
arguments += [
|
||||
"--mods=../build/libs/$modId-${version}.jar",
|
||||
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
|
||||
]
|
||||
}
|
||||
|
||||
args(arguments)
|
||||
}
|
||||
|
||||
tasks.withType(JavaExec).configureEach {
|
||||
javaLauncher.set(
|
||||
javaToolchains.launcherFor {
|
||||
languageVersion = projectJavaVersion
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
processResources
|
||||
{
|
||||
// this will ensure that this task is redone when the versions change.
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
|
||||
// replace stuff in mcmod.info, nothing else
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
filter(ReplaceTokens, tokens: minecraft.replacements)
|
||||
|
||||
// replace version and mcversion
|
||||
expand "minecraftVersion": project.minecraft.version,
|
||||
"modVersion": versionDetails().lastTag,
|
||||
"modId": modId,
|
||||
"modName": modName
|
||||
}
|
||||
|
||||
if(usesMixins.toBoolean()) {
|
||||
from refMap
|
||||
}
|
||||
|
||||
// copy everything else, thats not the mcmod.info
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
}
|
||||
}
|
||||
|
||||
task sourceJar(type: Jar) {
|
||||
from sourceSets.main.allSource
|
||||
def getManifestAttributes() {
|
||||
def manifestAttributes = [:]
|
||||
if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) {
|
||||
manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
|
||||
}
|
||||
|
||||
if(accessTransformersFile) {
|
||||
manifestAttributes += ["FMLAT" : accessTransformersFile.toString()]
|
||||
}
|
||||
|
||||
if(coreModClass) {
|
||||
manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass]
|
||||
}
|
||||
|
||||
if(usesMixins.toBoolean()) {
|
||||
manifestAttributes += [
|
||||
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
|
||||
"MixinConfigs" : "mixins." + modId + ".json",
|
||||
"ForceLoadAsMod" : containsMixinsAndOrCoreModOnly.toBoolean() == false
|
||||
]
|
||||
}
|
||||
return manifestAttributes
|
||||
}
|
||||
|
||||
task deobfJar(type: Jar) {
|
||||
from sourceSets.main.output.classesDir
|
||||
task sourcesJar(type: Jar) {
|
||||
from (sourceSets.main.allJava)
|
||||
from (file("$projectDir/LICENSE"))
|
||||
getArchiveClassifier().set('sources')
|
||||
}
|
||||
|
||||
jar {
|
||||
appendix = project.versuffix
|
||||
task shadowDevJar(type: ShadowJar) {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
from sourceSets.main.output
|
||||
getArchiveClassifier().set("dev")
|
||||
|
||||
manifest {
|
||||
attributes(getManifestAttributes())
|
||||
}
|
||||
|
||||
minimize() // This will only allow shading for actually used classes
|
||||
configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile]
|
||||
}
|
||||
|
||||
task relocateShadowDevJar(type: ConfigureShadowRelocation) {
|
||||
target = tasks.shadowDevJar
|
||||
prefix = modGroup + ".shadow"
|
||||
}
|
||||
|
||||
task circularResolverJar(type: Jar) {
|
||||
dependsOn(relocateShadowDevJar)
|
||||
dependsOn(shadowDevJar)
|
||||
enabled = false
|
||||
}
|
||||
|
||||
task devJar(type: Jar) {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
from sourceSets.main.output
|
||||
getArchiveClassifier().set("dev")
|
||||
|
||||
manifest {
|
||||
attributes(getManifestAttributes())
|
||||
}
|
||||
|
||||
if(usesShadowedDependencies.toBoolean()) {
|
||||
dependsOn(circularResolverJar)
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
task apiJar(type: Jar) {
|
||||
from (sourceSets.main.allJava) {
|
||||
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
|
||||
}
|
||||
|
||||
from (sourceSets.main.output) {
|
||||
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
|
||||
}
|
||||
|
||||
from (sourceSets.main.resources.srcDirs) {
|
||||
include("LICENSE")
|
||||
}
|
||||
|
||||
getArchiveClassifier().set('api')
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourceJar
|
||||
archives deobfJar
|
||||
if(!noPublishedSources) {
|
||||
archives sourcesJar
|
||||
}
|
||||
archives devJar
|
||||
if(apiPackage) {
|
||||
archives apiJar
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
// publishing
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
artifact deobfJar
|
||||
artifact source: usesShadowedDependencies.toBoolean() ? shadowJar : jar, classifier: ""
|
||||
if(!noPublishedSources) {
|
||||
artifact source: sourcesJar, classifier: "src"
|
||||
}
|
||||
artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev"
|
||||
if (apiPackage) {
|
||||
artifact source: apiJar, classifier: "api"
|
||||
}
|
||||
|
||||
artifact sourceJar {
|
||||
classifier "sources"
|
||||
groupId = System.getenv("ARTIFACT_GROUP_ID") ?: "com.github.GTNewHorizons"
|
||||
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
|
||||
// Using the identified version, not project.version as it has the prepended 1.7.10
|
||||
version = System.getenv("RELEASE_VERSION") ?: identifiedVersion
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases"
|
||||
credentials {
|
||||
username = System.getenv("MAVEN_USER") ?: "NONE"
|
||||
password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
|
||||
}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
url "file://var/www/maven"
|
||||
}
|
||||
}
|
||||
|
||||
// Updating
|
||||
task updateBuildScript {
|
||||
doLast {
|
||||
if (performBuildScriptUpdate(projectDir.toString())) return
|
||||
|
||||
print("Build script already up-to-date!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewBuildScriptVersionAvailable(projectDir.toString())) {
|
||||
if (autoUpdateBuildScript.toBoolean()) {
|
||||
performBuildScriptUpdate(projectDir.toString())
|
||||
} else {
|
||||
println("Build script update available! Run 'gradle updateBuildScript'")
|
||||
}
|
||||
}
|
||||
|
||||
static URL availableBuildScriptUrl() {
|
||||
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/main/build.gradle")
|
||||
}
|
||||
|
||||
boolean performBuildScriptUpdate(String projectDir) {
|
||||
if (isNewBuildScriptVersionAvailable(projectDir)) {
|
||||
def buildscriptFile = getFile("build.gradle")
|
||||
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
|
||||
print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
boolean isNewBuildScriptVersionAvailable(String projectDir) {
|
||||
Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
|
||||
|
||||
String currentBuildScript = getFile("build.gradle").getText()
|
||||
String currentBuildScriptHash = getVersionHash(currentBuildScript)
|
||||
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
|
||||
String availableBuildScriptHash = getVersionHash(availableBuildScript)
|
||||
|
||||
boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash
|
||||
return !isUpToDate
|
||||
}
|
||||
|
||||
static String getVersionHash(String buildScriptContent) {
|
||||
String versionLine = buildScriptContent.find("^//version: [a-z0-9]*")
|
||||
if(versionLine != null) {
|
||||
return versionLine.split(": ").last()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
configure(updateBuildScript) {
|
||||
group = 'forgegradle'
|
||||
description = 'Updates the build script to the latest version'
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
|
||||
def checkPropertyExists(String propertyName) {
|
||||
if (project.hasProperty(propertyName) == false) {
|
||||
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties")
|
||||
}
|
||||
}
|
||||
|
||||
def getFile(String relativePath) {
|
||||
return new File(projectDir, relativePath)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// Add your dependencies here
|
||||
|
||||
dependencies {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
modName = BD lib
|
||||
|
||||
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
|
||||
modId = bdlib
|
||||
|
||||
modGroup = net.bdew.lib
|
||||
|
||||
# WHY is there no version field?
|
||||
# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the
|
||||
# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/
|
||||
|
||||
# Will update your build.gradle automatically whenever an update is available
|
||||
autoUpdateBuildScript = false
|
||||
|
||||
minecraftVersion = 1.7.10
|
||||
forgeVersion = 10.13.4.1614
|
||||
|
||||
# Select a username for testing your mod with breakpoints. You may leave this empty for a random user name each time you
|
||||
# restart Minecraft in development. Choose this dependent on your mod:
|
||||
# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
|
||||
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
|
||||
developmentEnvironmentUserName = "Developer"
|
||||
|
||||
# Define a source file of your project with:
|
||||
# public static final String VERSION = "GRADLETOKEN_VERSION";
|
||||
# The string's content will be replaced with your mods version when compiled. You should use this to specify your mod's
|
||||
# version in @Mod([...], version = VERSION, [...])
|
||||
# Leave these properties empty to skip individual token replacements
|
||||
replaceGradleTokenInFile = BdLib.scala
|
||||
gradleTokenModId =
|
||||
gradleTokenModName =
|
||||
gradleTokenVersion = GRADLETOKEN_VERSION
|
||||
gradleTokenGroupName =
|
||||
|
||||
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise you can
|
||||
# leave this property empty.
|
||||
# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
|
||||
apiPackage =
|
||||
|
||||
# Specify the configuration file for Forge's access transformers here. I must be placed into /src/main/resources/META-INF/
|
||||
# Example value: mymodid_at.cfg
|
||||
accessTransformersFile =
|
||||
|
||||
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
|
||||
usesMixins = false
|
||||
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
|
||||
mixinPlugin =
|
||||
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
|
||||
mixinsPackage =
|
||||
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
|
||||
# This parameter is for legacy compatability only
|
||||
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
|
||||
coreModClass =
|
||||
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
|
||||
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
|
||||
containsMixinsAndOrCoreModOnly = false
|
||||
|
||||
# If enabled, you may use 'shadowImplementation' for dependencies. They will be integrated in your jar. It is your
|
||||
# responsibility check the licence and request permission for distribution, if required.
|
||||
usesShadowedDependencies = false
|
||||
Vendored
BIN
Binary file not shown.
+1
-2
@@ -1,6 +1,5 @@
|
||||
#Wed Jul 02 15:54:47 CDT 2014
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip
|
||||
@@ -1,4 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -6,47 +22,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# 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"
|
||||
@@ -61,9 +36,49 @@ while [ -h "$PRG" ] ; do
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# 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
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
@@ -90,7 +105,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -110,10 +125,11 @@ 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
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
@@ -154,11 +170,19 @@ if $cygwin ; then
|
||||
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=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+20
-10
@@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@@ -8,14 +24,14 @@
|
||||
@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 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="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@@ -46,10 +62,9 @@ echo location of your Java installation.
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows 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.
|
||||
@@ -60,11 +75,6 @@ set _SKIP=2
|
||||
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
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
before_install:
|
||||
- ./gradlew setupCIWorkspace
|
||||
@@ -0,0 +1,5 @@
|
||||
// Add any additional repositiroes for your dependencies here
|
||||
|
||||
repositories {
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
bdlib.multiblock.face.north=North
|
||||
bdlib.multiblock.face.south=South
|
||||
bdlib.multiblock.face.east=East
|
||||
bdlib.multiblock.face.west=West
|
||||
bdlib.multiblock.face.up=Top
|
||||
bdlib.multiblock.face.down=Bottom
|
||||
|
||||
bdlib.multiblock.disabled=Disabled
|
||||
bdlib.multiblock.incomplete=This machine is incomplete, it requires at least:
|
||||
bdlib.multiblock.notconnected=Not connected to a valid machine
|
||||
bdlib.multiblock.toomanyoutputs=Too many outputs connected, unable to attach new connection
|
||||
|
||||
bdlib.rsmode.always=Always ON
|
||||
bdlib.rsmode.never=Disabled
|
||||
bdlib.rsmode.rs_on=Enable on redstone
|
||||
bdlib.rsmode.rs_off=Disable on redstone
|
||||
|
||||
bdlib.label.empty=Empty
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = 'bdlib'
|
||||
File renamed without changes.
@@ -0,0 +1,30 @@
|
||||
bdlib.multiblock.face.north=North
|
||||
bdlib.multiblock.face.south=South
|
||||
bdlib.multiblock.face.east=East
|
||||
bdlib.multiblock.face.west=West
|
||||
bdlib.multiblock.face.up=Top
|
||||
bdlib.multiblock.face.down=Bottom
|
||||
|
||||
bdlib.multiblock.disabled=Disabled
|
||||
bdlib.multiblock.incomplete=This machine is incomplete, it requires at least:
|
||||
bdlib.multiblock.notconnected=Not connected to a valid machine
|
||||
bdlib.multiblock.toomanyoutputs=Too many outputs connected, unable to attach new connection
|
||||
bdlib.multiblock.tip.module=Can be installed in:
|
||||
bdlib.multiblock.tip.controller=Possible modules:
|
||||
bdlib.multiblock.tip.module.range= * %s (%s - %s)
|
||||
bdlib.multiblock.tip.module.max= * %s (up to %s)
|
||||
|
||||
bdlib.rsmode.always=Always ON
|
||||
bdlib.rsmode.never=Disabled
|
||||
bdlib.rsmode.rs_on=Enable on redstone
|
||||
bdlib.rsmode.rs_off=Disable on redstone
|
||||
|
||||
bdlib.label.empty=Empty
|
||||
|
||||
bdlib.oredistribution.usage=/oredistribution <radius> [<min height>] [<max height>] [--file]
|
||||
bdlib.oredistribution.start1=Checking ore distribution in (%s,%s,%s) to (%s,%s,%s) dim %s
|
||||
bdlib.oredistribution.start2=Server may lag for a while
|
||||
bdlib.oredistribution.entry=%s %s - %s (%s%%)
|
||||
bdlib.oredistribution.warn=%s Warning: %s has multiple variants generated:
|
||||
bdlib.oredistribution.saved=Ore distribution dumped to %s
|
||||
bdlib.oredistribution.error=Failed to save ore distribution dump: %s
|
||||
@@ -0,0 +1,18 @@
|
||||
bdlib.multiblock.face.north=Nord
|
||||
bdlib.multiblock.face.south=Sud
|
||||
bdlib.multiblock.face.east=Est
|
||||
bdlib.multiblock.face.west=Ouest
|
||||
bdlib.multiblock.face.up=Haut
|
||||
bdlib.multiblock.face.down=Bas
|
||||
|
||||
bdlib.multiblock.disabled=Désactivé(e)
|
||||
bdlib.multiblock.incomplete=Cette machine est incomplète, elle requiert au moins :
|
||||
bdlib.multiblock.notconnected=Pas connecté(e) à une machine valide
|
||||
bdlib.multiblock.toomanyoutputs=Trop de sorties connectées, incapable d'attacher de nouvelles connexions
|
||||
|
||||
bdlib.rsmode.always=Toujours en marche
|
||||
bdlib.rsmode.never=Désactivé(e)
|
||||
bdlib.rsmode.rs_on=Activer par la redstone
|
||||
bdlib.rsmode.rs_off=Désactiver par la redstone
|
||||
|
||||
bdlib.label.empty=Vide
|
||||
@@ -0,0 +1,30 @@
|
||||
bdlib.multiblock.face.north=Nord
|
||||
bdlib.multiblock.face.south=Sud
|
||||
bdlib.multiblock.face.east=Est
|
||||
bdlib.multiblock.face.west=Ouest
|
||||
bdlib.multiblock.face.up=Dessus
|
||||
bdlib.multiblock.face.down=Dessous
|
||||
|
||||
bdlib.multiblock.disabled=Désactivé
|
||||
bdlib.multiblock.incomplete=Cette machine est incomplète, elle exige au moins :
|
||||
bdlib.multiblock.notconnected=Pas connecté à une machine valide
|
||||
bdlib.multiblock.toomanyoutputs=Trop de sorties connectées, impossible d'ajouter une nouvelle connexion
|
||||
bdlib.multiblock.tip.module=Peut être installé dans :
|
||||
bdlib.multiblock.tip.controller=Modules possibles:
|
||||
bdlib.multiblock.tip.module.range= * %s (%s - %s)
|
||||
bdlib.multiblock.tip.module.max= * %s (plus de %s)
|
||||
|
||||
bdlib.rsmode.always=Toujours actif
|
||||
bdlib.rsmode.never=Désactivé
|
||||
bdlib.rsmode.rs_on=Activé par redstone
|
||||
bdlib.rsmode.rs_off=Désactivé par redstone
|
||||
|
||||
bdlib.label.empty=Vide
|
||||
|
||||
bdlib.oredistribution.usage=/oredistribution <rayon> [<hauteur mini>] [<hauteur maxi>] [--file]
|
||||
bdlib.oredistribution.start1=Valide la distribution de minerai entre (%s,%s,%s) et (%s,%s,%s) dim %s
|
||||
bdlib.oredistribution.start2=Le server peut ralentir pendantun certain temps
|
||||
bdlib.oredistribution.entry=%s %s - %s (%s%%)
|
||||
bdlib.oredistribution.warn=%s Attention: %s fait produire des variantes multiples :
|
||||
bdlib.oredistribution.saved=Distribution de minerai déposée dans %s
|
||||
bdlib.oredistribution.error=Impossible d'enregistrer la distribution de minerai : %s
|
||||
@@ -0,0 +1,18 @@
|
||||
bdlib.multiblock.face.north=Nord
|
||||
bdlib.multiblock.face.south=Sud
|
||||
bdlib.multiblock.face.east=Est
|
||||
bdlib.multiblock.face.west=Ovest
|
||||
bdlib.multiblock.face.up=Sopra
|
||||
bdlib.multiblock.face.down=Sotto
|
||||
|
||||
bdlib.multiblock.disabled=Disattivo
|
||||
bdlib.multiblock.incomplete=Questa macchina è incompleta, richiede almeno:
|
||||
bdlib.multiblock.notconnected=Non connesso ad una macchina valida
|
||||
bdlib.multiblock.toomanyoutputs=Troppi Output collegati,impossibile inserire una nuova connessione
|
||||
|
||||
bdlib.rsmode.always=Sempre Attivo
|
||||
bdlib.rsmode.never=Disattivo
|
||||
bdlib.rsmode.rs_on=Attivo su Impulso di Pietrarossa
|
||||
bdlib.rsmode.rs_off=Disattivo su Impulso di Pietrarossa
|
||||
|
||||
bdlib.label.empty=Vuoto
|
||||
File renamed without changes.
File renamed without changes.
@@ -1,9 +1,10 @@
|
||||
[
|
||||
{
|
||||
"modid": "bdlib",
|
||||
"name": "BD Lib",
|
||||
"modid": "${modId}",
|
||||
"name": "${modName}",
|
||||
"description": "",
|
||||
"version": "@BDLIB_VER@",
|
||||
"version": "${modVersion}",
|
||||
"mcversion": "${minecraftVersion}",
|
||||
"url": "bdew.net/mods/",
|
||||
"updateUrl": "",
|
||||
"authorList": [
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib
|
||||
|
||||
import java.util
|
||||
import java.util.Locale
|
||||
|
||||
import cpw.mods.fml.common.{ICrashCallable, ModAPIManager, ModContainer}
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
|
||||
object ApiReporter extends ICrashCallable {
|
||||
lazy val APIs = {
|
||||
val mods = new util.ArrayList[ModContainer]
|
||||
val nameLookup = new util.HashMap[String, ModContainer]
|
||||
ModAPIManager.INSTANCE.injectAPIModContainers(mods, nameLookup)
|
||||
(for (mod <- mods.sortBy(_.getModId.toLowerCase(Locale.US))) yield
|
||||
"\t\t* %s (%s) from %s".format(mod.getModId, mod.getVersion,
|
||||
if (mod.getSource.isDirectory)
|
||||
mod.getSource
|
||||
else
|
||||
mod.getSource.getName
|
||||
)).mkString(Misc.lineSeparator)
|
||||
}
|
||||
override def getLabel = "List of loaded APIs"
|
||||
override def call() = Misc.lineSeparator + APIs
|
||||
}
|
||||
@@ -9,17 +9,19 @@
|
||||
|
||||
package net.bdew.lib
|
||||
|
||||
import cpw.mods.fml.common.Mod
|
||||
import cpw.mods.fml.common.Mod.EventHandler
|
||||
import cpw.mods.fml.common.event.{FMLPreInitializationEvent, FMLServerStartingEvent, FMLServerStoppingEvent}
|
||||
import cpw.mods.fml.common.{FMLCommonHandler, Mod}
|
||||
import net.bdew.lib.multiblock.network.NetHandler
|
||||
import net.bdew.lib.tooltip.TooltipHandler
|
||||
import net.minecraft.command.CommandHandler
|
||||
import org.apache.logging.log4j.Logger
|
||||
|
||||
@Mod(modid = "bdlib", name = "BD lib", version = "BDLIB_VER", modLanguage = "scala")
|
||||
@Mod(modid = "bdlib", name = "BD lib", version = "GRADLETOKEN_VERSION", modLanguage = "scala")
|
||||
object BdLib {
|
||||
var log: Logger = null
|
||||
|
||||
def logDebug(msg: String, args: Any*) = log.debug(msg.format(args: _*))
|
||||
def logInfo(msg: String, args: Any*) = log.info(msg.format(args: _*))
|
||||
def logWarn(msg: String, args: Any*) = log.warn(msg.format(args: _*))
|
||||
def logError(msg: String, args: Any*) = log.error(msg.format(args: _*))
|
||||
@@ -32,14 +34,20 @@ object BdLib {
|
||||
@EventHandler
|
||||
def preInit(ev: FMLPreInitializationEvent) {
|
||||
log = ev.getModLog
|
||||
log.info("bdlib BDLIB_VER loaded")
|
||||
log.info("bdlib GRADLETOKEN_VERSION loaded")
|
||||
log.debug("List of loaded APIs: " + ApiReporter.APIs)
|
||||
FMLCommonHandler.instance().registerCrashCallable(ApiReporter)
|
||||
NetHandler.init()
|
||||
if (ev.getSide.isClient) {
|
||||
TooltipHandler.init()
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
def serverStarting(event: FMLServerStartingEvent) {
|
||||
val commandHandler = event.getServer.getCommandManager.asInstanceOf[CommandHandler]
|
||||
commandHandler.registerCommand(new CommandDumpRegistry)
|
||||
commandHandler.registerCommand(CommandDumpRegistry)
|
||||
commandHandler.registerCommand(CommandOreDistribution)
|
||||
onServerStarting.trigger(event)
|
||||
}
|
||||
|
||||
File renamed without changes.
+1
-1
@@ -19,7 +19,7 @@ import net.minecraft.item.ItemStack
|
||||
import net.minecraftforge.fluids.FluidRegistry
|
||||
import net.minecraftforge.oredict.OreDictionary
|
||||
|
||||
class CommandDumpRegistry extends CommandBase {
|
||||
object CommandDumpRegistry extends CommandBase {
|
||||
def getCommandName = "dumpregistry"
|
||||
override def getRequiredPermissionLevel = 2
|
||||
def getCommandUsage(c: ICommandSender) = "dumpregistry"
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib
|
||||
|
||||
import java.io.{BufferedWriter, File, FileWriter}
|
||||
|
||||
import cpw.mods.fml.common.registry.GameData
|
||||
import cpw.mods.fml.relauncher.FMLInjectionData
|
||||
import net.minecraft.command.{CommandBase, ICommandSender, WrongUsageException}
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.util.EnumChatFormatting
|
||||
import net.minecraftforge.oredict.OreDictionary
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object CommandOreDistribution extends CommandBase {
|
||||
def getCommandName = "oredistribution"
|
||||
override def getRequiredPermissionLevel = 2
|
||||
def getCommandUsage(c: ICommandSender) = "bdlib.oredistribution.usage"
|
||||
|
||||
def safeInt(s: String) =
|
||||
try {
|
||||
s.toInt
|
||||
} catch {
|
||||
case e: NumberFormatException => throw new WrongUsageException("bdlib.oredistribution.usage")
|
||||
}
|
||||
|
||||
def wrapColor(s: String, c: EnumChatFormatting) = c + s + EnumChatFormatting.RESET
|
||||
|
||||
def processCommand(sender: ICommandSender, baseParams: Array[String]) {
|
||||
val (flags, params) = baseParams.partition(_.startsWith("--"))
|
||||
|
||||
if (params.length < 1 || params.length > 3)
|
||||
throw new WrongUsageException(getCommandUsage(sender))
|
||||
|
||||
val (startX, startZ, world) =
|
||||
sender match {
|
||||
case p: EntityPlayerMP => (p.posX.toInt, p.posZ.toInt, p.worldObj)
|
||||
case _ => (0, 0, sender.getEntityWorld)
|
||||
}
|
||||
|
||||
val radius = safeInt(params.head)
|
||||
val minY = if (params.length >= 2) safeInt(params(1)) else 0
|
||||
val maxY = if (params.length >= 3) safeInt(params(2)) else world.getHeight - 1
|
||||
|
||||
if (minY < 0 || radius <= 0 || minY > maxY || maxY > world.getHeight - 1)
|
||||
throw new WrongUsageException(getCommandUsage(sender))
|
||||
|
||||
val toFile = flags.contains("--file")
|
||||
|
||||
// why java, WHY?
|
||||
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.start1",
|
||||
Array[Integer](startX - radius, minY, startZ - radius, startX + radius, maxY, startZ + radius, world.provider.dimensionId): _*)
|
||||
|
||||
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.start2")
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
|
||||
val ores = (OreDictionary.getOreNames.filter(x => x.startsWith("ore") || x.startsWith("denseore")) flatMap { name =>
|
||||
val fixedName =
|
||||
if (name.startsWith("ore"))
|
||||
name.substring(3)
|
||||
else if (name.startsWith("denseore"))
|
||||
"Dense " + name.substring(8)
|
||||
else name
|
||||
for (s <- OreDictionary.getOres(name)) yield (s.getItem, s.getItemDamage) -> fixedName
|
||||
}).toMap
|
||||
|
||||
val distribution = mutable.Map.empty[String, Int].withDefaultValue(0)
|
||||
val kinds = mutable.Map.empty[String, Set[(Item, Int)]].withDefaultValue(Set.empty)
|
||||
|
||||
for {
|
||||
x <- startX - radius to startX + radius
|
||||
y <- minY to maxY
|
||||
z <- startZ - radius to startZ + radius
|
||||
if !world.isAirBlock(x, y, z)
|
||||
} {
|
||||
val key = (Item.getItemFromBlock(world.getBlock(x, y, z)), world.getBlockMetadata(x, y, z))
|
||||
for (ore <- ores.get(key)) {
|
||||
distribution(ore) += 1
|
||||
kinds(ore) += key
|
||||
}
|
||||
}
|
||||
|
||||
val total = distribution.values.sum
|
||||
val warnings = kinds.filter(_._2.size > 1)
|
||||
|
||||
if (toFile) {
|
||||
// === OUTPUT TO FILE ===
|
||||
val mcHome = FMLInjectionData.data()(6).asInstanceOf[File] //is there a better way to get this?
|
||||
val dumpFile = new File(mcHome, "ore_distribution.txt")
|
||||
val dumpWriter = new BufferedWriter(new FileWriter(dumpFile))
|
||||
try {
|
||||
dumpWriter.write("Ore distribution report - (%d,%d,%d) to (%d,%d,%d) dim %d".format(
|
||||
startX - radius, minY, startZ - radius, startX + radius, maxY, startZ + radius, world.provider.dimensionId
|
||||
))
|
||||
dumpWriter.newLine()
|
||||
dumpWriter.newLine()
|
||||
if (warnings.nonEmpty) {
|
||||
for ((id, types) <- warnings.toList.sortBy(_._1)) {
|
||||
dumpWriter.write("Warning: %s has multiple variants generated:".format(id))
|
||||
dumpWriter.newLine()
|
||||
for ((item, dmg) <- types) {
|
||||
dumpWriter.write(" - %s@%s".format(GameData.getItemRegistry.getNameForObject(item), dmg))
|
||||
dumpWriter.newLine()
|
||||
}
|
||||
dumpWriter.newLine()
|
||||
}
|
||||
dumpWriter.write("=================")
|
||||
dumpWriter.newLine()
|
||||
dumpWriter.newLine()
|
||||
}
|
||||
for ((id, num) <- distribution.filter(_._2 > 0).toList.sortBy(-_._2)) {
|
||||
dumpWriter.write("%s - %s (%s%%)".format(id, DecFormat.round(num), DecFormat.short(100F * num / total)))
|
||||
dumpWriter.newLine()
|
||||
}
|
||||
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.saved", dumpFile.getCanonicalPath)
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.error", e.toString)
|
||||
BdLib.logErrorException("Failed to save ore distribution dump", e)
|
||||
} finally {
|
||||
dumpWriter.close()
|
||||
}
|
||||
} else {
|
||||
// === OUTPUT TO CHAT ===
|
||||
for ((id, types) <- warnings.toList.sortBy(_._1)) {
|
||||
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.warn",
|
||||
wrapColor(" !", EnumChatFormatting.RED), wrapColor(id, EnumChatFormatting.RED))
|
||||
for ((item, dmg) <- types)
|
||||
CommandBase.func_152373_a(sender, this, wrapColor(" - ", EnumChatFormatting.RED) + GameData.getItemRegistry.getNameForObject(item) + "@" + dmg)
|
||||
}
|
||||
for ((id, num) <- distribution.filter(_._2 > 0).toList.sortBy(-_._2)) {
|
||||
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.entry",
|
||||
" *", wrapColor(id, EnumChatFormatting.YELLOW),
|
||||
DecFormat.round(num), DecFormat.short(100F * num / total))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib
|
||||
|
||||
import java.text.DecimalFormat
|
||||
|
||||
object DecFormat {
|
||||
val thousandsFmt = new DecimalFormat("#,##0")
|
||||
val dec2Fmt = new DecimalFormat("#,##0.00")
|
||||
val dec1Fmt = new DecimalFormat("#,##0.0")
|
||||
|
||||
def round(x: Double) = thousandsFmt.format(x).replace('\u00A0', ' ')
|
||||
def round(x: Float) = thousandsFmt.format(x).replace('\u00A0', ' ')
|
||||
def round(x: Int) = thousandsFmt.format(x).replace('\u00A0', ' ')
|
||||
|
||||
def dec2(x: Double) = dec2Fmt.format(x).replace('\u00A0', ' ')
|
||||
def dec2(x: Float) = dec2Fmt.format(x).replace('\u00A0', ' ')
|
||||
def dec2(x: Int) = dec2Fmt.format(x).replace('\u00A0', ' ')
|
||||
|
||||
def short(x: Double) = (if (x > 10) thousandsFmt.format(x) else if (x > 1) dec1Fmt.format(x) else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
def short(x: Float) = (if (x > 10) thousandsFmt.format(x) else if (x > 1) dec1Fmt.format(x) else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
def short(x: Int) = (if (x > 10) thousandsFmt.format(x) else if (x > 1) dec1Fmt.format(x) else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
}
|
||||
@@ -12,7 +12,7 @@ package net.bdew.lib
|
||||
class EventBase[T] extends {
|
||||
var listeners = Seq.empty[T]
|
||||
def listen(x: T) = listeners :+= x
|
||||
def hasListeners = listeners.size > 0
|
||||
def hasListeners = listeners.nonEmpty
|
||||
}
|
||||
|
||||
class Event0 extends EventBase[() => Unit] {
|
||||
@@ -9,9 +9,12 @@
|
||||
|
||||
package net.bdew.lib
|
||||
|
||||
import cpw.mods.fml.common.Loader
|
||||
import java.util
|
||||
import java.util.Locale
|
||||
|
||||
import cpw.mods.fml.common.registry.GameRegistry
|
||||
import cpw.mods.fml.common.versioning.{ArtifactVersion, VersionParser}
|
||||
import cpw.mods.fml.common.versioning.VersionParser
|
||||
import cpw.mods.fml.common.{Loader, ModAPIManager, ModContainer}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
@@ -22,26 +25,16 @@ import net.minecraftforge.fluids.{Fluid, FluidStack}
|
||||
import net.minecraftforge.oredict.ShapedOreRecipe
|
||||
|
||||
object Misc {
|
||||
def iterNbtCompoundList(parent: NBTTagCompound, name: String): Iterable[NBTTagCompound] = {
|
||||
val list = parent.getTagList(name, 10)
|
||||
for (i <- 0 until list.tagCount()) yield list.getCompoundTagAt(i)
|
||||
}
|
||||
|
||||
def iterNbtIntArray(parent: NBTTagCompound, name: String): Iterable[Array[Int]] = {
|
||||
val list = parent.getTagList(name, 11)
|
||||
for (i <- 0 until list.tagCount()) yield list.func_150306_c(i)
|
||||
}
|
||||
|
||||
def getActiveModId = Loader.instance().activeModContainer().getModId
|
||||
def getActiveModId = Option(Loader.instance().activeModContainer().getModId) getOrElse "<UNKNOWN>"
|
||||
|
||||
def toLocal(s: String) = StatCollector.translateToLocal(s)
|
||||
def toLocalF(s: String, params: Any*) = StatCollector.translateToLocal(s).format(params: _*)
|
||||
def hasLocal(s: String) = StatCollector.canTranslate(s)
|
||||
|
||||
def flattenRecipe(pattern: Seq[String], items: Map[Char, AnyRef]) =
|
||||
pattern ++ items.map {
|
||||
pattern ++ items.flatMap {
|
||||
case (k, v) => Seq(new Character(k), v)
|
||||
}.flatten
|
||||
}
|
||||
|
||||
def wrapTag(n: String, f: (NBTTagCompound) => Any)(t: NBTTagCompound) {
|
||||
val p = t.getCompoundTag(n)
|
||||
@@ -67,17 +60,28 @@ object Misc {
|
||||
|
||||
def getBiomeByName(name: String) = BiomeGenBase.getBiomeGenArray.find(x => x != null && x.biomeName == name).orNull
|
||||
|
||||
def haveModVersion(spec: String): Boolean = {
|
||||
val req = VersionParser.parseVersionReference(spec)
|
||||
val modId = req.getLabel
|
||||
private lazy val modLookup = {
|
||||
val mods = new util.ArrayList[ModContainer]
|
||||
val nameLookup = new util.HashMap[String, ModContainer]
|
||||
|
||||
if (!Loader.instance.getIndexedModList.containsKey(modId)) return false
|
||||
nameLookup.putAll(Loader.instance().getIndexedModList)
|
||||
ModAPIManager.INSTANCE.injectAPIModContainers(mods, nameLookup)
|
||||
|
||||
val found: ArtifactVersion = Loader.instance.getIndexedModList.get(modId).getProcessedVersion
|
||||
import scala.collection.JavaConverters._
|
||||
nameLookup.asScala
|
||||
}
|
||||
|
||||
if (found == null || !req.containsVersion(found)) return false
|
||||
def haveModVersion(modId: String) = {
|
||||
val spec = VersionParser.parseVersionReference(modId)
|
||||
modLookup.contains(spec.getLabel) && spec.containsVersion(modLookup(spec.getLabel).getProcessedVersion)
|
||||
}
|
||||
|
||||
return true
|
||||
def getModVersion(modId: String) =
|
||||
modLookup.get(modId) map (_.getVersion)
|
||||
|
||||
def getModVersionString(modId: String): String = {
|
||||
val cont = modLookup.getOrElse(modId, return "NOT FOUND")
|
||||
cont.getModId + " " + cont.getVersion
|
||||
}
|
||||
|
||||
// Because writing this every time is awkward
|
||||
@@ -105,6 +109,22 @@ object Misc {
|
||||
init
|
||||
}
|
||||
|
||||
def nextInSeq[T](seq: Seq[T], elem: T) = {
|
||||
val pos = seq.indexOf(elem)
|
||||
if (pos < 0 || pos == seq.size - 1)
|
||||
seq.head
|
||||
else
|
||||
seq(pos + 1)
|
||||
}
|
||||
|
||||
def prevInSeq[T](seq: Seq[T], elem: T) = {
|
||||
val pos = seq.indexOf(elem)
|
||||
if (pos <= 0)
|
||||
seq.last
|
||||
else
|
||||
seq(pos - 1)
|
||||
}
|
||||
|
||||
def getFluidIcon(fs: FluidStack): IIcon =
|
||||
if (fs != null && fs.getFluid != null && fs.getFluid.getIcon != null)
|
||||
fs.getFluid.getIcon(fs)
|
||||
@@ -119,5 +139,37 @@ object Misc {
|
||||
|
||||
def getFluidColor(f: Fluid): Int =
|
||||
if (f != null) getFluidColor(new FluidStack(f, 1)) else 0xFFFFFF
|
||||
|
||||
lazy val lineSeparator = System.getProperty("line.separator")
|
||||
|
||||
/**
|
||||
* Provides something like java try-with-resources in scala
|
||||
*/
|
||||
def withAutoClose[T <: AutoCloseable, R](o: T)(f: T => R): R = {
|
||||
val res = try {
|
||||
f(o)
|
||||
} catch {
|
||||
case t1: Throwable =>
|
||||
if (o != null) {
|
||||
try {
|
||||
o.close()
|
||||
} catch {
|
||||
case t2: Throwable =>
|
||||
t1.addSuppressed(t2)
|
||||
}
|
||||
}
|
||||
throw t1
|
||||
}
|
||||
if (o != null)
|
||||
o.close()
|
||||
res
|
||||
}
|
||||
|
||||
def iconName(domain: String, name: String, path: String*) =
|
||||
if (path.isEmpty)
|
||||
"%s:%s".format(domain, name).toLowerCase(Locale.US)
|
||||
else
|
||||
"%s:%s/%s".format(domain, name, path.mkString("/")).toLowerCase(Locale.US)
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.async
|
||||
|
||||
import scala.concurrent.{Future, Promise}
|
||||
|
||||
object Async {
|
||||
def inOtherThread[T](f: => T) = {
|
||||
val p = Promise[T]()
|
||||
val t = new Thread(new Runnable {
|
||||
override def run(): Unit =
|
||||
try {
|
||||
p.success(f)
|
||||
} catch {
|
||||
case t: Throwable => p.failure(t)
|
||||
}
|
||||
})
|
||||
t.start()
|
||||
p.future
|
||||
}
|
||||
|
||||
def inServerThread[T](f: => T) = Future(f)(ServerTickExecutionContext)
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.async
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent
|
||||
import net.bdew.lib.BdLib
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.ExecutionContext
|
||||
|
||||
object ServerTickExecutionContext extends ExecutionContext {
|
||||
private val queue = mutable.Queue.empty[Runnable]
|
||||
|
||||
FMLCommonHandler.instance.bus.register(this)
|
||||
|
||||
BdLib.logDebug("Installed ServerTickExecutionContext")
|
||||
|
||||
private def getNextBatch = this.synchronized {
|
||||
if (queue.nonEmpty) {
|
||||
val res = queue.toList
|
||||
queue.clear()
|
||||
res
|
||||
} else List.empty
|
||||
}
|
||||
|
||||
override def execute(runnable: Runnable): Unit =
|
||||
this.synchronized {
|
||||
queue += runnable
|
||||
}
|
||||
|
||||
override def reportFailure(cause: Throwable): Unit =
|
||||
BdLib.logErrorException("Error in execution context", cause)
|
||||
|
||||
def doSingleLoop(): Unit = {
|
||||
for (r <- getNextBatch) {
|
||||
try {
|
||||
r.run()
|
||||
} catch {
|
||||
case t: Throwable => reportFailure(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
def onTick(ev: ServerTickEvent): Unit = doSingleLoop()
|
||||
}
|
||||
File renamed without changes.
+5
-3
@@ -18,9 +18,11 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
case class BlockRef(x: Int, y: Int, z: Int) {
|
||||
def block(w: IBlockAccess) = Option(w.getBlock(x, y, z))
|
||||
def tile(w: IBlockAccess) = Option(w.getTileEntity(x, y, z))
|
||||
def meta(w: IBlockAccess) = w.getBlockMetadata(x, y, z)
|
||||
def isValid(w: IBlockAccess) = y >= 0 && y < 256 // hardcoded because getHeight is unavailable on servers :(
|
||||
|
||||
def block(w: IBlockAccess) = if (isValid(w)) Option(w.getBlock(x, y, z)) else None
|
||||
def tile(w: IBlockAccess) = if (isValid(w)) Option(w.getTileEntity(x, y, z)) else None
|
||||
def meta(w: IBlockAccess) = if (isValid(w)) w.getBlockMetadata(x, y, z) else 0
|
||||
|
||||
def blockIs(w: IBlockAccess, other: Block) = block(w).contains(other)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.block
|
||||
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.item.ItemBlock
|
||||
|
||||
/**
|
||||
* If defined on a block - defines a custom ItemBlock class that will be used when registering
|
||||
* Supported by BlockManager and Machine
|
||||
*/
|
||||
trait HasItemBlock extends Block {
|
||||
def ItemBlockClass: Class[_ <: ItemBlock]
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.block
|
||||
|
||||
import java.util
|
||||
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.{ItemBlock, ItemStack}
|
||||
|
||||
trait BlockTooltip extends Block with HasItemBlock {
|
||||
override val ItemBlockClass: Class[_ <: ItemBlock] = classOf[ItemBlockTooltip]
|
||||
def getTooltip(stack: ItemStack, player: EntityPlayer, advanced: Boolean): List[String]
|
||||
}
|
||||
|
||||
class ItemBlockTooltip(b: Block) extends ItemBlock(b) {
|
||||
override def addInformation(stack: ItemStack, player: EntityPlayer, list: util.List[_], advanced: Boolean): Unit = {
|
||||
import scala.collection.JavaConversions._
|
||||
if (b.isInstanceOf[BlockTooltip])
|
||||
list.asInstanceOf[util.List[String]].addAll(b.asInstanceOf[BlockTooltip].getTooltip(stack, player, advanced))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.block
|
||||
|
||||
import java.util
|
||||
|
||||
import net.bdew.lib.nbt.NBT
|
||||
import net.bdew.lib.tile.TileExtended
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.MovingObjectPosition
|
||||
import net.minecraft.world.World
|
||||
|
||||
/**
|
||||
* Mixin for blocks to keep their data when broken
|
||||
* Must have a TileEntity that extends TileKeepData
|
||||
*/
|
||||
trait BlockKeepData extends Block with HasItemBlock {
|
||||
this: HasTE[_ <: TileKeepData] =>
|
||||
|
||||
override val ItemBlockClass: Class[_ <: ItemBlockKeepData] = classOf[ItemBlockKeepData]
|
||||
|
||||
def getSavedBlock(world: World, x: Int, y: Int, z: Int, metadata: Int) = {
|
||||
val stack = new ItemStack(getItemDropped(metadata, world.rand, 0), 1, damageDropped(metadata))
|
||||
getTE(world, x, y, z).saveToItem(stack)
|
||||
stack
|
||||
}
|
||||
|
||||
override def getDrops(world: World, x: Int, y: Int, z: Int, metadata: Int, fortune: Int): util.ArrayList[ItemStack] = {
|
||||
val drops = new util.ArrayList[ItemStack]()
|
||||
drops.add(getSavedBlock(world, x, y, z, metadata))
|
||||
drops
|
||||
}
|
||||
|
||||
override def removedByPlayer(world: World, player: EntityPlayer, x: Int, y: Int, z: Int, willHarvest: Boolean): Boolean =
|
||||
if (willHarvest)
|
||||
true
|
||||
else
|
||||
super.removedByPlayer(world, player, x, y, z, willHarvest)
|
||||
|
||||
override def harvestBlock(world: World, player: EntityPlayer, x: Int, y: Int, z: Int, meta: Int): Unit = {
|
||||
super.harvestBlock(world, player, x, y, z, meta)
|
||||
world.setBlockToAir(x, y, z)
|
||||
}
|
||||
|
||||
override def getPickBlock(target: MovingObjectPosition, world: World, x: Int, y: Int, z: Int, player: EntityPlayer): ItemStack = {
|
||||
getSavedBlock(world, x, y, z, world.getBlockMetadata(x, y, z))
|
||||
}
|
||||
|
||||
/**
|
||||
* Override for special actions on placing
|
||||
* ItemStack might or might not contain actual data
|
||||
* Called with the TE created and added to world, after onBlockPlacedBy & co
|
||||
*/
|
||||
def restoreTileEntity(world: World, x: Int, y: Int, z: Int, is: ItemStack, player: EntityPlayer) = getTE(world, x, y, z).loadFromItem(is)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin for tile entities to keep their data when broken
|
||||
* Block class has to extend BlockKeepData
|
||||
*/
|
||||
trait TileKeepData extends TileExtended {
|
||||
/**
|
||||
* Override to modify data that will be stored in an item
|
||||
* @param t Automatically serialized data
|
||||
* @return Modified serialized data
|
||||
*/
|
||||
def afterTileBreakSave(t: NBTTagCompound) = t
|
||||
|
||||
/**
|
||||
* Override to modify data that will be load from an item
|
||||
* After the tile entity is fully constructed and added to world
|
||||
* @param t Automatically serialized data
|
||||
* @return Modified serialized data
|
||||
*/
|
||||
def beforeTileBreakLoad(t: NBTTagCompound) = t
|
||||
|
||||
final def saveToItem(is: ItemStack): Unit = {
|
||||
if (!is.hasTagCompound) is.setTagCompound(new NBTTagCompound)
|
||||
is.getTagCompound.setTag("data", afterTileBreakSave(NBT.from(persistSave.trigger)))
|
||||
}
|
||||
|
||||
final def loadFromItem(is: ItemStack): Unit = {
|
||||
if (is.hasTagCompound && is.getTagCompound.hasKey("data")) {
|
||||
persistLoad.trigger(beforeTileBreakLoad(is.getTagCompound.getCompoundTag("data")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom ItemBlock that handles loading data to the Tile Entity
|
||||
*/
|
||||
class ItemBlockKeepData(b: Block) extends ItemBlockTooltip(b) {
|
||||
override def placeBlockAt(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, metadata: Int): Boolean = {
|
||||
if (super.placeBlockAt(stack, player, world, x, y, z, side, hitX, hitY, hitZ, metadata)) {
|
||||
if (!world.isRemote && b.isInstanceOf[BlockKeepData])
|
||||
b.asInstanceOf[BlockKeepData].restoreTileEntity(world, x, y, z, stack, player)
|
||||
true
|
||||
} else false
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -15,6 +15,8 @@ import net.minecraft.block.Block
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.client.renderer.texture.IIconRegister
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
trait NamedBlock extends Block {
|
||||
def name: String
|
||||
}
|
||||
@@ -25,6 +27,6 @@ class SimpleBlock(val name: String, material: Material) extends Block(material)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def registerBlockIcons(reg: IIconRegister) {
|
||||
blockIcon = reg.registerIcon(modId + ":" + name.toLowerCase)
|
||||
blockIcon = reg.registerIcon(Misc.iconName(modId, name))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.config
|
||||
|
||||
import cpw.mods.fml.common.ObfuscationReflectionHelper
|
||||
import cpw.mods.fml.common.registry.GameRegistry
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.block.{HasItemBlock, HasTE, NamedBlock}
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.creativetab.CreativeTabs
|
||||
import net.minecraft.item.{ItemBlock, ItemStack}
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
|
||||
class BlockManager(creativeTab: CreativeTabs) {
|
||||
def regBlock[T <: NamedBlock](block: T): T = regBlock(block, block.name)
|
||||
|
||||
def regSpecial[T <: NamedBlock](block: T, addStack: Boolean = false, skipTileEntityReg: Boolean = false): T =
|
||||
regBlock(block, block.name, addStack, skipTileEntityReg)
|
||||
|
||||
def regBlock[T <: Block](block: T, name: String, addStack: Boolean = false, skipTileEntityReg: Boolean = false): T = {
|
||||
val itemClass: Class[_ <: ItemBlock] = if (block.isInstanceOf[HasItemBlock])
|
||||
block.asInstanceOf[HasItemBlock].ItemBlockClass
|
||||
else
|
||||
classOf[ItemBlock]
|
||||
|
||||
GameRegistry.registerBlock(block, itemClass, name)
|
||||
|
||||
block.setCreativeTab(creativeTab)
|
||||
|
||||
if (addStack)
|
||||
GameRegistry.registerCustomItemStack(name, new ItemStack(block))
|
||||
|
||||
if (block.isInstanceOf[HasTE[_]] && !skipTileEntityReg)
|
||||
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass,
|
||||
"%s.%s".format(Misc.getActiveModId, name))
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a legacy TE name->class mapping. Stolen from GameRegistry.registerTileEntityWithAlternatives
|
||||
*/
|
||||
def registerLegacyTileEntity(name: String, cls: Class[_ <: TileEntity]): Unit = {
|
||||
val teMappings: java.util.Map[String, Class[_]] = ObfuscationReflectionHelper.getPrivateValue(classOf[TileEntity], null, "field_" + "145855_i", "nameToClassMap")
|
||||
if (!teMappings.containsKey(name))
|
||||
teMappings.put(name, cls)
|
||||
}
|
||||
|
||||
def load() {}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
+25
@@ -9,8 +9,11 @@
|
||||
|
||||
package net.bdew.lib.config
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui.{GuiHandler, GuiProvider}
|
||||
import net.bdew.lib.machine.Machine
|
||||
import net.bdew.lib.multiblock.MachineCore
|
||||
import net.bdew.lib.multiblock.block.BlockModule
|
||||
import net.bdew.lib.recipes.gencfg.ConfigSection
|
||||
import net.minecraft.creativetab.CreativeTabs
|
||||
|
||||
@@ -25,5 +28,27 @@ class MachineManager(val tuning: ConfigSection, guiHandler: GuiHandler, creative
|
||||
}
|
||||
return machine
|
||||
}
|
||||
|
||||
def load() {}
|
||||
}
|
||||
|
||||
trait MachineManagerMultiblock extends MachineManager {
|
||||
var controllers = Set.empty[MachineCore]
|
||||
|
||||
override def registerMachine[R <: Machine[_]](machine: R): R = {
|
||||
super.registerMachine(machine)
|
||||
if (machine.enabled) {
|
||||
Misc.asInstanceOpt(machine, classOf[MachineCore]) foreach { controllerMachine =>
|
||||
controllers += controllerMachine
|
||||
controllerMachine.getController.machine = controllerMachine
|
||||
}
|
||||
}
|
||||
machine
|
||||
}
|
||||
|
||||
def getMachinesForBlock(b: BlockModule[_]): Map[MachineCore, (Int, Int)] = {
|
||||
(for (machine <- controllers; max <- machine.modules.get(b.kind)) yield {
|
||||
machine ->(machine.required.getOrElse(b.kind, 0), max)
|
||||
}).toMap
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.covers
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.block.{BlockRef, HasTE}
|
||||
import net.bdew.lib.items.ItemUtils
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.IIcon
|
||||
import net.minecraft.world.{IBlockAccess, World}
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def getRenderType = CoverRenderer.id
|
||||
|
||||
private def getCoverItem(w: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection): Option[(ItemCover, ItemStack, TileCoverable)] = {
|
||||
val te = getTE(w, x, y, z)
|
||||
for {
|
||||
coverStack <- Option(te.covers(side).value)
|
||||
coverItemMaybe <- Option(coverStack.getItem)
|
||||
coverItem <- Misc.asInstanceOpt(coverItemMaybe, classOf[ItemCover])
|
||||
} yield (coverItem, coverStack, te)
|
||||
}
|
||||
|
||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, face: Int, xOffs: Float, yOffs: Float, zOffs: Float): Boolean = {
|
||||
val te = getTE(world, x, y, z)
|
||||
val side = Misc.forgeDirection(face)
|
||||
|
||||
// Shift+RightClick with empty hand should remove cover
|
||||
if (player.getCurrentEquippedItem == null && player.isSneaking) {
|
||||
for {
|
||||
cover <- Option(te.covers(side).value)
|
||||
coverItem <- Misc.asInstanceOpt(cover.getItem, classOf[ItemCover])
|
||||
} {
|
||||
if (!world.isRemote) {
|
||||
te.covers(side) := null
|
||||
te.onCoversChanged()
|
||||
coverChanged(world, x, y, z, side)
|
||||
ItemUtils.dropItemToPlayer(world, player, coverItem.onRemove(cover))
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// If held item is cover - try to install it
|
||||
for {
|
||||
activeStack <- Option(player.getCurrentEquippedItem)
|
||||
activeItem <- Option(activeStack.getItem)
|
||||
coverItem <- Misc.asInstanceOpt(activeItem, classOf[ItemCover])
|
||||
if te.isValidCover(side, activeStack) && coverItem.isValidTile(te, activeStack)
|
||||
} {
|
||||
if (!world.isRemote && player.isInstanceOf[EntityPlayerMP]) {
|
||||
for {
|
||||
oldCover <- Option(te.covers(side).value)
|
||||
oldItem <- Misc.asInstanceOpt(oldCover.getItem, classOf[ItemCover])
|
||||
} {
|
||||
ItemUtils.throwItemAt(world, te.xCoord + side.offsetX, te.yCoord + side.offsetY, te.zCoord + side.offsetZ, oldItem.onRemove(oldCover))
|
||||
}
|
||||
|
||||
te.covers(side) := coverItem.onInstall(te, side, activeStack.splitStack(1), player.asInstanceOf[EntityPlayerMP])
|
||||
|
||||
if (activeStack.stackSize <= 0)
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, null)
|
||||
|
||||
te.onCoversChanged()
|
||||
coverChanged(world, x, y, z, side)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// If has cover - let it handle the click
|
||||
for ((item, stack, te) <- getCoverItem(world, x, y, z, side)) {
|
||||
if (item.clickCover(te, side, stack, player)) return true
|
||||
}
|
||||
|
||||
super.onBlockActivated(world, x, y, z, player, face, xOffs, yOffs, zOffs)
|
||||
}
|
||||
|
||||
override def canProvidePower = true
|
||||
|
||||
override def isProvidingWeakPower(w: IBlockAccess, x: Int, y: Int, z: Int, side: Int): Int = {
|
||||
val direction = Misc.forgeDirection(side).getOpposite
|
||||
for ((item, stack, te) <- getCoverItem(w, x, y, z, direction)) {
|
||||
if (item.isEmittingSignal(te, direction, stack)) return 15
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
def coverChanged(w: World, x: Int, y: Int, z: Int, side: ForgeDirection): Unit = {
|
||||
val pos = BlockRef(x, y, z).neighbour(side)
|
||||
w.notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, pos.block(w).orNull)
|
||||
}
|
||||
|
||||
def getCoverIcon(w: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection): Option[IIcon] =
|
||||
for ((item, stack, te) <- getCoverItem(w, x, y, z, side))
|
||||
yield item.getCoverIcon(te, side, stack)
|
||||
|
||||
override def breakBlock(world: World, x: Int, y: Int, z: Int, block: Block, meta: Int) {
|
||||
if (!world.isRemote) {
|
||||
val te = getTE(world, x, y, z)
|
||||
for {
|
||||
(dir, covOpt) <- te.covers
|
||||
cover <- Option(covOpt.value)
|
||||
item <- Misc.asInstanceOpt(cover.getItem, classOf[ItemCover])
|
||||
} {
|
||||
te.covers(dir) := null
|
||||
ItemUtils.throwItemAt(world, x, y, z, item.onRemove(cover))
|
||||
coverChanged(world, x, y, z, dir)
|
||||
}
|
||||
}
|
||||
super.breakBlock(world, x, y, z, block, meta)
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -23,12 +23,13 @@ object CoverRenderer extends BaseBlockRenderHandler {
|
||||
|
||||
override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks) = {
|
||||
renderer.renderStandardBlock(block, x, y, z)
|
||||
for {
|
||||
blockCov <- Misc.asInstanceOpt(block, classOf[BlockCoverable[_]])
|
||||
face <- ForgeDirection.VALID_DIRECTIONS
|
||||
icon <- blockCov.getCoverIcon(world, x, y, z, face)
|
||||
if block.shouldSideBeRendered(world, x + face.offsetX, y + face.offsetY, z + face.offsetZ, face.ordinal())
|
||||
} ConnectedHelper.draw(face, 8).doDraw(ConnectedHelper.Vec3F(x, y, z), icon)
|
||||
if (!renderer.hasOverrideBlockTexture)
|
||||
for {
|
||||
blockCov <- Misc.asInstanceOpt(block, classOf[BlockCoverable[_]])
|
||||
face <- ForgeDirection.VALID_DIRECTIONS
|
||||
icon <- blockCov.getCoverIcon(world, x, y, z, face)
|
||||
if block.shouldSideBeRendered(world, x + face.offsetX, y + face.offsetY, z + face.offsetZ, face.ordinal())
|
||||
} ConnectedHelper.draw(face, 8).doDraw(ConnectedHelper.Vec3F(x, y, z), icon)
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.covers
|
||||
|
||||
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
|
||||
import net.minecraft.item.{Item, ItemStack}
|
||||
import net.minecraft.util.IIcon
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait ItemCover extends Item {
|
||||
/**
|
||||
* @return true if tickCover should be called
|
||||
*/
|
||||
def isCoverTicking: Boolean
|
||||
|
||||
/**
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
* @return Icon to render, MUST be on terrain sprite sheet (0), not item!
|
||||
*/
|
||||
def getCoverIcon(te: TileCoverable, side: ForgeDirection, cover: ItemStack): IIcon
|
||||
|
||||
/**
|
||||
* Perform tick, called on server only
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
*/
|
||||
def tickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack): Unit = {}
|
||||
|
||||
/**
|
||||
* Checks if this cover can be installed on a specific TE
|
||||
* @param te Potential host TileEntity
|
||||
* @param cover Cover ItemStack
|
||||
* @return true if can be installed
|
||||
*/
|
||||
def isValidTile(te: TileCoverable, cover: ItemStack): Boolean
|
||||
|
||||
/**
|
||||
* Handle click on covered side - called on both client and server
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
* @param player Player clicking the cover
|
||||
* @return true if click was handled by cover
|
||||
*/
|
||||
def clickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack, player: EntityPlayer): Boolean = false
|
||||
|
||||
/**
|
||||
* Check if cover is emitting RS signal
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
* @return true if cover is emitting RS signal
|
||||
*/
|
||||
def isEmittingSignal(te: TileCoverable, side: ForgeDirection, cover: ItemStack): Boolean = false
|
||||
|
||||
/**
|
||||
* Called when cover is installed on a block - called only on server
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack - do not modify!
|
||||
* @param player Player entity doing the installation
|
||||
* @return cover ItemStack - copy if modified
|
||||
*/
|
||||
def onInstall(te:TileCoverable, side: ForgeDirection, cover: ItemStack, player: EntityPlayerMP): ItemStack = cover
|
||||
|
||||
/**
|
||||
* Called when cover is removed from block or block is destroyed - called only on server
|
||||
* @param cover Cover ItemStack - do not modify!
|
||||
* @return cover ItemStack - copy if modified
|
||||
*/
|
||||
def onRemove(cover: ItemStack): ItemStack = cover
|
||||
}
|
||||
+3
-1
@@ -9,6 +9,8 @@
|
||||
|
||||
package net.bdew.lib.covers
|
||||
|
||||
import java.util.Locale
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.DataSlotItemStack
|
||||
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
|
||||
@@ -17,7 +19,7 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait TileCoverable extends TileDataSlots {
|
||||
val covers = (ForgeDirection.VALID_DIRECTIONS map { x =>
|
||||
x -> DataSlotItemStack("cover_" + x.toString.toLowerCase, this).setUpdate(UpdateKind.SAVE, UpdateKind.WORLD, UpdateKind.RENDER)
|
||||
x -> DataSlotItemStack("cover_" + x.toString.toLowerCase(Locale.US), this).setUpdate(UpdateKind.SAVE, UpdateKind.WORLD, UpdateKind.RENDER)
|
||||
}).toMap
|
||||
|
||||
/**
|
||||
+2
-2
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotBoolean(name: String, parent: TileDataSlots, default: Boolean = false) extends DataSlotVal[Boolean] {
|
||||
case class DataSlotBoolean(name: String, parent: DataSlotContainer, default: Boolean = false) extends DataSlotVal[Boolean] {
|
||||
var value = default
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setBoolean(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getBoolean(name)
|
||||
+2
-2
@@ -9,11 +9,11 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
case class DataSlotDirection(name: String, parent: TileDataSlots) extends DataSlotVal[ForgeDirection] {
|
||||
case class DataSlotDirection(name: String, parent: DataSlotContainer) extends DataSlotVal[ForgeDirection] {
|
||||
var value = ForgeDirection.UP
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setByte(name, value.ordinal().toByte)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = ForgeDirection.getOrientation(t.getByte(name))
|
||||
+2
-2
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotDouble(name: String, parent: TileDataSlots, default: Double = 0) extends DataSlotNumeric[Double](default) {
|
||||
case class DataSlotDouble(name: String, parent: DataSlotContainer, default: Double = 0) extends DataSlotNumeric[Double](default) {
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setDouble(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getDouble(name)
|
||||
}
|
||||
+2
-2
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotFloat(name: String, parent: TileDataSlots, default: Float = 0) extends DataSlotNumeric[Float](default) {
|
||||
case class DataSlotFloat(name: String, parent: DataSlotContainer, default: Float = 0) extends DataSlotNumeric[Float](default) {
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setFloat(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getFloat(name)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.fluids.{Fluid, FluidRegistry}
|
||||
|
||||
case class DataSlotFluidOption(name: String, parent: DataSlotContainer) extends DataSlotOption[Fluid] {
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
|
||||
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
value foreach { x => t.setString(name, x.getName) }
|
||||
}
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value): Unit = {
|
||||
if (t.hasKey(name)) {
|
||||
val fluidName = t.getString(name)
|
||||
if (FluidRegistry.isFluidRegistered(fluidName)) {
|
||||
value = Option(FluidRegistry.getFluid(fluidName))
|
||||
} else unset()
|
||||
} else unset()
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -12,11 +12,11 @@ package net.bdew.lib.data
|
||||
import java.util.UUID
|
||||
|
||||
import com.mojang.authlib.GameProfile
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
|
||||
case class DataSlotGameProfile(name: String, parent: TileDataSlots) extends DataSlotVal[GameProfile] {
|
||||
case class DataSlotGameProfile(name: String, parent: DataSlotContainer) extends DataSlotVal[GameProfile] {
|
||||
override var value: GameProfile = null
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) = {
|
||||
@@ -29,8 +29,8 @@ case class DataSlotGameProfile(name: String, parent: TileDataSlots) extends Data
|
||||
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) = {
|
||||
if (value != null) {
|
||||
Option(value.getId) map (id => t.setString(name + "_uid", id.toString))
|
||||
Option(value.getName) filterNot (name => StringUtils.isBlank(name)) map (name => t.setString(name + "_name", name))
|
||||
Option(value.getId) foreach (id => t.setString(name + "_uid", id.toString))
|
||||
Option(value.getName) filterNot (name => StringUtils.isBlank(name)) foreach (name => t.setString(name + "_name", name))
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotInt(name: String, parent: TileDataSlots, default: Int = 0) extends DataSlotNumeric[Int](default) {
|
||||
case class DataSlotInt(name: String, parent: DataSlotContainer, default: Int = 0) extends DataSlotNumeric[Int](default) {
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setInteger(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getInteger(name)
|
||||
}
|
||||
+5
-5
@@ -9,13 +9,12 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.bdew.lib.tile.inventory.BaseInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
|
||||
case class DataSlotInventory(name: String, parent: TileDataSlots, size: Int) extends DataSlot with BaseInventory {
|
||||
case class DataSlotInventory(name: String, parent: DataSlotContainer, size: Int) extends DataSlot with BaseInventory {
|
||||
setUpdate(UpdateKind.SAVE)
|
||||
|
||||
override def getSizeInventory = size
|
||||
@@ -23,9 +22,10 @@ case class DataSlotInventory(name: String, parent: TileDataSlots, size: Int) ext
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
inv = new Array[ItemStack](getSizeInventory)
|
||||
for (nbtItem <- Misc.iterNbtCompoundList(t, name)) {
|
||||
import net.bdew.lib.nbt._
|
||||
for (nbtItem <- t.getList[NBTTagCompound](name)) {
|
||||
val slot = nbtItem.getByte("Slot")
|
||||
if (slot >= 0 && slot < inv.size) {
|
||||
if (slot >= 0 && slot < inv.length) {
|
||||
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -9,11 +9,11 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotItemStack(name: String, parent: TileDataSlots) extends DataSlotVal[ItemStack] {
|
||||
case class DataSlotItemStack(name: String, parent: DataSlotContainer) extends DataSlotVal[ItemStack] {
|
||||
var value: ItemStack = null
|
||||
|
||||
override def update(v: ItemStack) = {
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, DataInputStream, DataOutputStream}
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotMovingAverage(name: String, parent: DataSlotContainer, size: Int) extends DataSlot {
|
||||
val values = mutable.Queue.empty[Double]
|
||||
var average: Double = 0
|
||||
|
||||
setUpdate(UpdateKind.GUI, UpdateKind.SAVE)
|
||||
|
||||
def reset() {
|
||||
values.clear()
|
||||
average = 0
|
||||
}
|
||||
|
||||
def update(v: Double) = {
|
||||
values += v
|
||||
if (values.length > size)
|
||||
values.dequeue()
|
||||
average = values.sum / values.length
|
||||
parent.dataSlotChanged(this)
|
||||
}
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
if (kind == UpdateKind.GUI) {
|
||||
t.setDouble(name, average)
|
||||
} else {
|
||||
val b = new ByteArrayOutputStream()
|
||||
val o = new DataOutputStream(b)
|
||||
o.writeByte(values.size)
|
||||
values.foreach(o.writeDouble)
|
||||
t.setByteArray(name, b.toByteArray)
|
||||
o.close()
|
||||
}
|
||||
}
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
if (kind == UpdateKind.GUI) {
|
||||
average = t.getDouble(name)
|
||||
} else {
|
||||
values.clear()
|
||||
if (t.hasKey(name)) {
|
||||
val i = new DataInputStream(new ByteArrayInputStream(t.getByteArray(name)))
|
||||
val len = i.readByte()
|
||||
values ++= (for (x <- 0 until Math.min(len, size)) yield i.readDouble())
|
||||
i.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+2
-2
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotString(name: String, parent: TileDataSlots, default: String = null) extends DataSlotVal[String] {
|
||||
case class DataSlotString(name: String, parent: DataSlotContainer, default: String = null) extends DataSlotVal[String] {
|
||||
var value: String = default
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = if (value != null) t.setString(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = if (t.hasKey(name)) t.getString(name) else null
|
||||
+11
-9
@@ -9,14 +9,14 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.fluids.{FluidStack, FluidTank, IFluidTank}
|
||||
import net.minecraftforge.fluids._
|
||||
|
||||
abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank with DataSlot {
|
||||
var oldStack: FluidStack = null
|
||||
|
||||
parent.serverTick.listen(checkUpdate)
|
||||
parent.onServerTick(checkUpdate)
|
||||
|
||||
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
|
||||
|
||||
@@ -50,28 +50,30 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
|
||||
if (sendCapacityOnUpdateKind.contains(k))
|
||||
setCapacity(tag.getInteger("size"))
|
||||
}
|
||||
|
||||
override def setFluid(fluid: FluidStack) = execWithChangeNotify(super.setFluid(fluid))
|
||||
override def setCapacity(capacity: Int) = execWithChangeNotify(super.setCapacity(capacity))
|
||||
|
||||
override def drain(maxDrain: Int, doDrain: Boolean) =
|
||||
if (doDrain)
|
||||
execWithChangeNotify(super.drain(maxDrain, true))
|
||||
execWithChangeNotifyConditional[FluidStack](super.drain(maxDrain, true), _ != null)
|
||||
else
|
||||
super.drain(maxDrain, false)
|
||||
|
||||
override def fill(resource: FluidStack, doFill: Boolean) =
|
||||
if (doFill)
|
||||
execWithChangeNotify(super.fill(resource, true))
|
||||
execWithChangeNotifyConditional[Int](super.fill(resource, true), _ > 0)
|
||||
else
|
||||
super.fill(resource, false)
|
||||
}
|
||||
|
||||
case class DataSlotTank(name: String, parent: TileDataSlots, size: Int) extends DataSlotTankBase(size)
|
||||
case class DataSlotTank(name: String, parent: DataSlotContainer, size: Int) extends DataSlotTankBase(size)
|
||||
|
||||
case class DataSlotTankRestricted(name: String, parent: TileDataSlots, var size: Int, fluidID: Int) extends DataSlotTankBase(size) {
|
||||
def fill(amount: Int, doFill: Boolean) = super.fill(new FluidStack(fluidID, amount), doFill)
|
||||
case class DataSlotTankRestricted(name: String, parent: DataSlotContainer, var size: Int, filterFluid: Fluid) extends DataSlotTankBase(size) {
|
||||
def fill(amount: Int, doFill: Boolean) = super.fill(new FluidStack(filterFluid, amount), doFill)
|
||||
|
||||
override def fill(resource: FluidStack, doFill: Boolean): Int = {
|
||||
if ((resource != null) && (resource.fluidID != fluidID)) return 0
|
||||
if ((resource != null) && (resource.getFluid != filterFluid)) return 0
|
||||
return super.fill(resource, doFill)
|
||||
}
|
||||
}
|
||||
File renamed without changes.
+8
-1
@@ -19,7 +19,7 @@ trait DataSlot {
|
||||
* Tile Entity that owns this slot
|
||||
* Accessed in constructor, so should be in parameters or a lazy val, otherwise will crash
|
||||
*/
|
||||
val parent: TileDataSlots
|
||||
val parent: DataSlotContainer
|
||||
|
||||
/**
|
||||
* Unique name
|
||||
@@ -41,6 +41,13 @@ trait DataSlot {
|
||||
v
|
||||
}
|
||||
|
||||
def execWithChangeNotifyConditional[T](f: => T, condition: T => Boolean): T = {
|
||||
val v = f
|
||||
if (condition(v))
|
||||
parent.dataSlotChanged(this)
|
||||
v
|
||||
}
|
||||
|
||||
def setUpdate(vals: UpdateKind.Value*): this.type = {
|
||||
updateKind = vals.toSet
|
||||
return this
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.data.base
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* Base Trait for objects that can contain Data Slots, this allows implementing them on things that aren't TEs
|
||||
*/
|
||||
trait DataSlotContainer {
|
||||
|
||||
// Can't use getWorldObj - it fails to get remapped and stuff breaks in obfuscated environment
|
||||
def getWorldObject: World
|
||||
|
||||
/**
|
||||
* Called when a dataslot value changes
|
||||
*/
|
||||
def dataSlotChanged(slot: DataSlot): Unit
|
||||
|
||||
/**
|
||||
* Register a function to run on every server tick
|
||||
*/
|
||||
def onServerTick(f: () => Unit): Unit
|
||||
|
||||
/**
|
||||
* List of dataslots in this container
|
||||
*/
|
||||
val dataSlots = mutable.HashMap.empty[String, DataSlot]
|
||||
|
||||
/**
|
||||
* The value of getTotalWorldTime when the last change happened
|
||||
*/
|
||||
var lastChange = 0L
|
||||
|
||||
/**
|
||||
* The value of getTotalWorldTime when the last GUI packet was sent happened
|
||||
*/
|
||||
var lastGuiPacket = 0L
|
||||
|
||||
final val TRACE = false
|
||||
|
||||
def doSave(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
if (kind == UpdateKind.GUI)
|
||||
t.setLong("BDLib_TS", getWorldObject.getTotalWorldTime)
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
s.save(t, kind)
|
||||
if (TRACE) printf("%s: %s S=> %s\n".format(kind, n, t.getTag(n)))
|
||||
}
|
||||
}
|
||||
|
||||
def doLoad(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
if (kind == UpdateKind.GUI) {
|
||||
val ts = t.getLong("BDLib_TS")
|
||||
if (ts > lastGuiPacket) {
|
||||
lastGuiPacket = ts
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
if (TRACE) printf("%s: %s L<= %s\n".format(kind, n, t.getTag(n)))
|
||||
s.load(t, kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -19,4 +19,9 @@ abstract class DataSlotNumeric[T](default: T)(implicit n: Numeric[T]) extends Da
|
||||
def +=(that: T) = update(n.plus(value, that))
|
||||
def -=(that: T) = update(n.minus(value, that))
|
||||
def *=(that: T) = update(n.times(value, that))
|
||||
|
||||
/* Special Int versions, using the conversion from numeric */
|
||||
def +=(that: Int) = update(n.plus(value, n.fromInt(that)))
|
||||
def -=(that: Int) = update(n.minus(value, n.fromInt(that)))
|
||||
def *=(that: Int) = update(n.times(value, n.fromInt(that)))
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
+14
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
@@ -14,40 +14,25 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.network.Packet
|
||||
import net.minecraft.network.play.server.S35PacketUpdateTileEntity
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
trait TileDataSlots extends TileExtended {
|
||||
val dataSlots = mutable.HashMap.empty[String, DataSlot]
|
||||
var lastChange = 0L
|
||||
|
||||
final val TRACE = false
|
||||
|
||||
def doSave(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
s.save(t, kind)
|
||||
if (TRACE) printf("%s: %s S=> %s\n".format(kind, n, t.getTag(n)))
|
||||
}
|
||||
}
|
||||
|
||||
def doLoad(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
if (TRACE) printf("%s: %s L<= %s\n".format(kind, n, t.getTag(n)))
|
||||
s.load(t, kind)
|
||||
if (kind == UpdateKind.WORLD && s.updateKind.contains(UpdateKind.RENDER))
|
||||
getWorldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord)
|
||||
}
|
||||
}
|
||||
|
||||
trait TileDataSlots extends TileExtended with DataSlotContainer {
|
||||
persistSave.listen(doSave(UpdateKind.SAVE, _))
|
||||
persistLoad.listen(doLoad(UpdateKind.SAVE, _))
|
||||
sendClientUpdate.listen(doSave(UpdateKind.WORLD, _))
|
||||
handleClientUpdate.listen(doLoad(UpdateKind.WORLD, _))
|
||||
handleClientUpdate.listen { tag =>
|
||||
doLoad(UpdateKind.WORLD, tag)
|
||||
if (dataSlots.values.exists(_.updateKind.contains(UpdateKind.RENDER)))
|
||||
getWorldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord)
|
||||
}
|
||||
|
||||
def dataSlotChanged(slot: DataSlot) {
|
||||
override def getWorldObject = getWorldObj
|
||||
|
||||
override def onServerTick(f: () => Unit) = serverTick.listen(f)
|
||||
|
||||
override def dataSlotChanged(slot: DataSlot) = {
|
||||
if (getWorldObj != null) {
|
||||
if (slot.updateKind.contains(UpdateKind.GUI))
|
||||
lastChange = getWorldObj.getTotalWorldTime
|
||||
if (slot.updateKind.contains(UpdateKind.WORLD))
|
||||
if (!getWorldObj.isRemote && slot.updateKind.contains(UpdateKind.WORLD))
|
||||
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
|
||||
if (slot.updateKind.contains(UpdateKind.SAVE))
|
||||
getWorldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this)
|
||||
@@ -57,7 +42,7 @@ trait TileDataSlots extends TileExtended {
|
||||
def getDataSlotPacket: Packet = {
|
||||
val tag = new NBTTagCompound()
|
||||
doSave(UpdateKind.GUI, tag)
|
||||
return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, ACT_GUI, tag)
|
||||
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, ACT_GUI, tag)
|
||||
}
|
||||
|
||||
override protected def extDataPacket(id: Int, data: NBTTagCompound) {
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -16,7 +16,7 @@ case class BaseRect[T: Numeric](x: T, y: T, w: T, h: T) {
|
||||
|
||||
def this(p: BasePoint[T], w: T, h: T) = this(p.x, p.y, w, h)
|
||||
|
||||
def contains(p: BasePoint[T]) = n.gteq(p.x, x) && n.gteq(p.y, y) && n.lteq(p.x, x2) && n.lteq(p.y, y2)
|
||||
def contains(p: BasePoint[T]) = n.gteq(p.x, x) && n.gteq(p.y, y) && n.lt(p.x, x2) && n.lt(p.y, y2)
|
||||
|
||||
def origin = BasePoint(x, y)
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
|
||||
if (tip.size > 0)
|
||||
if (tip.nonEmpty)
|
||||
drawHoveringText(tip, x, y, getFontRenderer)
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+9
-2
@@ -23,6 +23,13 @@ trait GuiProvider {
|
||||
def getContainer(te: TEClass, player: EntityPlayer): AnyRef
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def getGui(te: TileEntity, player: EntityPlayer): AnyRef = getGui(te.asInstanceOf[TEClass], player)
|
||||
def getContainer(te: TileEntity, player: EntityPlayer): AnyRef = getContainer(te.asInstanceOf[TEClass], player)
|
||||
def getGui(te: TileEntity, player: EntityPlayer): AnyRef =
|
||||
if (te != null)
|
||||
getGui(te.asInstanceOf[TEClass], player)
|
||||
else null
|
||||
|
||||
def getContainer(te: TileEntity, player: EntityPlayer): AnyRef =
|
||||
if (te != null)
|
||||
getContainer(te.asInstanceOf[TEClass], player)
|
||||
else null
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* http://bdew.net/minecraft-mod-public-license/
|
||||
*/
|
||||
|
||||
package net.bdew.lib.helpers
|
||||
|
||||
import net.minecraft.util._
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
class RichChatComponent(v: IChatComponent) {
|
||||
def &(that: IChatComponent) = v.appendSibling(that)
|
||||
|
||||
private def applyStyle(f: ChatStyle => Unit) = {
|
||||
f(v.getChatStyle)
|
||||
v
|
||||
}
|
||||
|
||||
def setColor(c: EnumChatFormatting) = applyStyle(_.setColor(c))
|
||||
def setBold(b: Boolean) = applyStyle(_.setBold(b))
|
||||
def setItalic(b: Boolean) = applyStyle(_.setItalic(b))
|
||||
def setObfuscated(b: Boolean) = applyStyle(_.setObfuscated(b))
|
||||
def setStrikethrough(b: Boolean) = applyStyle(_.setStrikethrough(b))
|
||||
def setUnderlined(b: Boolean) = applyStyle(_.setUnderlined(b))
|
||||
|
||||
}
|
||||
|
||||
object ChatHelper {
|
||||
|
||||
object Color {
|
||||
val BLACK = EnumChatFormatting.BLACK
|
||||
val DARK_BLUE = EnumChatFormatting.DARK_BLUE
|
||||
val DARK_GREEN = EnumChatFormatting.DARK_GREEN
|
||||
val DARK_AQUA = EnumChatFormatting.DARK_AQUA
|
||||
val DARK_RED = EnumChatFormatting.DARK_RED
|
||||
val DARK_PURPLE = EnumChatFormatting.DARK_PURPLE
|
||||
val GOLD = EnumChatFormatting.GOLD
|
||||
val GRAY = EnumChatFormatting.GRAY
|
||||
val DARK_GRAY = EnumChatFormatting.DARK_GRAY
|
||||
val BLUE = EnumChatFormatting.BLUE
|
||||
val GREEN = EnumChatFormatting.GREEN
|
||||
val AQUA = EnumChatFormatting.AQUA
|
||||
val RED = EnumChatFormatting.RED
|
||||
val LIGHT_PURPLE = EnumChatFormatting.LIGHT_PURPLE
|
||||
val YELLOW = EnumChatFormatting.YELLOW
|
||||
val WHITE = EnumChatFormatting.WHITE
|
||||
}
|
||||
|
||||
implicit def str2chat(s: String): ChatComponentText = new ChatComponentText(s)
|
||||
implicit def str2rich(s: String): RichChatComponent = new RichChatComponent(new ChatComponentText(s))
|
||||
implicit def pimpIChatComponent(v: IChatComponent): RichChatComponent = new RichChatComponent(v)
|
||||
|
||||
def C(s: String) = new ChatComponentText(s)
|
||||
def L(s: String, params: IChatComponent*) = new ChatComponentTranslation(s, params: _*)
|
||||
}
|
||||
Loaded 100 of 236 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user