Compare commits
No commits in common. "ac41344a3c9aad460c2c9e0acdd9f47da05e0024" and "ddc78efa0ecaa95aa30ce6ceeddcbdcf3b37292e" have entirely different histories.
ac41344a3c
...
ddc78efa0e
60 changed files with 191 additions and 2690 deletions
61
.github/workflows/deploy.yml
vendored
61
.github/workflows/deploy.yml
vendored
|
@ -1,61 +0,0 @@
|
||||||
# A deployment template that works out of the box
|
|
||||||
# It supports these objectives:
|
|
||||||
# - Deploy to Maven (Build Job) [Secrets: MAVEN_USER, MAVEN_PASS]
|
|
||||||
# - Deploy to CurseForge (Upload Job) [Secrets: CURSEFORGE_TOKEN]
|
|
||||||
# - Deploy to Modrinth (Upload Job) [Secrets: MODRINTH_TOKEN]
|
|
||||||
|
|
||||||
name: Deploy
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- '[0-9]+.[0-9]+.[0-9]+'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Grant Execute Permission for gradlew
|
|
||||||
run: chmod +x gradlew
|
|
||||||
|
|
||||||
- name: Read gradle.properties
|
|
||||||
uses: BrycensRanch/read-properties-action@v1
|
|
||||||
id: properties
|
|
||||||
with:
|
|
||||||
file: gradle.properties
|
|
||||||
all: true
|
|
||||||
|
|
||||||
- name: Setup Java
|
|
||||||
uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
java-version: '17'
|
|
||||||
distribution: 'zulu'
|
|
||||||
cache: gradle
|
|
||||||
|
|
||||||
- name: Publish to Maven
|
|
||||||
if: steps.properties.outputs.publish_to_maven == 'true' && steps.properties.outputs.publish_to_local_maven == 'true'
|
|
||||||
uses: gradle/gradle-build-action@v2
|
|
||||||
with:
|
|
||||||
arguments: |
|
|
||||||
publish
|
|
||||||
-P${{ steps.properties.outputs.maven_name }}Username=${{ secrets.MAVEN_USER }}
|
|
||||||
-P${{ steps.properties.outputs.maven_name }}Password=${{ secrets.MAVEN_PASS }}
|
|
||||||
|
|
||||||
- name: Publish to CurseForge
|
|
||||||
if: steps.properties.outputs.publish_to_curseforge == 'true'
|
|
||||||
uses: gradle/gradle-build-action@v2
|
|
||||||
env:
|
|
||||||
CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }}
|
|
||||||
with:
|
|
||||||
arguments: curseforge
|
|
||||||
|
|
||||||
- name: Publish to Modrinth
|
|
||||||
if: steps.properties.outputs.publish_to_modrinth == 'true'
|
|
||||||
uses: gradle/gradle-build-action@v2
|
|
||||||
env:
|
|
||||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
|
||||||
with:
|
|
||||||
arguments: modrinth
|
|
|
@ -1,6 +0,0 @@
|
||||||
# Changelog
|
|
||||||
|
|
||||||
## [1.0.0] - 2023-09-15
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- This is a default template changelog that follows the [KeepAChangelog Convention](https://keepachangelog.com/en/1.1.0/)
|
|
18
LICENSE
18
LICENSE
|
@ -1,11 +1,21 @@
|
||||||
All Rights Reserved
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2024 Octol1ttle
|
Copyright (c) 2022 CleanroomMC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
THE SOFTWARE.
|
SOFTWARE.
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Template workspace for modding Minecraft 1.12.2. Licensed under MIT, it is made for public use.
|
Template workspace for modding Minecraft 1.12.2. Licensed under MIT, it is made for public use.
|
||||||
|
|
||||||
This template currently utilizies **Gradle 8.7** + **[RetroFuturaGradle](https://github.com/GTNewHorizons/RetroFuturaGradle) 1.3.35** + **Forge 14.23.5.2847**.
|
This template currently utilizies **Gradle 8.1.1** + **[RetroFuturaGradle](https://github.com/GTNewHorizons/RetroFuturaGradle) 1.3.6** + **Forge 14.23.5.2847**.
|
||||||
|
|
||||||
With **coremod and mixin support** that is easy to configure.
|
With **coremod and mixin support** that is easy to configure.
|
||||||
|
|
||||||
|
@ -14,7 +14,3 @@ With **coremod and mixin support** that is easy to configure.
|
||||||
4. Open the project folder in IDEA.
|
4. Open the project folder in IDEA.
|
||||||
5. Right-click in IDEA `build.gradle` of your project, and select `Link Gradle Project`, after completion, hit `Refresh All` in the gradle tab on the right.
|
5. Right-click in IDEA `build.gradle` of your project, and select `Link Gradle Project`, after completion, hit `Refresh All` in the gradle tab on the right.
|
||||||
6. Run `gradlew runClient` and `gradlew runServer`, or use the auto-imported run configurations in IntelliJ like `1. Run Client`.
|
6. Run `gradlew runClient` and `gradlew runServer`, or use the auto-imported run configurations in IntelliJ like `1. Run Client`.
|
||||||
|
|
||||||
### Mixins:
|
|
||||||
|
|
||||||
- When writing Mixins on IntelliJ, it is advisable to use latest [MinecraftDev Fork for RetroFuturaGradle](https://github.com/eigenraven/MinecraftDev/releases).
|
|
||||||
|
|
354
build.gradle
354
build.gradle
|
@ -1,67 +1,34 @@
|
||||||
/**
|
import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar
|
||||||
* It is advised that you do not edit anything in the build.gradle; unless you are sure of what you are doing
|
|
||||||
*/
|
|
||||||
import com.gtnewhorizons.retrofuturagradle.mcp.InjectTagsTask
|
|
||||||
import org.jetbrains.changelog.Changelog
|
|
||||||
import org.jetbrains.gradle.ext.Gradle
|
import org.jetbrains.gradle.ext.Gradle
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id("java")
|
||||||
id 'java-library'
|
id("java-library")
|
||||||
id 'maven-publish'
|
id("maven-publish")
|
||||||
id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7'
|
id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7"
|
||||||
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.35'
|
id("eclipse")
|
||||||
id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
|
id("com.gtnewhorizons.retrofuturagradle") version "1.3.9"
|
||||||
id 'com.modrinth.minotaur' version '2.+' apply false
|
id("com.matthewprenger.cursegradle") version "1.4.0"
|
||||||
id 'org.jetbrains.changelog' version '2.2.0'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: 'gradle/scripts/helpers.gradle'
|
version = project.mod_version
|
||||||
|
group = project.maven_group
|
||||||
// Early Assertions
|
archivesBaseName = project.archives_base_name
|
||||||
assertProperty 'mod_version'
|
|
||||||
assertProperty 'root_package'
|
|
||||||
assertProperty 'mod_id'
|
|
||||||
assertProperty 'mod_name'
|
|
||||||
|
|
||||||
assertSubProperties 'use_tags', 'tag_class_name'
|
|
||||||
assertSubProperties 'use_access_transformer', 'access_transformer_locations'
|
|
||||||
assertSubProperties 'use_mixins', 'mixin_booter_version', 'mixin_refmap'
|
|
||||||
assertSubProperties 'is_coremod', 'coremod_includes_mod', 'coremod_plugin_class_name'
|
|
||||||
assertSubProperties 'use_asset_mover', 'asset_mover_version'
|
|
||||||
|
|
||||||
setDefaultProperty 'use_modern_java_syntax', false, false
|
|
||||||
setDefaultProperty 'generate_sources_jar', true, false
|
|
||||||
setDefaultProperty 'generate_javadocs_jar', true, false
|
|
||||||
setDefaultProperty 'mapping_channel', true, 'stable'
|
|
||||||
setDefaultProperty 'mapping_version', true, '39'
|
|
||||||
setDefaultProperty 'use_dependency_at_files', true, true
|
|
||||||
setDefaultProperty 'minecraft_username', true, 'Developer'
|
|
||||||
setDefaultProperty 'extra_jvm_args', false, ''
|
|
||||||
setDefaultProperty 'extra_tweak_classes', false, ''
|
|
||||||
setDefaultProperty 'change_minecraft_sources', false, false
|
|
||||||
|
|
||||||
version = propertyString('mod_version')
|
|
||||||
group = propertyString('root_package')
|
|
||||||
|
|
||||||
base {
|
|
||||||
archivesName.set(propertyString('mod_id'))
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.decompressDecompiledSources.enabled !propertyBool('change_minecraft_sources')
|
|
||||||
|
|
||||||
|
// Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod
|
||||||
java {
|
java {
|
||||||
toolchain {
|
toolchain {
|
||||||
languageVersion.set(JavaLanguageVersion.of(propertyBool('use_modern_java_syntax') ? 16 : 8))
|
languageVersion.set(JavaLanguageVersion.of(8))
|
||||||
// Azul covers the most platforms for Java 8 toolchains, crucially including MacOS arm64
|
// Azul covers the most platforms for Java 8 toolchains, crucially including MacOS arm64
|
||||||
vendor.set(JvmVendorSpec.AZUL)
|
vendor.set(org.gradle.jvm.toolchain.JvmVendorSpec.AZUL)
|
||||||
}
|
}
|
||||||
if (propertyBool('generate_sources_jar')) {
|
// Generate sources and javadocs jars when building and publishing
|
||||||
withSourcesJar()
|
withSourcesJar()
|
||||||
}
|
|
||||||
if (propertyBool('generate_javadocs_jar')) {
|
|
||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
|
@ -70,139 +37,131 @@ configurations {
|
||||||
}
|
}
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
mcVersion.set('1.12.2')
|
mcVersion = '1.12.2'
|
||||||
|
def args = ["-ea:${project.group}"]
|
||||||
mcpMappingChannel.set(propertyString('mapping_channel'))
|
if (project.use_coremod.toBoolean()) {
|
||||||
mcpMappingVersion.set(propertyString('mapping_version'))
|
args << '-Dfml.coreMods.load=' + coremod_plugin_class_name
|
||||||
|
}
|
||||||
useDependencyAccessTransformers.set(propertyBool('use_dependency_at_files'))
|
if (project.use_mixins.toBoolean()) {
|
||||||
|
|
||||||
username.set(propertyString('minecraft_username'))
|
|
||||||
|
|
||||||
// Add any additional tweaker classes here
|
|
||||||
extraTweakClasses.addAll(propertyStringList('extra_tweak_classes'))
|
|
||||||
|
|
||||||
// Add various JVM arguments here for runtime
|
|
||||||
def args = ['-ea:' + group]
|
|
||||||
if (propertyBool('use_mixins')) {
|
|
||||||
args << '-Dmixin.hotSwap=true'
|
args << '-Dmixin.hotSwap=true'
|
||||||
args << '-Dmixin.checks.interfaces=true'
|
args << '-Dmixin.checks.interfaces=true'
|
||||||
args << '-Dmixin.debug.export=true'
|
args << '-Dmixin.debug.export=true'
|
||||||
}
|
}
|
||||||
extraRunJvmArguments.addAll(args)
|
extraRunJvmArguments.addAll(args)
|
||||||
extraRunJvmArguments.addAll(propertyStringList('extra_jvm_args'))
|
|
||||||
|
|
||||||
if (propertyBool('use_tags')) {
|
useDependencyAccessTransformers = true
|
||||||
if (file('tags.properties').exists()) {
|
|
||||||
Properties props = new Properties().tap { it.load(file('tags.properties').newInputStream()); it }
|
injectedTags.put("VERSION", project.version)
|
||||||
if (!props.isEmpty()) {
|
|
||||||
injectedTags.set(props.collectEntries { k, v -> [(k): interpolate(v)] })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a my.project.Tags class with the version number as a field
|
||||||
|
tasks.injectTags.configure {
|
||||||
|
outputClassName.set("${project.group}.Tags")
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
name 'CleanroomMC Maven'
|
url = 'https://maven.cleanroommc.com'
|
||||||
url 'https://maven.cleanroommc.com'
|
|
||||||
}
|
}
|
||||||
|
maven { url = "https://repo.spongepowered.org/maven" }
|
||||||
|
//maven { url "https://maven.mcmoddev.com/" }
|
||||||
|
maven {
|
||||||
|
url "https://cursemaven.com"
|
||||||
|
content {
|
||||||
|
includeGroup "curse.maven"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mavenLocal() // Must be last for caching to work
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
if (propertyBool('use_modern_java_syntax')) {
|
if (project.use_assetmover.toBoolean()) {
|
||||||
annotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0'
|
implementation 'com.cleanroommc:assetmover:2.0'
|
||||||
// Workaround for https://github.com/bsideup/jabel/issues/174
|
|
||||||
annotationProcessor 'net.java.dev.jna:jna-platform:5.13.0'
|
|
||||||
compileOnly ('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') {
|
|
||||||
transitive = false
|
|
||||||
}
|
}
|
||||||
// Allow jdk.unsupported classes like sun.misc.Unsafe, workaround for JDK-8206937 and fixes crashes in tests
|
if (project.use_mixins.toBoolean()) {
|
||||||
patchedMinecraft 'me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0'
|
implementation 'zone.rong:mixinbooter:7.0'
|
||||||
// Include for tests
|
|
||||||
testAnnotationProcessor 'com.github.bsideup.jabel:jabel-javac-plugin:1.0.0'
|
|
||||||
testCompileOnly('com.github.bsideup.jabel:jabel-javac-plugin:1.0.0') {
|
|
||||||
transitive = false // We only care about the 1 annotation class
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Example deobf dependency
|
||||||
|
// compileOnly rfg.deobf("curse.maven:endercore-231868:2972849:")
|
||||||
|
|
||||||
|
if (project.use_mixins.toBoolean()) {
|
||||||
|
api ("org.spongepowered:mixin:0.8.3") {transitive = false}
|
||||||
|
annotationProcessor('org.ow2.asm:asm-debug-all:5.2')
|
||||||
|
annotationProcessor('com.google.guava:guava:24.1.1-jre')
|
||||||
|
annotationProcessor('com.google.code.gson:gson:2.8.6')
|
||||||
|
annotationProcessor ("org.spongepowered:mixin:0.8.3") {transitive = false}
|
||||||
}
|
}
|
||||||
if (propertyBool('use_asset_mover')) {
|
|
||||||
implementation "com.cleanroommc:assetmover:${propertyString('asset_mover_version')}"
|
|
||||||
}
|
}
|
||||||
if (propertyBool('use_mixins')) {
|
|
||||||
String mixin = modUtils.enableMixins("zone.rong:mixinbooter:${propertyString('mixin_booter_version')}", propertyString('mixin_refmap'))
|
def mixinConfigRefMap = 'mixins.' + project.archives_base_name + '.refmap.json'
|
||||||
api (mixin) {
|
def mixinTmpDir = buildDir.path + File.separator + 'tmp' + File.separator + 'mixins'
|
||||||
transitive = false
|
def refMap = "${mixinTmpDir}" + File.separator + mixinConfigRefMap
|
||||||
|
def mixinSrg = "${mixinTmpDir}" + File.separator + "mixins.srg"
|
||||||
|
|
||||||
|
if (project.use_mixins.toBoolean()) {
|
||||||
|
tasks.named("reobfJar", ReobfuscatedJar).configure {
|
||||||
|
extraSrgFiles.from(mixinSrg)
|
||||||
}
|
}
|
||||||
annotationProcessor 'org.ow2.asm:asm-debug-all:5.2'
|
|
||||||
annotationProcessor 'com.google.guava:guava:24.1.1-jre'
|
tasks.named("compileJava", JavaCompile).configure {
|
||||||
annotationProcessor 'com.google.code.gson:gson:2.8.6'
|
doFirst {
|
||||||
annotationProcessor (mixin) {
|
new File(mixinTmpDir).mkdirs()
|
||||||
transitive = false
|
|
||||||
}
|
}
|
||||||
}
|
options.compilerArgs += [
|
||||||
if (propertyBool('enable_junit_testing')) {
|
"-AreobfSrgFile=${tasks.reobfJar.srg.get().asFile}",
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.1'
|
"-AoutSrgFile=${mixinSrg}",
|
||||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
"-AoutRefMapFile=${refMap}",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: 'gradle/scripts/dependencies.gradle'
|
if (project.use_access_transformer.toBoolean()) {
|
||||||
|
for (File at : sourceSets.getByName("main").resources.files) {
|
||||||
// Adds Access Transformer files to tasks
|
if (at.name.toLowerCase().endsWith("_at.cfg")) {
|
||||||
if (propertyBool('use_access_transformer')) {
|
tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at)
|
||||||
for (def location : propertyStringList('access_transformer_locations')) {
|
tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at)
|
||||||
def fileLocation = file("${projectDir}/src/main/resources/${location}")
|
|
||||||
if (fileLocation.exists()) {
|
|
||||||
tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(fileLocation)
|
|
||||||
tasks.srgifyBinpatchedJar.accessTransformerFiles.from(fileLocation)
|
|
||||||
} else {
|
|
||||||
throw new GradleException("Access Transformer file [$fileLocation] does not exist!")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
// this will ensure that this task is redone when the versions change.
|
||||||
def filterList = ['mcmod.info', 'pack.mcmeta']
|
inputs.property 'version', project.version
|
||||||
filterList.addAll(propertyStringList('mixin_configs').collect(config -> "mixins.${config}.json" as String))
|
inputs.property 'mcversion', project.minecraft.version
|
||||||
|
// replace stuff in mcmod.info, nothing else
|
||||||
filesMatching(filterList) { fcd ->
|
filesMatching(['mcmod.info', 'pack.mcmeta']) { fcd ->
|
||||||
|
// replace version and mcversion
|
||||||
fcd.expand (
|
fcd.expand (
|
||||||
'mod_id': propertyString('mod_id'),
|
'version': project.version,
|
||||||
'mod_name': propertyString('mod_name'),
|
'mcversion': project.minecraft.version
|
||||||
'mod_version': propertyString('mod_version'),
|
|
||||||
'mod_description': propertyString('mod_description'),
|
|
||||||
'mod_authors': "[${propertyStringList('mod_authors', ',').join(', ')}]",
|
|
||||||
'mod_credits': propertyString('mod_credits'),
|
|
||||||
'mod_url': propertyString('mod_url'),
|
|
||||||
'mod_update_json': propertyString('mod_update_json'),
|
|
||||||
'mod_logo_path': propertyString('mod_logo_path'),
|
|
||||||
'mixin_refmap': propertyString('mixin_refmap'),
|
|
||||||
'mixin_package': propertyString('mixin_package')
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyBool('use_access_transformer')) {
|
if (project.use_access_transformer.toBoolean()) {
|
||||||
rename '(.+_at.cfg)', 'META-INF/$1'
|
rename '(.+_at.cfg)', 'META-INF/$1' // Access Transformers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (project.use_mixins.toBoolean()) {
|
||||||
|
// Embed mixin refmap
|
||||||
|
from refMap
|
||||||
|
dependsOn("compileJava")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
manifest {
|
manifest {
|
||||||
def attribute_map = [:]
|
def attribute_map = [:]
|
||||||
if (propertyBool('is_coremod')) {
|
if (project.use_coremod.toBoolean()) {
|
||||||
attribute_map['FMLCorePlugin'] = propertyString('coremod_plugin_class_name')
|
attribute_map['FMLCorePlugin'] = project.coremod_plugin_class_name
|
||||||
if (propertyBool('coremod_includes_mod')) {
|
if (project.include_mod.toBoolean()) {
|
||||||
attribute_map['FMLCorePluginContainsFMLMod'] = true
|
attribute_map['FMLCorePluginContainsFMLMod'] = true
|
||||||
def currentTasks = gradle.startParameter.taskNames
|
attribute_map['ForceLoadAsMod'] = project.gradle.startParameter.taskNames[0] == "build"
|
||||||
if (currentTasks[0] == 'build' || currentTasks[0] == 'prepareObfModsFolder' || currentTasks[0] == 'runObfClient') {
|
|
||||||
attribute_map['ForceLoadAsMod'] = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (project.use_access_transformer.toBoolean()) {
|
||||||
if (propertyBool('use_access_transformer')) {
|
attribute_map['FMLAT'] = project.archives_base_name + '_at.cfg'
|
||||||
attribute_map['FMLAT'] = propertyString('access_transformer_locations')
|
|
||||||
}
|
}
|
||||||
attributes(attribute_map)
|
attributes(attribute_map)
|
||||||
}
|
}
|
||||||
|
@ -211,11 +170,8 @@ jar {
|
||||||
}
|
}
|
||||||
|
|
||||||
idea {
|
idea {
|
||||||
module {
|
module { inheritOutputDirs = true }
|
||||||
inheritOutputDirs = true
|
project { settings {
|
||||||
}
|
|
||||||
project {
|
|
||||||
settings {
|
|
||||||
runConfigurations {
|
runConfigurations {
|
||||||
"1. Run Client"(Gradle) {
|
"1. Run Client"(Gradle) {
|
||||||
taskNames = ["runClient"]
|
taskNames = ["runClient"]
|
||||||
|
@ -238,109 +194,9 @@ idea {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileTestJava {
|
tasks.named("processIdeaSettings").configure {
|
||||||
sourceCompatibility = targetCompatibility = 8
|
dependsOn("injectTags")
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
javaLauncher.set(javaToolchains.launcherFor {
|
|
||||||
languageVersion = JavaLanguageVersion.of(8)
|
|
||||||
})
|
|
||||||
if (propertyBool('show_testing_output')) {
|
|
||||||
testLogging {
|
|
||||||
showStandardStreams = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String parserChangelog() {
|
|
||||||
if (!file('CHANGELOG.md').exists()) {
|
|
||||||
throw new GradleException('publish_with_changelog is true, but CHANGELOG.md does not exist in the workspace!')
|
|
||||||
}
|
|
||||||
String parsedChangelog = changelog.renderItem(
|
|
||||||
changelog.get(propertyString('mod_version')).withHeader(false).withEmptySections(false),
|
|
||||||
Changelog.OutputType.MARKDOWN)
|
|
||||||
if (parsedChangelog.isEmpty()) {
|
|
||||||
throw new GradleException('publish_with_changelog is true, but the changelog for the latest version is empty!')
|
|
||||||
}
|
|
||||||
return parsedChangelog
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register('generateMixinJson') {
|
|
||||||
group 'cleanroom helpers'
|
|
||||||
def missingConfig = propertyStringList('mixin_configs').findAll(config -> !file("src/main/resources/mixins.${config}.json").exists())
|
|
||||||
onlyIf {
|
|
||||||
if (propertyBool('use_mixins') && propertyBool('generate_mixins_json')) {
|
|
||||||
return !missingConfig.empty
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
doLast {
|
|
||||||
for (String mixinConfig : missingConfig) {
|
|
||||||
def file = file("src/main/resources/mixins.${mixinConfig}.json")
|
|
||||||
file << """{\n\t"package": "",\n\t"required": true,\n\t"refmap": "${mixin_refmap}",\n\t"target": "@env(DEFAULT)",\n\t"minVersion": "0.8.5",\n\t"compatibilityLevel": "JAVA_8",\n\t"mixins": [],\n\t"server": [],\n\t"client": []\n}"""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(JavaCompile).configureEach {
|
|
||||||
options.encoding = 'UTF-8'
|
|
||||||
if (propertyBool('use_modern_java_syntax')) {
|
|
||||||
if (it.name in ['compileMcLauncherJava', 'compilePatchedMcJava']) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
sourceCompatibility = 17
|
|
||||||
options.release.set(8)
|
|
||||||
javaCompiler.set(javaToolchains.compilerFor {
|
|
||||||
languageVersion.set(JavaLanguageVersion.of(16))
|
|
||||||
vendor.set(JvmVendorSpec.AZUL)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register('cleanroomAfterSync') {
|
|
||||||
group 'cleanroom helpers'
|
|
||||||
dependsOn 'injectTags', 'generateMixinJson'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propertyBool('use_modern_java_syntax')) {
|
|
||||||
tasks.withType(Javadoc).configureEach {
|
|
||||||
sourceCompatibility = 17
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.named('injectTags', InjectTagsTask).configure {
|
|
||||||
onlyIf {
|
|
||||||
return propertyBool('use_tags') && !it.getTags().get().isEmpty()
|
|
||||||
}
|
|
||||||
it.outputClassName.set(propertyString('tag_class_name'))
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.named('prepareObfModsFolder').configure {
|
|
||||||
finalizedBy 'prioritizeCoremods'
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register('prioritizeCoremods') {
|
|
||||||
dependsOn 'prepareObfModsFolder'
|
|
||||||
doLast {
|
|
||||||
fileTree('run/obfuscated').forEach {
|
|
||||||
if (it.isFile() && it.name =~ '(mixinbooter|configanytime)(-)([0-9])+\\.+([0-9])+(.jar)') {
|
|
||||||
it.renameTo(new File(it.parentFile, "!${it.name}"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
idea.project.settings {
|
|
||||||
taskTriggers {
|
|
||||||
afterSync 'cleanroomAfterSync'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: 'gradle/scripts/publishing.gradle'
|
|
||||||
apply from: 'gradle/scripts/extra.gradle'
|
|
||||||
|
|
|
@ -1,126 +1,22 @@
|
||||||
# Gradle Properties
|
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||||
|
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||||
org.gradle.jvmargs = -Xmx3G
|
org.gradle.jvmargs = -Xmx3G
|
||||||
|
|
||||||
# Source Options
|
|
||||||
# Use Modern Java(9+) Syntax (Courtesy of Jabel)
|
|
||||||
use_modern_java_syntax = false
|
|
||||||
|
|
||||||
# Compilation Options
|
|
||||||
generate_sources_jar = true
|
|
||||||
generate_javadocs_jar = false
|
|
||||||
|
|
||||||
# Testing
|
|
||||||
enable_junit_testing = true
|
|
||||||
show_testing_output = false
|
|
||||||
|
|
||||||
# Mod Information
|
# Mod Information
|
||||||
# HIGHLY RECOMMEND complying with SemVer for mod_version: https://semver.org/
|
mod_version = 1.0
|
||||||
mod_version = 1.0.0
|
maven_group = com.cleanroommc
|
||||||
root_package = ru.octol1ttle
|
archives_base_name = modid
|
||||||
mod_id = knockdowns
|
|
||||||
mod_name = Knockdowns (Legacy)
|
|
||||||
|
|
||||||
# Mod Metadata (Optional)
|
# If any properties changes below this line, run `gradlew setupDecompWorkspace` and refresh gradle again to ensure everything is working correctly.
|
||||||
mod_description =
|
|
||||||
mod_url =
|
|
||||||
mod_update_json =
|
|
||||||
# Delimit authors with commas
|
|
||||||
mod_authors = Octol1ttle
|
|
||||||
mod_credits =
|
|
||||||
mod_logo_path =
|
|
||||||
|
|
||||||
# Mapping Properties
|
# Boilerplate Options
|
||||||
mapping_channel = stable
|
use_mixins = false
|
||||||
mapping_version = 39
|
use_coremod = false
|
||||||
use_dependency_at_files = true
|
use_assetmover = false
|
||||||
|
|
||||||
# Run Configurations
|
# Access Transformer files should be in the root of `resources` folder and with the filename formatted as: `{archives_base_name}_at.cfg`
|
||||||
# If multiple arguments/tweak classes are stated, use spaces as the delimiter
|
|
||||||
minecraft_username = Developer
|
|
||||||
extra_jvm_args =
|
|
||||||
extra_tweak_classes =
|
|
||||||
|
|
||||||
# Maven Publishing (Provide secret: MAVEN_USER, MAVEN_PASS)
|
|
||||||
publish_to_maven = false
|
|
||||||
# Good for debugging artifacts before uploading to remote maven
|
|
||||||
# GitHub actions won't run if this is true, test this by running the task `publishToMavenLocal`
|
|
||||||
publish_to_local_maven = false
|
|
||||||
maven_name = ${mod_name}
|
|
||||||
maven_url =
|
|
||||||
|
|
||||||
# Publishing
|
|
||||||
# release_type can only be: release, beta or alpha (applies to CurseForge / Modrinth)
|
|
||||||
release_type = release
|
|
||||||
publish_with_changelog = ${{ it.file('CHANGELOG.md').exists() }}
|
|
||||||
|
|
||||||
# Publishing to CurseForge (Provide secret: CURSEFORGE_TOKEN)
|
|
||||||
# To configure dependencies, head to publishing.gradle's curseforge block
|
|
||||||
publish_to_curseforge = false
|
|
||||||
# CurseForge project ID must be the numerical ID and not the slug
|
|
||||||
curseforge_project_id =
|
|
||||||
curseforge_debug = false
|
|
||||||
|
|
||||||
# Publishing to Modrinth (Provide secret: MODRINTH_TOKEN), the token must have the `CREATE_VERSION` and `PROJECT_WRITE` permissions
|
|
||||||
# To configure dependencies, head to publishing.gradle's modrinth block
|
|
||||||
publish_to_modrinth = false
|
|
||||||
modrinth_project_id =
|
|
||||||
# Allows gradle to publish updated READMEs to the project body (via the modrinthSyncBody task)
|
|
||||||
modrinth_sync_readme = false
|
|
||||||
modrinth_debug = false
|
|
||||||
|
|
||||||
# If any properties changes below this line, refresh gradle again to ensure everything is working correctly.
|
|
||||||
|
|
||||||
# Modify Minecraft Sources
|
|
||||||
# RetroFuturaGradle allows Minecraft sources to be edited, and have the changes reflected upon running it
|
|
||||||
# Good for previews when coremodding, or generally seeing how behaviours can change with certain code applied/unapplied
|
|
||||||
# Turning this on allows Minecraft sources to persist and not regenerate
|
|
||||||
change_minecraft_sources = false
|
|
||||||
|
|
||||||
# Tags
|
|
||||||
# A RetroFuturaGradle concept akin to Ant ReplaceTokens
|
|
||||||
# A class is generated at build-time for compilation, to describe properties that have values that could change at build time such as versioning
|
|
||||||
# Class name is configurable with the `tag_class_name` property
|
|
||||||
# Tag properties can be stated in the `tags.properties` file, references are allowed
|
|
||||||
use_tags = true
|
|
||||||
tag_class_name = ${root_package}.${mod_id}.Tags
|
|
||||||
|
|
||||||
# Access Transformers
|
|
||||||
# A way to change visibility of Minecraft's classes, methods and fields
|
|
||||||
# An example access transformer file is given in the path: `src/main/resources/example_at.cfg`
|
|
||||||
# AT files should be in the root of src/main/resources with the filename formatted as: `mod_id_at.cfg`
|
|
||||||
# Use the property `access_transformer_locations` to state custom AT files if you aren't using the default `mod_id_at.cfg` location
|
|
||||||
# If multiple locations are stated, use spaces as the delimiter
|
|
||||||
use_access_transformer = false
|
use_access_transformer = false
|
||||||
access_transformer_locations = ${mod_id}_at.cfg
|
|
||||||
|
|
||||||
# Mixins
|
# Coremod Arguments
|
||||||
# Powerful tool to do runtime description changes of classes
|
include_mod = true
|
||||||
# Wiki: https://github.com/SpongePowered/Mixin/wiki + https://github.com/CleanroomMC/MixinBooter/ + https://cleanroommc.com/wiki/forge-mod-development/mixin/preface
|
coremod_plugin_class_name =
|
||||||
# Only use mixins once you understand the underlying structure
|
|
||||||
use_mixins = true
|
|
||||||
mixin_booter_version = 9.1
|
|
||||||
# A configuration defines a mixin set, and you may have as many mixin sets as you require for your application.
|
|
||||||
# Each config can only have one and only one package root.
|
|
||||||
# Generate missing configs, obtain from mixin_configs and generate file base on name convention: "mixins.config_name.json"
|
|
||||||
# You should change package root once they are generated
|
|
||||||
generate_mixins_json = true
|
|
||||||
# Delimit configs with spaces. Should only put configs name instead of full file name
|
|
||||||
mixin_configs = ${mod_id}
|
|
||||||
# A refmap is a json that denotes mapping conversions, this json is generated automatically, with the name `mixins.mod_id.refmap.json`
|
|
||||||
# Use the property `mixin_refmap` if you want it to use a different name, only one name is accepted
|
|
||||||
mixin_refmap = mixins.${mod_id}.refmap.json
|
|
||||||
|
|
||||||
# Coremods
|
|
||||||
# The most powerful way to change java classes at runtime, it is however very primitive with little documentation.
|
|
||||||
# Only make a coremod if you are absolutely sure of what you are doing
|
|
||||||
# Change the property `coremod_includes_mod` to false if your coremod doesn't have a @Mod annotation
|
|
||||||
# You MUST state a class name for `coremod_plugin_class_name` if you are making a coremod, the class should implement `IFMLLoadingPlugin`
|
|
||||||
is_coremod = true
|
|
||||||
coremod_includes_mod = true
|
|
||||||
coremod_plugin_class_name = ru.octol1ttle.knockdowns.common.KnockdownsFMLLoadingPlugin
|
|
||||||
|
|
||||||
# AssetMover
|
|
||||||
# Convenient way to allow downloading of assets from official vanilla Minecraft servers, CurseForge, or any direct links
|
|
||||||
# Documentation: https://github.com/CleanroomMC/AssetMover
|
|
||||||
use_asset_mover = false
|
|
||||||
asset_mover_version = 2.5
|
|
|
@ -1,62 +0,0 @@
|
||||||
apply from: 'gradle/scripts/helpers.gradle'
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
// Other repositories described by default:
|
|
||||||
// CleanroomMC: https://maven.cleanroommc.com
|
|
||||||
exclusiveContent {
|
|
||||||
forRepository {
|
|
||||||
maven {
|
|
||||||
name 'CurseMaven'
|
|
||||||
url 'https://cursemaven.com'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filter {
|
|
||||||
includeGroup 'curse.maven'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exclusiveContent {
|
|
||||||
forRepository {
|
|
||||||
maven {
|
|
||||||
name 'Modrinth'
|
|
||||||
url 'https://api.modrinth.com/maven'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filter {
|
|
||||||
includeGroup 'maven.modrinth'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mavenLocal() // Must be last for caching to work
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// Example - Dependency descriptor:
|
|
||||||
// 'com.google.code.gson:gson:2.8.6' << group: com.google.code.gson, name:gson, version:2.8.6
|
|
||||||
// 'group:name:version:classifier' where classifier is optional
|
|
||||||
|
|
||||||
// Example - Deobfuscating dependencies:
|
|
||||||
// rfg.deobf('curse.maven:had-enough-items-557549:4543375')
|
|
||||||
// By wrapping a dependency descriptor in rfg.deobf() method call, the dependency is queued for deobfuscation
|
|
||||||
// When deobfuscating, RFG respects the mapping_channel + mapping_version stated in gradle.properties
|
|
||||||
|
|
||||||
// Example - CurseMaven dependencies:
|
|
||||||
// 'curse.maven:had-enough-items-557549:4543375' << had-enough-items = project slug, 557549 = project id, 4543375 = file id
|
|
||||||
// Full documentation: https://cursemaven.com/
|
|
||||||
|
|
||||||
// Example - Modrinth dependencies:
|
|
||||||
// 'maven.modrinth:jei:4.16.1.1000' << jei = project name, 4.16.1.1000 = file version
|
|
||||||
// Full documentation: https://docs.modrinth.com/docs/tutorials/maven/
|
|
||||||
|
|
||||||
// Common dependency types (configuration):
|
|
||||||
// implementation = dependency available at both compile time and runtime
|
|
||||||
// runtimeOnly = runtime dependency
|
|
||||||
// compileOnly = compile time dependency
|
|
||||||
// annotationProcessor = annotation processing dependencies
|
|
||||||
|
|
||||||
// Transitive dependencies:
|
|
||||||
// (Dependencies that your dependency depends on)
|
|
||||||
// If you wish to exclude transitive dependencies in the described dependencies
|
|
||||||
// Use a closure as such:
|
|
||||||
// implementation ('com.google.code.gson:gson:2.8.6') {
|
|
||||||
// transitive = false
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
// You may write any gradle buildscript component in this file
|
|
||||||
// This file is automatically applied after build.gradle + dependencies.gradle is ran
|
|
||||||
|
|
||||||
// If you wish to use the default helper methods, uncomment the line below
|
|
||||||
// apply from: 'gradle/scripts/helpers.gradle'
|
|
|
@ -1,96 +0,0 @@
|
||||||
import groovy.text.SimpleTemplateEngine
|
|
||||||
import org.codehaus.groovy.runtime.MethodClosure
|
|
||||||
|
|
||||||
ext.propertyString = this.&propertyString as MethodClosure
|
|
||||||
ext.propertyBool = this.&propertyBool as MethodClosure
|
|
||||||
ext.propertyStringList = this.&propertyStringList as MethodClosure
|
|
||||||
ext.interpolate = this.&interpolate as MethodClosure
|
|
||||||
ext.assertProperty = this.&assertProperty as MethodClosure
|
|
||||||
ext.assertSubProperties = this.&assertSubProperties as MethodClosure
|
|
||||||
ext.setDefaultProperty = this.&setDefaultProperty as MethodClosure
|
|
||||||
ext.assertEnvironmentVariable = this.&assertEnvironmentVariable as MethodClosure
|
|
||||||
|
|
||||||
String propertyString(String key) {
|
|
||||||
return $property(key).toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean propertyBool(String key) {
|
|
||||||
return propertyString(key).toBoolean()
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<String> propertyStringList(String key) {
|
|
||||||
return propertyStringList(key, ' ')
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<String> propertyStringList(String key, String delimit) {
|
|
||||||
return propertyString(key).split(delimit).findAll { !it.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object $property(String key) {
|
|
||||||
def value = project.findProperty(key)
|
|
||||||
if (value instanceof String) {
|
|
||||||
return interpolate(value)
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
String interpolate(String value) {
|
|
||||||
if (value.startsWith('${{') && value.endsWith('}}')) {
|
|
||||||
value = value.substring(3, value.length() - 2)
|
|
||||||
Binding newBinding = new Binding(this.binding.getVariables())
|
|
||||||
newBinding.setProperty('it', this)
|
|
||||||
return new GroovyShell(this.getClass().getClassLoader(), newBinding).evaluate(value)
|
|
||||||
}
|
|
||||||
if (value.contains('${')) {
|
|
||||||
return new SimpleTemplateEngine().createTemplate(value).make(project.properties).toString()
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertProperty(String propertyName) {
|
|
||||||
def property = property(propertyName)
|
|
||||||
if (property == null) {
|
|
||||||
throw new GradleException("Property ${propertyName} is not defined!")
|
|
||||||
}
|
|
||||||
if (property.isEmpty()) {
|
|
||||||
throw new GradleException("Property ${propertyName} is empty!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertSubProperties(String propertyName, String... subPropertyNames) {
|
|
||||||
assertProperty(propertyName)
|
|
||||||
if (propertyBool(propertyName)) {
|
|
||||||
for (String subPropertyName : subPropertyNames) {
|
|
||||||
assertProperty(subPropertyName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDefaultProperty(String propertyName, boolean warn, defaultValue) {
|
|
||||||
def property = property(propertyName)
|
|
||||||
def exists = true
|
|
||||||
if (property == null) {
|
|
||||||
exists = false
|
|
||||||
if (warn) {
|
|
||||||
project.logger.log(LogLevel.WARN, "Property ${propertyName} is not defined!")
|
|
||||||
}
|
|
||||||
} else if (property.isEmpty()) {
|
|
||||||
exists = false
|
|
||||||
if (warn) {
|
|
||||||
project.logger.log(LogLevel.WARN, "Property ${propertyName} is empty!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!exists) {
|
|
||||||
project.setProperty(propertyName, defaultValue.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assertEnvironmentVariable(String propertyName) {
|
|
||||||
def property = System.getenv(propertyName)
|
|
||||||
if (property == null) {
|
|
||||||
throw new GradleException("System Environment Variable $propertyName is not defined!")
|
|
||||||
}
|
|
||||||
if (property.isEmpty()) {
|
|
||||||
throw new GradleException("Property $propertyName is empty!")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,107 +0,0 @@
|
||||||
apply from: 'gradle/scripts/helpers.gradle'
|
|
||||||
|
|
||||||
setDefaultProperty('publish_to_maven', true, false)
|
|
||||||
setDefaultProperty('publish_to_curseforge', true, false)
|
|
||||||
setDefaultProperty('publish_to_modrinth', true, false)
|
|
||||||
|
|
||||||
if (propertyBool('publish_to_maven')) {
|
|
||||||
assertProperty('maven_name')
|
|
||||||
assertProperty('maven_url')
|
|
||||||
publishing {
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name propertyString('maven_name').replaceAll("\\s", "")
|
|
||||||
url propertyString('maven_url')
|
|
||||||
credentials(PasswordCredentials)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
publications {
|
|
||||||
mavenJava(MavenPublication) {
|
|
||||||
from components.java // Publish with standard artifacts
|
|
||||||
setGroupId(propertyString('root_package'))// Publish with root package as maven group
|
|
||||||
setArtifactId(propertyString('mod_id')) // Publish artifacts with mod id as the artifact id
|
|
||||||
|
|
||||||
// Custom artifact:
|
|
||||||
// If you want to publish a different artifact to the one outputted when building normally
|
|
||||||
// Create a different gradle task (Jar task), in extra.gradle
|
|
||||||
// Remove the 'from components.java' line above
|
|
||||||
// Add this line (change the task name):
|
|
||||||
// artifacts task_name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Documentation here: https://github.com/matthewprenger/CurseGradle/wiki/
|
|
||||||
if (propertyBool('publish_to_curseforge')) {
|
|
||||||
apply plugin: 'com.matthewprenger.cursegradle'
|
|
||||||
assertProperty('curseforge_project_id')
|
|
||||||
assertProperty('release_type')
|
|
||||||
setDefaultProperty('curseforge_debug', false, false)
|
|
||||||
curseforge {
|
|
||||||
apiKey = System.getenv('CURSEFORGE_TOKEN') == null ? "" : System.getenv('CURSEFORGE_TOKEN')
|
|
||||||
// noinspection GroovyAssignabilityCheck
|
|
||||||
project {
|
|
||||||
id = propertyString('curseforge_project_id')
|
|
||||||
addGameVersion 'Java 8'
|
|
||||||
addGameVersion 'Forge'
|
|
||||||
addGameVersion '1.12.2'
|
|
||||||
releaseType = propertyString('release_type')
|
|
||||||
if (!propertyBool('publish_with_changelog')) {
|
|
||||||
changelog = parserChangelog()
|
|
||||||
changelogType = 'markdown'
|
|
||||||
}
|
|
||||||
mainArtifact tasks.reobfJar, {
|
|
||||||
displayName = "${propertyString('mod_name')} ${propertyString('mod_version')}"
|
|
||||||
if (propertyBool('use_mixins')) {
|
|
||||||
relations {
|
|
||||||
requiredDependency 'mixin-booter'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (propertyBool('use_asset_mover')) {
|
|
||||||
relations {
|
|
||||||
requiredDependency 'assetmover'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
options {
|
|
||||||
debug = propertyBool('curseforge_debug')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Documentation here: https://github.com/modrinth/minotaur
|
|
||||||
if (propertyBool('publish_to_modrinth')) {
|
|
||||||
apply plugin: 'com.modrinth.minotaur'
|
|
||||||
assertProperty('modrinth_project_id')
|
|
||||||
assertProperty('release_type')
|
|
||||||
setDefaultProperty('modrinth_debug', false, false)
|
|
||||||
modrinth {
|
|
||||||
token = System.getenv('MODRINTH_TOKEN') ? "" : System.getenv('MODRINTH_TOKEN')
|
|
||||||
projectId = propertyString('modrinth_project_id')
|
|
||||||
versionNumber = propertyString('mod_version')
|
|
||||||
versionType = propertyString('release_type')
|
|
||||||
uploadFile = tasks.reobfJar
|
|
||||||
gameVersions = ['1.12.2']
|
|
||||||
loaders = ['forge']
|
|
||||||
debugMode = propertyBool('modrinth_debug')
|
|
||||||
if (propertyBool('use_mixins') || propertyBool('use_asset_mover')) {
|
|
||||||
dependencies {
|
|
||||||
if (propertyBool('use_mixins')) {
|
|
||||||
required.project 'mixinbooter'
|
|
||||||
}
|
|
||||||
if (propertyBool('use_asset_mover')) {
|
|
||||||
required.project 'assetmover'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!propertyBool('publish_with_changelog')) {
|
|
||||||
changelog = parserChangelog()
|
|
||||||
}
|
|
||||||
if (propertyBool('modrinth_sync_readme')) {
|
|
||||||
syncBodyFrom = file('README.md').text
|
|
||||||
tasks.modrinth.dependsOn(tasks.modrinthSyncBody)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -2,11 +2,12 @@ pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
// RetroFuturaGradle
|
// RetroFuturaGradle
|
||||||
name 'GTNH Maven'
|
name = "GTNH Maven"
|
||||||
url 'https://nexus.gtnewhorizons.com/repository/public/'
|
url = uri("http://jenkins.usrv.eu:8081/nexus/content/groups/public/")
|
||||||
|
allowInsecureProtocol = true
|
||||||
mavenContent {
|
mavenContent {
|
||||||
includeGroup 'com.gtnewhorizons'
|
includeGroup("com.gtnewhorizons")
|
||||||
includeGroup 'com.gtnewhorizons.retrofuturagradle'
|
includeGroup("com.gtnewhorizons.retrofuturagradle")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
|
@ -17,9 +18,7 @@ pluginManagement {
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
// Automatic toolchain provisioning
|
// Automatic toolchain provisioning
|
||||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0'
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.4.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to an IntelliJ bug, this has to be done
|
rootProject.name = archives_base_name
|
||||||
// rootProject.name = archives_base_name
|
|
||||||
rootProject.name = rootProject.projectDir.getName()
|
|
||||||
|
|
2
src/main/java/com/cleanroommc/README.md
Normal file
2
src/main/java/com/cleanroommc/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
- Here lies the root of the `io.github.cleanroommc` package, add another level with your mod id and use that as the root for your mod classes.
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import ru.octol1ttle.knockdowns.client.communication.CalloutManager;
|
|
||||||
import ru.octol1ttle.knockdowns.client.communication.KnockedNotificationManager;
|
|
||||||
import ru.octol1ttle.knockdowns.client.event.KnockdownsKeyListener;
|
|
||||||
import ru.octol1ttle.knockdowns.client.util.DirectionalCallSound;
|
|
||||||
import ru.octol1ttle.knockdowns.common.IClientProxy;
|
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsMod;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerKnockedDownS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizePlayerDataS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizeReviversS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.registry.KnockdownsSoundEvents;
|
|
||||||
|
|
||||||
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class ClientProxy implements IClientProxy {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFMLInit(FMLInitializationEvent event) {
|
|
||||||
KnockdownsMod.LOGGER.info("Registering key bindings");
|
|
||||||
KnockdownsKeyListener.registerKeyBindings();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T handleMessage(IMessage message) {
|
|
||||||
if (message instanceof PlayerCalloutS2CPacket) {
|
|
||||||
PlayerCalloutS2CPacket packet = (PlayerCalloutS2CPacket) message;
|
|
||||||
client.addScheduledTask(() -> {
|
|
||||||
if (CalloutManager.addOrUpdateCallout(packet)) {
|
|
||||||
CalloutManager.playCalloutSound(packet);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (message instanceof PlayerKnockedDownS2CPacket) {
|
|
||||||
PlayerKnockedDownS2CPacket packet = (PlayerKnockedDownS2CPacket) message;
|
|
||||||
client.addScheduledTask(() -> {
|
|
||||||
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
|
|
||||||
if (entity != null) {
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
|
|
||||||
data.setKnockedDown(true);
|
|
||||||
data.setReviveTimeLeft(INITIAL_REVIVE_TIME_LEFT);
|
|
||||||
data.getRevivers().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client.player.dimension == packet.dimensionId) {
|
|
||||||
client.getSoundHandler().playSound(new DirectionalCallSound(KnockdownsSoundEvents.KNOCKED_DOWN, entity, packet.position));
|
|
||||||
KnockedNotificationManager.addKnockedNotification(packet.playerId, packet.position);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (message instanceof SynchronizePlayerDataS2CPacket.KnockedDown) {
|
|
||||||
SynchronizePlayerDataS2CPacket.KnockedDown packet = (SynchronizePlayerDataS2CPacket.KnockedDown) message;
|
|
||||||
client.addScheduledTask(() -> {
|
|
||||||
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
|
|
||||||
if (entity != null) {
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
|
|
||||||
data.setKnockedDown(packet.knockedDown);
|
|
||||||
data.setReviveTimeLeft(INITIAL_REVIVE_TIME_LEFT);
|
|
||||||
data.getRevivers().clear();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (message instanceof SynchronizePlayerDataS2CPacket.ReviveTimeLeft) {
|
|
||||||
SynchronizePlayerDataS2CPacket.ReviveTimeLeft packet = (SynchronizePlayerDataS2CPacket.ReviveTimeLeft) message;
|
|
||||||
client.addScheduledTask(() -> {
|
|
||||||
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
|
|
||||||
if (entity != null) {
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
|
|
||||||
data.setReviveTimeLeft(packet.reviveTimeLeft);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (message instanceof SynchronizePlayerDataS2CPacket.Full) {
|
|
||||||
SynchronizePlayerDataS2CPacket.Full packet = (SynchronizePlayerDataS2CPacket.Full) message;
|
|
||||||
client.addScheduledTask(() -> {
|
|
||||||
EntityPlayer entity = (EntityPlayer) client.world.getEntityByID(packet.playerId);
|
|
||||||
if (entity != null) {
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(entity);
|
|
||||||
data.setKnockedDown(packet.knockedDown);
|
|
||||||
data.setReviveTimeLeft(packet.reviveTimeLeft);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (message instanceof SynchronizeReviversS2CPacket.Add) {
|
|
||||||
SynchronizeReviversS2CPacket.Add packet = (SynchronizeReviversS2CPacket.Add) message;
|
|
||||||
client.addScheduledTask(() -> {
|
|
||||||
EntityPlayer knocked = (EntityPlayer) client.world.getEntityByID(packet.knockedId);
|
|
||||||
EntityPlayer reviver = (EntityPlayer) client.world.getEntityByID(packet.reviverId);
|
|
||||||
if (knocked != null && reviver != null) {
|
|
||||||
IKnockdownsPlayerData.get(knocked).getRevivers().add(reviver);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (message instanceof SynchronizeReviversS2CPacket.Remove) {
|
|
||||||
SynchronizeReviversS2CPacket.Remove packet = (SynchronizeReviversS2CPacket.Remove) message;
|
|
||||||
client.addScheduledTask(() -> {
|
|
||||||
EntityPlayer knocked = (EntityPlayer) client.world.getEntityByID(packet.knockedId);
|
|
||||||
EntityPlayer reviver = (EntityPlayer) client.world.getEntityByID(packet.reviverId);
|
|
||||||
if (knocked != null && reviver != null) {
|
|
||||||
IKnockdownsPlayerData.get(knocked).getRevivers().remove(reviver);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("Unknown packet received on the client: " + message.getClass().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.communication;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import ru.octol1ttle.knockdowns.client.util.Callout;
|
|
||||||
import ru.octol1ttle.knockdowns.client.util.DirectionalCallSound;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.registry.KnockdownsSoundEvents;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class CalloutManager {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
private static final Map<Integer, Callout> callouts = new HashMap<>();
|
|
||||||
|
|
||||||
public static Set<Map.Entry<Integer, Callout>> getCallouts() {
|
|
||||||
return callouts.entrySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean addOrUpdateCallout(PlayerCalloutS2CPacket message) {
|
|
||||||
return callouts.put(message.playerId, new Callout(message.position, message.type, client.world.getTotalWorldTime())) == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void playCalloutSound(PlayerCalloutS2CPacket message) {
|
|
||||||
client.getSoundHandler().playSound(new DirectionalCallSound(KnockdownsSoundEvents.CALLOUT, client.world.getEntityByID(message.playerId), message.position));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clearCallouts() {
|
|
||||||
callouts.clear();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.communication;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import ru.octol1ttle.knockdowns.client.util.KnockedPlayerData;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class KnockedNotificationManager {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
private static final List<KnockedPlayerData> knockedDatas = new ArrayList<>();
|
|
||||||
|
|
||||||
public static void addKnockedNotification(int playerId, Vec3d position) {
|
|
||||||
knockedDatas.add(new KnockedPlayerData(playerId, position, client.world.getTotalWorldTime()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Collection<KnockedPlayerData> getKnockedPlayerDatas() {
|
|
||||||
return knockedDatas;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clearDatas() {
|
|
||||||
knockedDatas.clear();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.event;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
|
||||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.gameevent.InputEvent;
|
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
import ru.octol1ttle.knockdowns.client.communication.CalloutManager;
|
|
||||||
import ru.octol1ttle.knockdowns.client.communication.KnockedNotificationManager;
|
|
||||||
import ru.octol1ttle.knockdowns.client.gui.CommunicationGui;
|
|
||||||
import ru.octol1ttle.knockdowns.client.gui.KnockedNotificationGui;
|
|
||||||
import ru.octol1ttle.knockdowns.client.gui.ReviveGui;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.c2s.CancelReviveC2SPacket;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
@Mod.EventBusSubscriber(value = Side.CLIENT, modid = Tags.MOD_ID)
|
|
||||||
public class KnockdownsClientEventListener {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
private static final CommunicationGui communicationGui = new CommunicationGui();
|
|
||||||
private static final KnockedNotificationGui notificationGui = new KnockedNotificationGui();
|
|
||||||
private static final ReviveGui reviveGui = new ReviveGui();
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onTick(TickEvent.ClientTickEvent event) {
|
|
||||||
if (event.phase == TickEvent.Phase.START) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (client.world == null) {
|
|
||||||
CalloutManager.clearCallouts();
|
|
||||||
KnockedNotificationManager.clearDatas();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CalloutManager.getCallouts().removeIf(callout -> client.world.getTotalWorldTime() - callout.getValue().getReceiveTime() > 60);
|
|
||||||
KnockedNotificationManager.getKnockedPlayerDatas().removeIf(notification -> client.world.getTotalWorldTime() - notification.getReceiveTime() > 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
|
|
||||||
List<EntityPlayer> revivers = IKnockdownsPlayerData.get(event.player).getRevivers();
|
|
||||||
if (revivers.contains(client.player) && !event.player.equals(client.pointedEntity)) {
|
|
||||||
KnockdownsNetwork.sendToServer(new CancelReviveC2SPacket());
|
|
||||||
revivers.remove(client.player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onRenderWorldLast(RenderWorldLastEvent event) {
|
|
||||||
notificationGui.renderNotifications(event.getPartialTicks());
|
|
||||||
communicationGui.renderCallouts(event.getPartialTicks());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onRenderGameOverlay(RenderGameOverlayEvent.Chat event) {
|
|
||||||
communicationGui.render(event.getPartialTicks(), event.getResolution());
|
|
||||||
reviveGui.render(event.getPartialTicks(), event.getResolution());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onKeyInput(InputEvent.KeyInputEvent event) {
|
|
||||||
KnockdownsKeyListener.tickKeys();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.event;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import org.lwjgl.input.Keyboard;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
import ru.octol1ttle.knockdowns.common.communication.CalloutType;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.c2s.PlayerCalloutC2SPacket;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
@Mod.EventBusSubscriber(value = Side.CLIENT, modid = Tags.MOD_ID)
|
|
||||||
public class KnockdownsKeyListener {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
public static final Map<KeyBinding, Supplier<CalloutType>> calloutBindings = new HashMap<>();
|
|
||||||
|
|
||||||
public static void registerKeyBindings() {
|
|
||||||
calloutBindings.put(
|
|
||||||
new KeyBinding("knockdowns.key.callout.danger", Keyboard.KEY_LEFT, "knockdowns.key.category"),
|
|
||||||
() -> CalloutType.DANGER
|
|
||||||
);
|
|
||||||
calloutBindings.put(
|
|
||||||
new KeyBinding("knockdowns.key.callout.booyah", Keyboard.KEY_DOWN, "knockdowns.key.category"),
|
|
||||||
() -> CalloutType.BOOYAH
|
|
||||||
);
|
|
||||||
calloutBindings.put(
|
|
||||||
new KeyBinding("knockdowns.key.callout.this_way_help", Keyboard.KEY_UP, "knockdowns.key.category"),
|
|
||||||
() -> IKnockdownsPlayerData.get(client.player).isKnockedDown() ? CalloutType.HELP : CalloutType.THIS_WAY
|
|
||||||
);
|
|
||||||
calloutBindings.put(
|
|
||||||
new KeyBinding("knockdowns.key.callout.ouch", Keyboard.KEY_RIGHT, "knockdowns.key.category"),
|
|
||||||
() -> CalloutType.OUCH
|
|
||||||
);
|
|
||||||
|
|
||||||
for (KeyBinding binding : calloutBindings.keySet()) {
|
|
||||||
ClientRegistry.registerKeyBinding(binding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void tickKeys() {
|
|
||||||
for (KeyBinding binding : calloutBindings.keySet()) {
|
|
||||||
if (binding.isPressed()) {
|
|
||||||
KnockdownsNetwork.sendToServer(new PlayerCalloutC2SPacket(calloutBindings.get(binding).get()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,175 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.gui;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
|
||||||
import net.minecraft.client.gui.ScaledResolution;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.client.resources.I18n;
|
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import org.lwjgl.input.Keyboard;
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
import ru.octol1ttle.knockdowns.client.communication.CalloutManager;
|
|
||||||
import ru.octol1ttle.knockdowns.client.event.KnockdownsKeyListener;
|
|
||||||
import ru.octol1ttle.knockdowns.client.util.Callout;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class CommunicationGui extends KnockdownsBaseGui {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
private static final ResourceLocation LEFT_ARROW = new ResourceLocation(Tags.MOD_ID, "textures/gui/left_arrow.png");
|
|
||||||
private static final ResourceLocation DOWN_ARROW = new ResourceLocation(Tags.MOD_ID, "textures/gui/down_arrow.png");
|
|
||||||
private static final ResourceLocation UP_ARROW = new ResourceLocation(Tags.MOD_ID, "textures/gui/up_arrow.png");
|
|
||||||
private static final ResourceLocation RIGHT_ARROW = new ResourceLocation(Tags.MOD_ID, "textures/gui/right_arrow.png");
|
|
||||||
private static final int SCREEN_EDGE_MARGIN = 5;
|
|
||||||
private static final int SEPARATOR_MARGIN = 2;
|
|
||||||
private static final int KEY_SIZE = 17;
|
|
||||||
private float totalPartialTicks;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(float partialTicks, ScaledResolution resolution) {
|
|
||||||
FontRenderer font = client.fontRenderer;
|
|
||||||
|
|
||||||
int x = SCREEN_EDGE_MARGIN;
|
|
||||||
int y = resolution.getScaledHeight() - SCREEN_EDGE_MARGIN - font.FONT_HEIGHT;
|
|
||||||
|
|
||||||
KeyBinding[] sortedBindings = new KeyBinding[4];
|
|
||||||
for (KeyBinding binding : KnockdownsKeyListener.calloutBindings.keySet())
|
|
||||||
{
|
|
||||||
switch (binding.getKeyCode()) {
|
|
||||||
case Keyboard.KEY_LEFT:
|
|
||||||
sortedBindings[0] = binding;
|
|
||||||
break;
|
|
||||||
case Keyboard.KEY_DOWN:
|
|
||||||
sortedBindings[1] = binding;
|
|
||||||
break;
|
|
||||||
case Keyboard.KEY_UP:
|
|
||||||
sortedBindings[2] = binding;
|
|
||||||
break;
|
|
||||||
case Keyboard.KEY_RIGHT:
|
|
||||||
sortedBindings[3] = binding;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyBinding leftCallout = sortedBindings[0];
|
|
||||||
if (leftCallout != null) {
|
|
||||||
String text = I18n.format(KnockdownsKeyListener.calloutBindings.get(leftCallout).get().getTextKey());
|
|
||||||
font.drawStringWithShadow(
|
|
||||||
text,
|
|
||||||
x,
|
|
||||||
y - 12,
|
|
||||||
0xFFFFFF
|
|
||||||
);
|
|
||||||
|
|
||||||
x += font.getStringWidth(text) + SEPARATOR_MARGIN;
|
|
||||||
client.getTextureManager().bindTexture(LEFT_ARROW);
|
|
||||||
this.drawTexture(
|
|
||||||
x,
|
|
||||||
y - KEY_SIZE,
|
|
||||||
KEY_SIZE,
|
|
||||||
KEY_SIZE
|
|
||||||
);
|
|
||||||
x += KEY_SIZE + SEPARATOR_MARGIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyBinding downCallout = sortedBindings[1];
|
|
||||||
if (downCallout != null) {
|
|
||||||
String text = I18n.format(KnockdownsKeyListener.calloutBindings.get(downCallout).get().getTextKey());
|
|
||||||
font.drawStringWithShadow(
|
|
||||||
text,
|
|
||||||
x + KEY_SIZE * 0.5f - font.getStringWidth(text) * 0.5f,
|
|
||||||
y + SEPARATOR_MARGIN,
|
|
||||||
0xFFFFFF
|
|
||||||
);
|
|
||||||
client.getTextureManager().bindTexture(DOWN_ARROW);
|
|
||||||
this.drawTexture(
|
|
||||||
x,
|
|
||||||
y - KEY_SIZE,
|
|
||||||
KEY_SIZE,
|
|
||||||
KEY_SIZE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyBinding upCallout = sortedBindings[2];
|
|
||||||
if (upCallout != null) {
|
|
||||||
String text = I18n.format(KnockdownsKeyListener.calloutBindings.get(upCallout).get().getTextKey());
|
|
||||||
font.drawStringWithShadow(
|
|
||||||
text,
|
|
||||||
x + KEY_SIZE * 0.5f - font.getStringWidth(text) * 0.5f,
|
|
||||||
y - KEY_SIZE * 2 - 12,
|
|
||||||
0xFFFFFF
|
|
||||||
);
|
|
||||||
|
|
||||||
client.getTextureManager().bindTexture(UP_ARROW);
|
|
||||||
this.drawTexture(
|
|
||||||
x,
|
|
||||||
y - KEY_SIZE * 2 - 2,
|
|
||||||
KEY_SIZE,
|
|
||||||
KEY_SIZE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyBinding rightCallout = sortedBindings[3];
|
|
||||||
if (rightCallout != null) {
|
|
||||||
x += KEY_SIZE + SEPARATOR_MARGIN;
|
|
||||||
String text = I18n.format(KnockdownsKeyListener.calloutBindings.get(rightCallout).get().getTextKey());
|
|
||||||
font.drawStringWithShadow(
|
|
||||||
text,
|
|
||||||
x + KEY_SIZE + SEPARATOR_MARGIN,
|
|
||||||
y - 12,
|
|
||||||
0xFFFFFF
|
|
||||||
);
|
|
||||||
|
|
||||||
client.getTextureManager().bindTexture(RIGHT_ARROW);
|
|
||||||
this.drawTexture(
|
|
||||||
x,
|
|
||||||
y - KEY_SIZE,
|
|
||||||
KEY_SIZE,
|
|
||||||
KEY_SIZE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderCallouts(float partialTicks) {
|
|
||||||
totalPartialTicks += partialTicks;
|
|
||||||
for (Map.Entry<Integer, Callout> calloutEntry : CalloutManager.getCallouts()) {
|
|
||||||
Entity entity = client.world.getEntityByID(calloutEntry.getKey());
|
|
||||||
renderCallout(
|
|
||||||
I18n.format(calloutEntry.getValue().getType().getTextKey()),
|
|
||||||
entity != null ? entity.getPositionEyes(partialTicks).add(0, 1, 0) : calloutEntry.getValue().getPosition(),
|
|
||||||
client.getRenderManager().playerViewX,
|
|
||||||
client.getRenderManager().playerViewY,
|
|
||||||
client.getRenderManager().options.thirdPersonView == 2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderCallout(String text, Vec3d position, float pitch, float yaw, boolean isThirdPersonFrontal) {
|
|
||||||
FontRenderer font = client.fontRenderer;
|
|
||||||
|
|
||||||
Vec3d deltaPos = position.subtract(client.getRenderManager().viewerPosX, client.getRenderManager().viewerPosY, client.getRenderManager().viewerPosZ);
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
|
||||||
GlStateManager.translate(deltaPos.x, deltaPos.y, deltaPos.z);
|
|
||||||
GlStateManager.rotate(-yaw, 0.0F, 1.0F, 0.0F);
|
|
||||||
GlStateManager.rotate((float)(isThirdPersonFrontal ? -1 : 1) * pitch, 1.0F, 0.0F, 0.0F);
|
|
||||||
float scale = (float) Math.max(deltaPos.length() / 8.0f, 1.0f) * (0.75f + MathHelper.abs((float) (MathHelper.sin(totalPartialTicks / 10F) / Math.PI)));
|
|
||||||
GlStateManager.scale(-0.025F * scale, -0.025F * scale, 0.025F * scale);
|
|
||||||
GlStateManager.color(1f, 1f, 1f, 1f);
|
|
||||||
GlStateManager.disableCull();
|
|
||||||
GlStateManager.depthFunc(GL11.GL_ALWAYS);
|
|
||||||
|
|
||||||
font.drawStringWithShadow(text, -font.getStringWidth(text) * 0.5f, -font.FONT_HEIGHT * 0.5f, 0xFFFFFF);
|
|
||||||
|
|
||||||
GlStateManager.depthFunc(GL11.GL_LEQUAL);
|
|
||||||
GlStateManager.enableCull();
|
|
||||||
GlStateManager.popMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.gui;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.Gui;
|
|
||||||
import net.minecraft.client.gui.ScaledResolution;
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public abstract class KnockdownsBaseGui extends Gui {
|
|
||||||
public abstract void render(float partialTicks, ScaledResolution resolution);
|
|
||||||
|
|
||||||
protected void drawTexture(int x, int y, int width, int height) {
|
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
|
||||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
|
||||||
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX);
|
|
||||||
bufferbuilder.pos(x, y, this.zLevel).tex(0, 0).endVertex();
|
|
||||||
bufferbuilder.pos(x, y + height, this.zLevel).tex(0, 1).endVertex();
|
|
||||||
bufferbuilder.pos(x + width, y + height, this.zLevel).tex(1, 1).endVertex();
|
|
||||||
bufferbuilder.pos(x + width, y, this.zLevel).tex(1, 0).endVertex();
|
|
||||||
tessellator.draw();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.gui;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.ScaledResolution;
|
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
import ru.octol1ttle.knockdowns.client.communication.KnockedNotificationManager;
|
|
||||||
import ru.octol1ttle.knockdowns.client.util.KnockedPlayerData;
|
|
||||||
|
|
||||||
public class KnockedNotificationGui extends KnockdownsBaseGui {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
private static final int KNOCKED_ICON_SIZE = 18;
|
|
||||||
private static final ResourceLocation KNOCKED_ICON = new ResourceLocation(Tags.MOD_ID, "textures/gui/knocked_icon.png");
|
|
||||||
private float totalPartialTicks;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public void render(float partialTicks, ScaledResolution resolution) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void renderNotifications(float partialTicks) {
|
|
||||||
totalPartialTicks += partialTicks;
|
|
||||||
for (KnockedPlayerData data : KnockedNotificationManager.getKnockedPlayerDatas()) {
|
|
||||||
Entity entity = client.world.getEntityByID(data.getPlayerId());
|
|
||||||
renderKnockedNotification(
|
|
||||||
entity != null ? entity.getPositionEyes(partialTicks).add(0, 1, 0) : data.getPosition(),
|
|
||||||
client.getRenderManager().playerViewX,
|
|
||||||
client.getRenderManager().playerViewY,
|
|
||||||
client.getRenderManager().options.thirdPersonView == 2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderKnockedNotification(Vec3d position, float pitch, float yaw, boolean isThirdPersonFrontal) {
|
|
||||||
Vec3d deltaPos = position.subtract(client.getRenderManager().viewerPosX, client.getRenderManager().viewerPosY, client.getRenderManager().viewerPosZ);
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
|
||||||
GlStateManager.translate(deltaPos.x, deltaPos.y, deltaPos.z);
|
|
||||||
GlStateManager.rotate(-yaw, 0.0F, 1.0F, 0.0F);
|
|
||||||
GlStateManager.rotate((float)(isThirdPersonFrontal ? -1 : 1) * pitch, 1.0F, 0.0F, 0.0F);
|
|
||||||
float scale = (float) Math.max(deltaPos.length() / 8.0f, 1.0f) * (0.75f + MathHelper.abs((float) (MathHelper.sin(totalPartialTicks / 10F) / Math.PI)));
|
|
||||||
GlStateManager.scale(0.05F * scale, 0.05F * scale, 0.05F * scale);
|
|
||||||
GlStateManager.color(1f, 1f, 1f, 1f);
|
|
||||||
GlStateManager.disableCull();
|
|
||||||
GlStateManager.depthFunc(GL11.GL_ALWAYS);
|
|
||||||
|
|
||||||
client.getTextureManager().bindTexture(KNOCKED_ICON);
|
|
||||||
this.drawTexture(
|
|
||||||
-KNOCKED_ICON_SIZE / 2,
|
|
||||||
-KNOCKED_ICON_SIZE / 2,
|
|
||||||
KNOCKED_ICON_SIZE,
|
|
||||||
KNOCKED_ICON_SIZE
|
|
||||||
);
|
|
||||||
|
|
||||||
GlStateManager.depthFunc(GL11.GL_LEQUAL);
|
|
||||||
GlStateManager.enableCull();
|
|
||||||
GlStateManager.popMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.gui;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
|
||||||
import net.minecraft.client.gui.ScaledResolution;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.util.text.TextFormatting;
|
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsUtils;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
|
|
||||||
public class ReviveGui extends KnockdownsBaseGui {
|
|
||||||
private static final Minecraft client = Minecraft.getMinecraft();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(float partialTicks, ScaledResolution resolution) {
|
|
||||||
EntityPlayer reviving =
|
|
||||||
client.pointedEntity instanceof EntityPlayer && IKnockdownsPlayerData.get((EntityPlayer) client.pointedEntity).getRevivers().contains(client.player)
|
|
||||||
? (EntityPlayer) client.pointedEntity
|
|
||||||
: client.player;
|
|
||||||
if (IKnockdownsPlayerData.get(reviving).getReviveTimeLeft() == KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(reviving);
|
|
||||||
|
|
||||||
FontRenderer font = client.fontRenderer;
|
|
||||||
|
|
||||||
String timerText = String.format("%.1f", data.getReviveTimeLeft() / 20.0f);
|
|
||||||
float timerX = (resolution.getScaledWidth() - font.getStringWidth(timerText)) * 0.5f;
|
|
||||||
|
|
||||||
data.getRevivers().removeIf(reviver -> reviver.isDead || !reviver.isEntityAlive() || IKnockdownsPlayerData.get(reviver).isKnockedDown());
|
|
||||||
int reviverCount = data.getRevivers().size();
|
|
||||||
TextFormatting color;
|
|
||||||
if (reviverCount == 0) {
|
|
||||||
color = TextFormatting.RED;
|
|
||||||
} else if (reviverCount == 1) {
|
|
||||||
color = TextFormatting.WHITE;
|
|
||||||
} else {
|
|
||||||
color = TextFormatting.GREEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
String reviverCountText = "x" + reviverCount;
|
|
||||||
float reviveCountX = (resolution.getScaledWidth() - font.getStringWidth(reviverCountText)) * 0.5f;
|
|
||||||
|
|
||||||
font.drawStringWithShadow(color + timerText, timerX, resolution.getScaledHeight() * 0.5f + 5, 0xFFFFFF);
|
|
||||||
font.drawStringWithShadow(color + reviverCountText, reviveCountX, resolution.getScaledHeight() * 0.5f + 14, 0xFFFFFF);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.util;
|
|
||||||
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import ru.octol1ttle.knockdowns.common.communication.CalloutType;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class Callout {
|
|
||||||
private final Vec3d position;
|
|
||||||
private final CalloutType type;
|
|
||||||
private final long receiveTime;
|
|
||||||
|
|
||||||
public Callout(Vec3d position, CalloutType type, long receiveTime) {
|
|
||||||
this.position = position;
|
|
||||||
this.type = type;
|
|
||||||
this.receiveTime = receiveTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3d getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CalloutType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getReceiveTime() {
|
|
||||||
return receiveTime;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.util;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.audio.MovingSound;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.util.SoundCategory;
|
|
||||||
import net.minecraft.util.SoundEvent;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public class DirectionalCallSound extends MovingSound {
|
|
||||||
private final @Nullable Entity entity;
|
|
||||||
private final Vec3d position;
|
|
||||||
private int time;
|
|
||||||
|
|
||||||
public DirectionalCallSound(SoundEvent event, @Nullable Entity entity, Vec3d position) {
|
|
||||||
super(event, SoundCategory.PLAYERS);
|
|
||||||
this.entity = entity;
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update() {
|
|
||||||
this.time++;
|
|
||||||
if (this.time > 40 || this.entity != null && this.entity.isDead) {
|
|
||||||
this.donePlaying = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Minecraft client = Minecraft.getMinecraft();
|
|
||||||
Vec3d calloutPos = this.entity != null ? this.entity.getPositionVector() : this.position;
|
|
||||||
Vec3d directionVec = calloutPos.subtract(client.player.getPositionVector()).normalize();
|
|
||||||
Vec3d finalPos = client.player.getPositionVector().add(directionVec);
|
|
||||||
|
|
||||||
this.xPosF = (float) finalPos.x;
|
|
||||||
this.yPosF = (float) finalPos.y;
|
|
||||||
this.zPosF = (float) finalPos.z;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.client.util;
|
|
||||||
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
|
|
||||||
public class KnockedPlayerData {
|
|
||||||
private final int playerId;
|
|
||||||
private final Vec3d position;
|
|
||||||
private final long receiveTime;
|
|
||||||
|
|
||||||
public KnockedPlayerData(int playerId, Vec3d position, long receiveTime) {
|
|
||||||
this.playerId = playerId;
|
|
||||||
this.position = position;
|
|
||||||
this.receiveTime = receiveTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPlayerId() {
|
|
||||||
return playerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vec3d getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getReceiveTime() {
|
|
||||||
return receiveTime;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common;
|
|
||||||
|
|
||||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
|
|
||||||
public interface IClientProxy {
|
|
||||||
void onFMLInit(FMLInitializationEvent event);
|
|
||||||
|
|
||||||
<T> T handleMessage(IMessage message);
|
|
||||||
|
|
||||||
class Dummy implements IClientProxy {
|
|
||||||
@Override
|
|
||||||
public void onFMLInit(FMLInitializationEvent event) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T handleMessage(IMessage message) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,259 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.EntityLiving;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import net.minecraft.init.MobEffects;
|
|
||||||
import net.minecraft.potion.PotionEffect;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.util.DamageSource;
|
|
||||||
import net.minecraft.util.EnumActionResult;
|
|
||||||
import net.minecraft.util.SoundEvent;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
|
||||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
|
||||||
import net.minecraftforge.event.RegistryEvent;
|
|
||||||
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
|
||||||
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
|
|
||||||
import net.minecraftforge.event.entity.player.AttackEntityEvent;
|
|
||||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
|
||||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
|
|
||||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent;
|
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.KnockdownsCapability;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerKnockedDownS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizePlayerDataS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizeReviversS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.registry.KnockdownsSoundEvents;
|
|
||||||
|
|
||||||
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT;
|
|
||||||
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.KNOCKED_HURT_PERIOD;
|
|
||||||
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.KNOCKED_INVULNERABILITY_TICKS;
|
|
||||||
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.KNOCKED_TENACITY;
|
|
||||||
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.allPlayersKnocked;
|
|
||||||
import static ru.octol1ttle.knockdowns.common.KnockdownsUtils.resetKnockedState;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber(modid = Tags.MOD_ID)
|
|
||||||
public class KnockdownsCommonEventListener {
|
|
||||||
public static void onFMLInit(FMLInitializationEvent event) {
|
|
||||||
KnockdownsMod.LOGGER.info("Registering network packets");
|
|
||||||
KnockdownsNetwork.registerPackets();
|
|
||||||
KnockdownsMod.LOGGER.info("Registering capability");
|
|
||||||
KnockdownsCapability.register();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onSoundsRegister(RegistryEvent.Register<SoundEvent> event) {
|
|
||||||
event.getRegistry().register(KnockdownsSoundEvents.CALLOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onCapabilitiesAttach(AttachCapabilitiesEvent<Entity> event) {
|
|
||||||
if (event.getObject() instanceof EntityPlayer) {
|
|
||||||
event.addCapability(KnockdownsCapability.ID, new KnockdownsCapability());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
|
|
||||||
MinecraftServer server = event.player.getServer();
|
|
||||||
if (event.phase == TickEvent.Phase.START || server == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
EntityPlayerMP knocked = (EntityPlayerMP) event.player;
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(knocked);
|
|
||||||
if (!data.isKnockedDown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allPlayersKnocked(server, knocked)) {
|
|
||||||
knocked.attackEntityFrom(DamageSource.GENERIC, knocked.getMaxHealth());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<EntityPlayer> revivers = data.getRevivers();
|
|
||||||
revivers.removeIf(reviver -> reviver.isDead || !reviver.isEntityAlive() || IKnockdownsPlayerData.get(reviver).isKnockedDown());
|
|
||||||
if (!revivers.isEmpty()) {
|
|
||||||
data.setReviveTimeLeft(data.getReviveTimeLeft() - revivers.size());
|
|
||||||
KnockdownsNetwork.sendToMultiple(
|
|
||||||
new SynchronizePlayerDataS2CPacket.ReviveTimeLeft(knocked.getEntityId(), data.getReviveTimeLeft()),
|
|
||||||
revivers,
|
|
||||||
knocked
|
|
||||||
);
|
|
||||||
|
|
||||||
if (data.getReviveTimeLeft() <= 0) {
|
|
||||||
resetKnockedState(knocked, data);
|
|
||||||
|
|
||||||
knocked.setEntityInvulnerable(false);
|
|
||||||
knocked.setHealth(knocked.getMaxHealth() * 0.3f);
|
|
||||||
knocked.setAbsorptionAmount(0.0f);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int oldReviveTimeLeft = data.getReviveTimeLeft();
|
|
||||||
data.setReviveTimeLeft(Math.min(INITIAL_REVIVE_TIME_LEFT, oldReviveTimeLeft + 1));
|
|
||||||
if (data.getReviveTimeLeft() != oldReviveTimeLeft) {
|
|
||||||
KnockdownsNetwork.sendToPlayer(
|
|
||||||
new SynchronizePlayerDataS2CPacket.ReviveTimeLeft(knocked.getEntityId(), data.getReviveTimeLeft()),
|
|
||||||
knocked
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setTicksKnocked(data.getTicksKnocked() + 1);
|
|
||||||
|
|
||||||
int period = MathHelper.floor(KNOCKED_HURT_PERIOD * 20);
|
|
||||||
if (data.getTicksKnocked() >= KNOCKED_INVULNERABILITY_TICKS && data.getTicksKnocked() % period == 0) {
|
|
||||||
knocked.setEntityInvulnerable(false);
|
|
||||||
knocked.attackEntityFrom(DamageSource.GENERIC, knocked.getMaxHealth() / (KNOCKED_TENACITY / KNOCKED_HURT_PERIOD));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onPlayerDeath(LivingDeathEvent event) {
|
|
||||||
if (!(event.getEntityLiving() instanceof EntityPlayerMP)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityPlayerMP player = (EntityPlayerMP) event.getEntityLiving();
|
|
||||||
IKnockdownsPlayerData data = player.getCapability(KnockdownsCapability.CAPABILITY, null);
|
|
||||||
if (data == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.isKnockedDown() || allPlayersKnocked(player.getServer(), player)) {
|
|
||||||
data.getRevivers().clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.clearActivePotions();
|
|
||||||
player.setEntityInvulnerable(true);
|
|
||||||
player.setHealth(1.0f);
|
|
||||||
player.setAbsorptionAmount(player.getMaxHealth() - 1.0f);
|
|
||||||
player.extinguish();
|
|
||||||
player.setAir(300);
|
|
||||||
player.clearElytraFlying();
|
|
||||||
|
|
||||||
player.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 6000, 3));
|
|
||||||
|
|
||||||
Entity trueSource = event.getSource().getTrueSource();
|
|
||||||
if (trueSource instanceof EntityLiving) {
|
|
||||||
((EntityLiving) trueSource).setAttackTarget(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setKnockedDown(true);
|
|
||||||
data.setReviveTimeLeft(INITIAL_REVIVE_TIME_LEFT);
|
|
||||||
data.setTicksKnocked(0);
|
|
||||||
|
|
||||||
KnockdownsNetwork.sendToAll(new PlayerKnockedDownS2CPacket(player.getEntityId(), player.dimension, player.getPositionEyes(1).add(0, 1, 0)));
|
|
||||||
|
|
||||||
TextComponentTranslation deathMessage = (TextComponentTranslation) player.getCombatTracker().getDeathMessage();
|
|
||||||
|
|
||||||
String knockdownKey = deathMessage.getKey().replace("death.", "knockdown.");
|
|
||||||
TextComponentTranslation knockdownTranslation = new TextComponentTranslation(knockdownKey, deathMessage.getFormatArgs());
|
|
||||||
player.getServer().getPlayerList().sendMessage(
|
|
||||||
!knockdownTranslation.getUnformattedComponentText().equals(knockdownKey) ? knockdownTranslation : deathMessage,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
event.setCanceled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onMobTarget(LivingSetAttackTargetEvent event) {
|
|
||||||
if (event.getTarget() instanceof EntityPlayer && IKnockdownsPlayerData.get((EntityPlayer) event.getTarget()).isKnockedDown()) {
|
|
||||||
((EntityLiving)event.getEntityLiving()).setAttackTarget(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onPlayerStartTracking(PlayerEvent.StartTracking event) {
|
|
||||||
if (event.getTarget() instanceof EntityPlayerMP) {
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get((EntityPlayer) event.getTarget());
|
|
||||||
if (data.isKnockedDown()) {
|
|
||||||
KnockdownsNetwork.sendToPlayer(
|
|
||||||
new SynchronizePlayerDataS2CPacket.KnockedDown(
|
|
||||||
event.getTarget().getEntityId(),
|
|
||||||
data.isKnockedDown()
|
|
||||||
),
|
|
||||||
(EntityPlayerMP) event.getEntityPlayer()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onKnockedAttack(AttackEntityEvent event) {
|
|
||||||
if (IKnockdownsPlayerData.get(event.getEntityPlayer()).isKnockedDown()) {
|
|
||||||
event.setCanceled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onKnockedInteraction(PlayerInteractEvent event) {
|
|
||||||
if (IKnockdownsPlayerData.get(event.getEntityPlayer()).isKnockedDown()) {
|
|
||||||
if (!(event instanceof PlayerInteractEvent.RightClickBlock) && event.isCancelable()) {
|
|
||||||
event.setCanceled(true);
|
|
||||||
event.setCancellationResult(EnumActionResult.FAIL);
|
|
||||||
}
|
|
||||||
} else if (event instanceof PlayerInteractEvent.EntityInteract) {
|
|
||||||
onPlayerInteraction((PlayerInteractEvent.EntityInteract) event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void onPlayerInteraction(PlayerInteractEvent.EntityInteract event) {
|
|
||||||
if (event.getTarget() instanceof EntityPlayerMP) {
|
|
||||||
EntityPlayerMP knocked = (EntityPlayerMP) event.getTarget();
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(knocked);
|
|
||||||
if (data.isKnockedDown() && !data.getRevivers().contains(event.getEntityPlayer())) {
|
|
||||||
for (EntityPlayer reviver : data.getRevivers()) {
|
|
||||||
KnockdownsNetwork.sendToPlayer(
|
|
||||||
new SynchronizeReviversS2CPacket.Add(event.getTarget().getEntityId(), reviver.getEntityId()),
|
|
||||||
(EntityPlayerMP) event.getEntityPlayer()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
data.getRevivers().add(event.getEntityPlayer());
|
|
||||||
KnockdownsNetwork.sendToMultiple(
|
|
||||||
new SynchronizeReviversS2CPacket.Add(event.getTarget().getEntityId(), event.getEntityPlayer().getEntityId()),
|
|
||||||
data.getRevivers(),
|
|
||||||
knocked
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onPlayerJoin(PlayerLoggedInEvent event) {
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(event.player);
|
|
||||||
KnockdownsNetwork.sendToPlayer(
|
|
||||||
new SynchronizePlayerDataS2CPacket.Full(event.player.getEntityId(), data.isKnockedDown(), data.getReviveTimeLeft()),
|
|
||||||
(EntityPlayerMP) event.player
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onPlayerLeave(PlayerLoggedOutEvent event) {
|
|
||||||
for (EntityPlayer knocked : event.player.world.playerEntities) {
|
|
||||||
List<EntityPlayer> revivers = IKnockdownsPlayerData.get(knocked).getRevivers();
|
|
||||||
if (revivers.contains(event.player)) {
|
|
||||||
revivers.remove(event.player);
|
|
||||||
KnockdownsNetwork.sendToMultiple(
|
|
||||||
new SynchronizeReviversS2CPacket.Remove(knocked.getEntityId(), event.player.getEntityId()),
|
|
||||||
revivers,
|
|
||||||
(EntityPlayerMP) knocked
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
|
|
||||||
import zone.rong.mixinbooter.IEarlyMixinLoader;
|
|
||||||
|
|
||||||
@IFMLLoadingPlugin.MCVersion("1.12.2")
|
|
||||||
public class KnockdownsFMLLoadingPlugin implements IFMLLoadingPlugin, IEarlyMixinLoader {
|
|
||||||
@Override
|
|
||||||
public String[] getASMTransformerClass() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getModContainerClass() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public String getSetupClass() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void injectData(Map<String, Object> data) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAccessTransformerClass() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getMixinConfigs() {
|
|
||||||
ArrayList<String> list = new ArrayList<>();
|
|
||||||
list.add("mixins.knockdowns.json");
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common;
|
|
||||||
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.SidedProxy;
|
|
||||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
|
|
||||||
@Mod(modid = Tags.MOD_ID, name = Tags.MOD_NAME, version = Tags.VERSION)
|
|
||||||
public class KnockdownsMod {
|
|
||||||
public static final Logger LOGGER = LogManager.getLogger(Tags.MOD_NAME);
|
|
||||||
@SidedProxy(clientSide = "ru.octol1ttle.knockdowns.client.ClientProxy", serverSide = "ru.octol1ttle.knockdowns.common.IClientProxy$Dummy")
|
|
||||||
public static IClientProxy clientProxy;
|
|
||||||
|
|
||||||
@Mod.EventHandler
|
|
||||||
public void onFMLInit(FMLInitializationEvent event) {
|
|
||||||
LOGGER.info("Initializing");
|
|
||||||
clientProxy.onFMLInit(event);
|
|
||||||
KnockdownsCommonEventListener.onFMLInit(event);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common;
|
|
||||||
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import net.minecraft.init.MobEffects;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.KnockdownsNetwork;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizePlayerDataS2CPacket;
|
|
||||||
|
|
||||||
public class KnockdownsUtils {
|
|
||||||
public static final int INITIAL_REVIVE_TIME_LEFT = 200;
|
|
||||||
public static final float KNOCKED_INVULNERABILITY_TICKS = 3.0f * 20.0f;
|
|
||||||
public static final float KNOCKED_HURT_PERIOD = 1.2f;
|
|
||||||
public static final float KNOCKED_TENACITY = 60.0f;
|
|
||||||
|
|
||||||
public static boolean allPlayersKnocked(MinecraftServer server, EntityPlayer except) {
|
|
||||||
for (EntityPlayer player : server.getPlayerList().getPlayers()) {
|
|
||||||
if (player.equals(except)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(player);
|
|
||||||
if (player.isEntityAlive() && !data.isKnockedDown()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void resetKnockedState(EntityPlayerMP player, IKnockdownsPlayerData data) {
|
|
||||||
player.removePotionEffect(MobEffects.SLOWNESS);
|
|
||||||
data.setKnockedDown(false);
|
|
||||||
data.setReviveTimeLeft(INITIAL_REVIVE_TIME_LEFT);
|
|
||||||
data.setTicksKnocked(0);
|
|
||||||
|
|
||||||
KnockdownsNetwork.sendToTrackingAndSelf(
|
|
||||||
new SynchronizePlayerDataS2CPacket.KnockedDown(player.getEntityId(), data.isKnockedDown()),
|
|
||||||
player
|
|
||||||
);
|
|
||||||
|
|
||||||
data.getRevivers().clear();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.communication;
|
|
||||||
|
|
||||||
public enum CalloutType {
|
|
||||||
DANGER((byte) 0, "knockdowns.callout.danger"),
|
|
||||||
BOOYAH((byte) 1, "knockdowns.callout.booyah"),
|
|
||||||
THIS_WAY((byte) 2, "knockdowns.callout.this_way"),
|
|
||||||
OUCH((byte) 3, "knockdowns.callout.ouch"),
|
|
||||||
HELP((byte) 4, "knockdowns.callout.help");
|
|
||||||
|
|
||||||
private final byte id;
|
|
||||||
private final String textKey;
|
|
||||||
|
|
||||||
CalloutType(byte id, String textKey) {
|
|
||||||
this.id = id;
|
|
||||||
this.textKey = textKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTextKey() {
|
|
||||||
return textKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CalloutType byId(byte id) {
|
|
||||||
for (CalloutType type : CalloutType.values()) {
|
|
||||||
if (id == type.getId()) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.data;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraftforge.common.util.INBTSerializable;
|
|
||||||
import ru.octol1ttle.knockdowns.common.util.UniqueOnlyList;
|
|
||||||
|
|
||||||
public interface IKnockdownsPlayerData extends INBTSerializable<NBTTagCompound> {
|
|
||||||
boolean isKnockedDown();
|
|
||||||
void setKnockedDown(boolean knockedDown);
|
|
||||||
|
|
||||||
int getReviveTimeLeft();
|
|
||||||
void setReviveTimeLeft(int reviveTimeLeft);
|
|
||||||
|
|
||||||
int getTicksKnocked();
|
|
||||||
void setTicksKnocked(int ticksKnocked);
|
|
||||||
|
|
||||||
UniqueOnlyList<EntityPlayer> getRevivers();
|
|
||||||
|
|
||||||
static IKnockdownsPlayerData get(EntityPlayer player) {
|
|
||||||
return Objects.requireNonNull(player.getCapability(KnockdownsCapability.CAPABILITY, null));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.data;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
|
||||||
import net.minecraft.util.LazyLoadBase;
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
|
||||||
import net.minecraftforge.common.capabilities.CapabilityInject;
|
|
||||||
import net.minecraftforge.common.capabilities.CapabilityManager;
|
|
||||||
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
|
|
||||||
public class KnockdownsCapability implements ICapabilitySerializable<NBTTagCompound> {
|
|
||||||
@CapabilityInject(IKnockdownsPlayerData.class)
|
|
||||||
public static Capability<IKnockdownsPlayerData> CAPABILITY;
|
|
||||||
public static final ResourceLocation ID = new ResourceLocation(Tags.MOD_ID, "data");
|
|
||||||
|
|
||||||
private KnockdownsPlayerData playerData = null;
|
|
||||||
private final LazyLoadBase<KnockdownsPlayerData> lazy = new LazyLoadBase<KnockdownsPlayerData>() {
|
|
||||||
@Override
|
|
||||||
protected KnockdownsPlayerData load() {
|
|
||||||
return playerData == null ? (playerData = new KnockdownsPlayerData()) : playerData;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static void register() {
|
|
||||||
CapabilityManager.INSTANCE.register(IKnockdownsPlayerData.class, new Capability.IStorage<IKnockdownsPlayerData>() {
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public NBTBase writeNBT(Capability<IKnockdownsPlayerData> capability, IKnockdownsPlayerData instance, EnumFacing side) {
|
|
||||||
return instance.serializeNBT();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readNBT(Capability<IKnockdownsPlayerData> capability, IKnockdownsPlayerData instance, EnumFacing side, NBTBase nbt) {
|
|
||||||
instance.deserializeNBT((NBTTagCompound) nbt);
|
|
||||||
}
|
|
||||||
}, KnockdownsPlayerData::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
|
|
||||||
return capability == CAPABILITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
|
|
||||||
return capability == CAPABILITY ? (T) lazy.getValue() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NBTTagCompound serializeNBT() {
|
|
||||||
return lazy.getValue().serializeNBT();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deserializeNBT(NBTTagCompound nbt) {
|
|
||||||
lazy.getValue().deserializeNBT(nbt);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.data;
|
|
||||||
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsUtils;
|
|
||||||
import ru.octol1ttle.knockdowns.common.util.UniqueOnlyList;
|
|
||||||
|
|
||||||
public class KnockdownsPlayerData implements IKnockdownsPlayerData {
|
|
||||||
private static final String KEY_KNOCKED_DOWN = "KnockedDown";
|
|
||||||
private static final String KEY_REVIVE_TIME_LEFT = "ReviveTimeLeft";
|
|
||||||
private static final String KEY_TICKS_KNOCKED = "TicksKnocked";
|
|
||||||
private boolean knockedDown = false;
|
|
||||||
private int reviveTimeLeft = KnockdownsUtils.INITIAL_REVIVE_TIME_LEFT;
|
|
||||||
private int ticksKnocked = 0;
|
|
||||||
private final UniqueOnlyList<EntityPlayer> revivers = new UniqueOnlyList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isKnockedDown() {
|
|
||||||
return this.knockedDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setKnockedDown(boolean knockedDown) {
|
|
||||||
this.knockedDown = knockedDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getReviveTimeLeft() {
|
|
||||||
return this.reviveTimeLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setReviveTimeLeft(int reviveTimeLeft) {
|
|
||||||
this.reviveTimeLeft = reviveTimeLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getTicksKnocked() {
|
|
||||||
return this.ticksKnocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTicksKnocked(int ticksKnocked) {
|
|
||||||
this.ticksKnocked = ticksKnocked;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UniqueOnlyList<EntityPlayer> getRevivers() {
|
|
||||||
return revivers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NBTTagCompound serializeNBT() {
|
|
||||||
NBTTagCompound nbt = new NBTTagCompound();
|
|
||||||
nbt.setBoolean(KEY_KNOCKED_DOWN, this.knockedDown);
|
|
||||||
nbt.setInteger(KEY_REVIVE_TIME_LEFT, this.reviveTimeLeft);
|
|
||||||
nbt.setInteger(KEY_TICKS_KNOCKED, this.ticksKnocked);
|
|
||||||
return nbt;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deserializeNBT(NBTTagCompound nbt) {
|
|
||||||
this.knockedDown = nbt.getBoolean(KEY_KNOCKED_DOWN);
|
|
||||||
this.reviveTimeLeft = nbt.getInteger(KEY_REVIVE_TIME_LEFT);
|
|
||||||
this.ticksKnocked = nbt.getInteger(KEY_TICKS_KNOCKED);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.mixins;
|
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsUtils;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
|
|
||||||
@SuppressWarnings("ConstantValue")
|
|
||||||
@Mixin(EntityLivingBase.class)
|
|
||||||
public abstract class EntityLivingBaseMixin extends Entity {
|
|
||||||
public EntityLivingBaseMixin(World worldIn) {
|
|
||||||
super(worldIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "checkTotemDeathProtection", at = @At("RETURN"))
|
|
||||||
public void onTotemActivation(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
if (cir.getReturnValue() && ((Object) this) instanceof EntityPlayerMP) {
|
|
||||||
EntityPlayerMP player = (EntityPlayerMP) (Object) this;
|
|
||||||
IKnockdownsPlayerData data = IKnockdownsPlayerData.get(player);
|
|
||||||
if (data.isKnockedDown()) {
|
|
||||||
KnockdownsUtils.resetKnockedState(player, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.mixins;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
|
|
||||||
@SuppressWarnings("ConstantValue")
|
|
||||||
@Mixin(EntityPlayer.class)
|
|
||||||
public class EntityPlayerMixin {
|
|
||||||
@ModifyReturnValue(method = "shouldHeal", at = @At("RETURN"))
|
|
||||||
private boolean dontHealIfKnockedDown(boolean original) {
|
|
||||||
if (((Object) this) instanceof EntityPlayer) {
|
|
||||||
EntityPlayer player = (EntityPlayer) (Object) this;
|
|
||||||
if (IKnockdownsPlayerData.get(player).isKnockedDown()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
|
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
import ru.octol1ttle.knockdowns.common.KnockdownsMod;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.c2s.CancelReviveC2SPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.c2s.PlayerCalloutC2SPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerKnockedDownS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizePlayerDataS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizeReviversS2CPacket;
|
|
||||||
|
|
||||||
public class KnockdownsNetwork {
|
|
||||||
private static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(Tags.MOD_ID);
|
|
||||||
private static int packetId = 0;
|
|
||||||
|
|
||||||
public static void registerPackets() {
|
|
||||||
INSTANCE.registerMessage(KnockdownsServerPacketHandler.Callout.class, PlayerCalloutC2SPacket.class, packetId++, Side.SERVER);
|
|
||||||
INSTANCE.registerMessage(KnockdownsServerPacketHandler.CancelRevive.class, CancelReviveC2SPacket.class, packetId++, Side.SERVER);
|
|
||||||
|
|
||||||
IMessageHandler<IMessage, IMessage> clientProxyHandler = (message, ctx) -> KnockdownsMod.clientProxy.handleMessage(message);
|
|
||||||
INSTANCE.registerMessage(clientProxyHandler, PlayerCalloutS2CPacket.class, packetId++, Side.CLIENT);
|
|
||||||
INSTANCE.registerMessage(clientProxyHandler, PlayerKnockedDownS2CPacket.class, packetId++, Side.CLIENT);
|
|
||||||
INSTANCE.registerMessage(clientProxyHandler, SynchronizePlayerDataS2CPacket.KnockedDown.class, packetId++, Side.CLIENT);
|
|
||||||
INSTANCE.registerMessage(clientProxyHandler, SynchronizePlayerDataS2CPacket.ReviveTimeLeft.class, packetId++, Side.CLIENT);
|
|
||||||
INSTANCE.registerMessage(clientProxyHandler, SynchronizePlayerDataS2CPacket.Full.class, packetId++, Side.CLIENT);
|
|
||||||
INSTANCE.registerMessage(clientProxyHandler, SynchronizeReviversS2CPacket.Add.class, packetId++, Side.CLIENT);
|
|
||||||
INSTANCE.registerMessage(clientProxyHandler, SynchronizeReviversS2CPacket.Remove.class, packetId++, Side.CLIENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
|
||||||
public static void sendToServer(IMessage message) {
|
|
||||||
INSTANCE.sendToServer(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToAll(IMessage message) {
|
|
||||||
INSTANCE.sendToAll(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToDimension(IMessage message, MessageContext context) {
|
|
||||||
INSTANCE.sendToDimension(message, context.getServerHandler().player.dimension);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToTrackingAndSelf(IMessage message, EntityPlayerMP player) {
|
|
||||||
sendToPlayer(message, player);
|
|
||||||
sendToTracking(message, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToMultiple(IMessage message, List<EntityPlayer> players, EntityPlayerMP player) {
|
|
||||||
sendToPlayer(message, player);
|
|
||||||
for (EntityPlayer listed : players) {
|
|
||||||
sendToPlayer(message, (EntityPlayerMP) listed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToTracking(IMessage message, Entity entity) {
|
|
||||||
INSTANCE.sendToAllTracking(message, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendToPlayer(IMessage message, EntityPlayerMP player) {
|
|
||||||
INSTANCE.sendTo(message, player);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
|
||||||
import ru.octol1ttle.knockdowns.common.data.IKnockdownsPlayerData;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.c2s.CancelReviveC2SPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.c2s.PlayerCalloutC2SPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.PlayerCalloutS2CPacket;
|
|
||||||
import ru.octol1ttle.knockdowns.common.network.packets.s2c.SynchronizeReviversS2CPacket;
|
|
||||||
|
|
||||||
public class KnockdownsServerPacketHandler {
|
|
||||||
public static class Callout implements IMessageHandler<PlayerCalloutC2SPacket, IMessage> {
|
|
||||||
@Override
|
|
||||||
public IMessage onMessage(PlayerCalloutC2SPacket message, MessageContext ctx) {
|
|
||||||
KnockdownsNetwork.sendToDimension(
|
|
||||||
new PlayerCalloutS2CPacket(
|
|
||||||
ctx.getServerHandler().player.getEntityId(),
|
|
||||||
ctx.getServerHandler().player.getPositionEyes(1).add(0, 1, 0),
|
|
||||||
message.type
|
|
||||||
),
|
|
||||||
ctx
|
|
||||||
);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CancelRevive implements IMessageHandler<CancelReviveC2SPacket, IMessage> {
|
|
||||||
@Override
|
|
||||||
public IMessage onMessage(CancelReviveC2SPacket message, MessageContext ctx) {
|
|
||||||
EntityPlayerMP player = ctx.getServerHandler().player;
|
|
||||||
for (EntityPlayer knocked : player.world.playerEntities) {
|
|
||||||
List<EntityPlayer> revivers = IKnockdownsPlayerData.get(knocked).getRevivers();
|
|
||||||
if (revivers.contains(player)) {
|
|
||||||
revivers.remove(player);
|
|
||||||
KnockdownsNetwork.sendToMultiple(
|
|
||||||
new SynchronizeReviversS2CPacket.Remove(knocked.getEntityId(), player.getEntityId()),
|
|
||||||
revivers,
|
|
||||||
(EntityPlayerMP) knocked
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets.c2s;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
|
|
||||||
public class CancelReviveC2SPacket implements IMessage {
|
|
||||||
public CancelReviveC2SPacket() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets.c2s;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
import ru.octol1ttle.knockdowns.common.communication.CalloutType;
|
|
||||||
|
|
||||||
public class PlayerCalloutC2SPacket implements IMessage {
|
|
||||||
public PlayerCalloutC2SPacket() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public CalloutType type;
|
|
||||||
public PlayerCalloutC2SPacket(CalloutType type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeByte(this.type.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.type = CalloutType.byId(buf.readByte());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets.s2c;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
import ru.octol1ttle.knockdowns.common.communication.CalloutType;
|
|
||||||
|
|
||||||
public class PlayerCalloutS2CPacket implements IMessage {
|
|
||||||
public PlayerCalloutS2CPacket() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int playerId;
|
|
||||||
public Vec3d position;
|
|
||||||
public CalloutType type;
|
|
||||||
|
|
||||||
public PlayerCalloutS2CPacket(int playerId, Vec3d position, CalloutType type) {
|
|
||||||
this.playerId = playerId;
|
|
||||||
this.position = position;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeInt(this.playerId);
|
|
||||||
buf.writeDouble(this.position.x);
|
|
||||||
buf.writeDouble(this.position.y);
|
|
||||||
buf.writeDouble(this.position.z);
|
|
||||||
buf.writeByte(this.type.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.playerId = buf.readInt();
|
|
||||||
this.position = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
|
|
||||||
this.type = CalloutType.byId(buf.readByte());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets.s2c;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
|
|
||||||
public class PlayerKnockedDownS2CPacket implements IMessage {
|
|
||||||
public PlayerKnockedDownS2CPacket() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int playerId;
|
|
||||||
public int dimensionId;
|
|
||||||
public Vec3d position;
|
|
||||||
|
|
||||||
public PlayerKnockedDownS2CPacket(int playerId, int dimensionId, Vec3d position) {
|
|
||||||
this.playerId = playerId;
|
|
||||||
this.dimensionId = dimensionId;
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeInt(this.playerId);
|
|
||||||
buf.writeInt(this.dimensionId);
|
|
||||||
buf.writeDouble(this.position.x);
|
|
||||||
buf.writeDouble(this.position.y);
|
|
||||||
buf.writeDouble(this.position.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.playerId = buf.readInt();
|
|
||||||
this.dimensionId = buf.readInt();
|
|
||||||
this.position = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets.s2c;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
|
|
||||||
public class SynchronizePlayerDataS2CPacket {
|
|
||||||
public static class KnockedDown implements IMessage {
|
|
||||||
public KnockedDown() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int playerId;
|
|
||||||
public boolean knockedDown;
|
|
||||||
|
|
||||||
public KnockedDown(int playerId, boolean knockedDown) {
|
|
||||||
this.playerId = playerId;
|
|
||||||
this.knockedDown = knockedDown;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeInt(this.playerId);
|
|
||||||
buf.writeBoolean(this.knockedDown);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.playerId = buf.readInt();
|
|
||||||
this.knockedDown = buf.readBoolean();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ReviveTimeLeft implements IMessage {
|
|
||||||
public ReviveTimeLeft() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int playerId;
|
|
||||||
public int reviveTimeLeft;
|
|
||||||
|
|
||||||
public ReviveTimeLeft(int playerId, int reviveTimeLeft) {
|
|
||||||
this.playerId = playerId;
|
|
||||||
this.reviveTimeLeft = reviveTimeLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeInt(this.playerId);
|
|
||||||
buf.writeInt(this.reviveTimeLeft);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.playerId = buf.readInt();
|
|
||||||
this.reviveTimeLeft = buf.readInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Full implements IMessage {
|
|
||||||
public Full() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int playerId;
|
|
||||||
public boolean knockedDown;
|
|
||||||
public int reviveTimeLeft;
|
|
||||||
|
|
||||||
public Full(int playerId, boolean knockedDown, int reviveTimeLeft) {
|
|
||||||
this.playerId = playerId;
|
|
||||||
this.knockedDown = knockedDown;
|
|
||||||
this.reviveTimeLeft = reviveTimeLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeInt(this.playerId);
|
|
||||||
buf.writeBoolean(this.knockedDown);
|
|
||||||
buf.writeInt(this.reviveTimeLeft);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.playerId = buf.readInt();
|
|
||||||
this.knockedDown = buf.readBoolean();
|
|
||||||
this.reviveTimeLeft = buf.readInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.network.packets.s2c;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
|
|
||||||
public class SynchronizeReviversS2CPacket {
|
|
||||||
public static class Add implements IMessage {
|
|
||||||
public Add() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int knockedId;
|
|
||||||
public int reviverId;
|
|
||||||
|
|
||||||
public Add(int knockedId, int reviverId) {
|
|
||||||
this.knockedId = knockedId;
|
|
||||||
this.reviverId = reviverId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeInt(this.knockedId);
|
|
||||||
buf.writeInt(this.reviverId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.knockedId = buf.readInt();
|
|
||||||
this.reviverId = buf.readInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Remove implements IMessage {
|
|
||||||
public Remove() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public int knockedId;
|
|
||||||
public int reviverId;
|
|
||||||
|
|
||||||
public Remove(int knockedId, int reviverId) {
|
|
||||||
this.knockedId = knockedId;
|
|
||||||
this.reviverId = reviverId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf) {
|
|
||||||
buf.writeInt(this.knockedId);
|
|
||||||
buf.writeInt(this.reviverId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf) {
|
|
||||||
this.knockedId = buf.readInt();
|
|
||||||
this.reviverId = buf.readInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.registry;
|
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.SoundEvent;
|
|
||||||
import ru.octol1ttle.knockdowns.Tags;
|
|
||||||
|
|
||||||
public class KnockdownsSoundEvents {
|
|
||||||
public static final SoundEvent CALLOUT;
|
|
||||||
public static final SoundEvent KNOCKED_DOWN;
|
|
||||||
static {
|
|
||||||
ResourceLocation callout = new ResourceLocation(Tags.MOD_ID, "callout");
|
|
||||||
CALLOUT = new SoundEvent(callout).setRegistryName(callout);
|
|
||||||
|
|
||||||
ResourceLocation knockedDown = new ResourceLocation(Tags.MOD_ID, "knocked_down");
|
|
||||||
KNOCKED_DOWN = new SoundEvent(knockedDown).setRegistryName(knockedDown);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package ru.octol1ttle.knockdowns.common.util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class UniqueOnlyList<T> extends ArrayList<T> {
|
|
||||||
@Override
|
|
||||||
public void add(int index, T element) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(T t) {
|
|
||||||
if (this.contains(t)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return super.add(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T set(int index, T element) {
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
knockdowns.key.category=Knockdowns
|
|
||||||
knockdowns.key.callout.danger=Call out "Danger!"
|
|
||||||
knockdowns.key.callout.booyah=Call out "Booyah!"
|
|
||||||
knockdowns.key.callout.this_way_help=Call out "This way!" ("Help!" when knocked down)
|
|
||||||
knockdowns.key.callout.ouch=Call out "Ouch..."
|
|
||||||
|
|
||||||
knockdowns.callout.danger=Danger!
|
|
||||||
knockdowns.callout.booyah=Booyah!
|
|
||||||
knockdowns.callout.this_way=This way!
|
|
||||||
knockdowns.callout.ouch=Ouch...
|
|
||||||
knockdowns.callout.help=Help!
|
|
||||||
|
|
||||||
knockdowns.subtitles.callout=Player calls out
|
|
||||||
knockdowns.subtitles.knocked_down=Player knocked down
|
|
||||||
|
|
||||||
knockdown.fell.accident.ladder=%1$s was knocked down by falling off a ladder
|
|
||||||
knockdown.fell.accident.vines=%1$s was knocked down by falling off some vines
|
|
||||||
knockdown.fell.accident.water=%1$s was knocked down by falling out of the water
|
|
||||||
knockdown.fell.accident.generic=%1$s was knocked down by a fall
|
|
||||||
knockdown.fell.killer=%1$s was doomed to get knocked down
|
|
||||||
knockdown.fell.assist=%1$s was doomed to get knocked down by %2$s
|
|
||||||
knockdown.fell.assist.item=%1$s was doomed to get knocked down by %2$s using %3$s
|
|
||||||
knockdown.fell.finish=%1$s fell too far and was knocked down by %2$s
|
|
||||||
knockdown.fell.finish.item=%1$s fell too far and was knocked down by %2$s using %3$s
|
|
||||||
|
|
||||||
knockdown.attack.lightningBolt=%1$s was knocked down by lightning
|
|
||||||
knockdown.attack.inFire=%1$s was knocked down by the fire below
|
|
||||||
knockdown.attack.inFire.player=%1$s was knocked down by the fire below whilst fighting %2$s
|
|
||||||
knockdown.attack.onFire=%1$s was knocked down by fire
|
|
||||||
knockdown.attack.onFire.player=%1$s was knocked down by fire whilst fighting %2$s
|
|
||||||
knockdown.attack.lava=%1$s was knocked down by lava
|
|
||||||
knockdown.attack.lava.player=%1$s was knocked down by lava to escape %2$s
|
|
||||||
knockdown.attack.hotFloor=%1$s was knocked down by the floor
|
|
||||||
knockdown.attack.hotFloor.player=%1$s was knocked down by the floor due to %2$s
|
|
||||||
knockdown.attack.inWall=%1$s was knocked down by a wall
|
|
||||||
knockdown.attack.cramming=%1$s was knocked down by social anxiety
|
|
||||||
knockdown.attack.drown=%1$s was knocked down by lack of air
|
|
||||||
knockdown.attack.drown.player=%1$s was knocked down by lack of air whilst trying to escape %2$s
|
|
||||||
knockdown.attack.starve=%1$s was knocked down by hunger
|
|
||||||
knockdown.attack.cactus=%1$s was knocked down by a cactus
|
|
||||||
knockdown.attack.cactus.player=%1$s was knocked down by a cactus whilst trying to escape %2$s
|
|
||||||
knockdown.attack.generic=%1$s was knocked down
|
|
||||||
knockdown.attack.explosion=%1$s was knocked down by an explosion
|
|
||||||
knockdown.attack.explosion.player=%1$s was knocked down by an explosion due to %2$s
|
|
||||||
knockdown.attack.magic=%1$s was knocked down by magic
|
|
||||||
knockdown.attack.wither=%1$s was knocked down by withering
|
|
||||||
knockdown.attack.anvil=%1$s was knocked down by a falling anvil
|
|
||||||
knockdown.attack.fallingBlock=%1$s was knocked down by a falling block
|
|
||||||
knockdown.attack.mob=%1$s was knocked down by %2$s
|
|
||||||
knockdown.attack.player=%1$s was knocked down by %2$s
|
|
||||||
knockdown.attack.player.item=%1$s was knocked down by %2$s using %3$s
|
|
||||||
knockdown.attack.arrow=%1$s was knocked down by an arrow shot by %2$s
|
|
||||||
knockdown.attack.arrow.item=%1$s was knocked down by an arrow shot by %2$s using %3$s
|
|
||||||
knockdown.attack.fireball=%1$s was knocked down by a fireball shot by %2$s
|
|
||||||
knockdown.attack.fireball.item=%1$s was knocked down by a fireball shot by %2$s using %3$s
|
|
||||||
knockdown.attack.thrown=%1$s was knocked down after being pummeled by %2$s
|
|
||||||
knockdown.attack.thrown.item=%1$s was knocked down after being pummeled by %2$s using %3$s
|
|
||||||
knockdown.attack.indirectMagic=%1$s was knocked down by %2$s using magic
|
|
||||||
knockdown.attack.indirectMagic.item=%1$s was knocked down by %2$s using %3$s
|
|
||||||
knockdown.attack.thorns=%1$s was knocked down trying to hurt %2$s
|
|
||||||
knockdown.attack.fall=%1$s was knocked down by the ground below
|
|
||||||
knockdown.attack.outOfWorld=%1$s was knocked down by the void
|
|
||||||
knockdown.attack.dragonBreath=%1$s was knocked down by dragon breath
|
|
||||||
knockdown.attack.flyIntoWall=%1$s was knocked down by physics
|
|
||||||
knockdown.attack.fireworks=%1$s was knocked down by a firework
|
|
|
@ -1,64 +0,0 @@
|
||||||
knockdowns.key.category=Knockdowns
|
|
||||||
knockdowns.key.callout.danger="Опасность!"
|
|
||||||
knockdowns.key.callout.booyah="Йо-хо!"
|
|
||||||
knockdowns.key.callout.this_way_help="Сюда!" ("SOS!" когда тяжело ранен)
|
|
||||||
knockdowns.key.callout.ouch="Непруха!"
|
|
||||||
|
|
||||||
knockdowns.callout.danger=Опасность!
|
|
||||||
knockdowns.callout.booyah=Йо-хо!
|
|
||||||
knockdowns.callout.this_way=Сюда!
|
|
||||||
knockdowns.callout.ouch=Непруха!
|
|
||||||
knockdowns.callout.help=SOS!
|
|
||||||
|
|
||||||
knockdowns.subtitles.callout=Игрок зовёт союзников
|
|
||||||
knockdowns.subtitles.knocked_down=Игрок тяжело ранен
|
|
||||||
|
|
||||||
knockdown.attack.anvil=%1$s тяжело ранен упавшей наковальней
|
|
||||||
knockdown.attack.arrow=%1$s тяжело ранен стрелой %2$s
|
|
||||||
knockdown.attack.arrow.item=%1$s тяжело ранен стрелой %2$s с помощью %3$s
|
|
||||||
knockdown.attack.cactus=%1$s исколот до тяжелого ранения
|
|
||||||
knockdown.attack.cactus.player=%1$s тяжело ранен кактусом, спасаясь от %2$s
|
|
||||||
knockdown.attack.cramming=%1$s расплющен до тяжелого ранения
|
|
||||||
knockdown.attack.dragonBreath=%1$s тяжело ранен в драконьем дыхании
|
|
||||||
knockdown.attack.drown=%1$s тяжело ранен от нехватки воздуха
|
|
||||||
knockdown.attack.drown.player=%1$s тяжело ранен от нехватки воздуха, спасаясь от %2$s
|
|
||||||
knockdown.attack.explosion=%1$s тяжело ранен взрывом
|
|
||||||
knockdown.attack.explosion.player=%1$s был тяжело ранен взрывом %2$s
|
|
||||||
knockdown.attack.fall=%1$s разбился до тяжелого ранения
|
|
||||||
knockdown.attack.fallingBlock=%1$s тяжело ранен упавшим блоком
|
|
||||||
knockdown.attack.fireball=%1$s тяжело ранен файерболом %2$s
|
|
||||||
knockdown.attack.fireball.item=%1$s тяжело ранен файерболом %2$s с помощью %3$s
|
|
||||||
knockdown.attack.fireworks=%1$s с треском тяжело ранен
|
|
||||||
knockdown.attack.flyIntoWall=%1$s преобразовал кинетическую энергию в тяжелое ранение
|
|
||||||
knockdown.attack.generic=%1$s тяжело ранен
|
|
||||||
knockdown.attack.hotFloor=%1$s тяжело ранен, обнаружив под ногами лаву
|
|
||||||
knockdown.attack.hotFloor.player=%1$s зашёл в опасную зону тяжелого ранения из-за %2$s
|
|
||||||
knockdown.attack.inFire=%1$s сгорел до тяжелого ранения
|
|
||||||
knockdown.attack.inFire.player=%1$s тяжело ранен в огне, борясь с %2$s
|
|
||||||
knockdown.attack.inWall=%1$s погребён до тяжелого ранения
|
|
||||||
knockdown.attack.indirectMagic=%1$s был тяжело ранен %2$s с помощью магии
|
|
||||||
knockdown.attack.indirectMagic.item=%1$s был тяжело ранен %2$s с помощью %3$s
|
|
||||||
knockdown.attack.lava=%1$s решил получить тяжелое ранение в лаве
|
|
||||||
knockdown.attack.lava.player=%1$s получил тяжелое ранение от лавы, убегая от %2$s
|
|
||||||
knockdown.attack.lightningBolt=%1$s был тяжело ранен поражением молнией
|
|
||||||
knockdown.attack.magic=%1$s был тяжело ранен магией
|
|
||||||
knockdown.attack.mob=%1$s был тяжело ранен %2$s
|
|
||||||
knockdown.attack.onFire=%1$s сгорел до тяжелого ранения
|
|
||||||
knockdown.attack.onFire.player=%1$s был сожжён до тяжелого ранения, пока боролся с %2$s
|
|
||||||
knockdown.attack.outOfWorld=%1$s тяжело ранен отсутствием земли под собой
|
|
||||||
knockdown.attack.player=%1$s был тяжело ранен %2$s
|
|
||||||
knockdown.attack.player.item=%1$s был тяжело ранен %2$s с помощью %3$s
|
|
||||||
knockdown.attack.starve=%1$s тяжело ранен от голода
|
|
||||||
knockdown.attack.thorns=%1$s был тяжело ранен, пытаясь навредить %2$s
|
|
||||||
knockdown.attack.thrown=%1$s был избит до тяжелого ранения %2$s
|
|
||||||
knockdown.attack.thrown.item=%1$s был избит до тяжелого ранения %2$s с помощью %3$s
|
|
||||||
knockdown.attack.wither=%1$s тяжело ранен иссушением
|
|
||||||
knockdown.fell.accident.generic=%1$s разбился до тяжелого ранения
|
|
||||||
knockdown.fell.accident.ladder=%1$s свалился с лестницы и был тяжело ранен
|
|
||||||
knockdown.fell.accident.vines=%1$s сорвался с лианы и был тяжело ранен
|
|
||||||
knockdown.fell.accident.water=%1$s выпал из воды и был тяжело ранен
|
|
||||||
knockdown.fell.assist=%1$s свалился и был тяжело ранен благодаря %2$s
|
|
||||||
knockdown.fell.assist.item=%1$s был обречён на тяжелое ранение %2$s с помощью %3$s
|
|
||||||
knockdown.fell.finish=%1$s упал с высоты и был тяжело ранен %2$s
|
|
||||||
knockdown.fell.finish.item=%1$s упал с высоты и был тяжело ранен %2$s с помощью %3$s
|
|
||||||
knockdown.fell.killer=%1$s был обречён на тяжелое ранение
|
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
"callout": {
|
|
||||||
"subtitle": "knockdowns.subtitles.callout",
|
|
||||||
"sounds": [
|
|
||||||
{
|
|
||||||
"name": "knockdowns:callout"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"knocked_down": {
|
|
||||||
"subtitle": "knockdowns.subtitles.knocked_down",
|
|
||||||
"sounds": [
|
|
||||||
{
|
|
||||||
"name": "knockdowns:knocked_down"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 172 B |
Binary file not shown.
Before Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB |
|
@ -1,12 +1,16 @@
|
||||||
[{
|
[
|
||||||
"modid": "${mod_id}",
|
{
|
||||||
"name": "${mod_name}",
|
"modid": "examplemod",
|
||||||
"version": "${mod_version}",
|
"name": "Example Mod",
|
||||||
"mcversion": "1.12.2",
|
"description": "Example placeholder mod.",
|
||||||
"description": "${mod_description}",
|
"version": "${version}",
|
||||||
"authorList": ${mod_authors},
|
"mcversion": "${mcversion}",
|
||||||
"credits": "${mod_credits}",
|
"url": "",
|
||||||
"url": "${mod_url}",
|
"updateUrl": "",
|
||||||
"updateJSON": "${mod_update_json}",
|
"authorList": ["CleanroomMC"],
|
||||||
"logoFile": "${mod_logo_path}"
|
"credits": "Authors of this project",
|
||||||
}]
|
"logoFile": "",
|
||||||
|
"screenshots": [],
|
||||||
|
"dependencies": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"package": "ru.octol1ttle.knockdowns.common.mixins",
|
|
||||||
"required": true,
|
|
||||||
"refmap": "${mixin_refmap}",
|
|
||||||
"target": "@env(DEFAULT)",
|
|
||||||
"minVersion": "0.8.5",
|
|
||||||
"compatibilityLevel": "JAVA_8",
|
|
||||||
"mixins": [ "EntityLivingBaseMixin", "EntityPlayerMixin" ],
|
|
||||||
"server": [],
|
|
||||||
"client": []
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"pack": {
|
"pack": {
|
||||||
"description": "${mod_name} Resources",
|
"description": "examplemod resources",
|
||||||
"pack_format": 3
|
"pack_format": 3,
|
||||||
|
"_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)."
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
VERSION = ${mod_version}
|
|
||||||
MOD_ID = ${mod_id}
|
|
||||||
MOD_NAME = ${mod_name}
|
|
Loading…
Add table
Reference in a new issue