Compare commits
145 Commits
1.19.2-for
...
1.20
| Author | SHA1 | Date | |
|---|---|---|---|
| 470b5839a4 | |||
|
|
594c4decf3 | ||
|
|
ecb0dcee56 | ||
|
|
cc18c6f793 | ||
|
|
6e712fc8da | ||
|
|
06e722cb7c | ||
|
|
2ffe983e12 | ||
|
|
5462ec7e93 | ||
|
|
a603bdc8df | ||
|
|
21ffc08fcf | ||
|
|
cc0803de11 | ||
|
|
7e7133e08c | ||
|
|
2e30446281 | ||
|
|
9452482254 | ||
|
|
91557161e0 | ||
|
|
85b076d638 | ||
|
|
5292e97a8f | ||
|
|
f843376f7a | ||
|
|
84d475d61c | ||
|
|
f3f3cff079 | ||
|
|
fe81c18b5b | ||
|
|
ec904c199e | ||
|
|
281eb51c0d | ||
|
|
3d2f786049 | ||
|
|
3ca9f6ceb1 | ||
|
|
92bd6924b0 | ||
|
|
639fdefcce | ||
|
|
1de20710fe | ||
|
|
5b37a39dbc | ||
|
|
0bc5b3b67d | ||
|
|
dbd8fba683 | ||
|
|
d6da33da63 | ||
|
|
2969470796 | ||
|
|
074cedc85c | ||
|
|
a4b4162fa9 | ||
|
|
a2f81aeeac | ||
|
|
c2d6f01991 | ||
|
|
a9d9dcfecf | ||
|
|
96d7c92c37 | ||
|
|
6869461124 | ||
|
|
66212d2d16 | ||
|
|
aa8c545089 | ||
|
|
5ac5bada9d | ||
|
|
2a2d3077f4 | ||
|
|
92d5da727e | ||
|
|
ce718eeea2 | ||
|
|
e0ab3d2495 | ||
|
|
a4f8b630ef | ||
|
|
3548b5806c | ||
|
|
95dc94d108 | ||
|
|
48a46969ba | ||
|
|
42421a031a | ||
|
|
583fcc7be8 | ||
|
|
2fc7c49977 | ||
|
|
260027f12e | ||
|
|
5281694d6a | ||
|
|
2c931928d8 | ||
|
|
0867dd68d7 | ||
|
|
f7f92cd19c | ||
|
|
76a2a704dd | ||
|
|
be68ca40f0 | ||
|
|
55be33ac44 | ||
|
|
4c0b89de04 | ||
|
|
0c2f13439f | ||
|
|
c2c7df3b16 | ||
|
|
727808adbc | ||
|
|
0749e35431 | ||
|
|
44a2dd5b37 | ||
|
|
7283da4c87 | ||
|
|
0f5f9e43cc | ||
|
|
d6ed36063d | ||
|
|
b4754dd15c | ||
|
|
58bc77a72a | ||
|
|
f9a7649b0e | ||
|
|
7c89d3a9b8 | ||
|
|
7db99e2195 | ||
|
|
26dab07419 | ||
|
|
9cfbc07b44 | ||
|
|
5ce9e4574d | ||
|
|
78160917eb | ||
|
|
c066176c79 | ||
|
|
de2bc44a8e | ||
|
|
e1ae67c7a2 | ||
|
|
e2f6ac39a5 | ||
|
|
5d3426706f | ||
|
|
246eb45d90 | ||
|
|
54d49a1e02 | ||
|
|
0dda6eafb7 | ||
|
|
f16414f724 | ||
|
|
bb7b3a9034 | ||
|
|
116f7290d0 | ||
|
|
7d3de1fcc5 | ||
|
|
4ac3edb4af | ||
|
|
7c7d008589 | ||
|
|
a9b205e651 | ||
|
|
52f7695c1c | ||
|
|
64cfb61a27 | ||
|
|
0219b56d26 | ||
|
|
53b12a3294 | ||
|
|
5780cd1199 | ||
|
|
3719448331 | ||
|
|
dcf23fe6e1 | ||
|
|
c197bffaf7 | ||
|
|
bc16cf9769 | ||
|
|
3c141d9e1b | ||
|
|
ff55cbf1b2 | ||
|
|
0d0c201fba | ||
|
|
2aa3b3f456 | ||
|
|
b01e15ab73 | ||
|
|
b9716dd537 | ||
|
|
9e8d46d8ab | ||
|
|
3b5ad2112f | ||
|
|
f4dbd00f9d | ||
|
|
cd31a5efab | ||
|
|
3f22a1a4ab | ||
|
|
7a33e30de7 | ||
|
|
26f6aa5de4 | ||
|
|
a4f9fdca7a | ||
|
|
cf70556ce8 | ||
|
|
d9e75f6ada | ||
|
|
9dbe5b78f2 | ||
|
|
5e23f8272f | ||
|
|
c9589d9e3c | ||
|
|
06597c4506 | ||
|
|
efd632083b | ||
|
|
cb570bb85f | ||
|
|
b588e975bc | ||
|
|
f78f3bb686 | ||
|
|
bc7de9a7b6 | ||
|
|
e5c3731236 | ||
|
|
83e0094a56 | ||
|
|
99187b3081 | ||
|
|
aea8513eb0 | ||
|
|
1ec3c5e5d9 | ||
|
|
b9bf414b47 | ||
|
|
ea294e1cd6 | ||
|
|
3335a0e866 | ||
|
|
d66be53fb8 | ||
|
|
57beebfc02 | ||
|
|
374b4ee993 | ||
|
|
7d66708a5e | ||
|
|
883269c20c | ||
|
|
e5ee14536a | ||
|
|
1f7563cc34 | ||
|
|
7fb2170e34 |
22
LICENSE
22
LICENSE
|
|
@ -1 +1,21 @@
|
|||
This mod and its source code is now in public domain. Feel free to do whatever you want with it; make forks, distribute it... whatever I would appreciate it, of course, if you credited me 😊 Thank you!
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 CinemaMod Group
|
||||
|
||||
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
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
|
|||
37
README.md
37
README.md
|
|
@ -1,18 +1,25 @@
|
|||
# WebDisplays for Minecraft 1.12.2
|
||||
This is the WebDisplays mod for Minecraft 1.12.2. I don't have time to maintain it anymore, so I changed the license recently and anybody is welcome to create forks and/or re-distribute it. For more info see [LICENSE](LICENSE).
|
||||
# WebDisplays
|
||||
WebDisplays is a mod for creating and interacting with web browsers in Minecraft. You can create screens in your world and browse the internet.
|
||||
|
||||
### Wiki
|
||||
* The Wiki that details all blocks/items can be found on my website https://montoyo.net/wdwiki/
|
||||
WebDisplays was originally written by montoyo. It is currently maintained by CinemaMod Group.
|
||||
|
||||
### Things before release
|
||||
* Release ready. Targeted release date: 17/02/2018.
|
||||
Discussion: https://discord.gg/rNrh5kW8Ty
|
||||
|
||||
### Delayed things
|
||||
* Plugin API
|
||||
* The Shop
|
||||
* CC Interface, if CC gets updated...
|
||||
* Center camera to screen when using keyboard
|
||||
* minePad management: check GuiContainer.draggedStack for minePad
|
||||
* In-game command to add/remove blacklisted domains
|
||||
* Config: RPMP (Real pixels per Minecraft pixels)
|
||||
* Disable miniserv in solo
|
||||
## Install
|
||||
Download WebDisplays from either:
|
||||
- CurseForge: https://legacy.curseforge.com/minecraft/mc-mods/webdisplays
|
||||
- Modrinth: https://modrinth.com/mod/webdisplays
|
||||
|
||||
**WebDisplays Requires MCEF!** You must install MCEF in order for WebDisplays to work.
|
||||
|
||||
Download MCEF from either:
|
||||
- CurseForge: https://legacy.curseforge.com/minecraft/mc-mods/mcef
|
||||
- Modrinth: https://modrinth.com/mod/mcef
|
||||
|
||||
<img src='https://github.com/CinemaMod/webdisplays/assets/30220598/2acfd365-fa87-4adb-970a-33bb5c79f7ba' width='500'>
|
||||
<img src='https://github.com/CinemaMod/webdisplays/assets/30220598/4e9985a3-d09f-4ab4-8016-37733d4f4a99' width='500'>
|
||||
|
||||
## Wiki
|
||||
[Outdated Wiki from the original creator](https://montoyo.net/wdwiki/index.php?title=Main_Page)
|
||||
|
||||
[Outdated Getting Started](https://montoyo.net/wdwiki/index.php?title=Screen)
|
||||
|
|
|
|||
12
TODO.md
Normal file
12
TODO.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
### Delayed things
|
||||
* Plugin API
|
||||
* Center camera to screen when using keyboard
|
||||
* Allow actual cursor to be used via aiming it at the screen
|
||||
* maybe aim at the focused element instead of the center of the screen, depends on if that information can be extracted
|
||||
* minePad management: check GuiContainer.draggedStack for minePad
|
||||
* In-game command to add/remove blacklisted domains
|
||||
* CC Interface (for when it's actually possible, since the screens are client only currently, but a config option is planned to change that)
|
||||
* Redstone controls (same reason as CC interface)
|
||||
* Potentially redo minisrv logic?
|
||||
* Perhaps hook it up to vanilla networking
|
||||
* Maybe don't use it at all in single player
|
||||
244
build.gradle
244
build.gradle
|
|
@ -1,101 +1,179 @@
|
|||
plugins {
|
||||
id 'dev.architectury.loom' version '0.12.0-SNAPSHOT'
|
||||
id 'io.github.juuxel.loom-quiltflower' version '1.6.0'
|
||||
id 'java'
|
||||
id 'idea'
|
||||
id 'maven-publish'
|
||||
id 'com.github.johnrengelman.shadow' version '8.1.1'
|
||||
id 'net.neoforged.moddev.legacyforge' version '2.0.103'
|
||||
}
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
// Only add ProGuard if building with it
|
||||
def enableProguard = project.hasProperty("enableProguard") && project.enableProguard.toBoolean()
|
||||
if (enableProguard) {
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.guardsquare:proguard-gradle:7.7.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
archivesBaseName = project.archives_base_name
|
||||
version = project.mod_version
|
||||
group = project.maven_group
|
||||
base {
|
||||
archivesName = mod_id
|
||||
}
|
||||
|
||||
group = mod_group_id
|
||||
version = "${minecraft_version}-${mod_version}"
|
||||
|
||||
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||
|
||||
println "Java: ${System.getProperty 'java.version'}"
|
||||
|
||||
repositories {
|
||||
// Add repositories to retrieve artifacts from in here.
|
||||
// You should only use this when depending on other mods because
|
||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
||||
// for more information about repositories.
|
||||
maven { url "https://maven.shedaniel.me/" }
|
||||
maven { url 'https://jitpack.io' }
|
||||
maven {
|
||||
url = "https://maven.parchmentmc.org"
|
||||
mavenCentral()
|
||||
maven { url = "https://libraries.minecraft.net/" }
|
||||
maven { url = "https://cursemaven.com" }
|
||||
maven { url = "https://maven.parchmentmc.org" }
|
||||
maven { url = 'https://mcef-download.cinemamod.com/repositories/releases/' }
|
||||
maven { url = "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/" }
|
||||
maven { url = "https://maven.theillusivec4.top/" }
|
||||
maven { url = "https://repo.lucko.me/" }
|
||||
maven { url = "https://maven.kosmx.dev/" }
|
||||
maven { url = "https://modmaven.dev" }
|
||||
flatDir { dir "libs" }
|
||||
}
|
||||
|
||||
legacyForge {
|
||||
version = "${minecraft_version}-${forge_version}"
|
||||
|
||||
// Access transformer
|
||||
accessTransformers = files("src/main/resources/META-INF/accesstransformer.cfg")
|
||||
|
||||
// Parchment mappings
|
||||
parchment {
|
||||
minecraftVersion = minecraft_version
|
||||
mappingsVersion = mapping_lasting_version
|
||||
}
|
||||
maven {
|
||||
name = "cursemaven"
|
||||
url = "https://www.cursemaven.com"
|
||||
}
|
||||
}
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/webdisplays.accesswidener")
|
||||
}
|
||||
runs {
|
||||
configureEach {
|
||||
systemProperty 'forge.logging.console.level', 'debug'
|
||||
logLevel = org.slf4j.event.Level.DEBUG
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// To change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings loom.layered() {
|
||||
officialMojangMappings()
|
||||
parchment("org.parchmentmc.data:parchment-1.18.2:2022.05.02@zip")
|
||||
}
|
||||
forge "net.minecraftforge:forge:${project.forge_version}"
|
||||
client {
|
||||
client()
|
||||
programArgument "-mixin.config=${mod_id}.mixins.json"
|
||||
systemProperty 'mixin.debug.export', 'true'
|
||||
}
|
||||
|
||||
modImplementation "com.github.Mysticpasta1:mcef-forge:11826a2d11"
|
||||
modImplementation "curse.maven:cloth_config_forge-348521:3546623"
|
||||
// Uncomment the following line to enable the deprecated Fabric API modules.
|
||||
// These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time.
|
||||
server {
|
||||
server()
|
||||
programArgument "-mixin.config=${mod_id}.mixins.json"
|
||||
}
|
||||
|
||||
// modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"
|
||||
}
|
||||
|
||||
loom {
|
||||
forge {
|
||||
mixinConfigs = [
|
||||
"webdisplays.mixin.json"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
// Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
|
||||
it.options.release = 17
|
||||
}
|
||||
|
||||
java {
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this line, sources will not be generated.
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
jar {
|
||||
from("LICENSE") {
|
||||
rename { "${it}_${project.archivesBaseName}"}
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
data {
|
||||
data()
|
||||
programArguments.addAll '--mod', mod_id, '--all',
|
||||
'--output', file('src/generated/resources/').absolutePath,
|
||||
'--existing', file('src/main/resources/').absolutePath
|
||||
}
|
||||
}
|
||||
|
||||
mods {
|
||||
"${mod_id}" {
|
||||
sourceSet sourceSets.main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.main.resources {
|
||||
srcDir 'src/generated/resources'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// MCEF dependency
|
||||
modImplementation("com.cinemamod:mcef-forge:2.1.1-1.20.1") {
|
||||
transitive = false
|
||||
}
|
||||
|
||||
// Optional mods (make sure versions exist)
|
||||
modRuntimeOnly "curse.maven:spark-361579:4738952"
|
||||
modCompileOnly "curse.maven:vivecraft-667903:4794431"
|
||||
modImplementation "software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}"
|
||||
modCompileOnly "top.theillusivec4.curios:curios-forge:${curios_version}:api"
|
||||
modRuntimeOnly "top.theillusivec4.curios:curios-forge:${curios_version}"
|
||||
|
||||
// Mixin Extras
|
||||
compileOnly annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")
|
||||
modImplementation "io.github.llamalad7:mixinextras-forge:0.4.1"
|
||||
}
|
||||
|
||||
tasks.named('jar', Jar) {
|
||||
manifest {
|
||||
attributes([
|
||||
'Specification-Title': mod_name,
|
||||
'Specification-Vendor': mod_authors,
|
||||
'Specification-Version': '1',
|
||||
'Implementation-Title': project.name,
|
||||
'Implementation-Version': project.version,
|
||||
'Implementation-Vendor': mod_authors,
|
||||
'MixinConfigs': "${mod_id}.mixins.json"
|
||||
])
|
||||
}
|
||||
|
||||
// Exclude ProGuard renamed files if ProGuard is used
|
||||
if (enableProguard) {
|
||||
exclude 'META-INF/versions/**'
|
||||
}
|
||||
}
|
||||
|
||||
// Generate sources jar
|
||||
tasks.register('sourcesJar', Jar) {
|
||||
dependsOn classes
|
||||
archiveClassifier = 'sources'
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
// Reobfuscation handling
|
||||
tasks.named('reobfJar') {
|
||||
if (enableProguard) {
|
||||
dependsOn 'proguard'
|
||||
input = file("${buildDir}/libs/${mod_id}-${minecraft_version}-${mod_version}-proguard.jar")
|
||||
} else {
|
||||
dependsOn 'jar'
|
||||
input = tasks.jar.archiveFile.get().asFile
|
||||
}
|
||||
}
|
||||
|
||||
// ProGuard configuration (if enabled)
|
||||
if (enableProguard) {
|
||||
tasks.register('proguard', proguard.gradle.ProGuardTask) {
|
||||
dependsOn tasks.jar
|
||||
configuration 'proguard.pro'
|
||||
|
||||
libraryjars "${System.getProperty('java.home')}/jmods"
|
||||
|
||||
def inputJar = tasks.jar.archiveFile.get().asFile
|
||||
injars inputJar
|
||||
outjars "${buildDir}/libs/${mod_id}-${minecraft_version}-${mod_version}-proguard.jar"
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifactId = mod_id
|
||||
artifact reobfJar
|
||||
artifact sourcesJar
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
// Notice: This block does NOT have the same function as the block in the top level.
|
||||
// The repositories here will be used for publishing your artifact, not for
|
||||
// retrieving dependencies.
|
||||
maven {
|
||||
name = "local"
|
||||
url = layout.buildDirectory.dir("repo")
|
||||
}
|
||||
}
|
||||
}
|
||||
1
cursors.piskel
Normal file
1
cursors.piskel
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,17 +1,36 @@
|
|||
# Done to increase the memory available to gradle.
|
||||
# Gradle settings
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
loom.platform=forge
|
||||
org.gradle.daemon=false
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/develop
|
||||
minecraft_version=1.18.2
|
||||
yarn_mappings=1.18.2+build.3
|
||||
loader_version=0.14.8
|
||||
# ProGuard
|
||||
enableProguard=false
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.0
|
||||
maven_group = net.montoyo.wd
|
||||
archives_base_name = webdisplays
|
||||
# Mod properties
|
||||
mod_id=webdisplays
|
||||
mod_name=WebDisplays
|
||||
mod_version=2.0.3
|
||||
mod_group_id=com.cinemamod
|
||||
mod_authors=CinemaMod Group
|
||||
mod_description=Web browser displays for Minecraft
|
||||
mod_license=All Rights Reserved
|
||||
mod_credits=CinemaMod Group
|
||||
|
||||
# Dependencies
|
||||
forge_version=1.18.2-40.1.52
|
||||
# Minecraft/Forge versions
|
||||
minecraft_version=1.20.1
|
||||
forge_version=47.3.4
|
||||
minecraft_version_range=[1.20.1,1.21)
|
||||
forge_version_range=[47,)
|
||||
loader_version_range=[47,)
|
||||
|
||||
# Parchment mappings
|
||||
mapping_channel=parchment
|
||||
mapping_version=2023.09.03-1.20.1
|
||||
mapping_lasting_version=2023.09.03
|
||||
|
||||
# Other mod versions
|
||||
jei_version=15.20.0.112
|
||||
player_anim_version=1.0.2-rc1+1.20
|
||||
geckolib_version=4.2.1
|
||||
curios_version=5.5.0+1.20.1
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
|
||||
|
|
|
|||
|
|
@ -1,23 +1,11 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
pluginManagement {
|
||||
repositories {
|
||||
//jcenter() // jcenter will be stopped in 2022
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
maven { url "https://maven.architectury.dev/" }
|
||||
maven { url "https://files.minecraftforge.net/maven/" }
|
||||
maven {
|
||||
name = 'Cotton'
|
||||
url = 'https://server.bbkr.space/artifactory/libs-release/'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
gradlePluginPortal()
|
||||
maven { url = 'https://maven.neoforged.net/releases' }
|
||||
maven { url = 'https://maven.parchmentmc.org' } // Add this line
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
|
||||
}
|
||||
|
|
@ -4,40 +4,59 @@
|
|||
|
||||
package net.montoyo.wd;
|
||||
|
||||
import com.cinemamod.mcef.MCEF;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.minecraftforge.server.ServerLifecycleHooks;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.core.HasAdvancement;
|
||||
import net.montoyo.wd.core.JSServerRequest;
|
||||
import net.montoyo.wd.data.GuiData;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
import net.montoyo.wd.utilities.math.Vector2i;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.data.Rotation;
|
||||
import net.montoyo.wd.utilities.serialization.NameUUIDPair;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import static net.minecraftforge.api.distmarker.Dist.CLIENT;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SharedProxy {
|
||||
public void preInit() {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
MCEF.scheduleForInit((cef) -> onCefInit());
|
||||
}
|
||||
|
||||
public void postInit() {
|
||||
}
|
||||
|
||||
public void onCefInit() {
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public Level getWorld(ResourceKey<Level> dim) {
|
||||
return getServer().getLevel(dim);
|
||||
}
|
||||
|
||||
public BlockGetter getWorld(NetworkEvent.Context context) {
|
||||
if (context.getSender() != null) return context.getSender().level();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void enqueue(Runnable r) {
|
||||
ServerLifecycleHooks.getCurrentServer().addTickable(r);
|
||||
}
|
||||
|
|
@ -46,7 +65,7 @@ public class SharedProxy {
|
|||
Log.error("Called SharedProxy.displayGui() on server side...");
|
||||
}
|
||||
|
||||
public void trackScreen(TileEntityScreen tes, boolean track) {
|
||||
public void trackScreen(ScreenBlockEntity tes, boolean track) {
|
||||
}
|
||||
|
||||
public void onAutocompleteResult(NameUUIDPair pairs[]) {
|
||||
|
|
@ -65,11 +84,11 @@ public class SharedProxy {
|
|||
public void screenUpdateAutoVolumeInGui(Vector3i pos, BlockSide side, boolean av) {
|
||||
}
|
||||
|
||||
public void displaySetPadURLGui(String padURL) {
|
||||
public void displaySetPadURLGui(ItemStack is, String padURL) {
|
||||
Log.error("Called SharedProxy.displaySetPadURLGui() on server side...");
|
||||
}
|
||||
|
||||
public void openMinePadGui(int padId) {
|
||||
public void openMinePadGui(UUID padId) {
|
||||
Log.error("Called SharedProxy.openMinePadGui() on server side...");
|
||||
}
|
||||
|
||||
|
|
@ -110,4 +129,20 @@ public class SharedProxy {
|
|||
return false;
|
||||
}
|
||||
|
||||
public double distanceTo(ScreenBlockEntity tes, Vec3 position) {
|
||||
double dist = Double.POSITIVE_INFINITY;
|
||||
for (int i = 0; i < tes.screenCount(); i++) {
|
||||
ScreenData scrn = tes.getScreen(i);
|
||||
|
||||
Vector3d pos = new Vector3d(
|
||||
scrn.side.right.x * scrn.size.x / 2d + scrn.size.y * scrn.side.up.x / 2d,
|
||||
scrn.side.right.y * scrn.size.x / 2d + scrn.size.y * scrn.side.up.y / 2d,
|
||||
scrn.side.right.z * scrn.size.x / 2d + scrn.size.y * scrn.side.up.z / 2d
|
||||
).add(tes.getBlockPos().getX(), tes.getBlockPos().getY(), tes.getBlockPos().getZ());
|
||||
|
||||
double dist2 = position.distanceToSqr(pos.x, pos.y, pos.z);
|
||||
dist = Math.min(dist, dist2);
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,11 @@
|
|||
package net.montoyo.wd;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import me.shedaniel.autoconfig.AutoConfig;
|
||||
import me.shedaniel.autoconfig.ConfigHolder;
|
||||
import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
|
@ -20,59 +18,55 @@ import net.minecraft.sounds.SoundEvents;
|
|||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.client.event.ClientChatEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.event.AttachCapabilitiesEvent;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.ServerChatEvent;
|
||||
import net.minecraftforge.event.entity.item.ItemTossEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.wd.block.WDBlockContainer;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.client.gui.controls.*;
|
||||
import net.montoyo.wd.config.ModConfig;
|
||||
import net.montoyo.wd.client.gui.camera.KeyboardCamera;
|
||||
import net.montoyo.wd.config.ClientConfig;
|
||||
import net.montoyo.wd.config.CommonConfig;
|
||||
import net.montoyo.wd.controls.ScreenControlRegistry;
|
||||
import net.montoyo.wd.core.*;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.init.ItemInit;
|
||||
import net.montoyo.wd.init.TileInit;
|
||||
import net.montoyo.wd.miniserv.server.Server;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.client.CMessageServerInfo;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.client_bound.S2CMessageServerInfo;
|
||||
import net.montoyo.wd.registry.BlockRegistry;
|
||||
import net.montoyo.wd.registry.ItemRegistry;
|
||||
import net.montoyo.wd.registry.TileRegistry;
|
||||
import net.montoyo.wd.registry.WDTabs;
|
||||
import net.montoyo.wd.utilities.DistSafety;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import net.montoyo.wd.utilities.serialization.Util;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@Mod("webdisplays")
|
||||
public class WebDisplays {
|
||||
|
||||
public static final String MOD_VERSION = "1.1";
|
||||
|
||||
public static WebDisplays INSTANCE;
|
||||
|
||||
public static SharedProxy PROXY = DistExecutor.<SharedProxy>runForDist(() -> ClientProxy::new, () -> SharedProxy::new);
|
||||
|
||||
public static WDCreativeTab CREATIVE_TAB;
|
||||
public static SharedProxy PROXY = null;
|
||||
|
||||
public static final ResourceLocation ADV_PAD_BREAK = new ResourceLocation("webdisplays", "webdisplays/pad_break");
|
||||
public static final String BLACKLIST_URL = "mod://webdisplays/blacklisted.html";
|
||||
public static final Gson GSON = new Gson();
|
||||
|
|
@ -94,54 +88,40 @@ public class WebDisplays {
|
|||
|
||||
//Config
|
||||
public static final double PAD_RATIO = 59.0 / 30.0;
|
||||
public String homePage;
|
||||
public double padResX;
|
||||
public double padResY;
|
||||
private int lastPadId = 0;
|
||||
public boolean doHardRecipe;
|
||||
private boolean hasOC;
|
||||
private boolean hasCC;
|
||||
private List<String> blacklist;
|
||||
public boolean disableOwnershipThief;
|
||||
public double unloadDistance2;
|
||||
public double loadDistance2;
|
||||
public int maxResX;
|
||||
public int maxResY;
|
||||
public int maxScreenX;
|
||||
public int maxScreenY;
|
||||
public int miniservPort;
|
||||
public long miniservQuota;
|
||||
public boolean enableSoundDistance;
|
||||
public float ytVolume;
|
||||
public float avDist100;
|
||||
public float avDist0;
|
||||
|
||||
// mod detection
|
||||
private boolean hasOC;
|
||||
private boolean hasCC;
|
||||
|
||||
public WebDisplays() {
|
||||
INSTANCE = this;
|
||||
AutoConfig.register(ModConfig.class, Toml4jConfigSerializer::new);
|
||||
ConfigHolder<ModConfig> configHolder = AutoConfig.getConfigHolder(ModConfig.class);
|
||||
ModConfig config = configHolder.getConfig();
|
||||
configHolder.save();
|
||||
|
||||
this.blacklist = config.main.blacklist;
|
||||
doHardRecipe = config.main.hardRecipes;
|
||||
this.homePage = config.main.homepage;
|
||||
disableOwnershipThief = config.main.disableOwnershipThief;
|
||||
unloadDistance2 = config.client.unloadDistance * config.client.unloadDistance;
|
||||
loadDistance2 = config.client.loadDistance * config.client.loadDistance;
|
||||
this.maxResX = config.main.maxResolutionX;
|
||||
this.maxResY = config.main.maxResolutionY;
|
||||
this.miniservPort = config.main.miniservPort;
|
||||
this.miniservQuota = config.main.miniservQuota * 1024L;
|
||||
this.maxScreenX = config.main.maxScreenSizeX;
|
||||
this.maxScreenY = config.main.maxScreenSizeY;
|
||||
enableSoundDistance = config.client.autoVolumeControl.enableAutoVolume;
|
||||
this.ytVolume = (float) config.client.autoVolumeControl.ytVolume;
|
||||
avDist100 = (float) config.client.autoVolumeControl.dist100;
|
||||
avDist0 = (float) config.client.autoVolumeControl.dist0;
|
||||
|
||||
CREATIVE_TAB = new WDCreativeTab();
|
||||
|
||||
if(FMLEnvironment.dist.isClient()) {
|
||||
PROXY = DistSafety.createProxy();
|
||||
} else {
|
||||
PROXY = new SharedProxy();
|
||||
}
|
||||
|
||||
if (FMLEnvironment.dist.isClient()) {
|
||||
// proxies are annoying, so from now on, I'mma be just registering stuff in here
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(ClientProxy::onKeybindRegistry);
|
||||
MinecraftForge.EVENT_BUS.addListener(ClientProxy::onDrawSelection);
|
||||
MinecraftForge.EVENT_BUS.addListener(KeyboardCamera::updateCamera);
|
||||
MinecraftForge.EVENT_BUS.addListener(KeyboardCamera::gameTick);
|
||||
ClientConfig.init();
|
||||
}
|
||||
|
||||
CommonConfig.init();
|
||||
|
||||
//Criterions
|
||||
criterionPadBreak = new Criterion("pad_break");
|
||||
criterionUpgradeScreen = new Criterion("upgrade_screen");
|
||||
|
|
@ -149,23 +129,19 @@ public class WebDisplays {
|
|||
criterionKeyboardCat = new Criterion("keyboard_cat");
|
||||
registerTrigger(criterionPadBreak, criterionUpgradeScreen, criterionLinkPeripheral, criterionKeyboardCat);
|
||||
|
||||
//Read configuration
|
||||
padResY = config.main.padHeight;
|
||||
padResX = padResY * PAD_RATIO;
|
||||
|
||||
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
bus.addListener(Messages::registryNetworkPackets);
|
||||
BlockInit.init(bus);
|
||||
ItemInit.init(bus);
|
||||
ItemInit.registerUpgrade();
|
||||
ItemInit.registerComponents();
|
||||
TileInit.init(bus);
|
||||
|
||||
WDNetworkRegistry.init();
|
||||
SOUNDS.register(bus);
|
||||
onRegisterSounds();
|
||||
WDTabs.init(bus);
|
||||
BlockRegistry.init(bus);
|
||||
ItemRegistry.init(bus);
|
||||
TileRegistry.init(bus);
|
||||
|
||||
PROXY.preInit();
|
||||
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
|
||||
|
||||
//Other things
|
||||
PROXY.init();
|
||||
|
||||
|
|
@ -182,6 +158,10 @@ public class WebDisplays {
|
|||
t.printStackTrace();
|
||||
}
|
||||
} */
|
||||
|
||||
if (!FMLEnvironment.production) {
|
||||
ScreenControlRegistry.init();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
@ -191,23 +171,24 @@ public class WebDisplays {
|
|||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRegisterSounds(RegistryEvent.Register<SoundEvent> ev) {
|
||||
soundTyping = registerSound(ev, "keyboardType");
|
||||
soundUpgradeAdd = registerSound(ev, "upgradeAdd");
|
||||
soundUpgradeDel = registerSound(ev, "upgradeDel");
|
||||
soundScreenCfg = registerSound(ev, "screencfgOpen");
|
||||
soundServer = registerSound(ev, "server");
|
||||
soundIronic = registerSound(ev, "ironic");
|
||||
public void onRegisterSounds() {
|
||||
soundTyping = registerSound("keyboard_type");
|
||||
soundUpgradeAdd = registerSound("upgrade_add");
|
||||
soundUpgradeDel = registerSound("upgrade_del");
|
||||
soundScreenCfg = registerSound("screencfg_open");
|
||||
soundServer = registerSound("server");
|
||||
soundIronic = registerSound("ironic");
|
||||
}
|
||||
|
||||
ArrayList<ResourceKey<Level>> serverStartedDimensions = new ArrayList<>();
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldLoad(WorldEvent.Load ev) {
|
||||
if (ev.getWorld() instanceof Level level) {
|
||||
if (ev.getWorld().isClientSide() || level.dimension() != Level.OVERWORLD)
|
||||
public void onWorldLoad(LevelEvent.Load ev) {
|
||||
if (ev.getLevel() instanceof Level level) {
|
||||
if (ev.getLevel().isClientSide() || level.dimension() != Level.OVERWORLD)
|
||||
return;
|
||||
|
||||
File worldDir = Objects.requireNonNull(ev.getWorld().getServer()).getServerDirectory();
|
||||
File worldDir = Objects.requireNonNull(ev.getLevel().getServer()).getServerDirectory();
|
||||
File f = new File(worldDir, "wd_next.txt");
|
||||
|
||||
if (f.exists()) {
|
||||
|
|
@ -231,29 +212,34 @@ public class WebDisplays {
|
|||
|
||||
if (miniservPort != 0) {
|
||||
Server sv = Server.getInstance();
|
||||
sv.setPort(miniservPort);
|
||||
sv.setDirectory(new File(worldDir, "wd_filehost"));
|
||||
sv.start();
|
||||
|
||||
if(!serverStartedDimensions.contains(level.dimension())) {
|
||||
sv.setPort(miniservPort);
|
||||
sv.setDirectory(new File(worldDir, "wd_filehost"));
|
||||
sv.start();
|
||||
serverStartedDimensions.add(level.dimension());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldLeave(WorldEvent.Unload ev) throws IOException {
|
||||
if(ev.getWorld() instanceof Level level) {
|
||||
if (ev.getWorld().isClientSide() || level.dimension() != Level.OVERWORLD)
|
||||
public void onWorldLeave(LevelEvent.Unload ev) throws IOException {
|
||||
if(ev.getLevel() instanceof Level level) {
|
||||
if (ev.getLevel().isClientSide() || level.dimension() != Level.OVERWORLD)
|
||||
return;
|
||||
Server sw = Server.getInstance();
|
||||
sw.stopServer();
|
||||
serverStartedDimensions.remove(level.dimension());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onWorldSave(WorldEvent.Save ev) {
|
||||
if(ev.getWorld() instanceof Level level) {
|
||||
if (ev.getWorld().isClientSide() || level.dimension() != Level.OVERWORLD)
|
||||
public void onWorldSave(LevelEvent.Save ev) {
|
||||
if(ev.getLevel() instanceof Level level) {
|
||||
if (ev.getLevel().isClientSide() || level.dimension() != Level.OVERWORLD)
|
||||
return;
|
||||
File f = new File(Objects.requireNonNull(ev.getWorld().getServer()).getServerDirectory(), "wd_next.txt");
|
||||
File f = new File(Objects.requireNonNull(ev.getLevel().getServer()).getServerDirectory(), "wd_next.txt");
|
||||
|
||||
try {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
||||
|
|
@ -267,10 +253,10 @@ public class WebDisplays {
|
|||
|
||||
@SubscribeEvent
|
||||
public void onToss(ItemTossEvent ev) {
|
||||
if(!ev.getEntityItem().getLevel().isClientSide) {
|
||||
ItemStack is = ev.getEntityItem().getItem();
|
||||
if(!ev.getEntity().level().isClientSide) {
|
||||
ItemStack is = ev.getEntity().getItem();
|
||||
|
||||
if(is.getItem() == ItemInit.itemMinePad.get()) {
|
||||
if(is.getItem() == ItemRegistry.MINEPAD.get()) {
|
||||
CompoundTag tag = is.getTag();
|
||||
|
||||
if(tag == null) {
|
||||
|
|
@ -288,12 +274,12 @@ public class WebDisplays {
|
|||
|
||||
@SubscribeEvent
|
||||
public void onPlayerCraft(PlayerEvent.ItemCraftedEvent ev) {
|
||||
if(doHardRecipe && ev.getCrafting().getItem() == ItemInit.itemCraftComp.get() && (CraftComponent.EXTENSION_CARD.makeItemStack().is(ev.getCrafting().getItem()))) {
|
||||
if((ev.getPlayer() instanceof ServerPlayer && !hasPlayerAdvancement((ServerPlayer) ev.getPlayer(), ADV_PAD_BREAK)) || PROXY.hasClientPlayerAdvancement(ADV_PAD_BREAK) != HasAdvancement.YES) {
|
||||
ev.getCrafting().setDamageValue(CraftComponent.BAD_EXTENSION_CARD.ordinal());
|
||||
if(CommonConfig.hardRecipes && ItemRegistry.isCompCraftItem(ev.getCrafting().getItem()) && (CraftComponent.EXTCARD.makeItemStack().is(ev.getCrafting().getItem()))) {
|
||||
if((ev.getEntity() instanceof ServerPlayer && !hasPlayerAdvancement((ServerPlayer) ev.getEntity(), ADV_PAD_BREAK)) || PROXY.hasClientPlayerAdvancement(ADV_PAD_BREAK) != HasAdvancement.YES) {
|
||||
ev.getCrafting().setDamageValue(CraftComponent.BADEXTCARD.ordinal());
|
||||
|
||||
if(!ev.getPlayer().getLevel().isClientSide)
|
||||
ev.getPlayer().getLevel().playSound(null, ev.getPlayer().getX(), ev.getPlayer().getY(), ev.getPlayer().getZ(), SoundEvents.ITEM_BREAK, SoundSource.MASTER, 1.0f, 1.0f);
|
||||
if(!ev.getEntity().level().isClientSide)
|
||||
ev.getEntity().level().playSound(null, ev.getEntity().getX(), ev.getEntity().getY(), ev.getEntity().getZ(), SoundEvents.ITEM_BREAK, SoundSource.MASTER, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -305,35 +291,35 @@ public class WebDisplays {
|
|||
|
||||
@SubscribeEvent
|
||||
public void onLogIn(PlayerEvent.PlayerLoggedInEvent ev) {
|
||||
if(!ev.getPlayer().getLevel().isClientSide && ev.getPlayer() instanceof ServerPlayer) {
|
||||
IWDDCapability cap =
|
||||
ev.getPlayer().getCapability(WDDCapability.Provider.cap, null).orElseThrow(RuntimeException::new);
|
||||
if (!CommonConfig.joinMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(cap == null)
|
||||
Log.warning("Player %s (%s) has null IWDDCapability!", ev.getPlayer().getName(), ev.getPlayer().getGameProfile().getId().toString());
|
||||
else if(cap.isFirstRun()) {
|
||||
Util.toast(ev.getPlayer(), ChatFormatting.LIGHT_PURPLE, "welcome1");
|
||||
Util.toast(ev.getPlayer(), ChatFormatting.LIGHT_PURPLE, "welcome2");
|
||||
Util.toast(ev.getPlayer(), ChatFormatting.LIGHT_PURPLE, "welcome3");
|
||||
if(!ev.getEntity().level().isClientSide && ev.getEntity() instanceof ServerPlayer) {
|
||||
IWDDCapability cap = ev.getEntity().getCapability(WDDCapability.Provider.cap, null).orElseThrow(RuntimeException::new);
|
||||
|
||||
if(cap.isFirstRun()) {
|
||||
Util.toast(ev.getEntity(), ChatFormatting.LIGHT_PURPLE, "welcome1");
|
||||
Util.toast(ev.getEntity(), ChatFormatting.LIGHT_PURPLE, "welcome2");
|
||||
Util.toast(ev.getEntity(), ChatFormatting.LIGHT_PURPLE, "welcome3");
|
||||
|
||||
cap.clearFirstRun();
|
||||
}
|
||||
|
||||
PacketDistributor.PacketTarget packetDistrutor = PacketDistributor.PLAYER
|
||||
.with(
|
||||
() ->
|
||||
(ServerPlayer) ev.getPlayer());
|
||||
PacketDistributor.PacketTarget packetDistrutor = PacketDistributor.PLAYER.with(
|
||||
() -> (ServerPlayer) ev.getEntity()
|
||||
);
|
||||
|
||||
CMessageServerInfo message = new CMessageServerInfo(miniservPort);
|
||||
S2CMessageServerInfo message = new S2CMessageServerInfo(miniservPort);
|
||||
|
||||
Messages.INSTANCE.send(packetDistrutor, message);
|
||||
WDNetworkRegistry.INSTANCE.send(packetDistrutor, message);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onLogOut(PlayerEvent.PlayerLoggedOutEvent ev) {
|
||||
if(!ev.getPlayer().getLevel().isClientSide)
|
||||
Server.getInstance().getClientManager().revokeClientKey(ev.getPlayer().getGameProfile().getId());
|
||||
if(!ev.getEntity().level().isClientSide)
|
||||
Server.getInstance().getClientManager().revokeClientKey(ev.getEntity().getGameProfile().getId());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
@ -345,7 +331,7 @@ public class WebDisplays {
|
|||
@SubscribeEvent
|
||||
public void onPlayerClone(PlayerEvent.Clone ev) {
|
||||
IWDDCapability src = ev.getOriginal().getCapability(WDDCapability.Provider.cap, null).orElse(new WDDCapability.Factory().call());
|
||||
IWDDCapability dst = ev.getPlayer().getCapability(WDDCapability.Provider.cap, null).orElse(new WDDCapability.Factory().call());
|
||||
IWDDCapability dst = ev.getEntity().getCapability(WDDCapability.Provider.cap, null).orElse(new WDDCapability.Factory().call());
|
||||
|
||||
if(src == null) {
|
||||
Log.error("src is null");
|
||||
|
|
@ -362,7 +348,7 @@ public class WebDisplays {
|
|||
|
||||
@SubscribeEvent
|
||||
public void onServerChat(ServerChatEvent ev) {
|
||||
String msg = ev.getMessage().trim().replaceAll("\\s+", " ").toLowerCase();
|
||||
String msg = ev.getMessage().getString().replaceAll("\\s+", " ").toLowerCase();
|
||||
StringBuilder sb = new StringBuilder(msg.length());
|
||||
for(int i = 0; i < msg.length(); i++) {
|
||||
char chr = msg.charAt(i);
|
||||
|
|
@ -373,7 +359,7 @@ public class WebDisplays {
|
|||
|
||||
if(sb.toString().equals("ironic he could save others from death but not himself")) {
|
||||
Player ply = ev.getPlayer();
|
||||
ply.getLevel().playSound(null, ply.getX(), ply.getY(), ply.getZ(), soundIronic, SoundSource.PLAYERS, 1.0f, 1.0f);
|
||||
ply.level().playSound(null, ply.getX(), ply.getY(), ply.getZ(), soundIronic, SoundSource.PLAYERS, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -396,12 +382,13 @@ public class WebDisplays {
|
|||
return new WebDisplays().lastPadId++;
|
||||
}
|
||||
|
||||
private static SoundEvent registerSound(RegistryEvent.Register<SoundEvent> ev, String resName) {
|
||||
ResourceLocation resLoc = new ResourceLocation("webdisplays", resName);
|
||||
SoundEvent ret = new SoundEvent(resLoc);
|
||||
ret.setRegistryName(resLoc);
|
||||
public static DeferredRegister<SoundEvent> SOUNDS = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, "webdisplays");
|
||||
|
||||
ev.getRegistry().register(ret);
|
||||
private static SoundEvent registerSound(String resName) {
|
||||
ResourceLocation resLoc = new ResourceLocation("webdisplays", resName);
|
||||
SoundEvent ret = SoundEvent.createVariableRangeEvent(resLoc);
|
||||
|
||||
SOUNDS.register(resName, () -> ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -421,7 +408,9 @@ public class WebDisplays {
|
|||
public static boolean isSiteBlacklisted(String url) {
|
||||
try {
|
||||
URL url2 = new URL(Util.addProtocol(url));
|
||||
return new ModConfig.Main().blacklist.stream().anyMatch(str -> str.equalsIgnoreCase(url2.getHost()));
|
||||
for (String str : CommonConfig.Browser.blacklist)
|
||||
if (str.equalsIgnoreCase(url2.getHost())) return true;
|
||||
return false;
|
||||
} catch(MalformedURLException ex) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -430,6 +419,5 @@ public class WebDisplays {
|
|||
public static String applyBlacklist(String url) {
|
||||
return isSiteBlacklisted(url) ? BLACKLIST_URL : url;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,279 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.TileEntityInterfaceBase;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityPeripheralBase;
|
||||
import net.montoyo.wd.entity.TileEntityServer;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.client.CMessageCloseGui;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlockKeyboardLeft extends BlockPeripheral {
|
||||
|
||||
public static final EnumProperty<DefaultPeripheral> type = EnumProperty.create("type", DefaultPeripheral.class);
|
||||
public static final DirectionProperty facing = DirectionProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST);
|
||||
private static final Property<?>[] properties = new Property<?>[] { type, facing };
|
||||
|
||||
public BlockKeyboardLeft() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties);
|
||||
}
|
||||
|
||||
// @Nullable TODO: Fix
|
||||
// @Override
|
||||
// public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
// Direction rot = Direction.fromYRot(placer.getYHeadRot());
|
||||
// return defaultBlockState().setValue(type, DefaultPeripheral.fromMetadata(meta)).setValue(facing, rot);
|
||||
//
|
||||
//
|
||||
// return getStateForPlacement(context);
|
||||
// }
|
||||
//
|
||||
// public BlockState getStateForPlacement(@Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction nocare, float hitX,
|
||||
// float hitY, float hitZ, int meta, @Nonnull LivingEntity placer, InteractionHand hand) {
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
// for(DefaultPeripheral dp : DefaultPeripheral.values())
|
||||
// list.add(new ItemStack(getItem(), 1, dp.toMetadata(0)));
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// @Nonnull
|
||||
// public IBlockState getStateFromMeta(int meta) {
|
||||
// DefaultPeripheral dp = DefaultPeripheral.fromMetadata(meta);
|
||||
// IBlockState state = getDefaultState().withProperty(type, dp);
|
||||
//
|
||||
// if(dp.hasFacing())
|
||||
// state = state.withProperty(facing, (meta >> 2) & 3);
|
||||
//
|
||||
// return state;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getMetaFromState(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(state.getValue(facing));
|
||||
// }
|
||||
|
||||
|
||||
/*@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
BlockEntityType.BlockEntitySupplier<? extends BlockEntity> cls = state.getValue(type).getTEClass();
|
||||
if(cls == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
return cls.create(pos, state);
|
||||
} catch(Throwable t) {
|
||||
Log.errorEx("Couldn't instantiate peripheral TileEntity:", t);
|
||||
}
|
||||
|
||||
return null;
|
||||
} */
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int damageDropped(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(0);
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if(player.isShiftKeyDown())
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if(player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityKeyboard)
|
||||
return ((TileEntityKeyboard) te).onRightClick(player, hand);
|
||||
else if(te instanceof TileEntityServer) {
|
||||
((TileEntityServer) te).onPlayerRightClick(player);
|
||||
return InteractionResult.PASS;
|
||||
} else
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isFullCube(IBlockState state) { TODO: FIx.
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isFullBlock(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isOpaqueCube(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return state.getValue(type) == DefaultPeripheral.KEYBOARD ? BlockKeyboardRight.KEYBOARD_AABB : Shapes.block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
|
||||
if(state.getValue(type) == DefaultPeripheral.KEYBOARD) {
|
||||
//Keyboard special treatment
|
||||
Direction f = state.getValue(facing);
|
||||
Vec3i dir = f.getClockWise().getNormal();
|
||||
BlockPos left = pos.offset(dir);
|
||||
BlockPos right = pos.subtract(dir);
|
||||
|
||||
if(!world.isEmptyBlock(pos.below()) && BlockKeyboardRight.checkNeighborhood(world, pos, null)) {
|
||||
if(world.isEmptyBlock(right) && !world.isEmptyBlock(right.below()) && BlockKeyboardRight.checkNeighborhood(world, right, pos)) {
|
||||
world.setBlock(right, BlockInit.blockKbRight.get().defaultBlockState().setValue(BlockKeyboardRight.facing, f), 3);
|
||||
world.setBlock(pos.offset(f.getNormal()), BlockInit.blockKeyBoard.get().defaultBlockState().setValue(BlockKeyboardRight.facing, f), 3);
|
||||
return;
|
||||
} else if(world.isEmptyBlock(left) && !world.isEmptyBlock(left.below()) && BlockKeyboardRight.checkNeighborhood(world, left, pos)) {
|
||||
world.setBlock(left, state, 3);
|
||||
world.setBlock(pos.offset(f.getNormal()), BlockInit.blockKeyBoard.get().defaultBlockState().setValue(BlockKeyboardRight.facing, f), 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Not good; remove this shit...
|
||||
world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
|
||||
if(!(placer instanceof Player) || !((Player) placer).isCreative()) {
|
||||
// dropBlockAsItem(world, pos, state, 0); TODO: Loottable?
|
||||
}
|
||||
} else if(placer instanceof Player) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityServer)
|
||||
((TileEntityServer) te).setOwner((Player) placer);
|
||||
else if(te instanceof TileEntityInterfaceBase)
|
||||
((TileEntityInterfaceBase) te).setOwner((Player) placer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPistonPushReaction(BlockState state) {
|
||||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
private void removeRightPiece(Level world, BlockPos pos) {
|
||||
for(Direction nf: Direction.Plane.HORIZONTAL) {
|
||||
BlockPos np = pos.offset(nf.getNormal());
|
||||
|
||||
if(world.getBlockState(np).getBlock() instanceof BlockKeyboardRight) {
|
||||
world.setBlock(np, Blocks.AIR.defaultBlockState(), 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighborType, BlockPos neighbor, boolean isMoving) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if(te != null && te instanceof TileEntityPeripheralBase)
|
||||
((TileEntityPeripheralBase) te).onNeighborChange(neighborType, neighbor);
|
||||
|
||||
if(world.isClientSide || state.getValue(type) != DefaultPeripheral.KEYBOARD)
|
||||
return;
|
||||
|
||||
if(neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ() && world.isEmptyBlock(neighbor)) {
|
||||
removeRightPiece(world, pos);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||
// dropBlockAsItem(world, pos, state, 0); //TODO Loottable
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||
if(!world.isClientSide) {
|
||||
if(state.getBlock() == this && state.getValue(type) == DefaultPeripheral.KEYBOARD)
|
||||
removeRightPiece(world, pos);
|
||||
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockExploded(BlockState state, Level level, BlockPos pos, Explosion explosion) {
|
||||
playerDestroy(level, null, pos, level.getBlockState(pos), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
if(!world.isClientSide && world.getBlockState(pos).getValue(type) == DefaultPeripheral.KEYBOARD) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
|
||||
if(rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te != null && te instanceof TileEntityKeyboard)
|
||||
((TileEntityKeyboard) te).simulateCat(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PacketDistributor.TargetPoint point(Level world, BlockPos bp) {
|
||||
return new PacketDistributor.TargetPoint(bp.getX(), bp.getY(), bp.getZ(), 64.0, world.dimension());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.core.IPeripheral;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.init.TileInit;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.CallbackI;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BlockKeyboardRight extends Block implements IPeripheral {
|
||||
|
||||
public static final DirectionProperty facing = BlockStateProperties.HORIZONTAL_FACING;
|
||||
public static final VoxelShape KEYBOARD_AABB = Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0 / 16.0, 1.0);
|
||||
|
||||
public BlockKeyboardRight() {
|
||||
super(Properties.of(Material.STONE)
|
||||
.strength(1.5f, 10.f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(facing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionShapeFullBlock(BlockState state, BlockGetter level, BlockPos pos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return KEYBOARD_AABB;
|
||||
}
|
||||
|
||||
private TileEntityKeyboard getTileEntity(Level world, BlockPos pos) {
|
||||
for (Direction nf : Direction.Plane.HORIZONTAL) {
|
||||
BlockPos np = pos.offset(nf.getNormal());
|
||||
BlockState ns = world.getBlockState(np);
|
||||
|
||||
if(ns.getBlock() instanceof BlockPeripheral && ns.getValue(BlockPeripheral.type) == DefaultPeripheral.KEYBOARD) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (te instanceof TileEntityKeyboard)
|
||||
return (TileEntityKeyboard) te;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect(Level world, BlockPos pos, BlockState state, Vector3i scrPos, BlockSide scrSide) {
|
||||
TileEntityKeyboard keyboard = getTileEntity(world, pos);
|
||||
return keyboard != null && keyboard.connect(world, pos, state, scrPos, scrSide);
|
||||
}
|
||||
|
||||
public static boolean checkNeighborhood(Level world, BlockPos bp, BlockPos ignore) {
|
||||
for (Direction neighbor : Direction.Plane.HORIZONTAL) {
|
||||
BlockPos np = bp.offset(neighbor.getNormal());
|
||||
|
||||
if (ignore == null || !np.equals(ignore)) {
|
||||
BlockState state = world.getBlockState(np);
|
||||
|
||||
if (state.getBlock() instanceof BlockPeripheral) {
|
||||
if (state.getValue(BlockPeripheral.type) == DefaultPeripheral.KEYBOARD)
|
||||
return false;
|
||||
} else if (state.getBlock() instanceof BlockKeyboardRight)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeLeftPiece(Level world, BlockPos pos, boolean dropItem) {
|
||||
for (Direction nf : Direction.Plane.HORIZONTAL) {
|
||||
BlockPos np = pos.offset(nf.getNormal());
|
||||
BlockState ns = world.getBlockState(np);
|
||||
|
||||
if (ns.getBlock() instanceof BlockPeripheral && ns.getValue(BlockPeripheral.type) == DefaultPeripheral.KEYBOARD) {
|
||||
/* if(dropItem)
|
||||
if(world instanceof ServerLevel serverWorld) {
|
||||
// ns.getBlock().getDrops(ns, serverWorld, np,0);
|
||||
} */
|
||||
world.setBlock(np, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL_IMMEDIATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos neighbor, boolean isMoving) {
|
||||
if (world.isClientSide())
|
||||
return;
|
||||
|
||||
if (neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ()) {
|
||||
removeLeftPiece(world, pos, true);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), Block.UPDATE_ALL_IMMEDIATE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDestroyedByPlayer(BlockState state, Level world, BlockPos pos, Player ply, boolean willHarvest, FluidState fluid) {
|
||||
if (!world.isClientSide)
|
||||
removeLeftPiece(world, pos, !ply.isCreative());
|
||||
|
||||
return super.onDestroyedByPlayer(state, world, pos, ply, willHarvest, fluid);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
if (!world.isClientSide && rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
TileEntityKeyboard tek = getTileEntity(world, pos);
|
||||
|
||||
if (tek != null)
|
||||
tek.simulateCat(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeReplaced(BlockState state, BlockPlaceContext context) {
|
||||
if (!context.getItemInHand().isEmpty()) //Keyboard
|
||||
return false;
|
||||
|
||||
//Special checks for the keyboard
|
||||
BlockPos pos = context.getClickedPos().offset(context.getHorizontalDirection().getNormal());
|
||||
if (context.getLevel().getBlockState(pos.below()) == Blocks.AIR.defaultBlockState() || !BlockKeyboardRight.checkNeighborhood(context.getLevel(), pos, null))
|
||||
return true;
|
||||
|
||||
int f = (int) Math.floor(((double) (context.getPlayer().getYRot() * 4.0f / 360.0f)) + 2.5) & 3;
|
||||
Vec3i dir = Direction.from2DDataValue(f).getNormal();
|
||||
BlockPos left = pos.offset(dir);
|
||||
BlockPos right = pos.subtract(dir);
|
||||
|
||||
if (context.getLevel().getBlockState(right) == Blocks.AIR.defaultBlockState() && !(context.getLevel().getBlockState(right.below()) == Blocks.AIR.defaultBlockState()) && BlockKeyboardRight.checkNeighborhood(context.getLevel(), right, null))
|
||||
return false;
|
||||
else
|
||||
return !(context.getLevel().getBlockState(left) == Blocks.AIR.defaultBlockState() && !(context.getLevel().getBlockState(left.below()) == Blocks.AIR.defaultBlockState()) && BlockKeyboardRight.checkNeighborhood(context.getLevel(), left, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (player.isShiftKeyDown()) {
|
||||
ItemStack itemStack = player.getItemInHand(hand);
|
||||
if (canBeReplaced(state, new BlockPlaceContext(player, hand, itemStack, hit))) {
|
||||
int f = (int) Math.floor(((double) (player.getYRot() * 4.0f / 360.0f)) + 2.5) & 3;
|
||||
Vec3i dir = Direction.from2DDataValue(f).getNormal();
|
||||
level.setBlock(pos.offset(dir), BlockInit.blockKeyBoard.get().defaultBlockState(), UPDATE_ALL_IMMEDIATE);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if(player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.PASS;
|
||||
|
||||
TileEntityKeyboard tek = getTileEntity(level, pos);
|
||||
if(tek != null)
|
||||
return tek.onRightClick(player, hand);
|
||||
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.mcef.utilities.Log;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.TileEntityInterfaceBase;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityPeripheralBase;
|
||||
import net.montoyo.wd.entity.TileEntityServer;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.client.CMessageCloseGui;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlockPeripheral extends WDBlockContainer {
|
||||
|
||||
public static final EnumProperty<DefaultPeripheral> type = EnumProperty.create("type", DefaultPeripheral.class);
|
||||
public static final DirectionProperty facing = DirectionProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST);
|
||||
private static final Property<?>[] properties = new Property<?>[] { type, facing };
|
||||
|
||||
public BlockPeripheral() {
|
||||
super(BlockBehaviour.Properties.of(Material.STONE).strength(1.5f, 10.f));
|
||||
// setName("peripheral");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties);
|
||||
}
|
||||
|
||||
// @Nullable TODO: Fix
|
||||
// @Override
|
||||
// public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
// Direction rot = Direction.fromYRot(placer.getYHeadRot());
|
||||
// return defaultBlockState().setValue(type, DefaultPeripheral.fromMetadata(meta)).setValue(facing, rot);
|
||||
//
|
||||
//
|
||||
// return getStateForPlacement(context);
|
||||
// }
|
||||
//
|
||||
// public BlockState getStateForPlacement(@Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction nocare, float hitX,
|
||||
// float hitY, float hitZ, int meta, @Nonnull LivingEntity placer, InteractionHand hand) {
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
// for(DefaultPeripheral dp : DefaultPeripheral.values())
|
||||
// list.add(new ItemStack(getItem(), 1, dp.toMetadata(0)));
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// @Nonnull
|
||||
// public IBlockState getStateFromMeta(int meta) {
|
||||
// DefaultPeripheral dp = DefaultPeripheral.fromMetadata(meta);
|
||||
// IBlockState state = getDefaultState().withProperty(type, dp);
|
||||
//
|
||||
// if(dp.hasFacing())
|
||||
// state = state.withProperty(facing, (meta >> 2) & 3);
|
||||
//
|
||||
// return state;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getMetaFromState(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(state.getValue(facing));
|
||||
// }
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
BlockEntityType.BlockEntitySupplier<? extends BlockEntity> cls = state.getValue(type).getTEClass();
|
||||
if(cls == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
return cls.create(pos, state);
|
||||
} catch(Throwable t) {
|
||||
Log.errorEx("Couldn't instantiate peripheral TileEntity:", t);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int damageDropped(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(0);
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if(player.isShiftKeyDown())
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if(player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityPeripheralBase)
|
||||
return ((TileEntityPeripheralBase) te).onRightClick(player, hand);
|
||||
else if(te instanceof TileEntityServer) {
|
||||
((TileEntityServer) te).onPlayerRightClick(player);
|
||||
return InteractionResult.PASS;
|
||||
} else
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isFullCube(IBlockState state) { TODO: FIx.
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isFullBlock(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isOpaqueCube(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return state.getValue(type) == DefaultPeripheral.KEYBOARD ? BlockKeyboardRight.KEYBOARD_AABB : Shapes.block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
|
||||
if(state.getValue(type) == DefaultPeripheral.KEYBOARD) {
|
||||
//Keyboard special treatment
|
||||
Direction f = state.getValue(facing);
|
||||
Vec3i dir = f.getClockWise().getNormal();
|
||||
BlockPos left = pos.offset(dir);
|
||||
BlockPos right = pos.subtract(dir);
|
||||
|
||||
if(!world.isEmptyBlock(pos.below()) && BlockKeyboardRight.checkNeighborhood(world, pos, null)) {
|
||||
if(world.isEmptyBlock(right) && !world.isEmptyBlock(right.below()) && BlockKeyboardRight.checkNeighborhood(world, right, pos)) {
|
||||
world.setBlock(right, BlockInit.blockKbRight.get().defaultBlockState().setValue(BlockKeyboardRight.facing, f), 3);
|
||||
return;
|
||||
} else if(world.isEmptyBlock(left) && !world.isEmptyBlock(left.below()) && BlockKeyboardRight.checkNeighborhood(world, left, pos)) {
|
||||
world.setBlock(left, state, 3);
|
||||
world.setBlock(pos, BlockInit.blockKbRight.get().defaultBlockState().setValue(BlockKeyboardRight.facing, f), 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Not good; remove this shit...
|
||||
world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
|
||||
if(!(placer instanceof Player) || !((Player) placer).isCreative()) {
|
||||
// dropBlockAsItem(world, pos, state, 0); TODO: Loottable?
|
||||
}
|
||||
} else if(placer instanceof Player) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityServer)
|
||||
((TileEntityServer) te).setOwner((Player) placer);
|
||||
else if(te instanceof TileEntityInterfaceBase)
|
||||
((TileEntityInterfaceBase) te).setOwner((Player) placer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPistonPushReaction(BlockState state) {
|
||||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
private void removeRightPiece(Level world, BlockPos pos) {
|
||||
for(Direction nf: Direction.Plane.HORIZONTAL) {
|
||||
BlockPos np = pos.offset(nf.getNormal());
|
||||
|
||||
if(world.getBlockState(np).getBlock() instanceof BlockKeyboardRight) {
|
||||
world.setBlock(np, Blocks.AIR.defaultBlockState(), 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighborType, BlockPos neighbor, boolean isMoving) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if(te != null && te instanceof TileEntityPeripheralBase)
|
||||
((TileEntityPeripheralBase) te).onNeighborChange(neighborType, neighbor);
|
||||
|
||||
if(world.isClientSide || state.getValue(type) != DefaultPeripheral.KEYBOARD)
|
||||
return;
|
||||
|
||||
if(neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ() && world.isEmptyBlock(neighbor)) {
|
||||
removeRightPiece(world, pos);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||
// dropBlockAsItem(world, pos, state, 0); //TODO Loottable
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||
if(!world.isClientSide) {
|
||||
if(state.getBlock() == this && state.getValue(type) == DefaultPeripheral.KEYBOARD)
|
||||
removeRightPiece(world, pos);
|
||||
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockExploded(BlockState state, Level level, BlockPos pos, Explosion explosion) {
|
||||
playerDestroy(level, null, pos, level.getBlockState(pos), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
if(!world.isClientSide && world.getBlockState(pos).getValue(type) == DefaultPeripheral.KEYBOARD) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
|
||||
if(rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te != null && te instanceof TileEntityKeyboard)
|
||||
((TileEntityKeyboard) te).simulateCat(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PacketDistributor.TargetPoint point(Level world, BlockPos bp) {
|
||||
return new PacketDistributor.TargetPoint(bp.getX(), bp.getY(), bp.getZ(), 64.0, world.dimension());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.mcef.utilities.Log;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.*;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.client.CMessageCloseGui;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlockRCTRL extends WDBlockContainer {
|
||||
|
||||
public static final EnumProperty<DefaultPeripheral> type = BlockPeripheral.type;
|
||||
public static final DirectionProperty facing = DirectionProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST);
|
||||
private static final Property<?>[] properties = new Property<?>[] {type, facing};
|
||||
|
||||
public BlockRCTRL() {
|
||||
super(BlockBehaviour.Properties.of(Material.STONE).strength(1.5f, 10.f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties);
|
||||
}
|
||||
|
||||
// @Nullable TODO: Fix
|
||||
// @Override
|
||||
// public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
// Direction rot = Direction.fromYRot(placer.getYHeadRot());
|
||||
// return defaultBlockState().setValue(type, DefaultPeripheral.fromMetadata(meta)).setValue(facing, rot);
|
||||
//
|
||||
//
|
||||
// return getStateForPlacement(context);
|
||||
// }
|
||||
//
|
||||
// public BlockState getStateForPlacement(@Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction nocare, float hitX,
|
||||
// float hitY, float hitZ, int meta, @Nonnull LivingEntity placer, InteractionHand hand) {
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
// for(DefaultPeripheral dp : DefaultPeripheral.values())
|
||||
// list.add(new ItemStack(getItem(), 1, dp.toMetadata(0)));
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// @Nonnull
|
||||
// public IBlockState getStateFromMeta(int meta) {
|
||||
// DefaultPeripheral dp = DefaultPeripheral.fromMetadata(meta);
|
||||
// IBlockState state = getDefaultState().withProperty(type, dp);
|
||||
//
|
||||
// if(dp.hasFacing())
|
||||
// state = state.withProperty(facing, (meta >> 2) & 3);
|
||||
//
|
||||
// return state;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getMetaFromState(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(state.getValue(facing));
|
||||
// }
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new TileEntityRCtrl(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int damageDropped(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(0);
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if(player.isShiftKeyDown())
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if(player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
System.out.println(te);
|
||||
if(te instanceof TileEntityRCtrl)
|
||||
return ((TileEntityRCtrl) te).onRightClick(player, hand);
|
||||
else if(te instanceof TileEntityServer) {
|
||||
((TileEntityServer) te).onPlayerRightClick(player);
|
||||
return InteractionResult.PASS;
|
||||
} else
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isFullCube(IBlockState state) { TODO: FIx.
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isFullBlock(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isOpaqueCube(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
if(placer instanceof Player) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityServer)
|
||||
((TileEntityServer) te).setOwner((Player) placer);
|
||||
else if(te instanceof TileEntityInterfaceBase)
|
||||
((TileEntityInterfaceBase) te).setOwner((Player) placer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPistonPushReaction(BlockState state) {
|
||||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighborType, BlockPos neighbor, boolean isMoving) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if(te != null && te instanceof TileEntityPeripheralBase)
|
||||
((TileEntityPeripheralBase) te).onNeighborChange(neighborType, neighbor);
|
||||
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
|
||||
if(neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ() && world.isEmptyBlock(neighbor)) {
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||
// dropBlockAsItem(world, pos, state, 0); //TODO Loottable
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||
if(!world.isClientSide) {
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockExploded(BlockState state, Level level, BlockPos pos, Explosion explosion) {
|
||||
playerDestroy(level, null, pos, level.getBlockState(pos), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
if(!world.isClientSide) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
|
||||
if(rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te != null && te instanceof TileEntityKeyboard)
|
||||
((TileEntityKeyboard) te).simulateCat(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PacketDistributor.TargetPoint point(Level world, BlockPos bp) {
|
||||
return new PacketDistributor.TargetPoint(bp.getX(), bp.getY(), bp.getZ(), 64.0, world.dimension());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.mcef.utilities.Log;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.*;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.client.CMessageCloseGui;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlockRedCTRL extends WDBlockContainer {
|
||||
|
||||
public static final EnumProperty<DefaultPeripheral> type = BlockPeripheral.type;
|
||||
public static final DirectionProperty facing = DirectionProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST);
|
||||
private static final Property<?>[] properties = new Property<?>[] {type, facing};
|
||||
|
||||
public BlockRedCTRL() {
|
||||
super(BlockBehaviour.Properties.of(Material.STONE).strength(1.5f, 10.f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties);
|
||||
}
|
||||
|
||||
// @Nullable TODO: Fix
|
||||
// @Override
|
||||
// public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
// Direction rot = Direction.fromYRot(placer.getYHeadRot());
|
||||
// return defaultBlockState().setValue(type, DefaultPeripheral.fromMetadata(meta)).setValue(facing, rot);
|
||||
//
|
||||
//
|
||||
// return getStateForPlacement(context);
|
||||
// }
|
||||
//
|
||||
// public BlockState getStateForPlacement(@Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction nocare, float hitX,
|
||||
// float hitY, float hitZ, int meta, @Nonnull LivingEntity placer, InteractionHand hand) {
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
// for(DefaultPeripheral dp : DefaultPeripheral.values())
|
||||
// list.add(new ItemStack(getItem(), 1, dp.toMetadata(0)));
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// @Nonnull
|
||||
// public IBlockState getStateFromMeta(int meta) {
|
||||
// DefaultPeripheral dp = DefaultPeripheral.fromMetadata(meta);
|
||||
// IBlockState state = getDefaultState().withProperty(type, dp);
|
||||
//
|
||||
// if(dp.hasFacing())
|
||||
// state = state.withProperty(facing, (meta >> 2) & 3);
|
||||
//
|
||||
// return state;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getMetaFromState(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(state.getValue(facing));
|
||||
// }
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new TileEntityRedCtrl(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int damageDropped(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(0);
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if(player.isShiftKeyDown())
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if(player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityRedCtrl)
|
||||
return ((TileEntityRedCtrl) te).onRightClick(player, hand);
|
||||
else if(te instanceof TileEntityServer) {
|
||||
((TileEntityServer) te).onPlayerRightClick(player);
|
||||
return InteractionResult.PASS;
|
||||
} else
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isFullCube(IBlockState state) { TODO: FIx.
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isFullBlock(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isOpaqueCube(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
if(placer instanceof Player) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityServer)
|
||||
((TileEntityServer) te).setOwner((Player) placer);
|
||||
else if(te instanceof TileEntityInterfaceBase)
|
||||
((TileEntityInterfaceBase) te).setOwner((Player) placer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPistonPushReaction(BlockState state) {
|
||||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighborType, BlockPos neighbor, boolean isMoving) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if(te != null && te instanceof TileEntityPeripheralBase)
|
||||
((TileEntityPeripheralBase) te).onNeighborChange(neighborType, neighbor);
|
||||
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
|
||||
if(neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ() && world.isEmptyBlock(neighbor)) {
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||
// dropBlockAsItem(world, pos, state, 0); //TODO Loottable
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||
if(!world.isClientSide) {
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockExploded(BlockState state, Level level, BlockPos pos, Explosion explosion) {
|
||||
playerDestroy(level, null, pos, level.getBlockState(pos), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
if(!world.isClientSide) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
|
||||
if(rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te != null && te instanceof TileEntityKeyboard)
|
||||
((TileEntityKeyboard) te).simulateCat(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PacketDistributor.TargetPoint point(Level world, BlockPos bp) {
|
||||
return new PacketDistributor.TargetPoint(bp.getX(), bp.getY(), bp.getZ(), 64.0, world.dimension());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.mcef.utilities.Log;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.TileEntityInterfaceBase;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityPeripheralBase;
|
||||
import net.montoyo.wd.entity.TileEntityServer;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.client.CMessageCloseGui;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlockServer extends WDBlockContainer{
|
||||
|
||||
public static final EnumProperty<DefaultPeripheral> type = BlockPeripheral.type;
|
||||
public static final DirectionProperty facing = DirectionProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST);
|
||||
private static final Property<?>[] properties = new Property<?>[] {type, facing};
|
||||
|
||||
public BlockServer() {
|
||||
super(BlockBehaviour.Properties.of(Material.STONE).strength(1.5f, 10.f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties);
|
||||
}
|
||||
|
||||
// @Nullable TODO: Fix
|
||||
// @Override
|
||||
// public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
// Direction rot = Direction.fromYRot(placer.getYHeadRot());
|
||||
// return defaultBlockState().setValue(type, DefaultPeripheral.fromMetadata(meta)).setValue(facing, rot);
|
||||
//
|
||||
//
|
||||
// return getStateForPlacement(context);
|
||||
// }
|
||||
//
|
||||
// public BlockState getStateForPlacement(@Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction nocare, float hitX,
|
||||
// float hitY, float hitZ, int meta, @Nonnull LivingEntity placer, InteractionHand hand) {
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> list) {
|
||||
// for(DefaultPeripheral dp : DefaultPeripheral.values())
|
||||
// list.add(new ItemStack(getItem(), 1, dp.toMetadata(0)));
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// @Nonnull
|
||||
// public IBlockState getStateFromMeta(int meta) {
|
||||
// DefaultPeripheral dp = DefaultPeripheral.fromMetadata(meta);
|
||||
// IBlockState state = getDefaultState().withProperty(type, dp);
|
||||
//
|
||||
// if(dp.hasFacing())
|
||||
// state = state.withProperty(facing, (meta >> 2) & 3);
|
||||
//
|
||||
// return state;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getMetaFromState(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(state.getValue(facing));
|
||||
// }
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new TileEntityServer(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public int damageDropped(IBlockState state) {
|
||||
// return state.getValue(type).toMetadata(0);
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if(player.isShiftKeyDown())
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if(player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityServer) {
|
||||
((TileEntityServer) te).onPlayerRightClick(player);
|
||||
return InteractionResult.PASS;
|
||||
} else
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isFullCube(IBlockState state) { TODO: FIx.
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isFullBlock(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean isOpaqueCube(IBlockState state) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean doesSideBlockRendering(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing face) {
|
||||
// return state.getValue(type) != DefaultPeripheral.KEYBOARD;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
if(placer instanceof Player) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te instanceof TileEntityServer)
|
||||
((TileEntityServer) te).setOwner((Player) placer);
|
||||
else if(te instanceof TileEntityInterfaceBase)
|
||||
((TileEntityInterfaceBase) te).setOwner((Player) placer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPistonPushReaction(BlockState state) {
|
||||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighborType, BlockPos neighbor, boolean isMoving) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if(te != null && te instanceof TileEntityPeripheralBase)
|
||||
((TileEntityPeripheralBase) te).onNeighborChange(neighborType, neighbor);
|
||||
|
||||
if(world.isClientSide)
|
||||
return;
|
||||
|
||||
if(neighbor.getX() == pos.getX() && neighbor.getY() == pos.getY() - 1 && neighbor.getZ() == pos.getZ() && world.isEmptyBlock(neighbor)) {
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||
// dropBlockAsItem(world, pos, state, 0); //TODO Loottable
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||
if(!world.isClientSide) {
|
||||
Messages.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new CMessageCloseGui(pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockExploded(BlockState state, Level level, BlockPos pos, Explosion explosion) {
|
||||
playerDestroy(level, null, pos, level.getBlockState(pos), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
if(!world.isClientSide) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
|
||||
if(rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if(te != null && te instanceof TileEntityKeyboard)
|
||||
((TileEntityKeyboard) te).simulateCat(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static PacketDistributor.TargetPoint point(Level world, BlockPos bp) {
|
||||
return new PacketDistributor.TargetPoint(bp.getX(), bp.getY(), bp.getZ(), 64.0, world.dimension());
|
||||
}
|
||||
|
||||
}
|
||||
142
src/main/java/net/montoyo/wd/block/KeyboardBlockLeft.java
Normal file
142
src/main/java/net/montoyo/wd/block/KeyboardBlockLeft.java
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Copyright (C) 2019 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.KeyboardBlockEntity;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.client_bound.S2CMessageCloseGui;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class KeyboardBlockLeft extends PeripheralBlock {
|
||||
public static final EnumProperty<DefaultPeripheral> TYPE = EnumProperty.create("type", DefaultPeripheral.class);
|
||||
public static final DirectionProperty FACING = DirectionProperty.create("facing", Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST);
|
||||
// public static final DirectionProperty HALF = DirectionProperty.create("facing", Direction.EAST, Direction.WEST);
|
||||
|
||||
public static final VoxelShape[] KEYBOARD_AABBS = new VoxelShape[]{
|
||||
Shapes.box(0.0, 0.0, 3.0 / 16, 1.0, 1.0 / 16.0, 1.0),
|
||||
Shapes.box(0.0, 0.0, 0.0, 1.0, 1.0 / 16.0, 13 / 16.0),
|
||||
Shapes.box(3.0 / 16, 0.0, 0.0, 1.0, 1.0 / 16.0, 1.0),
|
||||
Shapes.box(0.0, 0.0, 0.0, 13 / 16.0, 1.0 / 16.0, 1.0),
|
||||
};
|
||||
|
||||
private static final Property<?>[] properties = new Property<?>[] {TYPE, FACING};
|
||||
|
||||
public KeyboardBlockLeft() {
|
||||
super(DefaultPeripheral.KEYBOARD);
|
||||
}
|
||||
|
||||
// TODO: make non static (for extensibility purposes)
|
||||
public static KeyboardBlockEntity getTileEntity(BlockState state, Level world, BlockPos pos) {
|
||||
if (state.getBlock() instanceof KeyboardBlockLeft) {
|
||||
BlockEntity te = world.getBlockEntity(pos); // TODO: check?
|
||||
if (te instanceof KeyboardBlockEntity)
|
||||
return (KeyboardBlockEntity) te;
|
||||
}
|
||||
|
||||
BlockPos relative = pos.relative(KeyboardBlockLeft.mapDirection(state.getValue(FACING).getOpposite()));
|
||||
BlockState ns = world.getBlockState(relative);
|
||||
|
||||
if (ns.getBlock() instanceof PeripheralBlock) {
|
||||
BlockEntity te = world.getBlockEntity(relative); // TODO: check?
|
||||
if (te instanceof KeyboardBlockEntity)
|
||||
return (KeyboardBlockEntity) te;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Direction mapDirection(Direction facing) {
|
||||
return switch (facing) {
|
||||
case NORTH -> Direction.EAST;
|
||||
case EAST -> Direction.SOUTH;
|
||||
case SOUTH -> Direction.WEST;
|
||||
case WEST -> Direction.NORTH;
|
||||
default -> facing;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
if (!world.isClientSide && rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
KeyboardBlockEntity tek = KeyboardBlockLeft.getTileEntity(state, world, pos);
|
||||
|
||||
if (tek != null)
|
||||
tek.simulateCat(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.PASS;
|
||||
|
||||
KeyboardBlockEntity tek = KeyboardBlockLeft.getTileEntity(state, level, pos);
|
||||
if (tek != null)
|
||||
return tek.onRightClick(player, hand);
|
||||
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return KEYBOARD_AABBS[state.getValue(FACING).ordinal() - 2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOcclusionShape(BlockState arg, BlockGetter arg2, BlockPos arg3) {
|
||||
return Shapes.empty();
|
||||
}
|
||||
|
||||
private static void removeRightPiece(BlockState state, Level world, BlockPos pos) {
|
||||
BlockPos relative = pos.relative(KeyboardBlockLeft.mapDirection(state.getValue(FACING)));
|
||||
|
||||
BlockState ns = world.getBlockState(relative);
|
||||
if (ns.getBlock() instanceof KeyboardBlockRight)
|
||||
world.setBlock(relative, Blocks.AIR.defaultBlockState(), 3);
|
||||
}
|
||||
|
||||
public static void remove(BlockState state, Level world, BlockPos pos, boolean setState, boolean drop) {
|
||||
removeRightPiece(state, world, pos);
|
||||
if (setState)
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new S2CMessageCloseGui(pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(BlockState arg, Level arg2, BlockPos arg3, BlockState arg4, boolean bl) {
|
||||
if (!arg2.isClientSide)
|
||||
remove(arg, arg2, arg3, false, false);
|
||||
super.onRemove(arg, arg2, arg3, arg4, bl);
|
||||
}
|
||||
}
|
||||
116
src/main/java/net/montoyo/wd/block/KeyboardBlockRight.java
Normal file
116
src/main/java/net/montoyo/wd/block/KeyboardBlockRight.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.wd.core.IPeripheral;
|
||||
import net.montoyo.wd.entity.KeyboardBlockEntity;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.client_bound.S2CMessageCloseGui;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static net.montoyo.wd.block.KeyboardBlockLeft.KEYBOARD_AABBS;
|
||||
import static net.montoyo.wd.block.PeripheralBlock.point;
|
||||
|
||||
// TODO: merge into KeyboardLeft
|
||||
public class KeyboardBlockRight extends Block implements IPeripheral {
|
||||
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
public KeyboardBlockRight() {
|
||||
super(Properties.copy(Blocks.STONE)
|
||||
.strength(1.5f, 10.f));
|
||||
}
|
||||
|
||||
private static void removeLeftPiece(BlockState state, Level world, BlockPos pos) {
|
||||
BlockPos relative = pos.relative(KeyboardBlockLeft.mapDirection(state.getValue(FACING).getOpposite()));
|
||||
|
||||
BlockState ns = world.getBlockState(relative);
|
||||
if (ns.getBlock() instanceof KeyboardBlockLeft)
|
||||
world.setBlock(relative, Blocks.AIR.defaultBlockState(), 3);
|
||||
}
|
||||
|
||||
public static void remove(BlockState state, Level world, BlockPos pos, boolean setState, boolean drop) {
|
||||
removeLeftPiece(state, world, pos);
|
||||
if (setState)
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new S2CMessageCloseGui(pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(BlockState arg, Level arg2, BlockPos arg3, BlockState arg4, boolean bl) {
|
||||
if (!arg2.isClientSide)
|
||||
remove(arg, arg2, arg3, false, false);
|
||||
super.onRemove(arg, arg2, arg3, arg4, bl);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollisionShapeFullBlock(BlockState state, BlockGetter level, BlockPos pos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return KEYBOARD_AABBS[state.getValue(FACING).ordinal() - 2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connect(Level world, BlockPos pos, BlockState state, Vector3i scrPos, BlockSide scrSide) {
|
||||
KeyboardBlockEntity keyboard = KeyboardBlockLeft.getTileEntity(state, world, pos);
|
||||
return keyboard != null && keyboard.connect(world, pos, state, scrPos, scrSide);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
|
||||
double rpos = (entity.getY() - ((double) pos.getY())) * 16.0;
|
||||
if (!world.isClientSide && rpos >= 1.0 && rpos <= 2.0 && Math.random() < 0.25) {
|
||||
KeyboardBlockEntity tek = KeyboardBlockLeft.getTileEntity(state, world, pos);
|
||||
|
||||
if (tek != null)
|
||||
tek.simulateCat(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.PASS;
|
||||
|
||||
KeyboardBlockEntity tek = KeyboardBlockLeft.getTileEntity(state, level, pos);
|
||||
if (tek != null)
|
||||
return tek.onRightClick(player, hand);
|
||||
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOcclusionShape(BlockState arg, BlockGetter arg2, BlockPos arg3) {
|
||||
return Shapes.empty();
|
||||
}
|
||||
}
|
||||
141
src/main/java/net/montoyo/wd/block/PeripheralBlock.java
Normal file
141
src/main/java/net/montoyo/wd/block/PeripheralBlock.java
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (C) 2019 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.montoyo.wd.core.DefaultPeripheral;
|
||||
import net.montoyo.wd.entity.AbstractInterfaceBlockEntity;
|
||||
import net.montoyo.wd.entity.AbstractPeripheralBlockEntity;
|
||||
import net.montoyo.wd.entity.ServerBlockEntity;
|
||||
import net.montoyo.wd.item.ItemLinker;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.client_bound.S2CMessageCloseGui;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PeripheralBlock extends WDContainerBlock {
|
||||
DefaultPeripheral type;
|
||||
|
||||
public PeripheralBlock(DefaultPeripheral type) {
|
||||
super(BlockBehaviour.Properties.copy(Blocks.STONE).strength(1.5f, 10.f));
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
BlockEntityType.BlockEntitySupplier<? extends BlockEntity> cls = type.getTEClass();
|
||||
if (cls == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
return cls.create(pos, state);
|
||||
} catch (Throwable t) {
|
||||
Log.errorEx("Couldn't instantiate peripheral TileEntity:", t);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
if (player.isShiftKeyDown())
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if (player.getItemInHand(hand).getItem() instanceof ItemLinker)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if (te instanceof AbstractPeripheralBlockEntity)
|
||||
return ((AbstractPeripheralBlockEntity) te).onRightClick(player, hand);
|
||||
else if (te instanceof ServerBlockEntity) {
|
||||
((ServerBlockEntity) te).onPlayerRightClick(player);
|
||||
return InteractionResult.SUCCESS;
|
||||
} else
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||
return Shapes.block();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
|
||||
if (world.isClientSide)
|
||||
return;
|
||||
|
||||
if (placer instanceof Player) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
|
||||
if (te instanceof ServerBlockEntity)
|
||||
((ServerBlockEntity) te).setOwner((Player) placer);
|
||||
else if (te instanceof AbstractInterfaceBlockEntity)
|
||||
((AbstractInterfaceBlockEntity) te).setOwner((Player) placer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PushReaction getPistonPushReaction(BlockState state) {
|
||||
return PushReaction.IGNORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block neighborType, BlockPos neighbor, boolean isMoving) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (te instanceof AbstractPeripheralBlockEntity)
|
||||
((AbstractPeripheralBlockEntity) te).onNeighborChange(neighborType, neighbor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||
if (!world.isClientSide) {
|
||||
WDNetworkRegistry.INSTANCE.send(PacketDistributor.NEAR.with(() -> point(world, pos)), new S2CMessageCloseGui(pos));
|
||||
}
|
||||
super.playerDestroy(world, player, pos, state, blockEntity, tool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockExploded(BlockState state, Level level, BlockPos pos, Explosion explosion) {
|
||||
playerDestroy(level, null, pos, level.getBlockState(pos), null, null);
|
||||
}
|
||||
|
||||
public static PacketDistributor.TargetPoint point(Player exclude, Level world, BlockPos bp) {
|
||||
return new PacketDistributor.TargetPoint((ServerPlayer) exclude, bp.getX(), bp.getY(), bp.getZ(), 64.0, world.dimension());
|
||||
}
|
||||
|
||||
public static PacketDistributor.TargetPoint point(Level world, BlockPos bp) {
|
||||
return new PacketDistributor.TargetPoint(bp.getX(), bp.getY(), bp.getZ(), 64.0, world.dimension());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -12,196 +12,158 @@ import net.minecraft.world.InteractionHand;
|
|||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.config.ModConfig;
|
||||
import net.montoyo.wd.config.CommonConfig;
|
||||
import net.montoyo.wd.core.DefaultUpgrade;
|
||||
import net.montoyo.wd.core.IUpgrade;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.data.SetURLData;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.init.BlockInit;
|
||||
import net.montoyo.wd.item.WDItem;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.item.ItemLaserPointer;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
import net.montoyo.wd.utilities.math.Vector2i;
|
||||
import net.montoyo.wd.utilities.math.Vector3f;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.serialization.Util;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class BlockScreen extends BaseEntityBlock {
|
||||
|
||||
public class ScreenBlock extends BaseEntityBlock {
|
||||
public static final BooleanProperty hasTE = BooleanProperty.create("haste");
|
||||
public static final BooleanProperty emitting = BooleanProperty.create("emitting");
|
||||
private static final Property<?>[] properties = new Property<?>[] { hasTE, emitting };
|
||||
public static final DirectionProperty FACING = BlockStateProperties.FACING;
|
||||
private static final Property<?>[] properties = new Property<?>[]{hasTE, emitting};
|
||||
|
||||
private static final int BAR_BOT = 1;
|
||||
private static final int BAR_RIGHT = 2;
|
||||
private static final int BAR_TOP = 4;
|
||||
private static final int BAR_LEFT = 8;
|
||||
|
||||
public BlockScreen(Properties properties) {
|
||||
public ScreenBlock(Properties properties) {
|
||||
super(properties.strength(1.5f, 10.f));
|
||||
// setCreativeTab(WebDisplays.CREATIVE_TAB);
|
||||
// setName("screen");
|
||||
this.registerDefaultState(this.defaultBlockState().setValue(hasTE, false).setValue(emitting, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties).add(FACING);
|
||||
}
|
||||
public void onRemove(BlockState p_60515_, Level p_60516_, BlockPos p_60517_, BlockState p_60518_, boolean p_60519_) {
|
||||
// TODO: make this also get called on client?
|
||||
if (p_60518_.getBlock() == p_60515_.getBlock()) return;
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
public static boolean isntScreenBlock(Level world, Vector3i pos) {
|
||||
return world.getBlockState(pos.toBlock()).getBlock() != BlockInit.blockScreen.get();
|
||||
}
|
||||
|
||||
|
||||
@org.jetbrains.annotations.Nullable
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
return super.getStateForPlacement(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) {
|
||||
return super.updateShape(state, direction, neighborState, level, currentPos, neighborPos);
|
||||
}
|
||||
|
||||
/* @Override
|
||||
@Nonnull
|
||||
public BlockState getExtendedState(@Nonnull BlockState ret, Level world, BlockPos bpos) {
|
||||
Vector3i pos = new Vector3i(bpos);
|
||||
|
||||
for(BlockSide side : BlockSide.values()) {
|
||||
int icon = 0;
|
||||
if(isntScreenBlock(world, side.up.clone().add(pos))) icon |= BAR_TOP;
|
||||
if(isntScreenBlock(world, side.down.clone().add(pos))) icon |= BAR_BOT;
|
||||
if(isntScreenBlock(world, side.left.clone().add(pos))) icon |= BAR_LEFT;
|
||||
if(isntScreenBlock(world, side.right.clone().add(pos))) icon |= BAR_RIGHT;
|
||||
|
||||
ret = ret.setValue(sideFlags[side.ordinal()], icon);
|
||||
for (BlockSide value : BlockSide.values()) {
|
||||
Vector3i vec = new Vector3i(p_60517_.getX(), p_60517_.getY(), p_60517_.getZ());
|
||||
Multiblock.findOrigin(p_60516_, vec, value, null);
|
||||
BlockPos bp = new BlockPos(vec.x, vec.y, vec.z);
|
||||
if (!bp.equals(p_60517_)) {
|
||||
p_60516_.removeBlockEntity(bp);
|
||||
p_60516_.setBlock(
|
||||
bp, p_60516_.getBlockState(bp).setValue(hasTE, false),
|
||||
11
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
// @Override
|
||||
// @Nonnull
|
||||
// public IBlockState getStateFromMeta(int meta) {
|
||||
// return getDefaultState().withProperty(hasTE, (meta & 1) != 0).withProperty(emitting, (meta & 2) != 0);
|
||||
// }
|
||||
//
|
||||
|
||||
public int getMetaFromState(BlockState state) {
|
||||
int ret = 0;
|
||||
if(state.getValue(hasTE))
|
||||
ret |= 1;
|
||||
|
||||
if(state.getValue(emitting))
|
||||
ret |= 2;
|
||||
|
||||
return ret;
|
||||
super.onRemove(p_60515_, p_60516_, p_60517_, p_60518_, p_60519_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos position, Player player, InteractionHand hand, BlockHitResult hit) {
|
||||
ItemStack heldItem = player.getItemInHand(hand);
|
||||
if(heldItem.isEmpty())
|
||||
boolean isUpgrade = false;
|
||||
if (heldItem.isEmpty())
|
||||
heldItem = null; //Easier to work with
|
||||
else if(!(heldItem.getItem() instanceof IUpgrade))
|
||||
else if (!(isUpgrade = heldItem.getItem() instanceof IUpgrade))
|
||||
return InteractionResult.FAIL;
|
||||
else if (heldItem.getItem() instanceof ItemLaserPointer)
|
||||
return InteractionResult.FAIL; // laser pointer already handles stuff
|
||||
|
||||
// handling the off hand leads to double clicking
|
||||
if (!isUpgrade && hand == InteractionHand.OFF_HAND)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
if(world.isClientSide)
|
||||
if (world.isClientSide)
|
||||
return InteractionResult.FAIL;
|
||||
|
||||
boolean sneaking = player.isShiftKeyDown();
|
||||
Vector3i pos = new Vector3i(position);
|
||||
|
||||
BlockSide side = BlockSide.values()[hit.getDirection().ordinal()];
|
||||
|
||||
Multiblock.findOrigin(world, pos, side, null);
|
||||
TileEntityScreen te = (TileEntityScreen) world.getBlockEntity(pos.toBlock());
|
||||
ScreenBlockEntity te = (ScreenBlockEntity) world.getBlockEntity(pos.toBlock());
|
||||
|
||||
if(te != null && te.getScreen(side) != null) {
|
||||
TileEntityScreen.Screen scr = te.getScreen(side);
|
||||
if (te != null && te.getScreen(side) != null) {
|
||||
ScreenData scr = te.getScreen(side);
|
||||
|
||||
if(sneaking) { //Set URL
|
||||
if((scr.rightsFor(player) & ScreenRights.CHANGE_URL) == 0)
|
||||
if (sneaking) { //Right Click
|
||||
if ((scr.rightsFor(player) & ScreenRights.CHANGE_URL) == 0)
|
||||
Util.toast(player, "restrictions");
|
||||
else
|
||||
(new SetURLData(pos, scr.side, scr.url)).sendTo((ServerPlayer) player);
|
||||
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if(heldItem != null && !te.hasUpgrade(side, heldItem)) { //Add upgrade
|
||||
if((scr.rightsFor(player) & ScreenRights.MANAGE_UPGRADES) == 0) {
|
||||
Util.toast(player, "restrictions");
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (heldItem != null) {
|
||||
if (!te.hasUpgrade(side, heldItem)) {
|
||||
if ((scr.rightsFor(player) & ScreenRights.MANAGE_UPGRADES) == 0) {
|
||||
Util.toast(player, "restrictions");
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
if (te.addUpgrade(side, heldItem, player, false)) {
|
||||
if (!player.isCreative())
|
||||
heldItem.shrink(1);
|
||||
|
||||
Util.toast(player, ChatFormatting.AQUA, "upgradeOk");
|
||||
if (player instanceof ServerPlayer)
|
||||
WebDisplays.INSTANCE.criterionUpgradeScreen.trigger(((ServerPlayer) player).getAdvancements());
|
||||
} else
|
||||
Util.toast(player, "upgradeError");
|
||||
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
if(te.addUpgrade(side, heldItem, player, false)) {
|
||||
if(!player.isCreative())
|
||||
heldItem.shrink(1);
|
||||
|
||||
Util.toast(player, ChatFormatting.AQUA, "upgradeOk");
|
||||
if(player instanceof ServerPlayer)
|
||||
WebDisplays.INSTANCE.criterionUpgradeScreen.trigger(((ServerPlayer) player).getAdvancements());
|
||||
} else
|
||||
Util.toast(player, "upgradeError");
|
||||
|
||||
return InteractionResult.SUCCESS;
|
||||
} else { //Click
|
||||
if((scr.rightsFor(player) & ScreenRights.CLICK) == 0) {
|
||||
} else {
|
||||
if ((scr.rightsFor(player) & ScreenRights.INTERACT) == 0) {
|
||||
Util.toast(player, "restrictions");
|
||||
return InteractionResult.SUCCESS;
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
Vector2i tmp = new Vector2i();
|
||||
if(hit2pixels(side, hit.getBlockPos(), pos, scr, (float) hit.getLocation().x, (float) hit.getLocation().y, (float) hit.getLocation().z, tmp))
|
||||
te.click(side, tmp);
|
||||
|
||||
return InteractionResult.SUCCESS;
|
||||
float hitX = ((float) hit.getLocation().x) - (float) te.getBlockPos().getX();
|
||||
float hitY = ((float) hit.getLocation().y) - (float) te.getBlockPos().getY();
|
||||
float hitZ = ((float) hit.getLocation().z) - (float) te.getBlockPos().getZ();
|
||||
|
||||
if (hit2pixels(side, hit.getBlockPos(), new Vector3i(hit.getBlockPos()), scr, hitX, hitY, hitZ, tmp))
|
||||
te.click(side, tmp);
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
} else if(sneaking) {
|
||||
Util.toast(player, "turnOn");
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
// else if(sneaking) {
|
||||
// Util.toast(player, "turnOn");
|
||||
// return InteractionResult.SUCCESS;
|
||||
// }
|
||||
|
||||
Vector2i size = Multiblock.measure(world, pos, side);
|
||||
if(size.x < 2 || size.y < 2) {
|
||||
if (size.x < 2 && size.y < 2) {
|
||||
Util.toast(player, "tooSmall");
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
if(size.x > WebDisplays.INSTANCE.maxScreenX || size.y > WebDisplays.INSTANCE.maxScreenY) {
|
||||
Util.toast(player, "tooBig", WebDisplays.INSTANCE.maxScreenX, WebDisplays.INSTANCE.maxScreenY);
|
||||
if (size.x > CommonConfig.Screen.maxScreenSizeX || size.y > CommonConfig.Screen.maxScreenSizeY) {
|
||||
Util.toast(player, "tooBig", CommonConfig.Screen.maxScreenSizeX, CommonConfig.Screen.maxScreenSizeY);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
Vector3i err = Multiblock.check(world, pos, size, side);
|
||||
if(err != null) {
|
||||
if (err != null) {
|
||||
Util.toast(player, "invalid", err.toString());
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
@ -209,60 +171,58 @@ public class BlockScreen extends BaseEntityBlock {
|
|||
boolean created = false;
|
||||
Log.info("Player %s (UUID %s) created a screen at %s of size %dx%d", player.getName(), player.getGameProfile().getId().toString(), pos.toString(), size.x, size.y);
|
||||
|
||||
if(te == null) {
|
||||
if (te == null) {
|
||||
BlockPos bp = pos.toBlock();
|
||||
world.setBlockAndUpdate(bp, world.getBlockState(bp).setValue(hasTE, true));
|
||||
te = (TileEntityScreen) world.getBlockEntity(bp);
|
||||
te = (ScreenBlockEntity) world.getBlockEntity(bp);
|
||||
created = true;
|
||||
}
|
||||
|
||||
te.addScreen(side, size, null, player, !created);
|
||||
te.addScreen(side, size, null, player, true);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos source, boolean isMoving) {
|
||||
if(block != this && !world.isClientSide && !state.getValue(emitting)) {
|
||||
for(BlockSide side: BlockSide.values()) {
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos source,
|
||||
boolean isMoving) {
|
||||
if (block != this && !world.isClientSide && !state.getValue(emitting)) {
|
||||
for (BlockSide side : BlockSide.values()) {
|
||||
Vector3i vec = new Vector3i(pos);
|
||||
Multiblock.findOrigin(world, vec, side, null);
|
||||
|
||||
TileEntityScreen tes = (TileEntityScreen) world.getBlockEntity(vec.toBlock());
|
||||
if(tes != null && tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_INPUT)) {
|
||||
ScreenBlockEntity tes = (ScreenBlockEntity) world.getBlockEntity(vec.toBlock());
|
||||
if (tes != null && tes.hasUpgrade(side, DefaultUpgrade.REDINPUT)) {
|
||||
Direction facing = Direction.from2DDataValue(side.reverse().ordinal()); //Opposite face
|
||||
vec.sub(pos.getX(), pos.getY(), pos.getZ()).neg();
|
||||
tes.updateJSRedstone(side, new Vector2i(vec.dot(side.right), vec.dot(side.up)), world.getSignal(pos, facing));
|
||||
// tes.updateJSRedstone(side, new Vector2i(vec.dot(side.right), vec.dot(side.up)), world.getSignal(pos, facing));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hit2pixels(BlockSide side, BlockPos bpos, Vector3i pos, TileEntityScreen.Screen scr, float hitX, float hitY, float hitZ, Vector2i dst) {
|
||||
|
||||
public static boolean hit2pixels(BlockSide side, BlockPos bpos, Vector3i pos, ScreenData scr, float hitX, float hitY, float hitZ, Vector2i dst) {
|
||||
if(side.right.x < 0)
|
||||
hitX -= 1.f;
|
||||
|
||||
if(side.right.z < 0 || side == BlockSide.TOP || side == BlockSide.BOTTOM)
|
||||
hitZ -= 1.f;
|
||||
|
||||
Vector3f rel = new Vector3f(pos.toBlock().getX(), pos.toBlock().getY(), pos.toBlock().getZ());
|
||||
rel.sub(hitX, hitY, hitZ);
|
||||
Vector3f rel = new Vector3f(hitX, hitY, hitZ);
|
||||
|
||||
float cx = Math.abs(rel.dot(side.right.toFloat()) - 2.f / 16.f);
|
||||
float cy = Math.abs(rel.dot(side.up.toFloat()) - 2.f / 16.f);
|
||||
// this dot is acting as a "get distance from plane" where the plane is the edge of the screen
|
||||
float cx = rel.dot(side.right.toFloat()) - 2.f / 16.f;
|
||||
float cy = rel.dot(side.up.toFloat()) - 2.f / 16.f;
|
||||
float sw = ((float) scr.size.x) - 4.f / 16.f;
|
||||
float sh = ((float) scr.size.y) - 4.f / 16.f;
|
||||
|
||||
cx /= sw;
|
||||
cy /= sh;
|
||||
|
||||
cx = cx - 0.05f;
|
||||
cy = cy - 0.05f;
|
||||
|
||||
if(cx >= 0 && cx <= 1 && cy >= 0 && cy <= 1) {
|
||||
if(side != BlockSide.BOTTOM)
|
||||
if (cx >= 0.f && cx <= 1.0 && cy >= 0.f && cy <= 1.f) {
|
||||
if (side != BlockSide.BOTTOM)
|
||||
cy = 1.f - cy;
|
||||
|
||||
switch(scr.rotation) {
|
||||
switch (scr.rotation) {
|
||||
case ROT_90:
|
||||
cy = 1.0f - cy;
|
||||
break;
|
||||
|
|
@ -275,15 +235,12 @@ public class BlockScreen extends BaseEntityBlock {
|
|||
case ROT_270:
|
||||
cx = 1.0f - cx;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cx *= (float) scr.resolution.x;
|
||||
cy *= (float) scr.resolution.y;
|
||||
|
||||
if(scr.rotation.isVertical) {
|
||||
if (scr.rotation.isVertical) {
|
||||
dst.x = (int) cy;
|
||||
dst.y = (int) cx;
|
||||
} else {
|
||||
|
|
@ -297,49 +254,41 @@ public class BlockScreen extends BaseEntityBlock {
|
|||
return false;
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
int meta = getMetaFromState(state);
|
||||
|
||||
if((meta & 1) == 0)
|
||||
return null;
|
||||
|
||||
return ((meta & 1) == 0) ? null : new TileEntityScreen(pos, state);
|
||||
}
|
||||
|
||||
/************************************************* DESTRUCTION HANDLING *************************************************/
|
||||
|
||||
private void onDestroy(Level world, BlockPos pos, Player ply) {
|
||||
if(!world.isClientSide) {
|
||||
if (!world.isClientSide) {
|
||||
Vector3i bp = new Vector3i(pos);
|
||||
Multiblock.BlockOverride override = new Multiblock.BlockOverride(bp, Multiblock.OverrideAction.SIMULATE);
|
||||
|
||||
for(BlockSide bs: BlockSide.values())
|
||||
for (BlockSide bs : BlockSide.values())
|
||||
destroySide(world, bp.clone(), bs, override, ply);
|
||||
}
|
||||
}
|
||||
|
||||
private void destroySide(Level world, Vector3i pos, BlockSide side, Multiblock.BlockOverride override, Player source) {
|
||||
private void destroySide(Level world, Vector3i pos, BlockSide side, Multiblock.BlockOverride override, Player
|
||||
source) {
|
||||
Multiblock.findOrigin(world, pos, side, override);
|
||||
BlockPos bp = pos.toBlock();
|
||||
BlockEntity te = world.getBlockEntity(bp);
|
||||
|
||||
if(te != null && te instanceof TileEntityScreen) {
|
||||
((TileEntityScreen) te).onDestroy(source);
|
||||
if (te instanceof ScreenBlockEntity) {
|
||||
((ScreenBlockEntity) te).onDestroy(source);
|
||||
world.setBlock(bp, world.getBlockState(bp).setValue(hasTE, false), Block.UPDATE_ALL_IMMEDIATE); //Destroy tile entity.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDestroyedByPlayer(BlockState state, Level level, BlockPos pos, Player player, boolean willHarvest, FluidState fluid) {
|
||||
public boolean onDestroyedByPlayer(BlockState state, Level level, BlockPos pos, Player player,
|
||||
boolean willHarvest, FluidState fluid) {
|
||||
onDestroy(level, pos, player);
|
||||
return super.onDestroyedByPlayer(state, level, pos, player, willHarvest, fluid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, @NotNull BlockPos pos, @NotNull BlockState state, @org.jetbrains.annotations.Nullable LivingEntity whoDidThisShit, @NotNull ItemStack stack) {
|
||||
if(world.isClientSide)
|
||||
public void setPlacedBy(Level world, @NotNull BlockPos pos, @NotNull BlockState
|
||||
state, @org.jetbrains.annotations.Nullable LivingEntity whoDidThisShit, @NotNull ItemStack stack) {
|
||||
if (world.isClientSide)
|
||||
return;
|
||||
|
||||
Multiblock.BlockOverride override = new Multiblock.BlockOverride(new Vector3i(pos), Multiblock.OverrideAction.IGNORE);
|
||||
|
|
@ -352,14 +301,16 @@ public class BlockScreen extends BaseEntityBlock {
|
|||
neighbors[4] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() + 1);
|
||||
neighbors[5] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() - 1);
|
||||
|
||||
for(Vector3i neighbor: neighbors) {
|
||||
if(world.getBlockState(neighbor.toBlock()).getBlock() instanceof BlockScreen) {
|
||||
for(BlockSide bs: BlockSide.values())
|
||||
for (Vector3i neighbor : neighbors) {
|
||||
if (world.getBlockState(neighbor.toBlock()).getBlock() instanceof ScreenBlock) {
|
||||
for (BlockSide bs : BlockSide.values())
|
||||
destroySide(world, neighbor.clone(), bs, override, (whoDidThisShit instanceof Player) ? ((Player) whoDidThisShit) : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************* STUFF THAT'S UNLIKELY TO BE TOUCHED BUT NEEDS TO BE HERE *************************************************/
|
||||
|
||||
@Override
|
||||
public @NotNull PushReaction getPistonPushReaction(BlockState state) {
|
||||
return PushReaction.IGNORE;
|
||||
|
|
@ -375,23 +326,18 @@ public class BlockScreen extends BaseEntityBlock {
|
|||
return state.getValue(emitting);
|
||||
}
|
||||
|
||||
// @Override //TODO: Add this
|
||||
// protected BlockItem createItemBlock() {
|
||||
// return new ItemBlockScreen(this);
|
||||
// }
|
||||
|
||||
private static class ItemBlockScreen extends BlockItem implements WDItem {
|
||||
|
||||
public ItemBlockScreen(BlockScreen screen) {
|
||||
super(screen, new Properties());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getWikiName(@Nonnull ItemStack is) {
|
||||
return is.getItem().getName(is).getString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return state.getValue(hasTE) ? new ScreenBlockEntity(pos, state) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(properties);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public abstract class WDBlock extends Block {
|
||||
|
||||
protected BlockItem itemBlock;
|
||||
|
||||
public WDBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
protected void setName(String name) {
|
||||
setRegistryName(name);
|
||||
}
|
||||
|
||||
public void makeItemBlock() {
|
||||
if(itemBlock != null)
|
||||
throw new RuntimeException("WDBlock.makeItemBlock() called twice!");
|
||||
|
||||
itemBlock = new BlockItem(this, new Item.Properties());
|
||||
itemBlock.setRegistryName(getRegistryName());
|
||||
}
|
||||
|
||||
public BlockItem getItem() {
|
||||
return itemBlock;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
|
||||
public abstract class WDBlockContainer extends BaseEntityBlock {
|
||||
|
||||
protected static BlockItem itemBlock;
|
||||
|
||||
public WDBlockContainer(Properties arg) {
|
||||
super(arg);
|
||||
}
|
||||
|
||||
protected void setName(String name) {
|
||||
// setRegistryName(name);
|
||||
}
|
||||
|
||||
protected static BlockItem createItemBlock(Block block) {
|
||||
return new BlockItem(block, new Item.Properties().tab(WebDisplays.CREATIVE_TAB));
|
||||
}
|
||||
|
||||
public static void makeItemBlock(Block block) {
|
||||
if(itemBlock != null)
|
||||
throw new RuntimeException("WDBlockContainer.makeItemBlock() called twice!");
|
||||
|
||||
itemBlock = createItemBlock(block);
|
||||
// itemBlock.setRegistryName(getName().getString());
|
||||
}
|
||||
|
||||
public BlockItem getItem() {
|
||||
return itemBlock;
|
||||
}
|
||||
|
||||
}
|
||||
22
src/main/java/net/montoyo/wd/block/WDContainerBlock.java
Normal file
22
src/main/java/net/montoyo/wd/block/WDContainerBlock.java
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.block;
|
||||
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.level.block.BaseEntityBlock;
|
||||
|
||||
public abstract class WDContainerBlock extends BaseEntityBlock {
|
||||
|
||||
protected static BlockItem itemBlock;
|
||||
|
||||
public WDContainerBlock(Properties arg) {
|
||||
super(arg);
|
||||
}
|
||||
|
||||
public BlockItem getItem() {
|
||||
return itemBlock;
|
||||
}
|
||||
|
||||
}
|
||||
54
src/main/java/net/montoyo/wd/block/item/KeyboardItem.java
Normal file
54
src/main/java/net/montoyo/wd/block/item/KeyboardItem.java
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
package net.montoyo.wd.block.item;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.montoyo.wd.block.KeyboardBlockLeft;
|
||||
import net.montoyo.wd.registry.BlockRegistry;
|
||||
|
||||
public class KeyboardItem extends BlockItem {
|
||||
public KeyboardItem(Block arg, Properties arg2) {
|
||||
super(arg, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean placeBlock(BlockPlaceContext arg, BlockState arg2) {
|
||||
Direction facing = arg.getHorizontalDirection();
|
||||
arg2 = arg2.setValue(KeyboardBlockLeft.FACING, facing);
|
||||
|
||||
Direction d = KeyboardBlockLeft.mapDirection(facing);
|
||||
|
||||
if (isValid(arg.getClickedPos(), arg.getLevel(), arg2, d)) {
|
||||
Block kbRight = BlockRegistry.blockKbRight.get();
|
||||
BlockState rightState = kbRight.defaultBlockState();
|
||||
|
||||
rightState = rightState.setValue(KeyboardBlockLeft.FACING, facing);
|
||||
if (!arg.getLevel().setBlock(
|
||||
arg.getClickedPos().relative(d),
|
||||
rightState,
|
||||
11
|
||||
)) return false;
|
||||
return arg.getLevel().setBlock(arg.getClickedPos(), arg2, 11);// 161
|
||||
} else if (isValid(arg.getClickedPos().relative(d.getOpposite(), 2), arg.getLevel(), arg2, d)) {
|
||||
Block kbRight = BlockRegistry.blockKbRight.get();
|
||||
BlockState rightState = kbRight.defaultBlockState();
|
||||
|
||||
rightState = rightState.setValue(KeyboardBlockLeft.FACING, facing);
|
||||
if (!arg.getLevel().setBlock(
|
||||
arg.getClickedPos(),
|
||||
rightState,
|
||||
11
|
||||
)) return false;
|
||||
return arg.getLevel().setBlock(arg.getClickedPos().relative(d.getOpposite()), arg2, 11);// 161
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isValid(BlockPos pos, Level level, BlockState state, Direction d) {
|
||||
return level.getBlockState(pos.relative(d)).isAir();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,371 +1,370 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.montoyo.mcef.api.IBrowser;
|
||||
import net.montoyo.mcef.api.IJSQueryCallback;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.block.BlockScreen;
|
||||
import net.montoyo.wd.core.DefaultUpgrade;
|
||||
import net.montoyo.wd.core.IScreenQueryHandler;
|
||||
import net.montoyo.wd.core.IUpgrade;
|
||||
import net.montoyo.wd.core.JSServerRequest;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.server.SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class JSQueryDispatcher {
|
||||
|
||||
private static final class QueryData {
|
||||
|
||||
private final IBrowser browser;
|
||||
private final String query;
|
||||
private final String args;
|
||||
private final IJSQueryCallback callback;
|
||||
|
||||
private QueryData(IBrowser b, String q, String a, IJSQueryCallback cb) {
|
||||
browser = b;
|
||||
query = q;
|
||||
args = a;
|
||||
callback = cb;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class ServerQuery {
|
||||
|
||||
private static int lastId = 0;
|
||||
|
||||
private final TileEntityScreen tes;
|
||||
private final BlockSide side;
|
||||
private final IJSQueryCallback callback;
|
||||
private final int id;
|
||||
|
||||
private ServerQuery(TileEntityScreen t, BlockSide s, IJSQueryCallback cb) {
|
||||
tes = t;
|
||||
side = s;
|
||||
callback = cb;
|
||||
id = lastId++;
|
||||
}
|
||||
|
||||
public TileEntityScreen getTileEntity() {
|
||||
return tes;
|
||||
}
|
||||
|
||||
public BlockSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public TileEntityScreen.Screen getScreen() {
|
||||
return tes.getScreen(side);
|
||||
}
|
||||
|
||||
public void success(String resp) {
|
||||
callback.success(resp);
|
||||
}
|
||||
|
||||
public void error(int errId, String errStr) {
|
||||
callback.failure(errId, errStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final ClientProxy proxy;
|
||||
private final ArrayDeque<QueryData> queue = new ArrayDeque<>();
|
||||
private final ClientProxy.ScreenSidePair lookupResult = new ClientProxy.ScreenSidePair();
|
||||
private final HashMap<String, IScreenQueryHandler> handlers = new HashMap<>();
|
||||
private final ArrayList<ServerQuery> serverQueries = new ArrayList<>();
|
||||
private final Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
public JSQueryDispatcher(ClientProxy proxy) {
|
||||
this.proxy = proxy;
|
||||
registerDefaults();
|
||||
}
|
||||
|
||||
public void enqueueQuery(IBrowser b, String q, String a, IJSQueryCallback cb) {
|
||||
synchronized(queue) {
|
||||
queue.offer(new QueryData(b, q, a, cb));
|
||||
}
|
||||
}
|
||||
|
||||
public void handleQueries() {
|
||||
while(true) {
|
||||
QueryData next;
|
||||
synchronized(queue) {
|
||||
next = queue.poll();
|
||||
}
|
||||
|
||||
if(next == null)
|
||||
break;
|
||||
|
||||
if(proxy.findScreenFromBrowser(next.browser, lookupResult)) {
|
||||
Object[] args = (next.args == null) ? new Object[0] : parseArgs(next.args);
|
||||
|
||||
if(args == null)
|
||||
next.callback.failure(400, "Malformed request parameters");
|
||||
else {
|
||||
try {
|
||||
handlers.get(next.query).handleQuery(next.callback, lookupResult.tes, lookupResult.side, args);
|
||||
} catch(Throwable t) {
|
||||
Log.warningEx("Could not execute JS query %s(%s)", t, next.query, (next.args == null) ? "" : next.args);
|
||||
next.callback.failure(500, "Internal error");
|
||||
}
|
||||
}
|
||||
} else
|
||||
next.callback.failure(403, "A screen is required");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canHandleQuery(String q) {
|
||||
return handlers.containsKey(q);
|
||||
}
|
||||
|
||||
private static Object[] parseArgs(String args) {
|
||||
ArrayList<String> array = new ArrayList<>();
|
||||
int lastIdx = 0;
|
||||
boolean inString = false;
|
||||
boolean escape = false;
|
||||
boolean hadString = false;
|
||||
|
||||
for(int i = 0; i < args.length(); i++) {
|
||||
char chr = args.charAt(i);
|
||||
|
||||
if(inString) {
|
||||
if(escape)
|
||||
escape = false;
|
||||
else {
|
||||
if(chr == '\"')
|
||||
inString = false;
|
||||
else if(chr == '\\')
|
||||
escape = true;
|
||||
}
|
||||
} else if(chr == '\"') {
|
||||
if(hadString)
|
||||
return null;
|
||||
|
||||
inString = true;
|
||||
hadString = true;
|
||||
} else if(chr == ',') {
|
||||
array.add(args.substring(lastIdx, i).trim());
|
||||
lastIdx = i + 1;
|
||||
hadString = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(inString)
|
||||
return null; //Non terminated string
|
||||
|
||||
array.add(args.substring(lastIdx).trim());
|
||||
Object[] ret = new Object[array.size()];
|
||||
|
||||
for(int i = 0; i < ret.length; i++) {
|
||||
String str = array.get(i);
|
||||
if(str.isEmpty())
|
||||
return null; //Nah...
|
||||
|
||||
if(str.charAt(0) == '\"') //String
|
||||
ret[i] = str.substring(1, str.length() - 1);
|
||||
else {
|
||||
try {
|
||||
ret[i] = Double.parseDouble(str);
|
||||
} catch(NumberFormatException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void register(String query, IScreenQueryHandler handler) {
|
||||
handlers.put(query.toLowerCase(), handler);
|
||||
}
|
||||
|
||||
public ServerQuery fulfillQuery(int id) {
|
||||
int toRemove = -1;
|
||||
|
||||
for(int i = 0; i < serverQueries.size(); i++) {
|
||||
ServerQuery sq = serverQueries.get(i);
|
||||
|
||||
if(sq.id == id) {
|
||||
toRemove = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(toRemove < 0)
|
||||
return null;
|
||||
else
|
||||
return serverQueries.remove(toRemove);
|
||||
}
|
||||
|
||||
private void makeServerQuery(TileEntityScreen tes, BlockSide side, IJSQueryCallback cb, JSServerRequest type, Object ... data) {
|
||||
ServerQuery ret = new ServerQuery(tes, side, cb);
|
||||
serverQueries.add(ret);
|
||||
|
||||
Messages.INSTANCE.sendToServer(SMessageScreenCtrl.jsRequest(tes, side, ret.id, type, data));
|
||||
}
|
||||
|
||||
private void registerDefaults() {
|
||||
register("GetSize", (cb, tes, side, args) -> {
|
||||
Vector2i size = tes.getScreen(side).size;
|
||||
cb.success("{\"x\":" + size.x + ",\"y\":" + size.y + "}");
|
||||
});
|
||||
|
||||
register("GetRedstoneAt", (cb, tes, side, args) -> {
|
||||
if(!tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_INPUT)) {
|
||||
cb.failure(403, "Missing upgrade");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
|
||||
TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
int x = ((Double) args[0]).intValue();
|
||||
int y = ((Double) args[1]).intValue();
|
||||
|
||||
if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y)
|
||||
cb.failure(403, "Out of range");
|
||||
else {
|
||||
BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock();
|
||||
int level = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting) ? 0 : tes.getLevel().getSignal(bpos, Direction.values()[side.reverse().ordinal()]);
|
||||
cb.success("{\"level\":" + level + "}");
|
||||
}
|
||||
} else
|
||||
cb.failure(400, "Wrong arguments");
|
||||
});
|
||||
|
||||
register("GetRedstoneArray", (cb, tes, side, args) -> {
|
||||
if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_INPUT)) {
|
||||
final Direction facing = Direction.values()[side.reverse().ordinal()];
|
||||
final StringJoiner resp = new StringJoiner(",", "{\"levels\":[", "]}");
|
||||
|
||||
tes.forEachScreenBlocks(side, bp -> {
|
||||
if(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting))
|
||||
resp.add("0");
|
||||
else
|
||||
resp.add("" + tes.getLevel().getSignal(bp, facing));
|
||||
});
|
||||
|
||||
cb.success(resp.toString());
|
||||
} else
|
||||
cb.failure(403, "Missing upgrade");
|
||||
});
|
||||
|
||||
register("ClearRedstone", (cb, tes, side, args) -> {
|
||||
if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
|
||||
if(tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId()))
|
||||
makeServerQuery(tes, side, cb, JSServerRequest.CLEAR_REDSTONE);
|
||||
else
|
||||
cb.success("{\"status\":\"notOwner\"}");
|
||||
} else
|
||||
cb.failure(403, "Missing upgrade");
|
||||
});
|
||||
|
||||
register("SetRedstoneAt", (cb, tes, side, args) -> {
|
||||
if(args.length != 3 || !Arrays.stream(args).allMatch((obj) -> obj instanceof Double)) {
|
||||
cb.failure(400, "Wrong arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
|
||||
cb.failure(403, "Missing upgrade");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())) {
|
||||
cb.success("{\"status\":\"notOwner\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
int x = ((Double) args[0]).intValue();
|
||||
int y = ((Double) args[1]).intValue();
|
||||
boolean state = ((Double) args[2]) > 0.0;
|
||||
|
||||
Vector2i size = tes.getScreen(side).size;
|
||||
if(x < 0 || x >= size.x || y < 0 || y >= size.y) {
|
||||
cb.failure(403, "Out of range");
|
||||
return;
|
||||
}
|
||||
|
||||
makeServerQuery(tes, side, cb, JSServerRequest.SET_REDSTONE_AT, x, y, state);
|
||||
});
|
||||
|
||||
register("IsEmitting", (cb, tes, side, args) -> {
|
||||
if(!tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
|
||||
cb.failure(403, "Missing upgrade");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
|
||||
TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
int x = ((Double) args[0]).intValue();
|
||||
int y = ((Double) args[1]).intValue();
|
||||
|
||||
if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y)
|
||||
cb.failure(403, "Out of range");
|
||||
else {
|
||||
BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock();
|
||||
boolean e = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting);
|
||||
cb.success("{\"emitting\":" + (e ? "true" : "false") + "}");
|
||||
}
|
||||
} else
|
||||
cb.failure(400, "Wrong arguments");
|
||||
});
|
||||
|
||||
register("GetEmissionArray", (cb, tes, side, args) -> {
|
||||
if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
|
||||
final StringJoiner resp = new StringJoiner(",", "{\"emission\":[", "]}");
|
||||
tes.forEachScreenBlocks(side, bp -> resp.add(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting) ? "1" : "0"));
|
||||
cb.success(resp.toString());
|
||||
} else
|
||||
cb.failure(403, "Missing upgrade");
|
||||
});
|
||||
|
||||
register("GetLocation", (cb, tes, side, args) -> {
|
||||
if(!tes.hasUpgrade(side, DefaultUpgrade.GPS)) {
|
||||
cb.failure(403, "Missing upgrade");
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos bp = tes.getBlockPos();
|
||||
cb.success("{\"x\":" + bp.getX() + ",\"y\":" + bp.getY() + ",\"z\":" + bp.getZ() + ",\"side\":\"" + side + "\"}");
|
||||
});
|
||||
|
||||
register("GetUpgrades", (cb, tes, side, args) -> {
|
||||
final StringBuilder sb = new StringBuilder("{\"upgrades\":[");
|
||||
final ArrayList<ItemStack> upgrades = tes.getScreen(side).upgrades;
|
||||
|
||||
for(int i = 0; i < upgrades.size(); i++) {
|
||||
if(i > 0)
|
||||
sb.append(',');
|
||||
|
||||
sb.append('\"');
|
||||
sb.append(Util.addSlashes(((IUpgrade) upgrades.get(i).getItem()).getJSName(upgrades.get(i))));
|
||||
sb.append('\"');
|
||||
}
|
||||
|
||||
cb.success(sb.append("]}").toString());
|
||||
});
|
||||
|
||||
register("IsOwner", (cb, tes, side, args) -> {
|
||||
boolean res = (tes.getScreen(side).owner != null && tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId()));
|
||||
cb.success("{\"isOwner\":" + (res ? "true}" : "false}"));
|
||||
});
|
||||
|
||||
register("GetRotation", (cb, tes, side, args) -> cb.success("{\"rotation\":" + tes.getScreen(side).rotation.ordinal() + "}"));
|
||||
register("GetSide", (cb, tes, side, args) -> cb.success("{\"side\":" + tes.getScreen(side).side.ordinal() + "}"));
|
||||
}
|
||||
|
||||
}
|
||||
///*
|
||||
// * Copyright (C) 2018 BARBOTIN Nicolas
|
||||
// */
|
||||
//
|
||||
//package net.montoyo.wd.client;
|
||||
//
|
||||
//import net.minecraft.client.Minecraft;
|
||||
//import net.minecraft.core.BlockPos;
|
||||
//import net.minecraft.core.Direction;
|
||||
//import net.minecraft.world.item.ItemStack;
|
||||
//import net.minecraftforge.api.distmarker.Dist;
|
||||
//import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
//import net.montoyo.wd.block.BlockScreen;
|
||||
//import net.montoyo.wd.core.DefaultUpgrade;
|
||||
//import net.montoyo.wd.core.IScreenQueryHandler;
|
||||
//import net.montoyo.wd.core.IUpgrade;
|
||||
//import net.montoyo.wd.core.JSServerRequest;
|
||||
//import net.montoyo.wd.entity.TileEntityScreen;
|
||||
//import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
//import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl;
|
||||
//import net.montoyo.wd.utilities.*;
|
||||
//
|
||||
//import java.util.*;
|
||||
//
|
||||
//@OnlyIn(Dist.CLIENT)
|
||||
//public final class JSQueryDispatcher {
|
||||
//
|
||||
// private static final class QueryData {
|
||||
//
|
||||
// private final IBrowser browser;
|
||||
// private final String query;
|
||||
// private final String args;
|
||||
// private final IJSQueryCallback callback;
|
||||
//
|
||||
// private QueryData(IBrowser b, String q, String a, IJSQueryCallback cb) {
|
||||
// browser = b;
|
||||
// query = q;
|
||||
// args = a;
|
||||
// callback = cb;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public static final class ServerQuery {
|
||||
//
|
||||
// private static int lastId = 0;
|
||||
//
|
||||
// private final TileEntityScreen tes;
|
||||
// private final BlockSide side;
|
||||
// private final IJSQueryCallback callback;
|
||||
// private final int id;
|
||||
//
|
||||
// private ServerQuery(TileEntityScreen t, BlockSide s, IJSQueryCallback cb) {
|
||||
// tes = t;
|
||||
// side = s;
|
||||
// callback = cb;
|
||||
// id = lastId++;
|
||||
// }
|
||||
//
|
||||
// public TileEntityScreen getTileEntity() {
|
||||
// return tes;
|
||||
// }
|
||||
//
|
||||
// public BlockSide getSide() {
|
||||
// return side;
|
||||
// }
|
||||
//
|
||||
// public TileEntityScreen.Screen getScreen() {
|
||||
// return tes.getScreen(side);
|
||||
// }
|
||||
//
|
||||
// public void success(String resp) {
|
||||
// callback.success(resp);
|
||||
// }
|
||||
//
|
||||
// public void error(int errId, String errStr) {
|
||||
// callback.failure(errId, errStr);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private final ClientProxy proxy;
|
||||
// private final ArrayDeque<QueryData> queue = new ArrayDeque<>();
|
||||
// private final ClientProxy.ScreenSidePair lookupResult = new ClientProxy.ScreenSidePair();
|
||||
// private final HashMap<String, IScreenQueryHandler> handlers = new HashMap<>();
|
||||
// private final ArrayList<ServerQuery> serverQueries = new ArrayList<>();
|
||||
// private final Minecraft mc = Minecraft.getInstance();
|
||||
//
|
||||
// public JSQueryDispatcher(ClientProxy proxy) {
|
||||
// this.proxy = proxy;
|
||||
// registerDefaults();
|
||||
// }
|
||||
//
|
||||
// public void enqueueQuery(IBrowser b, String q, String a, IJSQueryCallback cb) {
|
||||
// synchronized(queue) {
|
||||
// queue.offer(new QueryData(b, q, a, cb));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void handleQueries() {
|
||||
// while(true) {
|
||||
// QueryData next;
|
||||
// synchronized(queue) {
|
||||
// next = queue.poll();
|
||||
// }
|
||||
//
|
||||
// if(next == null)
|
||||
// break;
|
||||
//
|
||||
// if(proxy.findScreenFromBrowser(next.browser, lookupResult)) {
|
||||
// Object[] args = (next.args == null) ? new Object[0] : parseArgs(next.args);
|
||||
//
|
||||
// if(args == null)
|
||||
// next.callback.failure(400, "Malformed request parameters");
|
||||
// else {
|
||||
// try {
|
||||
// handlers.get(next.query).handleQuery(next.callback, lookupResult.tes, lookupResult.side, args);
|
||||
// } catch(Throwable t) {
|
||||
// Log.warningEx("Could not execute JS query %s(%s)", t, next.query, (next.args == null) ? "" : next.args);
|
||||
// next.callback.failure(500, "Internal error");
|
||||
// }
|
||||
// }
|
||||
// } else
|
||||
// next.callback.failure(403, "A screen is required");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public boolean canHandleQuery(String q) {
|
||||
// return handlers.containsKey(q);
|
||||
// }
|
||||
//
|
||||
// private static Object[] parseArgs(String args) {
|
||||
// ArrayList<String> array = new ArrayList<>();
|
||||
// int lastIdx = 0;
|
||||
// boolean inString = false;
|
||||
// boolean escape = false;
|
||||
// boolean hadString = false;
|
||||
//
|
||||
// for(int i = 0; i < args.length(); i++) {
|
||||
// char chr = args.charAt(i);
|
||||
//
|
||||
// if(inString) {
|
||||
// if(escape)
|
||||
// escape = false;
|
||||
// else {
|
||||
// if(chr == '\"')
|
||||
// inString = false;
|
||||
// else if(chr == '\\')
|
||||
// escape = true;
|
||||
// }
|
||||
// } else if(chr == '\"') {
|
||||
// if(hadString)
|
||||
// return null;
|
||||
//
|
||||
// inString = true;
|
||||
// hadString = true;
|
||||
// } else if(chr == ',') {
|
||||
// array.add(args.substring(lastIdx, i).trim());
|
||||
// lastIdx = i + 1;
|
||||
// hadString = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(inString)
|
||||
// return null; //Non terminated string
|
||||
//
|
||||
// array.add(args.substring(lastIdx).trim());
|
||||
// Object[] ret = new Object[array.size()];
|
||||
//
|
||||
// for(int i = 0; i < ret.length; i++) {
|
||||
// String str = array.get(i);
|
||||
// if(str.isEmpty())
|
||||
// return null; //Nah...
|
||||
//
|
||||
// if(str.charAt(0) == '\"') //String
|
||||
// ret[i] = str.substring(1, str.length() - 1);
|
||||
// else {
|
||||
// try {
|
||||
// ret[i] = Double.parseDouble(str);
|
||||
// } catch(NumberFormatException ex) {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return ret;
|
||||
// }
|
||||
//
|
||||
// public void register(String query, IScreenQueryHandler handler) {
|
||||
// handlers.put(query.toLowerCase(), handler);
|
||||
// }
|
||||
//
|
||||
// public ServerQuery fulfillQuery(int id) {
|
||||
// int toRemove = -1;
|
||||
//
|
||||
// for(int i = 0; i < serverQueries.size(); i++) {
|
||||
// ServerQuery sq = serverQueries.get(i);
|
||||
//
|
||||
// if(sq.id == id) {
|
||||
// toRemove = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(toRemove < 0)
|
||||
// return null;
|
||||
// else
|
||||
// return serverQueries.remove(toRemove);
|
||||
// }
|
||||
//
|
||||
// private void makeServerQuery(TileEntityScreen tes, BlockSide side, IJSQueryCallback cb, JSServerRequest type, Object ... data) {
|
||||
// ServerQuery ret = new ServerQuery(tes, side, cb);
|
||||
// serverQueries.add(ret);
|
||||
//
|
||||
// WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.jsRequest(tes, side, ret.id, type, data));
|
||||
// }
|
||||
//
|
||||
// private void registerDefaults() {
|
||||
// VideoType.registerQueries(this);
|
||||
//
|
||||
// register("GetSize", (cb, tes, side, args) -> {
|
||||
// Vector2i size = tes.getScreen(side).size;
|
||||
// cb.success("{\"x\":" + size.x + ",\"y\":" + size.y + "}");
|
||||
// });
|
||||
//
|
||||
// register("GetRedstoneAt", (cb, tes, side, args) -> {
|
||||
// if(!tes.hasUpgrade(side, DefaultUpgrade.REDINPUT)) {
|
||||
// cb.failure(403, "Missing upgrade");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
|
||||
// TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
// int x = ((Double) args[0]).intValue();
|
||||
// int y = ((Double) args[1]).intValue();
|
||||
//
|
||||
// if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y)
|
||||
// cb.failure(403, "Out of range");
|
||||
// else {
|
||||
// BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock();
|
||||
// int level = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting) ? 0 : tes.getLevel().getSignal(bpos, Direction.values()[side.reverse().ordinal()]);
|
||||
// cb.success("{\"level\":" + level + "}");
|
||||
// }
|
||||
// } else
|
||||
// cb.failure(400, "Wrong arguments");
|
||||
// });
|
||||
//
|
||||
// register("GetRedstoneArray", (cb, tes, side, args) -> {
|
||||
// if(tes.hasUpgrade(side, DefaultUpgrade.REDINPUT)) {
|
||||
// final Direction facing = Direction.values()[side.reverse().ordinal()];
|
||||
// final StringJoiner resp = new StringJoiner(",", "{\"levels\":[", "]}");
|
||||
//
|
||||
// tes.forEachScreenBlocks(side, bp -> {
|
||||
// if(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting))
|
||||
// resp.add("0");
|
||||
// else
|
||||
// resp.add("" + tes.getLevel().getSignal(bp, facing));
|
||||
// });
|
||||
//
|
||||
// cb.success(resp.toString());
|
||||
// } else
|
||||
// cb.failure(403, "Missing upgrade");
|
||||
// });
|
||||
//
|
||||
// register("ClearRedstone", (cb, tes, side, args) -> {
|
||||
// if(tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) {
|
||||
// if(tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId()))
|
||||
// makeServerQuery(tes, side, cb, JSServerRequest.CLEAR_REDSTONE);
|
||||
// else
|
||||
// cb.success("{\"status\":\"notOwner\"}");
|
||||
// } else
|
||||
// cb.failure(403, "Missing upgrade");
|
||||
// });
|
||||
//
|
||||
// register("SetRedstoneAt", (cb, tes, side, args) -> {
|
||||
// if(args.length != 3 || !Arrays.stream(args).allMatch((obj) -> obj instanceof Double)) {
|
||||
// cb.failure(400, "Wrong arguments");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(!tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) {
|
||||
// cb.failure(403, "Missing upgrade");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(!tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())) {
|
||||
// cb.success("{\"status\":\"notOwner\"}");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int x = ((Double) args[0]).intValue();
|
||||
// int y = ((Double) args[1]).intValue();
|
||||
// boolean state = ((Double) args[2]) > 0.0;
|
||||
//
|
||||
// Vector2i size = tes.getScreen(side).size;
|
||||
// if(x < 0 || x >= size.x || y < 0 || y >= size.y) {
|
||||
// cb.failure(403, "Out of range");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// makeServerQuery(tes, side, cb, JSServerRequest.SET_REDSTONE_AT, x, y, state);
|
||||
// });
|
||||
//
|
||||
// register("IsEmitting", (cb, tes, side, args) -> {
|
||||
// if(!tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) {
|
||||
// cb.failure(403, "Missing upgrade");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
|
||||
// TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
// int x = ((Double) args[0]).intValue();
|
||||
// int y = ((Double) args[1]).intValue();
|
||||
//
|
||||
// if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y)
|
||||
// cb.failure(403, "Out of range");
|
||||
// else {
|
||||
// BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock();
|
||||
// boolean e = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting);
|
||||
// cb.success("{\"emitting\":" + (e ? "true" : "false") + "}");
|
||||
// }
|
||||
// } else
|
||||
// cb.failure(400, "Wrong arguments");
|
||||
// });
|
||||
//
|
||||
// register("GetEmissionArray", (cb, tes, side, args) -> {
|
||||
// if(tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) {
|
||||
// final StringJoiner resp = new StringJoiner(",", "{\"emission\":[", "]}");
|
||||
// tes.forEachScreenBlocks(side, bp -> resp.add(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting) ? "1" : "0"));
|
||||
// cb.success(resp.toString());
|
||||
// } else
|
||||
// cb.failure(403, "Missing upgrade");
|
||||
// });
|
||||
//
|
||||
// register("GetLocation", (cb, tes, side, args) -> {
|
||||
// if(!tes.hasUpgrade(side, DefaultUpgrade.GPS)) {
|
||||
// cb.failure(403, "Missing upgrade");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// BlockPos bp = tes.getBlockPos();
|
||||
// cb.success("{\"x\":" + bp.getX() + ",\"y\":" + bp.getY() + ",\"z\":" + bp.getZ() + ",\"side\":\"" + side + "\"}");
|
||||
// });
|
||||
//
|
||||
// register("GetUpgrades", (cb, tes, side, args) -> {
|
||||
// final StringBuilder sb = new StringBuilder("{\"upgrades\":[");
|
||||
// final ArrayList<ItemStack> upgrades = tes.getScreen(side).upgrades;
|
||||
//
|
||||
// for(int i = 0; i < upgrades.size(); i++) {
|
||||
// if(i > 0)
|
||||
// sb.append(',');
|
||||
//
|
||||
// sb.append('\"');
|
||||
// sb.append(Util.addSlashes(((IUpgrade) upgrades.get(i).getItem()).getJSName(upgrades.get(i))));
|
||||
// sb.append('\"');
|
||||
// }
|
||||
//
|
||||
// cb.success(sb.append("]}").toString());
|
||||
// });
|
||||
//
|
||||
// register("IsOwner", (cb, tes, side, args) -> {
|
||||
// boolean res = (tes.getScreen(side).owner != null && tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId()));
|
||||
// cb.success("{\"isOwner\":" + (res ? "true}" : "false}"));
|
||||
// });
|
||||
//
|
||||
// register("GetRotation", (cb, tes, side, args) -> cb.success("{\"rotation\":" + tes.getScreen(side).rotation.ordinal() + "}"));
|
||||
// register("GetSide", (cb, tes, side, args) -> cb.success("{\"side\":" + tes.getScreen(side).side.ordinal() + "}"));
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client;
|
||||
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.montoyo.wd.client.renderers.IModelBaker;
|
||||
|
||||
public class ResourceModelPair {
|
||||
|
||||
private final ModelResourceLocation resLoc;
|
||||
private final IModelBaker model;
|
||||
|
||||
public ResourceModelPair(ModelResourceLocation rl, IModelBaker m) {
|
||||
resLoc = rl;
|
||||
model = m;
|
||||
}
|
||||
|
||||
public ModelResourceLocation getResourceLocation() {
|
||||
return resLoc;
|
||||
}
|
||||
|
||||
public IModelBaker getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
/*
|
||||
package net.montoyo.wd.client;
|
||||
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class StaticStateMapper {
|
||||
|
||||
private final ModelResourceLocation resLoc;
|
||||
|
||||
public StaticStateMapper(ModelResourceLocation rl) {
|
||||
resLoc = rl;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
protected ModelResourceLocation getModelResourceLocation(@Nonnull BlockState state) {
|
||||
return resLoc;
|
||||
}
|
||||
|
||||
} */
|
||||
|
|
@ -4,103 +4,127 @@
|
|||
|
||||
package net.montoyo.wd.client;
|
||||
|
||||
import net.montoyo.mcef.api.IScheme;
|
||||
import net.montoyo.mcef.api.ISchemeResponseData;
|
||||
import net.montoyo.mcef.api.ISchemeResponseHeaders;
|
||||
import net.montoyo.mcef.api.SchemePreResponse;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.miniserv.Constants;
|
||||
import net.montoyo.wd.miniserv.client.Client;
|
||||
import net.montoyo.wd.miniserv.client.ClientTaskGetFile;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import net.montoyo.wd.utilities.serialization.Util;
|
||||
import org.cef.callback.CefCallback;
|
||||
import org.cef.handler.CefResourceHandler;
|
||||
import org.cef.misc.IntRef;
|
||||
import org.cef.misc.StringRef;
|
||||
import org.cef.network.CefRequest;
|
||||
import org.cef.network.CefResponse;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WDScheme implements IScheme {
|
||||
public class WDScheme implements CefResourceHandler {
|
||||
|
||||
private static final String ERROR_PAGE = "<!DOCTYPE html><html><head></head><body><h1>%d %s</h1><hr /><i>Miniserv powered by WebDisplays</i></body></html>";
|
||||
private ClientTaskGetFile task;
|
||||
private boolean isErrorPage;
|
||||
|
||||
String url;
|
||||
boolean onlyError = false;
|
||||
|
||||
public WDScheme(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SchemePreResponse processRequest(String url) {
|
||||
url = url.substring("wd://".length());
|
||||
public boolean processRequest(CefRequest cefRequest, CefCallback cefCallback) {
|
||||
url = cefRequest.getURL();
|
||||
|
||||
url = url.substring("webdisplays://".length());
|
||||
|
||||
int pos = url.indexOf('/');
|
||||
if(pos < 0)
|
||||
return SchemePreResponse.NOT_HANDLED;
|
||||
if (pos < 0)
|
||||
return false;
|
||||
|
||||
String uuidStr = url.substring(0, pos);
|
||||
String fileStr = url.substring(pos + 1);
|
||||
|
||||
try {
|
||||
fileStr = URLDecoder.decode(fileStr, "UTF-8");
|
||||
} catch(UnsupportedEncodingException ex) {
|
||||
Log.warningEx("UTF-8 isn't supported... yeah... and I'm a billionaire...", ex);
|
||||
}
|
||||
fileStr = URLDecoder.decode(fileStr, StandardCharsets.UTF_8);
|
||||
|
||||
if(uuidStr.isEmpty() || Util.isFileNameInvalid(fileStr))
|
||||
return SchemePreResponse.NOT_HANDLED;
|
||||
if (uuidStr.isEmpty() || Util.isFileNameInvalid(fileStr)) {
|
||||
// invalid URL or no UUID
|
||||
onlyError = true;
|
||||
cefCallback.Continue();
|
||||
return true;
|
||||
}
|
||||
|
||||
UUID uuid;
|
||||
try {
|
||||
uuid = UUID.fromString(uuidStr);
|
||||
} catch(IllegalArgumentException ex) {
|
||||
return SchemePreResponse.NOT_HANDLED; //Invalid UUID
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// invalid UUID
|
||||
onlyError = true;
|
||||
cefCallback.Continue();
|
||||
return true;
|
||||
}
|
||||
|
||||
task = new ClientTaskGetFile(uuid, fileStr);
|
||||
return Client.getInstance().addTask(task) ? SchemePreResponse.HANDLED_CONTINUE : SchemePreResponse.NOT_HANDLED;
|
||||
boolean doContinue = Client.getInstance().addTask(task);
|
||||
if (doContinue) cefCallback.Continue();
|
||||
return doContinue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getResponseHeaders(ISchemeResponseHeaders resp) {
|
||||
Log.info("Waiting for response...");
|
||||
int status = task.waitForResponse();
|
||||
Log.info("Got response %d", status);
|
||||
public void getResponseHeaders(CefResponse cefResponse, IntRef contentLength, StringRef redir) {
|
||||
int status;
|
||||
if (onlyError) {
|
||||
status = Constants.GETF_STATUS_BAD_NAME;
|
||||
} else {
|
||||
Log.info("Waiting for response...");
|
||||
status = task.waitForResponse();
|
||||
Log.info("Got response %d", status);
|
||||
|
||||
if(status == 0) {
|
||||
//OK
|
||||
int extPos = task.getFileName().lastIndexOf('.');
|
||||
if(extPos >= 0) {
|
||||
String mime = ((ClientProxy) WebDisplays.PROXY).getMCEF().mimeTypeFromExtension(task.getFileName().substring(extPos + 1));
|
||||
if (status == 0) {
|
||||
//OK
|
||||
int extPos = task.getFileName().lastIndexOf('.');
|
||||
if (extPos >= 0) {
|
||||
String mime = mapMime(task.getFileName().substring(extPos + 1));
|
||||
|
||||
if(mime != null)
|
||||
resp.setMimeType(mime);
|
||||
if (mime != null)
|
||||
cefResponse.setMimeType(mime);
|
||||
}
|
||||
|
||||
cefResponse.setStatus(200);
|
||||
cefResponse.setStatusText("OK");
|
||||
contentLength.set(0);
|
||||
return;
|
||||
}
|
||||
|
||||
resp.setStatus(200);
|
||||
resp.setStatusText("OK");
|
||||
resp.setResponseLength(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
int errCode;
|
||||
String errStr;
|
||||
|
||||
if(status == Constants.GETF_STATUS_NOT_FOUND) {
|
||||
if (status == Constants.GETF_STATUS_NOT_FOUND) {
|
||||
errCode = 404;
|
||||
errStr = "Not Found";
|
||||
} else if (status == Constants.GETF_STATUS_TIMED_OUT) {
|
||||
errCode = 408;
|
||||
errStr = "Timed Out";
|
||||
} else if (status == Constants.GETF_STATUS_BAD_NAME) {
|
||||
errCode = 418;
|
||||
errStr = "I'm a teapot";
|
||||
} else {
|
||||
errCode = 500;
|
||||
errStr = "Internal Server Error";
|
||||
}
|
||||
|
||||
resp.setStatus(errCode);
|
||||
resp.setStatusText(errStr);
|
||||
// reporting the actual status and text makes CEF not display the page
|
||||
cefResponse.setStatus(200);
|
||||
cefResponse.setStatusText("OK");
|
||||
cefResponse.setMimeType("text/html");
|
||||
|
||||
try {
|
||||
dataToWrite = String.format(ERROR_PAGE, errCode, errStr).getBytes("UTF-8");
|
||||
dataOffset = 0;
|
||||
amountToWrite = dataToWrite.length;
|
||||
isErrorPage = true;
|
||||
resp.setResponseLength(amountToWrite);
|
||||
} catch(UnsupportedEncodingException ex) {
|
||||
resp.setResponseLength(0);
|
||||
}
|
||||
dataToWrite = String.format(ERROR_PAGE, errCode, errStr).getBytes(StandardCharsets.UTF_8);
|
||||
dataOffset = 0;
|
||||
amountToWrite = dataToWrite.length;
|
||||
isErrorPage = true;
|
||||
contentLength.set(0);
|
||||
}
|
||||
|
||||
private byte[] dataToWrite;
|
||||
|
|
@ -108,10 +132,10 @@ public class WDScheme implements IScheme {
|
|||
private int amountToWrite;
|
||||
|
||||
@Override
|
||||
public boolean readResponse(ISchemeResponseData data) {
|
||||
if(dataToWrite == null) {
|
||||
if(isErrorPage) {
|
||||
data.setAmountRead(0);
|
||||
public boolean readResponse(byte[] output, int bytesToRead, IntRef bytesRead, CefCallback cefCallback) {
|
||||
if (dataToWrite == null) {
|
||||
if (isErrorPage) {
|
||||
bytesRead.set(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -119,25 +143,25 @@ public class WDScheme implements IScheme {
|
|||
dataOffset = 3; //packet ID + size
|
||||
amountToWrite = task.getDataLength();
|
||||
|
||||
if(amountToWrite <= 0) {
|
||||
if (amountToWrite <= 0) {
|
||||
dataToWrite = null;
|
||||
data.setAmountRead(0);
|
||||
bytesRead.set(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int toWrite = data.getBytesToRead();
|
||||
if(toWrite > amountToWrite)
|
||||
int toWrite = bytesToRead;
|
||||
if (toWrite > amountToWrite)
|
||||
toWrite = amountToWrite;
|
||||
|
||||
System.arraycopy(dataToWrite, dataOffset, data.getDataArray(), 0, toWrite);
|
||||
data.setAmountRead(toWrite);
|
||||
System.arraycopy(dataToWrite, dataOffset, output, 0, toWrite);
|
||||
bytesRead.set(toWrite);
|
||||
|
||||
dataOffset += toWrite;
|
||||
amountToWrite -= toWrite;
|
||||
|
||||
if(amountToWrite <= 0) {
|
||||
if(!isErrorPage)
|
||||
if (amountToWrite <= 0) {
|
||||
if (!isErrorPage)
|
||||
task.nextData();
|
||||
|
||||
dataToWrite = null;
|
||||
|
|
@ -146,4 +170,46 @@ public class WDScheme implements IScheme {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
Log.info("Scheme query canceled or finished.");
|
||||
if (!onlyError)
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
public static String mapMime(String ext) {
|
||||
switch (ext) {
|
||||
case "htm":
|
||||
case "html":
|
||||
return "text/html";
|
||||
|
||||
case "css":
|
||||
return "text/css";
|
||||
|
||||
case "js":
|
||||
return "text/javascript";
|
||||
|
||||
case "png":
|
||||
return "image/png";
|
||||
|
||||
case "jpg":
|
||||
case "jpeg":
|
||||
return "image/jpeg";
|
||||
|
||||
case "gif":
|
||||
return "image/gif";
|
||||
|
||||
case "svg":
|
||||
return "image/svg+xml";
|
||||
|
||||
case "xml":
|
||||
return "text/xml";
|
||||
|
||||
case "txt":
|
||||
return "text/plain";
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
116
src/main/java/net/montoyo/wd/client/audio/WDAudioSource.java
Normal file
116
src/main/java/net/montoyo/wd/client/audio/WDAudioSource.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
package net.montoyo.wd.client.audio;
|
||||
|
||||
import net.minecraft.client.resources.sounds.Sound;
|
||||
import net.minecraft.client.resources.sounds.SoundInstance;
|
||||
import net.minecraft.client.sounds.AudioStream;
|
||||
import net.minecraft.client.sounds.SoundBufferLibrary;
|
||||
import net.minecraft.client.sounds.SoundManager;
|
||||
import net.minecraft.client.sounds.WeighedSoundEvents;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.valueproviders.SampledFloat;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class WDAudioSource implements SoundInstance {
|
||||
private static final ResourceLocation location = new ResourceLocation("webdisplays:audio_source");
|
||||
private static final WeighedSoundEvents events = new WeighedSoundEvents(
|
||||
location, "webdisplays.browser"
|
||||
);
|
||||
private static final SampledFloat CONST_1 = new SampledFloat() {
|
||||
@Override
|
||||
public float sample(RandomSource pRandom) {
|
||||
return 1.0f;
|
||||
}
|
||||
};
|
||||
private final Sound sound = new Sound(
|
||||
"unused",
|
||||
CONST_1,
|
||||
CONST_1,
|
||||
1, Sound.Type.SOUND_EVENT,
|
||||
true, false,
|
||||
100
|
||||
);
|
||||
ScreenBlockEntity blockEntity;
|
||||
ScreenData data;
|
||||
|
||||
public WDAudioSource(ScreenBlockEntity blockEntity, ScreenData data) {
|
||||
this.blockEntity = blockEntity;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public WeighedSoundEvents resolve(SoundManager pManager) {
|
||||
return events;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<AudioStream> getStream(SoundBufferLibrary soundBuffers, Sound sound, boolean looping) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sound getSound() {
|
||||
return sound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundSource getSource() {
|
||||
return SoundSource.RECORDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLooping() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRelative() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDelay() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getVolume() {
|
||||
return blockEntity.ytVolume;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getPitch() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return blockEntity.getBlockPos().getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return blockEntity.getBlockPos().getY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZ() {
|
||||
return blockEntity.getBlockPos().getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attenuation getAttenuation() {
|
||||
return Attenuation.LINEAR;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,53 +4,59 @@
|
|||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import com.sun.jna.platform.unix.X11;
|
||||
import com.cinemamod.mcef.MCEFBrowser;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Axis;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.event.InputEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.loading.FMLPaths;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.gui.camera.KeyboardCamera;
|
||||
import net.montoyo.wd.client.gui.controls.Button;
|
||||
import net.montoyo.wd.client.gui.controls.Control;
|
||||
import net.montoyo.wd.client.gui.controls.Label;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.server.SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.controls.builtin.ClickControl;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
import net.montoyo.wd.utilities.TypeData;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import org.apache.commons.lang3.CharUtils;
|
||||
import org.cef.browser.CefBrowserOsr;
|
||||
import org.jline.utils.Display;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector2i;
|
||||
import net.montoyo.wd.utilities.serialization.TypeData;
|
||||
import net.montoyo.wd.utilities.serialization.Util;
|
||||
import org.cef.browser.CefBrowser;
|
||||
import org.cef.misc.CefCursorType;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector4f;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.vivecraft.client_vr.gameplay.VRPlayer;
|
||||
import org.vivecraft.client_vr.gameplay.screenhandlers.KeyboardHandler;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.mojang.blaze3d.platform.InputConstants.*;
|
||||
import static java.awt.event.KeyEvent.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class GuiKeyboard extends WDScreen {
|
||||
|
||||
private static final String WARNING_FNAME = "wd_keyboard_warning.txt";
|
||||
|
||||
private TileEntityScreen tes;
|
||||
private ScreenBlockEntity tes;
|
||||
private BlockSide side;
|
||||
private ScreenData data;
|
||||
private final ArrayList<TypeData> evStack = new ArrayList<>();
|
||||
private BlockPos kbPos;
|
||||
private boolean showWarning = true;
|
||||
|
|
@ -65,7 +71,7 @@ public class GuiKeyboard extends WDScreen {
|
|||
super(Component.nullToEmpty(null));
|
||||
}
|
||||
|
||||
public GuiKeyboard(TileEntityScreen tes, BlockSide side, BlockPos kbPos) {
|
||||
public GuiKeyboard(ScreenBlockEntity tes, BlockSide side, BlockPos kbPos) {
|
||||
this();
|
||||
this.tes = tes;
|
||||
this.side = side;
|
||||
|
|
@ -77,6 +83,30 @@ public class GuiKeyboard extends WDScreen {
|
|||
vars.put("showWarning", showWarning ? 1.0 : 0.0);
|
||||
}
|
||||
|
||||
private static final boolean vivecraftPresent;
|
||||
|
||||
static {
|
||||
boolean vivePres = false;
|
||||
if (ModList.get().isLoaded("vivecraft")) vivePres = true;
|
||||
// I believe the non-mixin version of vivecraft is not a proper mod, so
|
||||
// detect the mod reflectively if the mod is not found
|
||||
else {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("org.vivecraft.gameplay.screenhandlers.KeyboardHandler");
|
||||
//noinspection ConstantConditions
|
||||
if (clazz == null) vivePres = false;
|
||||
else {
|
||||
Method m = clazz.getMethod("setOverlayShowing", boolean.class);
|
||||
//noinspection ConstantConditions
|
||||
vivePres = m != null;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
vivePres = false;
|
||||
}
|
||||
}
|
||||
vivecraftPresent = vivePres;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
|
@ -122,64 +152,77 @@ public class GuiKeyboard extends WDScreen {
|
|||
|
||||
defaultBackground = showWarning;
|
||||
syncTicks = 5;
|
||||
|
||||
if (vivecraftPresent)
|
||||
if (VRPlayer.get() != null)
|
||||
KeyboardHandler.setOverlayShowing(true);
|
||||
|
||||
KeyboardCamera.focus(tes, side);
|
||||
|
||||
data = tes.getScreen(side);
|
||||
CefBrowser browser = data.browser;
|
||||
((MCEFBrowser) browser).setCursor(CefCursorType.fromId(data.mouseType));
|
||||
((MCEFBrowser) browser).setCursorChangeListener((id) -> {
|
||||
data.mouseType = id;
|
||||
((MCEFBrowser) browser).setCursor(CefCursorType.fromId(id));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
super.removed();
|
||||
if (vivecraftPresent)
|
||||
if (VRPlayer.get() != null)
|
||||
KeyboardHandler.setOverlayShowing(false);
|
||||
KeyboardCamera.focus(null, null);
|
||||
CefBrowser browser = data.browser;
|
||||
if (browser instanceof MCEFBrowser mcef) {
|
||||
mcef.setCursor(CefCursorType.POINTER);
|
||||
mcef.setCursorChangeListener((cursor) -> data.mouseType = cursor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
removed();
|
||||
super.onClose();
|
||||
this.minecraft.popGuiLayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
key(keyCode, scanCode, true, modifiers);
|
||||
if (quitOnEscape && keyCode == GLFW.GLFW_KEY_ESCAPE) {
|
||||
onClose();
|
||||
return true;
|
||||
}
|
||||
addKey(new TypeData(TypeData.Action.PRESS, keyCode, modifiers, scanCode));
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char codePoint, int modifiers) {
|
||||
addKey(new TypeData(TypeData.Action.TYPE, codePoint, modifiers, 0));
|
||||
return super.charTyped(codePoint, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
|
||||
key(keyCode, scanCode, false, modifiers);
|
||||
addKey(new TypeData(TypeData.Action.RELEASE, keyCode, modifiers, scanCode));
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public void key(int keyCode, int scanCode, boolean pressed, int mod) {
|
||||
if (pressed) {
|
||||
if(quitOnEscape && keyCode == GLFW.GLFW_KEY_ESCAPE) {
|
||||
Minecraft.getInstance().setScreen(null);
|
||||
}
|
||||
void addKey(TypeData data) {
|
||||
tes.type(side, "[" + WebDisplays.GSON.toJson(data) + "]", kbPos);
|
||||
|
||||
int chr = getChar(keyCode, scanCode);
|
||||
evStack.add(new TypeData(TypeData.Action.PRESS, chr, mod));
|
||||
evStack.add(new TypeData(TypeData.Action.RELEASE, chr, mod));
|
||||
|
||||
if (keyCode != 0)
|
||||
evStack.add(new TypeData(TypeData.Action.TYPE, chr, mod));
|
||||
|
||||
if (!evStack.isEmpty() && !syncRequested())
|
||||
requestSync();
|
||||
}
|
||||
}
|
||||
|
||||
public int getChar(int keyCode, int scanCode) {
|
||||
String keystr = GLFW.glfwGetKeyName(keyCode, scanCode);
|
||||
if(keystr == null){
|
||||
keystr = "\0";
|
||||
}
|
||||
if(keyCode == GLFW.GLFW_KEY_ENTER){
|
||||
return 13;
|
||||
}
|
||||
if (keyCode == GLFW.GLFW_KEY_SPACE) {
|
||||
return 32;
|
||||
}
|
||||
if(keystr.length() == 0){
|
||||
return -1;
|
||||
}
|
||||
if(hasShiftDown()) {
|
||||
keystr = keystr.toUpperCase(Locale.ROOT);
|
||||
return CefBrowserOsr.remapKeycode(keyCode, keystr.charAt(keystr.length() - 1));
|
||||
} else {
|
||||
return CefBrowserOsr.remapKeycode(keyCode, keystr.charAt(keystr.length() - 1));
|
||||
}
|
||||
evStack.add(data);
|
||||
if (!evStack.isEmpty() && !syncRequested())
|
||||
requestSync();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sync() {
|
||||
if(!evStack.isEmpty()) {
|
||||
Messages.INSTANCE.sendToServer(SMessageScreenCtrl.type(tes, side, WebDisplays.GSON.toJson(evStack), kbPos));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.type(tes, side, WebDisplays.GSON.toJson(evStack), kbPos));
|
||||
evStack.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -207,7 +250,7 @@ public class GuiKeyboard extends WDScreen {
|
|||
|
||||
private boolean hasUserReadWarning() {
|
||||
try {
|
||||
File f = new File(FMLPaths.GAMEDIR.name(), WARNING_FNAME);
|
||||
File f = new File(FMLPaths.GAMEDIR.get().toString(), WARNING_FNAME);
|
||||
|
||||
if(f.exists()) {
|
||||
BufferedReader br = new BufferedReader(new FileReader(f));
|
||||
|
|
@ -225,7 +268,7 @@ public class GuiKeyboard extends WDScreen {
|
|||
|
||||
private void writeUserAcknowledge() {
|
||||
try {
|
||||
File f = new File(FMLPaths.GAMEDIR.name(), WARNING_FNAME);
|
||||
File f = new File(FMLPaths.GAMEDIR.get().toString(), WARNING_FNAME);
|
||||
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
|
||||
bw.write("read\n");
|
||||
|
|
@ -240,4 +283,89 @@ public class GuiKeyboard extends WDScreen {
|
|||
return bp.equals(kbPos) || (bp.equals(tes.getBlockPos()) && side == this.side);
|
||||
}
|
||||
|
||||
protected void mouse(double mouseX, double mouseY, Consumer<Vector2i> func) {
|
||||
float pct = Minecraft.getInstance().getPartialTick();
|
||||
|
||||
double fov = Minecraft.getInstance().gameRenderer.getFov(
|
||||
Minecraft.getInstance().getEntityRenderDispatcher().camera,
|
||||
pct, true
|
||||
);
|
||||
|
||||
mouseX /= width;
|
||||
mouseY /= height;
|
||||
|
||||
mouseX -= 0.5;
|
||||
mouseY -= 0.5;
|
||||
mouseY = -mouseY;
|
||||
|
||||
Matrix4f proj = Minecraft.getInstance().gameRenderer.getProjectionMatrix(fov);
|
||||
|
||||
Entity e = Minecraft.getInstance().getEntityRenderDispatcher().camera.getEntity();
|
||||
|
||||
PoseStack camera = new PoseStack();
|
||||
float[] angle = KeyboardCamera.getAngle(e, pct);
|
||||
camera.mulPose(Axis.XP.rotationDegrees(angle[0]));
|
||||
camera.mulPose(Axis.YP.rotationDegrees(angle[1] + 180.0F));
|
||||
|
||||
Vector4f coord = new Vector4f(2f * (float) mouseX, 2 * (float) mouseY, 0, 1f);
|
||||
coord.add(proj.invert().transform(coord));
|
||||
coord = camera.last().pose().invert().transform(coord);
|
||||
|
||||
Vec3 vec3 = e.getEyePosition(pct);
|
||||
Vec3 vec31 = new Vec3(coord.x, coord.y, coord.z).normalize();
|
||||
|
||||
BlockHitResult result = tes.trace(side, vec3, vec31);
|
||||
if (result.getType() != HitResult.Type.MISS) {
|
||||
tes.interact(result, func);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(double mouseX, double mouseY) {
|
||||
mouse(mouseX, mouseY, (hit) -> {
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.MOVE, hit, -1);
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserMove(tes, side, hit));
|
||||
});
|
||||
|
||||
super.mouseMoved(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
mouse(mouseX, mouseY, (hit) -> {
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.MOVE, hit, -1);
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.DOWN, hit, button);
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserDown(tes, side, hit, button));
|
||||
});
|
||||
|
||||
KeyboardCamera.setMouse(button, true);
|
||||
|
||||
return super.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
mouse(mouseX, mouseY, (hit) -> {
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.MOVE, hit, -1);
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.UP, hit, button);
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserUp(tes, side, button));
|
||||
});
|
||||
|
||||
KeyboardCamera.setMouse(button, false);
|
||||
|
||||
return super.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
double mouseX = Minecraft.getInstance().mouseHandler.xpos() / Minecraft.getInstance().getWindow().getWidth();
|
||||
double mouseY = Minecraft.getInstance().mouseHandler.ypos() / Minecraft.getInstance().getWindow().getHeight();
|
||||
|
||||
mouse(mouseX * width, mouseY * height, (hit) -> {
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.MOVE, hit, -1);
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserMove(tes, side, hit));
|
||||
});
|
||||
|
||||
super.tick();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,180 +4,354 @@
|
|||
|
||||
package net.montoyo.wd.client.gui;
|
||||
|
||||
import com.cinemamod.mcef.MCEFBrowser;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.locale.Language;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.browser.WDBrowser;
|
||||
import net.montoyo.wd.utilities.browser.handlers.js.Scripts;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import org.cef.misc.CefCursorType;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static net.minecraftforge.api.distmarker.Dist.CLIENT;
|
||||
import static org.lwjgl.opengl.GL11.glColor4f;
|
||||
|
||||
@OnlyIn(CLIENT)
|
||||
public class GuiMinePad extends WDScreen {
|
||||
|
||||
private ClientProxy.PadData pad;
|
||||
private double vx;
|
||||
private double vy;
|
||||
private double vw;
|
||||
private double vh;
|
||||
private ClientProxy.PadData pad;
|
||||
private double vx;
|
||||
private double vy;
|
||||
private double vw;
|
||||
private double vh;
|
||||
|
||||
public GuiMinePad() {
|
||||
super(Component.nullToEmpty(null));
|
||||
}
|
||||
public GuiMinePad() {
|
||||
super(Component.nullToEmpty(null));
|
||||
}
|
||||
|
||||
public GuiMinePad(ClientProxy.PadData pad) {
|
||||
this();
|
||||
this.pad = pad;
|
||||
}
|
||||
public GuiMinePad(ClientProxy.PadData pad) {
|
||||
this();
|
||||
this.pad = pad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
int trueWidth, trueHeight;
|
||||
|
||||
vw = ((double) width) - 32.0f;
|
||||
vh = vw / WebDisplays.PAD_RATIO;
|
||||
vx = 16.0f;
|
||||
vy = (((double) height) - vh) / 2.0f;
|
||||
}
|
||||
@Override
|
||||
public void init() {
|
||||
vw = ((double) width) - 32.0f;
|
||||
vh = vw / WebDisplays.PAD_RATIO;
|
||||
vx = 16.0f;
|
||||
vy = (((double) height) - vh) / 2.0f;
|
||||
|
||||
private static void addRect(BufferBuilder bb, double x, double y, double w, double h) {
|
||||
bb.vertex(x, y, 0.0).endVertex();
|
||||
bb.vertex(x + w, y, 0.0).endVertex();
|
||||
bb.vertex(x + w, y + h, 0.0).endVertex();
|
||||
bb.vertex(x, y + h, 0.0).endVertex();
|
||||
}
|
||||
trueWidth = width;
|
||||
trueHeight = height;
|
||||
|
||||
@Override
|
||||
public void render(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
renderBackground(poseStack);
|
||||
this.width = (int) vw;
|
||||
this.height = (int) vh;
|
||||
|
||||
RenderSystem.disableTexture();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.setShaderColor(0.73f, 0.73f, 0.73f, 1.0f);
|
||||
super.init();
|
||||
|
||||
Tesselator t = Tesselator.getInstance();
|
||||
BufferBuilder bb = t.getBuilder();
|
||||
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
|
||||
addRect(bb, vx, vy - 16, vw, 16);
|
||||
addRect(bb, vx, vy + vh, vw, 16);
|
||||
addRect(bb, vx - 16, vy, 16, vh);
|
||||
addRect(bb, vx + vw, vy, 16, vh);
|
||||
t.end();
|
||||
((MCEFBrowser) pad.view).setCursor(CefCursorType.fromId(pad.activeCursor));
|
||||
((MCEFBrowser) pad.view).setCursorChangeListener((id) -> {
|
||||
pad.activeCursor = id;
|
||||
((MCEFBrowser) pad.view).setCursor(CefCursorType.fromId(id));
|
||||
});
|
||||
}
|
||||
|
||||
RenderSystem.enableTexture();
|
||||
private static void addRect(BufferBuilder bb, double x, double y, double w, double h) {
|
||||
bb.vertex(x, y, 0.0).color(255, 255, 255, 255).endVertex();
|
||||
bb.vertex(x + w, y, 0.0).color(255, 255, 255, 255).endVertex();
|
||||
bb.vertex(x + w, y + h, 0.0).color(255, 255, 255, 255).endVertex();
|
||||
bb.vertex(x, y + h, 0.0).color(255, 255, 255, 255).endVertex();
|
||||
}
|
||||
|
||||
if (pad.view != null) {
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
pad.view.draw(poseStack, vx, vy + vh, vx + vw, vy);
|
||||
}
|
||||
@Override
|
||||
public void render(GuiGraphics graphics, int mouseX, int mouseY, float ptt) {
|
||||
width = trueWidth;
|
||||
height = trueHeight;
|
||||
renderBackground(graphics);
|
||||
width = (int) vw;
|
||||
height = (int) vh;
|
||||
|
||||
RenderSystem.enableCull();
|
||||
}
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.setShaderColor(0.73f, 0.73f, 0.73f, 1.0f);
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
key(keyCode, scanCode, true);
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
Tesselator t = Tesselator.getInstance();
|
||||
BufferBuilder bb = t.getBuilder();
|
||||
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
addRect(bb, vx, vy - 16, vw, 16);
|
||||
addRect(bb, vx, vy + vh, vw, 16);
|
||||
addRect(bb, vx - 16, vy, 16, vh);
|
||||
addRect(bb, vx + vw, vy, 16, vh);
|
||||
t.end();
|
||||
|
||||
if (pad.view != null) {
|
||||
// pad.view.draw(poseStack, vx, vy + vh, vx + vw, vy);
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
|
||||
RenderSystem.setShaderTexture(0, ((MCEFBrowser) pad.view).getRenderer().getTextureID());
|
||||
t = Tesselator.getInstance();
|
||||
BufferBuilder buffer = t.getBuilder();
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
|
||||
double x1 = vx;
|
||||
double y1 = vy;
|
||||
double x2 = vx + vw;
|
||||
double y2 = vy + vh;
|
||||
buffer.vertex(graphics.pose().last().pose(), (float) x1, (float) y1, 0.0f).uv(0.0F, 0.0F).color(255, 255, 255, 255).endVertex();
|
||||
buffer.vertex(graphics.pose().last().pose(), (float) x2, (float) y1, 0.0f).uv(1.0F, 0.0F).color(255, 255, 255, 255).endVertex();
|
||||
buffer.vertex(graphics.pose().last().pose(), (float) x2, (float) y2, 0.0f).uv(1.0F, 1.0F).color(255, 255, 255, 255).endVertex();
|
||||
buffer.vertex(graphics.pose().last().pose(), (float) x1, (float) y2, 0.0f).uv(0.0F, 1.0F).color(255, 255, 255, 255).endVertex();
|
||||
t.end();
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
|
||||
RenderSystem.enableCull();
|
||||
|
||||
@Override
|
||||
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
|
||||
key(keyCode, scanCode, false);
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
graphics.drawString(
|
||||
minecraft.font, Language.getInstance().getOrDefault(
|
||||
"webdisplays.gui.minepad.close"
|
||||
), (int) vx + 4, (int) vy - minecraft.font.lineHeight - 3, 16777215, true
|
||||
);
|
||||
}
|
||||
|
||||
public void key(int keyCode, int scanCode, boolean pressed) {
|
||||
Optional<Character> key = getChar(keyCode, scanCode);
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
return this.keyChanged(keyCode, scanCode, modifiers, true) || super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
if (pad.view != null && key.isPresent()) {
|
||||
char c = key.get();
|
||||
@Override
|
||||
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
|
||||
return this.keyChanged(keyCode, scanCode, modifiers, false) || super.keyReleased(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
if (pressed)
|
||||
pad.view.injectKeyPressedByKeyCode(keyCode, c, 0);
|
||||
else
|
||||
pad.view.injectKeyReleasedByKeyCode(keyCode, c, 0);
|
||||
@Override
|
||||
public boolean charTyped(char codePoint, int modifiers) {
|
||||
if (pad.view != null) {
|
||||
((MCEFBrowser) pad.view).sendKeyTyped(codePoint, modifiers);
|
||||
return true;
|
||||
} else {
|
||||
return super.charTyped(codePoint, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
if (c != 0)
|
||||
pad.view.injectKeyTyped(c, 0);
|
||||
}
|
||||
/* copied from MCEF */
|
||||
public boolean keyChanged(int keyCode, int scanCode, int modifiers, boolean pressed) {
|
||||
assert minecraft != null;
|
||||
if ((modifiers & GLFW.GLFW_MOD_SHIFT) == GLFW.GLFW_MOD_SHIFT && keyCode == GLFW.GLFW_KEY_ESCAPE) {
|
||||
onClose();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
InputConstants.Key iuKey = InputConstants.getKey(keyCode, scanCode);
|
||||
String keystr = iuKey.getDisplayName().getString();
|
||||
// System.out.println("KEY STR " + keystr);
|
||||
if (keystr.length() == 0)
|
||||
return false;
|
||||
|
||||
@Override
|
||||
public void mouseMoved(double mouseX, double mouseY) {
|
||||
super.mouseMoved(mouseX, mouseY);
|
||||
mouse(-1, false, (int) mouseX, (int) mouseY);
|
||||
}
|
||||
char key = keystr.charAt(keystr.length() - 1);
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
mouse(button, true, (int) mouseX, (int) mouseY);
|
||||
return super.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
if (keystr.equals("Enter")) {
|
||||
keyCode = 10;
|
||||
key = '\n';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
mouse(button, false, (int) mouseX, (int) mouseY);
|
||||
return super.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
if (pad.view != null) {
|
||||
if (pressed)
|
||||
((MCEFBrowser) pad.view).sendKeyPress(keyCode, scanCode, modifiers);
|
||||
else
|
||||
((MCEFBrowser) pad.view).sendKeyRelease(keyCode, scanCode, modifiers);
|
||||
|
||||
public void mouse(int btn, boolean pressed, int sx, int sy) {
|
||||
if (pressed && key == '\n')
|
||||
if (modifiers != 0) ((MCEFBrowser) pad.view).sendKeyTyped('\r', modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
int vx = screen2DisplayX((int) this.vx);
|
||||
int vy = screen2DisplayY((int) this.vy);
|
||||
int vh = screen2DisplayX((int) this.vh);
|
||||
int vw = screen2DisplayY((int) this.vw);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pad.view != null && sx >= vx && sx <= vx + vw && sy >= vy && sy <= vy + vh) {
|
||||
sx -= vx;
|
||||
sy -= vy;
|
||||
sy = vh - sy;
|
||||
@Override
|
||||
public void mouseMoved(double mouseX, double mouseY) {
|
||||
super.mouseMoved(mouseX, mouseY);
|
||||
mouse(-1, false, (int) mouseX, (int) mouseY, 0);
|
||||
}
|
||||
|
||||
//Scale again according to the webview
|
||||
sx = (int) (((double) sx) / ((double) vw) * WebDisplays.INSTANCE.padResX);
|
||||
sy = (int) (((double) sy) / ((double) vh) * WebDisplays.INSTANCE.padResY);
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
mouse(button, true, (int) mouseX, (int) mouseY, 0);
|
||||
return super.mouseClicked(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
if (btn == -1)
|
||||
pad.view.injectMouseMove(sx, sy, 0, false);
|
||||
else
|
||||
pad.view.injectMouseButton(sx, sy, 0, btn + 1, pressed, 1);
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
mouse(button, false, (int) mouseX, (int) mouseY, 0);
|
||||
return super.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
|
||||
double mx = (mouseX - vx) / vw;
|
||||
double my = (mouseY - vy) / vh;
|
||||
int sx = (int) (mx * WebDisplays.INSTANCE.padResX);
|
||||
int sy = (int) (my * WebDisplays.INSTANCE.padResY);
|
||||
// TODO: this doesn't work, and I don't understand why?
|
||||
((MCEFBrowser) pad.view).sendMouseWheel(sx, sy, amount, (hasControlDown() && !hasAltDown() && !hasShiftDown()) ? GLFW.GLFW_MOD_CONTROL : 0);
|
||||
|
||||
public static Optional<Character> getChar(int keyCode, int scanCode) {
|
||||
String keystr = GLFW.glfwGetKeyName(keyCode, scanCode);
|
||||
if(keystr == null){
|
||||
keystr = "\0";
|
||||
}
|
||||
if(keyCode == GLFW.GLFW_KEY_ENTER){
|
||||
keystr = "\n";
|
||||
}
|
||||
if(keystr.length() == 0){
|
||||
return Optional.empty();
|
||||
}
|
||||
return super.mouseScrolled(mouseX, mouseY, amount);
|
||||
}
|
||||
|
||||
return Optional.of(keystr.charAt(keystr.length() - 1));
|
||||
}
|
||||
public void capturedMouse(double scaledX, double scaledY, int sx, int sy) {
|
||||
double centerX = (int) (0.5 * (double) this.minecraft.getWindow().getGuiScaledWidth());
|
||||
double centerY = (int) (0.5 * (double) this.minecraft.getWindow().getGuiScaledHeight());
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if(pad.view == null)
|
||||
minecraft.setScreen(null); //In case the user dies with the pad in the hand
|
||||
}
|
||||
if (sx == (int) centerX && sy == (int) centerY) return;
|
||||
|
||||
@Override
|
||||
public boolean isForBlock(BlockPos bp, BlockSide side) {
|
||||
return false;
|
||||
}
|
||||
double mx = (centerX - vx) / vw;
|
||||
double my = (centerY - vy) / vh;
|
||||
double scaledCentX = (mx * WebDisplays.INSTANCE.padResX);
|
||||
double scaledCentY = (my * WebDisplays.INSTANCE.padResY);
|
||||
|
||||
double deltX = scaledX - scaledCentX;
|
||||
double deltY = scaledY - scaledCentY;
|
||||
|
||||
String scr = Scripts.MOUSE_EVENT;
|
||||
pad.view.executeJavaScript(
|
||||
scr
|
||||
.replace("%xCoord%", "" + (int) centerX)
|
||||
.replace("%yCoord%", "" + (int) centerY)
|
||||
.replace("%xDelta%", "" + (deltX))
|
||||
.replace("%yDelta%", "" + (deltY)),
|
||||
"WebDisplays", 0
|
||||
);
|
||||
|
||||
// lock mouse
|
||||
try {
|
||||
double xpos = (this.minecraft.getWindow().getScreenWidth() / 2);
|
||||
double ypos = (this.minecraft.getWindow().getScreenHeight() / 2);
|
||||
GLFW.glfwSetCursorPos(minecraft.getWindow().getWindow(), xpos, ypos);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public void mouse(int btn, boolean pressed, int sx, int sy, double scrollAmount) {
|
||||
double mx = (sx - vx) / vw;
|
||||
double my = (sy - vy) / vh;
|
||||
|
||||
if (pad.view != null && mx >= 0 && mx <= 1) {
|
||||
//Scale again according to the webview
|
||||
int scaledX = (int) (mx * WebDisplays.INSTANCE.padResX);
|
||||
int scaledY = (int) (my * WebDisplays.INSTANCE.padResY);
|
||||
|
||||
if (btn == -1) {
|
||||
if (locked)
|
||||
capturedMouse(mx * WebDisplays.INSTANCE.padResX, my * WebDisplays.INSTANCE.padResY, sx, sy);
|
||||
else ((MCEFBrowser) pad.view).sendMouseMove(scaledX, scaledY);
|
||||
} else if (pressed)
|
||||
((MCEFBrowser) pad.view).sendMousePress(scaledX, scaledY, btn);
|
||||
else ((MCEFBrowser) pad.view).sendMouseRelease(scaledX, scaledY, btn);
|
||||
pad.view.setFocus(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<Character> getChar(int keyCode, int scanCode) {
|
||||
String keystr = GLFW.glfwGetKeyName(keyCode, scanCode);
|
||||
if (keystr == null) {
|
||||
keystr = "\0";
|
||||
}
|
||||
if (keyCode == GLFW.GLFW_KEY_ENTER) {
|
||||
keystr = "\n";
|
||||
}
|
||||
if (keystr.length() == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(keystr.charAt(keystr.length() - 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (pad.view == null)
|
||||
minecraft.setScreen(null); //In case the user dies with the pad in the hand
|
||||
pollElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForBlock(BlockPos bp, BlockSide side) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
super.removed();
|
||||
InputConstants.updateRawMouseInput(
|
||||
minecraft.getWindow().getWindow(),
|
||||
Minecraft.getInstance().options.rawMouseInput().get()
|
||||
);
|
||||
if (pad.view instanceof MCEFBrowser browser) {
|
||||
browser.setCursor(CefCursorType.POINTER);
|
||||
browser.setCursorChangeListener((cursor) -> {
|
||||
pad.activeCursor = cursor;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
super.onClose();
|
||||
removed();
|
||||
this.minecraft.popGuiLayer();
|
||||
}
|
||||
|
||||
boolean locked = false;
|
||||
double lockCenterX = -1;
|
||||
double lockCenterY = -1;
|
||||
|
||||
protected void updateCrd(JsonObject obj) {
|
||||
if (obj.getAsJsonPrimitive("exists").getAsBoolean()) {
|
||||
locked = true;
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
InputConstants.updateRawMouseInput(
|
||||
minecraft.getWindow().getWindow(),
|
||||
obj.getAsJsonPrimitive("unadjust").getAsBoolean()
|
||||
);
|
||||
GLFW.glfwSetInputMode(Minecraft.getInstance().getWindow().getWindow(), 208897, GLFW.GLFW_CURSOR_DISABLED);
|
||||
});
|
||||
lockCenterX = obj.getAsJsonPrimitive("x").getAsDouble() + obj.getAsJsonPrimitive("w").getAsDouble() / 2;
|
||||
lockCenterY = obj.getAsJsonPrimitive("y").getAsDouble() + obj.getAsJsonPrimitive("h").getAsDouble() / 2;
|
||||
} else {
|
||||
if (locked) {
|
||||
locked = false;
|
||||
RenderSystem.recordRenderCall(()->{
|
||||
InputConstants.updateRawMouseInput(
|
||||
minecraft.getWindow().getWindow(),
|
||||
Minecraft.getInstance().options.rawMouseInput().get()
|
||||
);
|
||||
GLFW.glfwSetInputMode(Minecraft.getInstance().getWindow().getWindow(), 208897, GLFW.GLFW_CURSOR_NORMAL);
|
||||
GLFW.glfwSetCursor(Minecraft.getInstance().getWindow().getWindow(), CefCursorType.fromId(pad.activeCursor).glfwId);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void pollElement() {
|
||||
if (pad.view instanceof WDBrowser browser) {
|
||||
JsonObject object = browser.pointerLockElement().getObj();
|
||||
if (object != null) updateCrd(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,17 +7,11 @@ package net.montoyo.wd.client.gui;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.montoyo.mcef.api.API;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.client.gui.controls.Button;
|
||||
import net.montoyo.wd.client.gui.controls.TextField;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.server.SMessageRedstoneCtrl;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
|
@ -53,18 +47,18 @@ public class GuiRedstoneCtrl extends WDScreen {
|
|||
tfFallingEdge.setText(fallingEdgeURL);
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onClick(Button.ClickEvent ev) {
|
||||
if(ev.getSource() == btnOk) {
|
||||
API mcef = ((ClientProxy) WebDisplays.PROXY).getMCEF();
|
||||
|
||||
String rising = mcef.punycode(Util.addProtocol(tfRisingEdge.getText()));
|
||||
String falling = mcef.punycode(Util.addProtocol(tfFallingEdge.getText()));
|
||||
Messages.INSTANCE.sendToServer(new SMessageRedstoneCtrl(dimension, pos, rising, falling));
|
||||
}
|
||||
|
||||
minecraft.setScreen(null);
|
||||
}
|
||||
// @GuiSubscribe
|
||||
// public void onClick(Button.ClickEvent ev) {
|
||||
// if(ev.getSource() == btnOk) {
|
||||
// API mcef = ((ClientProxy) WebDisplays.PROXY).getMCEF();
|
||||
//
|
||||
// String rising = mcef.punycode(Util.addProtocol(tfRisingEdge.getText()));
|
||||
// String falling = mcef.punycode(Util.addProtocol(tfFallingEdge.getText()));
|
||||
// WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageRedstoneCtrl(pos, rising, falling));
|
||||
// }
|
||||
//
|
||||
// minecraft.setScreen(null);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean isForBlock(BlockPos bp, BlockSide side) {
|
||||
|
|
|
|||
|
|
@ -15,11 +15,17 @@ import net.montoyo.wd.WebDisplays;
|
|||
import net.montoyo.wd.client.gui.controls.*;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.item.WDItem;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.server.SMessageScreenCtrl;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
import net.montoyo.wd.utilities.math.Vector2i;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.data.Rotation;
|
||||
import net.montoyo.wd.utilities.serialization.NameUUIDPair;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -29,7 +35,7 @@ import java.util.UUID;
|
|||
public class GuiScreenConfig extends WDScreen {
|
||||
|
||||
//Screen data
|
||||
private final TileEntityScreen tes;
|
||||
private final ScreenBlockEntity tes;
|
||||
private final BlockSide side;
|
||||
private NameUUIDPair owner;
|
||||
private NameUUIDPair[] friends;
|
||||
|
|
@ -118,7 +124,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
private CheckBox[] friendBoxes;
|
||||
private CheckBox[] otherBoxes;
|
||||
|
||||
public GuiScreenConfig(Component component, TileEntityScreen tes, BlockSide side, NameUUIDPair[] friends, int fr, int or) {
|
||||
public GuiScreenConfig(Component component, ScreenBlockEntity tes, BlockSide side, NameUUIDPair[] friends, int fr, int or) {
|
||||
super(component);
|
||||
this.tes = tes;
|
||||
this.side = side;
|
||||
|
|
@ -133,20 +139,20 @@ public class GuiScreenConfig extends WDScreen {
|
|||
loadFrom(new ResourceLocation("webdisplays", "gui/screencfg.json"));
|
||||
|
||||
friendBoxes = new CheckBox[] { boxFResolution, boxFUpgrades, boxFOthers, boxFFriends, boxFClick, boxFSetUrl };
|
||||
boxFResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION);
|
||||
boxFResolution.setUserdata(ScreenRights.MODIFY_SCREEN);
|
||||
boxFUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES);
|
||||
boxFOthers.setUserdata(ScreenRights.MANAGE_OTHER_RIGHTS);
|
||||
boxFFriends.setUserdata(ScreenRights.MANAGE_FRIEND_LIST);
|
||||
boxFClick.setUserdata(ScreenRights.CLICK);
|
||||
boxFClick.setUserdata(ScreenRights.INTERACT);
|
||||
boxFSetUrl.setUserdata(ScreenRights.CHANGE_URL);
|
||||
|
||||
otherBoxes = new CheckBox[] { boxOResolution, boxOUpgrades, boxOClick, boxOSetUrl };
|
||||
boxOResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION);
|
||||
boxOResolution.setUserdata(ScreenRights.MODIFY_SCREEN);
|
||||
boxOUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES);
|
||||
boxOClick.setUserdata(ScreenRights.CLICK);
|
||||
boxOClick.setUserdata(ScreenRights.INTERACT);
|
||||
boxOSetUrl.setUserdata(ScreenRights.CHANGE_URL);
|
||||
|
||||
TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
ScreenData scr = tes.getScreen(side);
|
||||
if(scr != null) {
|
||||
owner = scr.owner;
|
||||
rotation = scr.rotation;
|
||||
|
|
@ -190,7 +196,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
}
|
||||
|
||||
private void clickSetRes() {
|
||||
TileEntityScreen.Screen scr = tes.getScreen(side);
|
||||
ScreenData scr = tes.getScreen(side);
|
||||
if(scr == null)
|
||||
return; //WHATDAFUQ?
|
||||
|
||||
|
|
@ -201,7 +207,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
throw new NumberFormatException(); //I'm lazy
|
||||
|
||||
if(x != scr.resolution.x || y != scr.resolution.y)
|
||||
Messages.INSTANCE.sendToServer(SMessageScreenCtrl.vec2(tes, side, SMessageScreenCtrl.CTRL_SET_RESOLUTION, new Vector2i(x, y)));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.resolution(tes, side, new Vector2i(x, y)));
|
||||
} catch(NumberFormatException ex) {
|
||||
//Roll back
|
||||
tfResX.setText("" + scr.resolution.x);
|
||||
|
|
@ -219,7 +225,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
clickSetRes();
|
||||
else if(ev.getSource() == btnChangeRot) {
|
||||
Rotation[] rots = Rotation.values();
|
||||
Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, rots[(rotation.ordinal() + 1) % rots.length]));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, rots[(rotation.ordinal() + 1) % rots.length]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -282,7 +288,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
@GuiSubscribe
|
||||
public void onRemovePlayer(List.EntryClick ev) {
|
||||
if(ev.getSource() == lstFriends)
|
||||
Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, (NameUUIDPair) ev.getUserdata(), true));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, (NameUUIDPair) ev.getUserdata(), true));
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
|
|
@ -312,13 +318,12 @@ public class GuiScreenConfig extends WDScreen {
|
|||
} catch(NumberFormatException ex) {
|
||||
cbLockRatio.setChecked(false);
|
||||
}
|
||||
} else if(ev.getSource() == cbAutoVolume)
|
||||
Messages.INSTANCE.sendToServer(SMessageScreenCtrl.autoVol(tes, side, ev.isChecked()));
|
||||
} else if(ev.getSource() == cbAutoVolume) WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.autoVol(tes, side, ev.isChecked()));
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onRemoveUpgrade(UpgradeGroup.ClickEvent ev) {
|
||||
Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, ev.getMouseOverStack()));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, ev.getMouseOverStack()));
|
||||
}
|
||||
|
||||
public boolean isFriendCheckbox(CheckBox cb) {
|
||||
|
|
@ -339,7 +344,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
|
||||
if(adding) {
|
||||
if(!hasFriend(pairs[0]))
|
||||
Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, pairs[0], false));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, pairs[0], false));
|
||||
|
||||
tfFriend.setDisabled(false);
|
||||
tfFriend.clear();
|
||||
|
|
@ -428,7 +433,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
|
||||
@Override
|
||||
protected void sync() {
|
||||
Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, friendRights, otherRights));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, friendRights, otherRights));
|
||||
Log.info("Sent sync packet");
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +461,7 @@ public class GuiScreenConfig extends WDScreen {
|
|||
flag = (myRights & ScreenRights.MANAGE_OTHER_RIGHTS) == 0;
|
||||
grpOthers.setDisabled(flag);
|
||||
|
||||
flag = (myRights & ScreenRights.CHANGE_RESOLUTION) == 0;
|
||||
flag = (myRights & ScreenRights.MODIFY_SCREEN) == 0;
|
||||
tfResX.setDisabled(flag);
|
||||
tfResY.setDisabled(flag);
|
||||
btnChangeRot.setDisabled(flag);
|
||||
|
|
@ -503,5 +508,16 @@ public class GuiScreenConfig extends WDScreen {
|
|||
|
||||
return "Screen_Configurator";
|
||||
}
|
||||
|
||||
// reason: allow closing the UI, lol
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
|
||||
Minecraft.getInstance().setScreen(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7,125 +7,147 @@ package net.montoyo.wd.client.gui;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.client.gui.controls.Button;
|
||||
import net.montoyo.wd.client.gui.controls.Event;
|
||||
import net.montoyo.wd.client.gui.controls.TextField;
|
||||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.init.ItemInit;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.server.SMessagePadCtrl;
|
||||
import net.montoyo.wd.net.server.SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.item.ItemMinePad2;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.server_bound.C2SMessageMinepadUrl;
|
||||
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.serialization.Util;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
@Mod.EventBusSubscriber(Dist.CLIENT)
|
||||
public class GuiSetURL2 extends WDScreen {
|
||||
|
||||
//Screen data
|
||||
private TileEntityScreen tileEntity;
|
||||
private BlockSide screenSide;
|
||||
private Vector3i remoteLocation;
|
||||
|
||||
//Pad data
|
||||
private final boolean isPad;
|
||||
|
||||
//Common
|
||||
private final String screenURL;
|
||||
|
||||
@FillControl
|
||||
private TextField tfURL;
|
||||
|
||||
@FillControl
|
||||
private Button btnShutDown;
|
||||
|
||||
@FillControl
|
||||
private Button btnCancel;
|
||||
|
||||
@FillControl
|
||||
private Button btnOk;
|
||||
|
||||
public GuiSetURL2(TileEntityScreen tes, BlockSide side, String url, Vector3i rl) {
|
||||
super(Component.nullToEmpty(null));
|
||||
tileEntity = tes;
|
||||
screenSide = side;
|
||||
remoteLocation = rl;
|
||||
isPad = false;
|
||||
screenURL = url;
|
||||
}
|
||||
|
||||
public GuiSetURL2(String url) {
|
||||
super(Component.nullToEmpty(null));
|
||||
isPad = true;
|
||||
screenURL = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
loadFrom(new ResourceLocation("webdisplays", "gui/seturl.json"));
|
||||
tfURL.setText(screenURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addLoadCustomVariables(Map<String, Double> vars) {
|
||||
vars.put("isPad", isPad ? 1.0 : 0.0);
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onButtonClicked(Button.ClickEvent ev) {
|
||||
if(ev.getSource() == btnCancel)
|
||||
minecraft.setScreen(null);
|
||||
else if(ev.getSource() == btnOk)
|
||||
validate(tfURL.getText());
|
||||
else if(ev.getSource() == btnShutDown) {
|
||||
if(isPad)
|
||||
Messages.INSTANCE.sendToServer(new SMessagePadCtrl(""));
|
||||
|
||||
minecraft.setScreen(null);
|
||||
}
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onEnterPressed(TextField.EnterPressedEvent ev) {
|
||||
validate(ev.getText());
|
||||
}
|
||||
|
||||
private void validate(String url) {
|
||||
if(!url.isEmpty()) {
|
||||
url = Util.addProtocol(url);
|
||||
url = ((ClientProxy) WebDisplays.PROXY).getMCEF().punycode(url);
|
||||
|
||||
if(isPad) {
|
||||
Messages.INSTANCE.sendToServer(new SMessagePadCtrl(url));
|
||||
ItemStack held = minecraft.player.getItemInHand(InteractionHand.MAIN_HAND);
|
||||
|
||||
if(held.getItem().equals(ItemInit.itemMinePad.get()) && held.getTag() != null && held.getTag().contains("PadID")) {
|
||||
ClientProxy.PadData pd = ((ClientProxy) WebDisplays.PROXY).getPadByID(held.getTag().getInt("PadID"));
|
||||
|
||||
if(pd != null && pd.view != null)
|
||||
pd.view.loadURL(WebDisplays.applyBlacklist(url));
|
||||
}
|
||||
} else
|
||||
Messages.INSTANCE.sendToServer(SMessageScreenCtrl.setURL(tileEntity, screenSide, url, remoteLocation));
|
||||
}
|
||||
|
||||
minecraft.setScreen(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForBlock(BlockPos bp, BlockSide side) {
|
||||
return (remoteLocation != null && remoteLocation.equalsBlockPos(bp)) || (bp.equals(tileEntity.getBlockPos()) && side == screenSide);
|
||||
}
|
||||
|
||||
|
||||
//Screen data
|
||||
private ScreenBlockEntity tileEntity;
|
||||
private BlockSide screenSide;
|
||||
private Vector3i remoteLocation;
|
||||
|
||||
//Pad data
|
||||
private ItemStack stack;
|
||||
private final boolean isPad;
|
||||
|
||||
//Common
|
||||
private final String screenURL;
|
||||
|
||||
@FillControl
|
||||
private TextField tfURL;
|
||||
|
||||
@FillControl
|
||||
private Button btnShutDown;
|
||||
|
||||
@FillControl
|
||||
private Button btnCancel;
|
||||
|
||||
@FillControl
|
||||
private Button btnOk;
|
||||
|
||||
public GuiSetURL2(ScreenBlockEntity tes, BlockSide side, String url, Vector3i rl) {
|
||||
super(Component.nullToEmpty(null));
|
||||
tileEntity = tes;
|
||||
screenSide = side;
|
||||
remoteLocation = rl;
|
||||
isPad = false;
|
||||
screenURL = url;
|
||||
}
|
||||
|
||||
public GuiSetURL2(ItemStack is, String url) {
|
||||
super(Component.nullToEmpty(null));
|
||||
isPad = true;
|
||||
stack = is;
|
||||
screenURL = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
loadFrom(new ResourceLocation("webdisplays", "gui/seturl.json"));
|
||||
tfURL.setText(screenURL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addLoadCustomVariables(Map<String, Double> vars) {
|
||||
vars.put("isPad", isPad ? 1.0 : 0.0);
|
||||
}
|
||||
|
||||
protected UUID getUUID() {
|
||||
if (stack == null || !(stack.getItem() instanceof ItemMinePad2))
|
||||
throw new RuntimeException("Get UUID is being called for a non-minepad UI");
|
||||
if (!stack.hasTag() || !stack.getTag().contains("PadID"))
|
||||
stack.getOrCreateTag().putUUID("PadID", UUID.randomUUID());
|
||||
|
||||
return stack.getTag().getUUID("PadID");
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onButtonClicked(Button.ClickEvent ev) {
|
||||
if (ev.getSource() == btnCancel)
|
||||
minecraft.setScreen(null);
|
||||
else if (ev.getSource() == btnOk)
|
||||
validate(tfURL.getText());
|
||||
else if (ev.getSource() == btnShutDown) {
|
||||
if (isPad) {
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageMinepadUrl(
|
||||
getUUID(),
|
||||
""
|
||||
));
|
||||
stack.getTag().remove("PadID");
|
||||
}
|
||||
|
||||
minecraft.setScreen(null);
|
||||
}
|
||||
}
|
||||
|
||||
@GuiSubscribe
|
||||
public void onEnterPressed(TextField.EnterPressedEvent ev) {
|
||||
validate(ev.getText());
|
||||
}
|
||||
|
||||
private void validate(String url) {
|
||||
if (!url.isEmpty()) {
|
||||
|
||||
try {
|
||||
ScreenBlockEntity.url(url);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
url = Util.addProtocol(url);
|
||||
// url = ((ClientProxy) WebDisplays.PROXY).getMCEF().punycode(url);
|
||||
|
||||
if (isPad) {
|
||||
UUID uuid = getUUID();
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageMinepadUrl(uuid, url));
|
||||
stack.getTag().putString("PadURL", url);
|
||||
|
||||
ClientProxy.PadData pd = ((ClientProxy) WebDisplays.PROXY).getPadByID(uuid);
|
||||
|
||||
if (pd != null && pd.view != null) {
|
||||
pd.view.loadURL(WebDisplays.applyBlacklist(url));
|
||||
}
|
||||
} else
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.setURL(tileEntity, screenSide, url, remoteLocation));
|
||||
}
|
||||
|
||||
minecraft.setScreen(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForBlock(BlockPos bp, BlockSide side) {
|
||||
return (remoteLocation != null && remoteLocation.equalsBlockPos(bp)) || (bp.equals(tileEntity.getBlockPos()) && side == screenSide);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package net.montoyo.wd.client.gui;
|
|||
import com.mojang.blaze3d.platform.Lighting;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
|
|
@ -77,15 +78,16 @@ public class RenderRecipe extends Screen {
|
|||
Log.info("Loaded %d recipes", recipes.size());
|
||||
nextRecipe();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTick) {
|
||||
renderBackground(poseStack);
|
||||
public void render(GuiGraphics context, int mouseX, int mouseY, float partialTick) {
|
||||
// renderBackground(poseStack);
|
||||
renderBackground(context);
|
||||
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
RenderSystem.setShaderTexture(0, CRAFTING_TABLE_GUI_TEXTURES);
|
||||
blit(poseStack, x, y, 0, 0, SIZE_X, SIZE_Y);
|
||||
font.draw(poseStack, I18n.get("container.crafting"), x + 28, y + 6, 0x404040);
|
||||
// context.blit(x, y, 0, 0, SIZE_X, SIZE_Y);
|
||||
// font.draw(poseStack, I18n.get("container.crafting"), x + 28, y + 6, 0x404040);
|
||||
|
||||
Lighting.setupForFlatItems();
|
||||
// RenderSystem.disableLighting(); //TODO: Need this?
|
||||
|
|
@ -98,15 +100,15 @@ public class RenderRecipe extends Screen {
|
|||
int x = this.x + 30 + sx * 18;
|
||||
int y = this.y + 17 + sy * 18;
|
||||
|
||||
renderItem.renderAndDecorateItem(minecraft.player, is, x, y, 0);
|
||||
renderItem.renderGuiItemDecorations(font, is, x, y, null);
|
||||
context.renderItem(is, x, y);
|
||||
context.renderItemDecorations(font, is, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(recipeResult != null) {
|
||||
renderItem.renderAndDecorateItem(minecraft.player, recipeResult, x + 124, y + 35, 0);
|
||||
renderItem.renderGuiItemDecorations(font, recipeResult, x + 124, y + 35, null);
|
||||
context.renderItem(recipeResult, x, y);
|
||||
context.renderItemDecorations(font, recipeResult, x, y);
|
||||
}
|
||||
|
||||
// GlStateManager.enableLighting();
|
||||
|
|
@ -127,7 +129,7 @@ public class RenderRecipe extends Screen {
|
|||
}
|
||||
}
|
||||
|
||||
recipeResult = recipe.getResultItem();
|
||||
// recipeResult = recipe.getResultItem();
|
||||
}
|
||||
|
||||
private void nextRecipe() {
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ package net.montoyo.wd.client.gui;
|
|||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.FormattedCharSequence;
|
||||
|
|
@ -23,10 +23,13 @@ import net.montoyo.wd.client.gui.controls.Event;
|
|||
import net.montoyo.wd.client.gui.loading.FillControl;
|
||||
import net.montoyo.wd.client.gui.loading.GuiLoader;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import net.montoyo.wd.net.Messages;
|
||||
import net.montoyo.wd.net.server.SMessageACQuery;
|
||||
import net.montoyo.wd.net.WDNetworkRegistry;
|
||||
import net.montoyo.wd.net.server_bound.C2SMessageACQuery;
|
||||
import net.montoyo.wd.utilities.*;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import net.montoyo.wd.utilities.data.Bounds;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.serialization.NameUUIDPair;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
|
|
@ -113,17 +116,19 @@ public abstract class WDScreen extends Screen {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void render(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(defaultBackground)
|
||||
renderBackground(poseStack);
|
||||
|
||||
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
for(Control ctrl: controls)
|
||||
ctrl.draw(poseStack, mouseX, mouseY, ptt);
|
||||
|
||||
for(Control ctrl: postDrawList)
|
||||
ctrl.postDraw(poseStack, mouseX, mouseY, ptt);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char codePoint, int modifiers) {
|
||||
boolean typed = false;
|
||||
|
|
@ -138,8 +143,21 @@ public abstract class WDScreen extends Screen {
|
|||
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||
boolean clicked = false;
|
||||
|
||||
for(Control ctrl: controls)
|
||||
clicked = clicked || ctrl.mouseClicked(mouseX, mouseY, button);
|
||||
Control clickedEl = null;
|
||||
for(Control ctrl: controls) {
|
||||
clicked = ctrl.mouseClicked(mouseX, mouseY, button);
|
||||
if (clicked) {
|
||||
clickedEl = ctrl;
|
||||
break; // don't assume the compiler will optimize stuff
|
||||
}
|
||||
}
|
||||
|
||||
if (clicked) {
|
||||
for (Control control : controls) {
|
||||
if (control != clickedEl)
|
||||
control.unfocus();
|
||||
}
|
||||
}
|
||||
|
||||
return clicked;
|
||||
}
|
||||
|
|
@ -151,7 +169,7 @@ public abstract class WDScreen extends Screen {
|
|||
for(Control ctrl: controls)
|
||||
mouseReleased = mouseReleased || ctrl.mouseReleased(mouseX, mouseY, button);
|
||||
|
||||
return mouseReleased || mouseClicked(mouseX, mouseY, button);
|
||||
return mouseReleased;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -167,7 +185,7 @@ public abstract class WDScreen extends Screen {
|
|||
@Override
|
||||
protected void init() {
|
||||
CURRENT_SCREEN = this;
|
||||
minecraft.keyboardHandler.setSendRepeatsToGui(true);
|
||||
// minecraft.keyboardHandler.setSendRepeatsToGui(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -180,7 +198,7 @@ public abstract class WDScreen extends Screen {
|
|||
for(Control ctrl : controls)
|
||||
ctrl.destroy();
|
||||
|
||||
Minecraft.getInstance().keyboardHandler.setSendRepeatsToGui(false);
|
||||
// Minecraft.getInstance().keyboardHandler.setSendRepeatsToGui(false);
|
||||
CURRENT_SCREEN = null;
|
||||
}
|
||||
|
||||
|
|
@ -209,9 +227,9 @@ public abstract class WDScreen extends Screen {
|
|||
boolean down = false;
|
||||
|
||||
for (Control ctrl : controls)
|
||||
down = down || ctrl.keyDown(keyCode);
|
||||
down = down || ctrl.keyDown(keyCode, scanCode, modifiers);
|
||||
|
||||
if (Minecraft.getInstance().screen instanceof GuiKeyboard) {
|
||||
if (this instanceof GuiKeyboard) {
|
||||
return down;
|
||||
} else {
|
||||
return new GuiServer(new Vector3i(), new NameUUIDPair()).keyPressed(keyCode, scanCode, modifiers);
|
||||
|
|
@ -223,7 +241,7 @@ public abstract class WDScreen extends Screen {
|
|||
boolean up = false;
|
||||
|
||||
for(Control ctrl : controls)
|
||||
up = up || ctrl.keyUp(keyCode);
|
||||
up = up || ctrl.keyUp(keyCode, scanCode, modifiers);
|
||||
|
||||
return up || super.keyReleased(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
|
@ -264,7 +282,9 @@ public abstract class WDScreen extends Screen {
|
|||
}
|
||||
|
||||
public void loadFrom(ResourceLocation resLoc) {
|
||||
JsonObject root = GuiLoader.getJson(resLoc);
|
||||
try {
|
||||
JsonObject root = GuiLoader.getJson(resLoc);
|
||||
|
||||
if(root == null)
|
||||
throw new RuntimeException("Could not load GUI file " + resLoc.toString());
|
||||
|
||||
|
|
@ -312,6 +332,10 @@ public abstract class WDScreen extends Screen {
|
|||
|
||||
if(root.has("center") && root.get("center").getAsBoolean())
|
||||
centerControls();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -324,7 +348,7 @@ public abstract class WDScreen extends Screen {
|
|||
}
|
||||
|
||||
protected void requestAutocomplete(String beginning, boolean matchExact) {
|
||||
Messages.INSTANCE.sendToServer(new SMessageACQuery(beginning, matchExact));
|
||||
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageACQuery(beginning, matchExact));
|
||||
}
|
||||
|
||||
public void onAutocompleteResult(NameUUIDPair pairs[]) {
|
||||
|
|
@ -356,12 +380,12 @@ public abstract class WDScreen extends Screen {
|
|||
}
|
||||
}
|
||||
|
||||
public void drawItemStackTooltip(PoseStack poseStack, ItemStack is, int x, int y) {
|
||||
renderTooltip(poseStack, is, x, y); //Since it's protected...
|
||||
public void drawItemStackTooltip(GuiGraphics poseStack, ItemStack is, int x, int y) {
|
||||
poseStack.renderTooltip(Minecraft.getInstance().font, is, x, y); //Since it's protected...
|
||||
}
|
||||
|
||||
public void drawTooltip(PoseStack poseStack, List<String> lines, int x, int y) {
|
||||
renderTooltip(poseStack, lines.stream().map(a -> FormattedCharSequence.forward(a, Style.EMPTY)).collect(Collectors.toList()), x, y, font); //This is also protected...
|
||||
public void drawTooltip(GuiGraphics poseStack, List<String> lines, int x, int y) {
|
||||
poseStack.renderTooltip(Minecraft.getInstance().font, lines.stream().map(a -> FormattedCharSequence.forward(a, Style.EMPTY)).collect(Collectors.toList()), x, y); //This is also protected...
|
||||
}
|
||||
|
||||
public void requirePostDraw(Control ctrl) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,273 @@
|
|||
package net.montoyo.wd.client.gui.camera;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.client.event.ViewportEvent;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.montoyo.wd.client.gui.GuiKeyboard;
|
||||
import net.montoyo.wd.config.ClientConfig;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import net.montoyo.wd.utilities.browser.WDBrowser;
|
||||
import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
|
||||
public class KeyboardCamera {
|
||||
private static ScreenBlockEntity tes;
|
||||
private static BlockSide side;
|
||||
|
||||
private static double oxCrd = -1;
|
||||
private static double xCrd = -1;
|
||||
private static double nxCrd = -1;
|
||||
private static double oyCrd = -1;
|
||||
private static double yCrd = -1;
|
||||
private static double nyCrd = -1;
|
||||
|
||||
private static double nextX = -1;
|
||||
private static double nextY = -1;
|
||||
private static double focalX = -1;
|
||||
private static double focalY = -1;
|
||||
|
||||
private static final boolean[] mouseStatus = new boolean[2];
|
||||
|
||||
protected static Vec2 pxToHit(ScreenData scr, Vec2 dst) {
|
||||
float cx, cy;
|
||||
if (scr.rotation.isVertical) {
|
||||
cy = dst.x;
|
||||
cx = dst.y;
|
||||
} else {
|
||||
cx = dst.x;
|
||||
cy = dst.y;
|
||||
}
|
||||
|
||||
cx /= (float) scr.resolution.x;
|
||||
cy /= (float) scr.resolution.y;
|
||||
|
||||
switch (scr.rotation) {
|
||||
case ROT_270:
|
||||
cx = 1.0f - cx;
|
||||
break;
|
||||
|
||||
case ROT_180:
|
||||
cx = 1.0f - cx;
|
||||
cy = 1.0f - cy;
|
||||
break;
|
||||
|
||||
case ROT_90:
|
||||
cy = 1.0f - cy;
|
||||
break;
|
||||
}
|
||||
|
||||
if (side != BlockSide.BOTTOM)
|
||||
cy = 1.0f - cy;
|
||||
|
||||
float swInverse = (((float) scr.size.x) - 4.f / 16.f);
|
||||
float shInverse = (((float) scr.size.y) - 4.f / 16.f);
|
||||
|
||||
cx *= swInverse;
|
||||
cy *= shInverse;
|
||||
|
||||
if (side.right.x > 0 || side.right.z > 0)
|
||||
cx += 1.f;
|
||||
|
||||
if (side == BlockSide.TOP || side == BlockSide.BOTTOM)
|
||||
cy -= 1.f;
|
||||
|
||||
return new Vec2(cx + (2 / 16f), cy + (2 / 16f));
|
||||
}
|
||||
|
||||
protected static void updateCrd(ElementCenterQuery lock) {
|
||||
ScreenData scr = tes.getScreen(side);
|
||||
if (scr != null) {
|
||||
Vec2 c;
|
||||
|
||||
if (!mouseStatus[0] && !mouseStatus[1]) {
|
||||
if (lock.hasFocused()) {
|
||||
if (ClientConfig.Input.keyboardCamera) {
|
||||
nextX = lock.getX();
|
||||
nextY = lock.getY();
|
||||
|
||||
c = pxToHit(scr, new Vec2((float) nextX, (float) nextY));
|
||||
} else c = new Vec2(scr.size.x / 2f, scr.size.y / 2f);
|
||||
} else c = new Vec2(scr.size.x / 2f, scr.size.y / 2f);
|
||||
// } else c = new Vec2((float) focalX, (float) focalY);
|
||||
} else return;
|
||||
|
||||
focalX = c.x;
|
||||
focalY = c.y;
|
||||
|
||||
nextX = c.x;
|
||||
nextY = c.y;
|
||||
|
||||
if (nextX < 0) nextX = 0;
|
||||
else if (nextX > scr.size.x) nextX = scr.size.x;
|
||||
if (nextY < 0) nextY = 0;
|
||||
else if (nextY > scr.size.y) nextY = scr.size.y;
|
||||
|
||||
float scl = Math.max(scr.size.x, scr.size.y);
|
||||
|
||||
double mx = Minecraft.getInstance().mouseHandler.xpos();
|
||||
mx /= Minecraft.getInstance().getWindow().getWidth();
|
||||
|
||||
double my = Minecraft.getInstance().mouseHandler.ypos();
|
||||
my /= Minecraft.getInstance().getWindow().getHeight();
|
||||
|
||||
Vec2 v2 = new Vec2((float) mx, (float) my).add(-0.5f);
|
||||
|
||||
nextX += v2.x * scl;
|
||||
nextY -= v2.y * scl;
|
||||
}
|
||||
}
|
||||
|
||||
protected static void pollElement() {
|
||||
ScreenBlockEntity teTmp = tes;
|
||||
BlockSide sdTmp = side;
|
||||
|
||||
// async nonsense can occur here
|
||||
if (teTmp == null || sdTmp == null) return;
|
||||
|
||||
ScreenData scr = teTmp.getScreen(sdTmp);
|
||||
if (scr != null) {
|
||||
if (scr.browser instanceof WDBrowser wdBrowser) {
|
||||
wdBrowser.focusedElement().dispatch(scr.browser);
|
||||
updateCrd(((WDBrowser) scr.browser).focusedElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float[] getAngle(Entity e, double pct) {
|
||||
BlockEntity tes = KeyboardCamera.tes;
|
||||
BlockSide side = KeyboardCamera.side;
|
||||
if (tes == null) return new float[]{Float.NaN, 0};
|
||||
if (side == null) return new float[]{Float.NaN, 0};
|
||||
|
||||
double coxCrd = Mth.lerp(0.5 * pct, oxCrd, xCrd);
|
||||
double coyCrd = Mth.lerp(0.5 * pct, oyCrd, yCrd);
|
||||
|
||||
double focalX = tes.getBlockPos().getX() +
|
||||
side.right.x * (coxCrd - 1) + side.up.x * coyCrd + Math.abs(side.forward.x) * 0.5;
|
||||
double focalY = tes.getBlockPos().getY() +
|
||||
side.right.y * (coxCrd - 1) + side.up.y * coyCrd + Math.abs(side.forward.y) * 0.5;
|
||||
double focalZ = tes.getBlockPos().getZ() +
|
||||
side.right.z * (coxCrd - 1) + side.up.z * coyCrd + Math.abs(side.forward.z) * 0.5;
|
||||
|
||||
focalX += side.forward.x * 0.5f;
|
||||
focalY += side.forward.y * 0.5f;
|
||||
focalZ += side.forward.z * 0.5f;
|
||||
|
||||
float[] angle = lookAt(
|
||||
e, EntityAnchorArgument.Anchor.EYES,
|
||||
new Vec3(focalX, focalY, focalZ)
|
||||
);
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
public static void setMouse(int side, boolean pressed) {
|
||||
mouseStatus[side] = pressed;
|
||||
}
|
||||
|
||||
public static void updateCamera(ViewportEvent.ComputeCameraAngles event) {
|
||||
if (tes == null) {
|
||||
xCrd = -1;
|
||||
yCrd = -1;
|
||||
return; // nothing to do
|
||||
}
|
||||
|
||||
if (xCrd == -1) return;
|
||||
if (yCrd == -1) return;
|
||||
|
||||
float[] angle = getAngle(event.getCamera().getEntity(), event.getPartialTick());
|
||||
|
||||
if (Float.isNaN(angle[0])) return;
|
||||
|
||||
// float xRot = event.getYaw(); // left right
|
||||
// float yRot = event.getPitch(); // up down
|
||||
|
||||
// TODO: smooth in/out
|
||||
event.setYaw(angle[1]);
|
||||
event.setPitch(angle[0]);
|
||||
}
|
||||
|
||||
public static void focus(ScreenBlockEntity screen, BlockSide side) {
|
||||
KeyboardCamera.tes = screen;
|
||||
KeyboardCamera.side = side;
|
||||
}
|
||||
|
||||
public static float[] lookAt(Entity entity, EntityAnchorArgument.Anchor pAnchor, Vec3 pTarget) {
|
||||
Vec3 vec3 = pAnchor.apply(entity);
|
||||
double d0 = pTarget.x - vec3.x;
|
||||
double d1 = pTarget.y - vec3.y;
|
||||
double d2 = pTarget.z - vec3.z;
|
||||
double d3 = Math.sqrt(d0 * d0 + d2 * d2);
|
||||
float xr = (Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * (double) (180F / (float) Math.PI)))));
|
||||
float yr = (Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * (double) (180F / (float) Math.PI)) - 90.0F));
|
||||
return new float[]{xr, yr};
|
||||
}
|
||||
|
||||
protected static int delay = 8;
|
||||
|
||||
public static void gameTick(TickEvent.ClientTickEvent event) {
|
||||
if (mouseStatus[0] || mouseStatus[1]) {
|
||||
oxCrd = Mth.lerp(0.5, oxCrd, xCrd);
|
||||
oyCrd = Mth.lerp(0.5, oyCrd, yCrd);
|
||||
return;
|
||||
}
|
||||
if (event.phase.equals(TickEvent.Phase.END)) {
|
||||
if (side == null) {
|
||||
delay = 1;
|
||||
oxCrd = -1;
|
||||
oyCrd = -1;
|
||||
xCrd = -1;
|
||||
yCrd = -1;
|
||||
nxCrd = -1;
|
||||
nyCrd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(Minecraft.getInstance().screen instanceof GuiKeyboard)) {
|
||||
tes = null;
|
||||
side = null;
|
||||
return;
|
||||
}
|
||||
|
||||
pollElement();
|
||||
|
||||
double anxx = nextX;
|
||||
double anxy = nextY;
|
||||
|
||||
if (
|
||||
anxx == -1 || anxy == -1 ||
|
||||
nxCrd == -1 || nyCrd == -1 ||
|
||||
oxCrd == -1 || oyCrd == -1 ||
|
||||
xCrd == -1 || yCrd == -1
|
||||
) {
|
||||
ScreenData data = tes.getScreen(side);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
anxx = data.size.x / 2.0;
|
||||
anxy = data.size.y / 2.0;
|
||||
|
||||
if (nxCrd == -1) {
|
||||
oxCrd = xCrd = anxx;
|
||||
oyCrd = yCrd = anxy;
|
||||
}
|
||||
}
|
||||
|
||||
nxCrd = anxx;
|
||||
nyCrd = anxy;
|
||||
|
||||
oxCrd = Mth.lerp(0.5, oxCrd, xCrd);
|
||||
xCrd = Mth.lerp(0.15, xCrd, nxCrd);
|
||||
|
||||
oyCrd = Mth.lerp(0.5, oyCrd, yCrd);
|
||||
yCrd = Mth.lerp(0.15, yCrd, nyCrd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,10 +5,16 @@
|
|||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentContents;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Button extends Control {
|
||||
|
||||
protected final net.minecraft.client.gui.components.Button btn;
|
||||
|
|
@ -31,17 +37,23 @@ public class Button extends Control {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public Button() {
|
||||
btn = new net.minecraft.client.gui.components.Button(0,0, 0, 0, Component.nullToEmpty(null), a -> {});
|
||||
btn = net.minecraft.client.gui.components.Button.builder(Component.nullToEmpty(""), a -> {})
|
||||
.bounds(0, 0, 0, 0)
|
||||
.build();
|
||||
}
|
||||
|
||||
public Button(String text, int x, int y, int width) {
|
||||
btn = new net.minecraft.client.gui.components.Button(x, y, width, 20, Component.nullToEmpty(text), a -> {});
|
||||
btn = net.minecraft.client.gui.components.Button.builder(Component.nullToEmpty(text), a -> {})
|
||||
.bounds(x, y, width, 20)
|
||||
.build();
|
||||
}
|
||||
|
||||
public Button(String text, int x, int y) {
|
||||
btn = new net.minecraft.client.gui.components.Button(0, 0, x, y, Component.nullToEmpty(text), a -> {});
|
||||
btn = net.minecraft.client.gui.components.Button.builder(Component.nullToEmpty(text), a -> {})
|
||||
.bounds(0, 0, x, y)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -71,7 +83,8 @@ public class Button extends Control {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
btn.setFGColor(16777215);
|
||||
btn.render(poseStack, mouseX, mouseY, ptt);
|
||||
}
|
||||
|
||||
|
|
@ -103,18 +116,17 @@ public class Button extends Control {
|
|||
|
||||
@Override
|
||||
public void setPos(int x, int y) {
|
||||
btn.x = x;
|
||||
btn.y = y;
|
||||
btn.setPosition(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return btn.x;
|
||||
return btn.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return btn.y;
|
||||
return btn.getY();
|
||||
}
|
||||
|
||||
public net.minecraft.client.gui.components.Button getMcButton() {
|
||||
|
|
@ -158,7 +170,7 @@ public class Button extends Control {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int key) {
|
||||
public boolean keyUp(int key, int scanCode, int modifiers) {
|
||||
if(key == GLFW.GLFW_KEY_LEFT_SHIFT || key == GLFW.GLFW_KEY_RIGHT_SHIFT) {
|
||||
shiftDown = false;
|
||||
btn.setFGColor(originalColor);
|
||||
|
|
@ -170,7 +182,7 @@ public class Button extends Control {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int key) {
|
||||
public boolean keyDown(int key, int scanCode, int modifiers) {
|
||||
if(key == GLFW.GLFW_KEY_LEFT_SHIFT || key == GLFW.GLFW_KEY_RIGHT_SHIFT) {
|
||||
shiftDown = true;
|
||||
btn.setFGColor(shiftColor);
|
||||
|
|
@ -204,11 +216,13 @@ public class Button extends Control {
|
|||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
btn.x = json.getInt("x", 0);
|
||||
btn.y = json.getInt("y", 0);
|
||||
btn.setPosition(
|
||||
json.getInt("x", 0),
|
||||
json.getInt("y", 0)
|
||||
);
|
||||
btn.setWidth(json.getInt("width", 200));
|
||||
btn.setHeight(json.getInt("height", 20));
|
||||
btn.setMessage(Component.nullToEmpty(tr(json.getString("label", btn.getMessage().getContents()))));
|
||||
btn.setMessage(Component.nullToEmpty(tr(json.getString("label", btn.getMessage().getContents().toString()))));
|
||||
btn.active = json.getBool("active", btn.active);
|
||||
btn.visible = json.getBool("visible", btn.visible);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,17 +7,14 @@ package net.montoyo.wd.client.gui.controls;
|
|||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraftforge.event.world.ChunkDataEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CheckBox extends BasicControl {
|
||||
|
||||
private static final ResourceLocation texUnchecked = new ResourceLocation("webdisplays", "textures/gui/checkbox.png");
|
||||
|
|
@ -72,29 +69,28 @@ public class CheckBox extends BasicControl {
|
|||
checked = !checked;
|
||||
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
|
||||
parent.actionPerformed(new CheckedEvent(this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(visible) {
|
||||
// GlStateManager.disableAlpha();
|
||||
poseStack.pushPose();
|
||||
RenderSystem.setShaderTexture(2, checked ? texChecked : texUnchecked);
|
||||
RenderSystem.bindTexture(2);
|
||||
poseStack.pose().pushPose();
|
||||
RenderSystem.enableBlend();
|
||||
fillTexturedRect(poseStack, x, y, WIDTH, HEIGHT, 0.0, 0.0, 1.0, 1.0);
|
||||
poseStack.blit(
|
||||
checked ? texChecked : texUnchecked, x, y, 0, 0, 0, WIDTH, HEIGHT, WIDTH, HEIGHT
|
||||
);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.bindTexture(-1);
|
||||
|
||||
poseStack.popPose();
|
||||
poseStack.pose().popPose();
|
||||
boolean inside = (!disabled && mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT);
|
||||
font.draw(poseStack, label, x + WIDTH + 2, y + 4, inside ? 0xFF0080FF : COLOR_WHITE);
|
||||
poseStack.drawString(Minecraft.getInstance().font, label, x + WIDTH + 2, y + 4, inside ? 0xFF0080FF : COLOR_WHITE, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +136,7 @@ public class CheckBox extends BasicControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void postDraw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void postDraw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(tooltip != null && !disabled && mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT)
|
||||
parent.drawTooltip(poseStack, tooltip, mouseX, mouseY);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.montoyo.wd.client.gui.loading.GuiLoader;
|
||||
import net.montoyo.wd.client.gui.loading.JsonAWrapper;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -36,24 +36,24 @@ public abstract class Container extends BasicControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int key) {
|
||||
public boolean keyUp(int key, int scanCode, int modifiers) {
|
||||
boolean up = false;
|
||||
|
||||
if(!disabled) {
|
||||
for(Control ctrl : childs)
|
||||
up = up || ctrl.keyUp(key);
|
||||
up = up || ctrl.keyUp(key, scanCode, modifiers);
|
||||
}
|
||||
|
||||
return up;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int key) {
|
||||
public boolean keyDown(int key, int scanCode, int modifiers) {
|
||||
boolean down = false;
|
||||
|
||||
if(!disabled) {
|
||||
for(Control ctrl : childs)
|
||||
down = down || ctrl.keyDown(key);
|
||||
down = down || ctrl.keyDown(key, scanCode, modifiers);
|
||||
}
|
||||
|
||||
return down;
|
||||
|
|
@ -67,8 +67,10 @@ public abstract class Container extends BasicControl {
|
|||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
for(Control ctrl : childs)
|
||||
clicked = clicked || ctrl.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
for(Control ctrl : childs) {
|
||||
clicked = ctrl.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
if (clicked) break; // don't assume compiler optimizations
|
||||
}
|
||||
}
|
||||
|
||||
return clicked;
|
||||
|
|
@ -136,13 +138,13 @@ public abstract class Container extends BasicControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(visible) {
|
||||
mouseX -= x + paddingX;
|
||||
mouseY -= y + paddingY;
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(x + paddingX, y + paddingY, 0.0);
|
||||
poseStack.pose().pushPose();
|
||||
poseStack.pose().translate(x + paddingX, y + paddingY, 0.0);
|
||||
|
||||
if(disabled) {
|
||||
for(Control ctrl : childs)
|
||||
|
|
@ -152,7 +154,7 @@ public abstract class Container extends BasicControl {
|
|||
ctrl.draw(poseStack, mouseX, mouseY, ptt);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
poseStack.pose().popPose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,4 +189,10 @@ public abstract class Container extends BasicControl {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unfocus() {
|
||||
for (Control control : childs) {
|
||||
control.unfocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,20 +8,26 @@ import com.mojang.blaze3d.pipeline.RenderTarget;
|
|||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import com.mojang.math.Matrix4f;
|
||||
import net.minecraft.client.KeyboardHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.montoyo.wd.client.gui.WDScreen;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import net.montoyo.wd.utilities.Bounds;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import net.montoyo.wd.utilities.data.Bounds;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.glEnable;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.mojang.math.Axis.XP;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract class Control {
|
||||
|
||||
public static final int COLOR_BLACK = 0xFF000000;
|
||||
|
|
@ -61,11 +67,11 @@ public abstract class Control {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean keyUp(int key) {
|
||||
public boolean keyUp(int key, int scanCode, int modifiers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean keyDown(int key) {
|
||||
public boolean keyDown(int key, int scanCode, int modifiers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +79,9 @@ public abstract class Control {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void unfocus() {
|
||||
}
|
||||
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int state) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -89,10 +98,10 @@ public abstract class Control {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
}
|
||||
|
||||
public void postDraw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void postDraw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
|
@ -108,7 +117,7 @@ public abstract class Control {
|
|||
public abstract int getHeight();
|
||||
public abstract void setPos(int x, int y);
|
||||
|
||||
public void fillRect(int x, double y, int w, int h, int color) {
|
||||
public void fillRect(MultiBufferSource.BufferSource source, int x, double y, int w, int h, int color) {
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + w);
|
||||
|
|
@ -118,34 +127,38 @@ public abstract class Control {
|
|||
int g = (color >> 8 ) & 0xFF;
|
||||
int b = color & 0xFF;
|
||||
|
||||
RenderSystem.setShaderColor(((float) r) / 255.f, ((float) g) / 255.f, ((float) b) / 255.f, ((float) a) / 255.f);
|
||||
RenderSystem.disableTexture();
|
||||
float[] sdrCol = Arrays.copyOf(RenderSystem.getShaderColor(), 4);
|
||||
RenderSystem.setShaderColor(1, 1, 1, 1f);
|
||||
// RenderSystem.disableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
vBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
|
||||
vBuffer.vertex(x1, y2, 0.0).endVertex();
|
||||
vBuffer.vertex(x2, y2, 0.0).endVertex();
|
||||
vBuffer.vertex(x2, y1, 0.0).endVertex();
|
||||
vBuffer.vertex(x1, y1, 0.0).endVertex();
|
||||
tessellator.end();
|
||||
VertexConsumer consumer = source.getBuffer(RenderType.gui());
|
||||
consumer.vertex(x1, y2, 0.0).color(r, g, b, a).endVertex();
|
||||
consumer.vertex(x2, y2, 0.0).color(r, g, b, a).endVertex();
|
||||
consumer.vertex(x2, y1, 0.0).color(r, g, b, a).endVertex();
|
||||
consumer.vertex(x1, y1, 0.0).color(r, g, b, a).endVertex();
|
||||
|
||||
RenderSystem.setShaderColor(sdrCol[0], sdrCol[1], sdrCol[2], sdrCol[3]);
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableTexture();glEnable(GL_TEXTURE_2D);
|
||||
// RenderSystem.enableTexture();
|
||||
}
|
||||
|
||||
public void fillTexturedRect(PoseStack poseStack, int x, int y, int w, int h, double u1, double v1, double u2, double v2) {
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + w);
|
||||
double y2 = (double) (y + h);
|
||||
float x1 = x;
|
||||
float y1 = y;
|
||||
float x2 = (x + w);
|
||||
float y2 = (y + h);
|
||||
|
||||
vBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
|
||||
vBuffer.vertex(x1, y2, 0.0).uv((float) u1, (float) v2).color(255, 255, 255, 255).endVertex();
|
||||
vBuffer.vertex(x2, y2, 0.0).uv((float) u2, (float) v2).color(255, 255, 255, 255).endVertex();
|
||||
vBuffer.vertex(x2, y1, 0.0).uv((float) u2, (float) v1).color(255, 255, 255, 255).endVertex();
|
||||
vBuffer.vertex(x1, y1, 0.0).uv((float) u1, (float) v1).color(255, 255, 255, 255).endVertex();
|
||||
tessellator.end();
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
|
||||
Matrix4f p = poseStack.last().pose();
|
||||
vBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
|
||||
vBuffer.vertex(p, x1, y2, 0.0f).color(255, 255, 255, 255).uv((float) u1, (float) v2).endVertex();
|
||||
vBuffer.vertex(p, x2, y2, 0.0f).color(255, 255, 255, 255).uv((float) u2, (float) v2).endVertex();
|
||||
vBuffer.vertex(p, x2, y1, 0.0f).color(255, 255, 255, 255).uv((float) u2, (float) v1).endVertex();
|
||||
vBuffer.vertex(p, x1, y1, 0.0f).color(255, 255, 255, 255).uv((float) u1, (float) v1).endVertex();
|
||||
BufferUploader.drawWithShader(vBuffer.end());
|
||||
}
|
||||
|
||||
public static void blend(boolean enable) {
|
||||
|
|
@ -163,11 +176,11 @@ public abstract class Control {
|
|||
RenderSystem.setShaderTexture(0, resLoc);
|
||||
}
|
||||
|
||||
public void drawBorder(PoseStack poseStack, int x, int y, int w, int h, int color) {
|
||||
public void drawBorder(GuiGraphics poseStack, int x, int y, int w, int h, int color) {
|
||||
drawBorder(poseStack, x, y, w, h, color, 1.0);
|
||||
}
|
||||
|
||||
public void drawBorder(PoseStack poseStack, int x, int y, int w, int h, int color, double sz) {
|
||||
public void drawBorder(GuiGraphics poseStack, int x, int y, int w, int h, int color, double sz) {
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + w);
|
||||
|
|
@ -177,8 +190,9 @@ public abstract class Control {
|
|||
int g = (color >> 8 ) & 0xFF;
|
||||
int b = color & 0xFF;
|
||||
|
||||
float[] sdrCol = Arrays.copyOf(RenderSystem.getShaderColor(), 4);
|
||||
RenderSystem.setShaderColor(((float) r) / 255.f, ((float) g) / 255.f, ((float) b) / 255.f, ((float) a) / 255.f);
|
||||
RenderSystem.enableTexture();
|
||||
// RenderSystem.enableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
|
@ -208,36 +222,46 @@ public abstract class Control {
|
|||
vBuffer.vertex(x2 - sz, y1, 0.0).endVertex();
|
||||
tessellator.end();
|
||||
|
||||
RenderSystem.setShaderColor(sdrCol[0], sdrCol[1], sdrCol[2], sdrCol[3]);
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableTexture();
|
||||
// RenderSystem.enableTexture();
|
||||
}
|
||||
|
||||
public PoseStack beginFramebuffer(RenderTarget fbo, float vpW, float vpH) {
|
||||
public GuiGraphics beginFramebuffer(RenderTarget fbo, float vpW, float vpH) {
|
||||
GuiGraphics tmpGraphics = new GuiGraphics(Minecraft.getInstance(), Minecraft.getInstance().renderBuffers().bufferSource());
|
||||
|
||||
fbo.bindWrite(true);
|
||||
|
||||
RenderSystem.backupProjectionMatrix();
|
||||
RenderSystem.setProjectionMatrix(Matrix4f.orthographic(0.0f, vpW, vpH, 0.0f, -1.0f,1.0f));
|
||||
RenderSystem.setProjectionMatrix(new Matrix4f().ortho(0.0f, vpW, vpH, 0.0f, -1.0f,1.0f), VertexSorting.ORTHOGRAPHIC_Z);
|
||||
|
||||
PoseStack poseStack = RenderSystem.getModelViewStack();
|
||||
tmpGraphics.pose().last().pose().set(RenderSystem.getModelViewStack().last().pose());
|
||||
tmpGraphics.pose().last().normal().set(RenderSystem.getModelViewStack().last().normal());
|
||||
PoseStack poseStack = tmpGraphics.pose();
|
||||
poseStack.pushPose();
|
||||
poseStack.setIdentity();
|
||||
// poseStack.mulPose(Vector3f.XP.rotationDegrees(180.0f));
|
||||
poseStack.mulPose(XP.rotationDegrees(180.0f));
|
||||
RenderSystem.getModelViewStack().pushPose();
|
||||
RenderSystem.getModelViewStack().last().pose().set(poseStack.last().pose());
|
||||
RenderSystem.getModelViewStack().last().normal().set(poseStack.last().normal());
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
|
||||
if(!fbo.useDepth)
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
return poseStack;
|
||||
return tmpGraphics;
|
||||
}
|
||||
|
||||
public void endFramebuffer(PoseStack poseStack, RenderTarget fbo) {
|
||||
public void endFramebuffer(GuiGraphics poseStack, RenderTarget fbo) {
|
||||
if(!fbo.useDepth)
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
|
||||
RenderSystem.colorMask(true, true, true, true);
|
||||
RenderSystem.restoreProjectionMatrix();
|
||||
poseStack.popPose();
|
||||
poseStack.pose().popPose();
|
||||
RenderSystem.getModelViewStack().popPose();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
fbo.unbindWrite();
|
||||
mc.getMainRenderTarget().bindWrite(true);
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ package net.montoyo.wd.client.gui.controls;
|
|||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import net.montoyo.wd.utilities.Bounds;
|
||||
import net.montoyo.wd.utilities.data.Bounds;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ControlGroup extends Container {
|
||||
|
||||
|
|
@ -94,22 +95,23 @@ public class ControlGroup extends Container {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
super.draw(poseStack, mouseX, mouseY, ptt);
|
||||
|
||||
if(visible) {
|
||||
poseStack.pushPose();
|
||||
poseStack.pose().pushPose();
|
||||
float[] sdrCol = Arrays.copyOf(RenderSystem.getShaderColor(), 4);
|
||||
RenderSystem.setShaderColor(0.5f, 0.5f, 0.5f, 1.f);
|
||||
RenderSystem.disableTexture();
|
||||
// RenderSystem.disableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
double x1 = (double) x;
|
||||
double y1 = (double) y;
|
||||
double x2 = (double) (x + width);
|
||||
double y2 = (double) (y + height);
|
||||
double x1 = x;
|
||||
double y1 = y;
|
||||
double x2 = (x + width);
|
||||
double y2 = (y + height);
|
||||
double bp = 4.0;
|
||||
double lw = (double) labelW;
|
||||
double lw = labelW;
|
||||
|
||||
x1 += bp;
|
||||
y1 += bp;
|
||||
|
|
@ -158,12 +160,14 @@ public class ControlGroup extends Container {
|
|||
vBuffer.vertex(x2 - 1.0, y1, 0.0).endVertex();
|
||||
tessellator.end();
|
||||
|
||||
RenderSystem.setShaderColor(sdrCol[0], sdrCol[1], sdrCol[2], sdrCol[3]);
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableTexture();
|
||||
poseStack.popPose();
|
||||
// RenderSystem.enableTexture();
|
||||
poseStack.pose().popPose();
|
||||
|
||||
if(labelW != 0)
|
||||
font.drawShadow(poseStack, label, x + 10 + ((int) bp), y, labelColor, labelShadowed);
|
||||
poseStack.drawString(Minecraft.getInstance().font, label, x + 10 + ((int) bp), y, labelColor, labelShadowed);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,6 +180,13 @@ public class ControlGroup extends Container {
|
|||
height = bounds.getHeight() + paddingY * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unfocus() {
|
||||
for (Control control : childs) {
|
||||
control.unfocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ package net.montoyo.wd.client.gui.controls;
|
|||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class Icon extends BasicControl {
|
||||
|
|
@ -44,17 +46,17 @@ public class Icon extends BasicControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(texture != null) {
|
||||
poseStack.pushPose();
|
||||
RenderSystem.enableTexture();
|
||||
poseStack.pose().pushPose();
|
||||
// RenderSystem.enableTexture();
|
||||
RenderSystem.setShaderTexture(1, texture);
|
||||
RenderSystem.bindTexture(1);
|
||||
RenderSystem.enableBlend();
|
||||
fillTexturedRect(poseStack, x, y, width, height, u1, v1, u2, v2);
|
||||
fillTexturedRect(poseStack.pose(), x, y, width, height, u1, v1, u2, v2);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.bindTexture(-1);
|
||||
poseStack.popPose();
|
||||
poseStack.pose().popPose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
public class Label extends BasicControl {
|
||||
|
|
@ -72,9 +74,12 @@ public class Label extends BasicControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(visible)
|
||||
font.drawShadow(poseStack, label, x, y, color, shadowed);
|
||||
poseStack.drawString(
|
||||
Minecraft.getInstance().font,
|
||||
label, x, y, color, shadowed
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -9,8 +9,13 @@ import com.mojang.blaze3d.pipeline.TextureTarget;
|
|||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -96,19 +101,21 @@ public class List extends BasicControl {
|
|||
if(fbo != null)
|
||||
fbo.destroyBuffers();
|
||||
|
||||
fbo = new TextureTarget(parent.screen2DisplayX(width), parent.screen2DisplayY(height), false, Minecraft.ON_OSX);
|
||||
fbo = new TextureTarget(parent.screen2DisplayX(width), parent.screen2DisplayY(height), true, Minecraft.ON_OSX);
|
||||
fbo.setFilterMode(GL_NEAREST);
|
||||
fbo.bindWrite(false);
|
||||
fbo.bindWrite(true);
|
||||
RenderSystem.clearColor(0.0f, 0.0f, 0.0f, 1.f); //Set alpha to 1
|
||||
RenderSystem.clearDepth(GL_COLOR_BUFFER_BIT);
|
||||
fbo.unbindWrite();
|
||||
mc.getMainRenderTarget().bindWrite(true);
|
||||
update = true;
|
||||
}
|
||||
|
||||
private void renderToFBO() {
|
||||
PoseStack poseStack = beginFramebuffer(fbo, width, height);
|
||||
poseStack.pushPose();
|
||||
fillRect(0, 0, width, height, COLOR_BLACK);
|
||||
private void renderToFBO(MultiBufferSource.BufferSource source) {
|
||||
GuiGraphics graphics = beginFramebuffer(fbo, width, height);
|
||||
GL11.glColorMask(true, true, true, true);
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
graphics.fill(0, 0, width, height, COLOR_BLACK);
|
||||
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
int offset = 4 - getYOffset();
|
||||
|
|
@ -120,13 +127,13 @@ public class List extends BasicControl {
|
|||
break;
|
||||
|
||||
int color = (i == selected) ? selColor : COLOR_WHITE;
|
||||
font.draw(poseStack, content.get(i).text, 4, i * 12 + offset, color);
|
||||
graphics.drawString(font, content.get(i).text, 4, i * 12 + offset, color);
|
||||
}
|
||||
}
|
||||
|
||||
drawBorder(poseStack, 0, 0, width, height, 0xFF808080);
|
||||
endFramebuffer(poseStack, fbo);
|
||||
poseStack.popPose();
|
||||
graphics.renderOutline(0, 0, width, height, 0xFF808080);
|
||||
graphics.flush();
|
||||
endFramebuffer(graphics, fbo);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -241,13 +248,16 @@ public class List extends BasicControl {
|
|||
if(isInScrollbar(mouseX, mouseY)) {
|
||||
scrolling = true;
|
||||
scrollGrab = mouseY - (y + 1 + scrollPos);
|
||||
} else if(selected >= 0)
|
||||
parent.actionPerformed(new EntryClick(this));
|
||||
return true;
|
||||
} else if(selected >= 0) {
|
||||
System.out.println(parent.actionPerformed(new EntryClick(this)));
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -308,19 +318,18 @@ public class List extends BasicControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics graphics, int mouseX, int mouseY, float ptt) {
|
||||
if(visible) {
|
||||
if(update) {
|
||||
renderToFBO();
|
||||
renderToFBO(graphics.bufferSource());
|
||||
update = false;
|
||||
}
|
||||
|
||||
fbo.bindRead(); //TODO: Make sure is right
|
||||
RenderSystem.setShaderTexture(0, fbo.getColorTextureId());
|
||||
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
|
||||
fillTexturedRect(poseStack, x, y, width, height, 0.0, 1.0, 1.0, 0.0);
|
||||
fbo.unbindRead();
|
||||
fillTexturedRect(graphics.pose(), x, y, width, height, 0.0, 1.0, 1.0, 0.0);
|
||||
|
||||
fillRect(x + width - 5, y + 1 + scrollPos, 4, scrollSize, (scrolling || isInScrollbar(mouseX, mouseY)) ? 0xFF202020 : 0xFF404040);
|
||||
fillRect(graphics.bufferSource(), x + width - 5, y + 1 + scrollPos, 4, scrollSize, (scrolling || isInScrollbar(mouseX, mouseY)) ? 0xFF202020 : 0xFF404040);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,18 @@
|
|||
package net.montoyo.wd.client.gui.controls;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import org.cef.browser.CefBrowserOsr;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static java.awt.event.KeyEvent.VK_ENTER;
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
public class TextField extends Control {
|
||||
|
||||
public static class EnterPressedEvent extends Event<TextField> {
|
||||
|
|
@ -94,40 +99,48 @@ public class TextField extends Control {
|
|||
|
||||
public TextField() {
|
||||
field = new EditBox(font, 1, 1, 198, 20, Component.nullToEmpty(""));
|
||||
setFocused(false);
|
||||
}
|
||||
|
||||
public TextField(int x, int y, int width, int height) {
|
||||
field = new EditBox(font, x + 1, y + 1, width - 2, height - 2, Component.nullToEmpty(""));
|
||||
setFocused(false);
|
||||
}
|
||||
|
||||
public TextField(int x, int y, int width, int height, String text) {
|
||||
field = new EditBox(font, x + 1, y + 1, width - 2, height - 2, Component.nullToEmpty(""));
|
||||
field.setValue(text);
|
||||
setFocused(false);
|
||||
}
|
||||
|
||||
|
||||
// TODO: make this public static in CefBrowserOSR
|
||||
private long mapScanCode(int key, char c) {
|
||||
if (key == GLFW_KEY_LEFT_CONTROL || key == GLFW_KEY_RIGHT_CONTROL) return 29;
|
||||
return switch (key) {
|
||||
case GLFW_KEY_DELETE -> 83;
|
||||
case GLFW_KEY_LEFT -> 75;
|
||||
case GLFW_KEY_DOWN -> 80;
|
||||
case GLFW_KEY_UP -> 72;
|
||||
case GLFW_KEY_RIGHT -> 77;
|
||||
case GLFW_KEY_PAGE_DOWN -> 81;
|
||||
case GLFW_KEY_PAGE_UP -> 73;
|
||||
case GLFW_KEY_END -> 79;
|
||||
case GLFW_KEY_HOME -> 71;
|
||||
case VK_ENTER, GLFW_KEY_ENTER, GLFW_KEY_KP_ENTER -> 28;
|
||||
default -> GLFW.glfwGetKeyScancode(key);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyDown(int key) {
|
||||
if(key == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
String old;
|
||||
if(enabled && field.isFocused())
|
||||
old = field.getValue();
|
||||
else
|
||||
old = null;
|
||||
|
||||
if(field.getValue().length() > 0)
|
||||
field.setValue(field.getValue().substring(0, field.getValue().length() - 1));
|
||||
|
||||
if(enabled && field.isFocused() && !field.getValue().equals(old)) {
|
||||
for(TextChangeListener tcl : listeners)
|
||||
tcl.onTextChange(this, old, field.getValue());
|
||||
|
||||
parent.actionPerformed(new TextChangedEvent(this, old));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public boolean keyDown(int key, int scanCode, int modifiers) {
|
||||
return field.keyPressed(key, scanCode, modifiers);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean keyUp(int key, int scanCode, int modifiers) {
|
||||
return field.keyReleased(key, scanCode, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(int keyCode, int modifier) {
|
||||
if(keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)
|
||||
|
|
@ -141,26 +154,56 @@ public class TextField extends Control {
|
|||
else
|
||||
old = null;
|
||||
|
||||
field.charTyped((char) keyCode, modifier);
|
||||
|
||||
if(enabled && field.isFocused() && !field.getValue().equals(old)) {
|
||||
for(TextChangeListener tcl : listeners)
|
||||
tcl.onTextChange(this, old, field.getValue());
|
||||
|
||||
parent.actionPerformed(new TextChangedEvent(this, old));
|
||||
}
|
||||
|
||||
return field.charTyped((char) keyCode, modifier);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
|
||||
return field.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
if (field.mouseClicked(mouseX, mouseY, mouseButton)) {
|
||||
setFocused(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void unfocus() {
|
||||
setFocused(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int state) {
|
||||
return field.mouseReleased(mouseX, mouseY, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClickMove(double mouseX, double mouseY, int button, double dragX, double dragY) {
|
||||
return field.mouseClicked(mouseX, mouseY, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseMove(double mouseX, double mouseY) {
|
||||
field.mouseMoved(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScroll(double mouseX, double mouseY, double amount) {
|
||||
return field.mouseScrolled(mouseX, mouseY, amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
field.render(poseStack, mouseX, mouseY, ptt);
|
||||
}
|
||||
|
||||
|
|
@ -211,23 +254,26 @@ public class TextField extends Control {
|
|||
|
||||
@Override
|
||||
public void setPos(int x, int y) {
|
||||
field.x = x + 1;
|
||||
field.y = y + 1;
|
||||
field.setPosition(
|
||||
x + 1,
|
||||
y + 1
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return field.x - 1;
|
||||
return field.getX() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getY() {
|
||||
return field.y - 1;
|
||||
return field.getY() - 1;
|
||||
}
|
||||
|
||||
public void setDisabled(boolean en) {
|
||||
enabled = !en;
|
||||
field.setFocus(enabled);
|
||||
if (!en)
|
||||
field.setFocused(false);
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
|
|
@ -235,12 +281,11 @@ public class TextField extends Control {
|
|||
}
|
||||
|
||||
public void enable() {
|
||||
field.setFocus(true);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
field.setFocus(false);
|
||||
field.setFocused(false);
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +306,7 @@ public class TextField extends Control {
|
|||
}
|
||||
|
||||
public void setFocused(boolean val) {
|
||||
field.setFocus(val);
|
||||
field.setFocused(val);
|
||||
}
|
||||
|
||||
public boolean hasFocus() {
|
||||
|
|
@ -269,15 +314,7 @@ public class TextField extends Control {
|
|||
}
|
||||
|
||||
public void focus() {
|
||||
field.setFocus(true);
|
||||
}
|
||||
|
||||
public void setMaxLength(int len) {
|
||||
field.setMaxLength(len);
|
||||
}
|
||||
|
||||
public int getMaxLength() {
|
||||
return field.getMaxLength(); //TODO: access transformer
|
||||
field.setFocused(true);
|
||||
}
|
||||
|
||||
public void setTextColor(int color) {
|
||||
|
|
@ -314,8 +351,10 @@ public class TextField extends Control {
|
|||
@Override
|
||||
public void load(JsonOWrapper json) {
|
||||
super.load(json);
|
||||
field.x = json.getInt("x", 0) + 1;
|
||||
field.y = json.getInt("y", 0) + 1;
|
||||
field.setPosition(
|
||||
json.getInt("x", 0) + 1,
|
||||
json.getInt("y", 0) + 1
|
||||
);
|
||||
field.setWidth(json.getInt("width", 200) - 2);
|
||||
field.setHeight(json.getInt("height", 22) - 2);
|
||||
field.setValue(tr(json.getString("text", "")));
|
||||
|
|
@ -328,7 +367,7 @@ public class TextField extends Control {
|
|||
|
||||
field.setTextColor(textColor);
|
||||
field.setTextColorUneditable(disabledColor);
|
||||
field.setFocus(enabled);
|
||||
setFocused(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ package net.montoyo.wd.client.gui.controls;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -27,23 +28,23 @@ public class UpgradeGroup extends BasicControl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(upgrades != null) {
|
||||
int x = this.x;
|
||||
|
||||
for(ItemStack is: upgrades) {
|
||||
if(is == overStack && !disabled)
|
||||
fillRect(x, y, 16, 16, 0x80FF0000);
|
||||
fillRect(poseStack.bufferSource(), x, y, 16, 16, 0x80FF0000);
|
||||
|
||||
renderItem.renderAndDecorateItem(mc.player, is, x, y, 0);
|
||||
renderItem.renderAndDecorateItem(is, font.lineHeight, x, y); //TODO is lineHeight right?
|
||||
poseStack.renderItem(is, x, y);
|
||||
poseStack.renderItemDecorations(font, is, x, y);
|
||||
x += 18;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postDraw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
|
||||
public void postDraw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) {
|
||||
if(overStack != null)
|
||||
parent.drawItemStackTooltip(poseStack, overStack, mouseX, mouseY);
|
||||
}
|
||||
|
|
@ -103,9 +104,15 @@ public class UpgradeGroup extends BasicControl {
|
|||
@Override
|
||||
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
|
||||
if(mouseButton == 0) {
|
||||
clickStack = overStack;
|
||||
|
||||
return true;
|
||||
// don't process the click if it's not inbounds, lol
|
||||
if (
|
||||
mouseX >= x && mouseX <= x + width &&
|
||||
mouseY >= y && mouseX <= y + height
|
||||
) {
|
||||
clickStack = overStack;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ package net.montoyo.wd.client.gui.controls;
|
|||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.montoyo.wd.client.gui.loading.JsonOWrapper;
|
||||
import net.montoyo.wd.utilities.Util;
|
||||
import net.montoyo.wd.utilities.serialization.Util;
|
||||
import net.montoyo.wd.utilities.VideoType;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
|
|
|||
|
|
@ -62,24 +62,15 @@ public class GuiLoader {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static JsonObject getJson(ResourceLocation resLoc) {
|
||||
public static JsonObject getJson(ResourceLocation resLoc) throws IOException {
|
||||
JsonObject ret = RESOURCES.get(resLoc);
|
||||
if(ret == null) {
|
||||
Resource resource;
|
||||
|
||||
try {
|
||||
resource = Minecraft.getInstance().getResourceManager().getResource(resLoc);
|
||||
} catch(IOException e) {
|
||||
Log.errorEx("Couldn't load JSON UI from file", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
resource = Minecraft.getInstance().getResourceManager().getResource(resLoc).get();
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
ret = parser.parse(new InputStreamReader(resource.getInputStream())).getAsJsonObject();
|
||||
|
||||
try {
|
||||
resource.close();
|
||||
} catch(IOException e) {}
|
||||
ret = parser.parse(new InputStreamReader(resource.open())).getAsJsonObject();
|
||||
|
||||
RESOURCES.put(resLoc, ret);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,17 @@ import net.minecraft.client.renderer.MultiBufferSource;
|
|||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public interface IItemRenderer {
|
||||
|
||||
void render(PoseStack stack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight);
|
||||
|
||||
|
||||
/**
|
||||
* @param pose the pose stack
|
||||
* @param stack the item stack
|
||||
* @param handSideSign TODO:
|
||||
* @param swingProgress TODO:
|
||||
* @param equipProgress TODO:
|
||||
* @param multiBufferSource the buffer source
|
||||
* @param packedLight packed light
|
||||
* @return whether or not to cancel vanilla rendering
|
||||
*/
|
||||
boolean render(PoseStack pose, ItemStack stack, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
|
||||
public interface IModelBaker extends IDynamicBakedModel{
|
||||
|
||||
void loadTextures(TextureAtlas texMap);
|
||||
|
||||
}
|
||||
|
|
@ -4,112 +4,127 @@
|
|||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import com.mojang.math.Vector3f;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.registry.ItemRegistry;
|
||||
import net.montoyo.wd.item.ItemLaserPointer;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static com.mojang.math.Axis.*;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class LaserPointerRenderer implements IItemRenderer {
|
||||
|
||||
private static final float PI = (float) Math.PI;
|
||||
private final Tesselator t = Tesselator.getInstance();
|
||||
private final BufferBuilder bb = t.getBuilder();
|
||||
private final VertexBuffer vb = new VertexBuffer();
|
||||
private final FloatBuffer matrix1 = BufferUtils.createFloatBuffer(16);
|
||||
private final FloatBuffer renderBuffer = BufferUtils.createFloatBuffer(8);
|
||||
|
||||
public boolean isOn = false;
|
||||
|
||||
public LaserPointerRenderer() {
|
||||
for(int i = 0; i < 8; i++)
|
||||
renderBuffer.put(0.0f);
|
||||
|
||||
renderBuffer.position(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(PoseStack poseStack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
|
||||
//This whole method is a fucking hack
|
||||
float sqrtSwingProg = (float) Math.sqrt(swingProgress);
|
||||
float sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
|
||||
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.disableTexture();
|
||||
|
||||
poseStack.pushPose();
|
||||
//Laser pointer
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, (float) (0.2f * Math.sin(sqrtSwingProg * PI * 2.0f)), (float) (-0.2f * Math.sin(swingProgress * PI)));
|
||||
poseStack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f);
|
||||
poseStack.mulPose(Vector3f.YP.rotationDegrees((float) (handSideSign * (45.0f - Math.sin(swingProgress * swingProgress * PI) * 20.0f))));
|
||||
poseStack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f));
|
||||
poseStack.mulPose(Vector3f.XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
|
||||
poseStack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -30.0f));
|
||||
poseStack.translate(0.0f, 0.2f, 0.0f);
|
||||
poseStack.mulPose(Vector3f.XP.rotationDegrees(10.0f));
|
||||
poseStack.scale(1.0f / 16.0f, 1.0f / 16.0f, 1.0f / 16.0f);
|
||||
|
||||
RenderSystem.setShaderColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
|
||||
bb.vertex(0.0, 0.0, 0.0).endVertex();
|
||||
bb.vertex(1.0, 0.0, 0.0).endVertex();
|
||||
bb.vertex(1.0, 0.0, 4.0).endVertex();
|
||||
bb.vertex(0.0, 0.0, 4.0).endVertex();
|
||||
|
||||
bb.vertex(0.0, 0.0, 0.0).endVertex();
|
||||
bb.vertex(0.0, -1.0, 0.0).endVertex();
|
||||
bb.vertex(0.0, -1.0, 4.0).endVertex();
|
||||
bb.vertex(0.0, 0.0, 4.0).endVertex();
|
||||
|
||||
bb.vertex(1.0, 0.0, 0.0).endVertex();
|
||||
bb.vertex(1.0, -1.0, 0.0).endVertex();
|
||||
bb.vertex(1.0, -1.0, 4.0).endVertex();
|
||||
bb.vertex(1.0, 0.0, 4.0).endVertex();
|
||||
|
||||
bb.vertex(0.0, -1.0, 4.0).endVertex();
|
||||
bb.vertex(1.0, -1.0, 4.0).endVertex();
|
||||
bb.vertex(1.0, 0.0, 4.0).endVertex();
|
||||
bb.vertex(0.0, 0.0, 4.0).endVertex();
|
||||
t.end();
|
||||
if(isOn) {
|
||||
poseStack.translate(0.5f, -0.5f, 0.0f);
|
||||
matrix1.position(0);
|
||||
RenderSystem.getModelViewMatrix(); //Hax to get that damn position
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
|
||||
if(isOn) {
|
||||
//Actual laser
|
||||
poseStack.pushPose();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.DST_ALPHA);
|
||||
RenderSystem.setShaderColor(1.0f, 0.0f, 0.0f, 0.5f);
|
||||
RenderSystem.lineWidth(3.0f);
|
||||
|
||||
matrix1.position(12);
|
||||
renderBuffer.put(matrix1.get());
|
||||
renderBuffer.put(matrix1.get());
|
||||
renderBuffer.put(matrix1.get() - 0.02f); //I know this is stupid, but it's the only thing that worked...
|
||||
renderBuffer.put(matrix1.get());
|
||||
renderBuffer.position(0);
|
||||
RenderSystem.drawElements(GL_LINES, 0, GL_UNSIGNED_INT);
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
RenderSystem.enableTexture(); //Fix for shitty minecraft fire
|
||||
RenderSystem.enableCull();
|
||||
}
|
||||
|
||||
private final Tesselator t = Tesselator.getInstance();
|
||||
private final BufferBuilder bb = t.getBuilder();
|
||||
|
||||
public LaserPointerRenderer() {
|
||||
}
|
||||
|
||||
public static boolean isOn() {
|
||||
if (Minecraft.getInstance().screen != null) return false;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
return mc.player != null && mc.level != null &&
|
||||
(
|
||||
ClientProxy.mouseOn ||
|
||||
ItemLaserPointer.isOn()
|
||||
) &&
|
||||
mc.player.getItemInHand(InteractionHand.MAIN_HAND).getItem().equals(ItemRegistry.LASER_POINTER.get()) &&
|
||||
(mc.hitResult == null || mc.hitResult.getType() == HitResult.Type.BLOCK || mc.hitResult.getType() == HitResult.Type.MISS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean render(PoseStack poseStack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
|
||||
RenderSystem.disableCull();
|
||||
// RenderSystem.disableTexture();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.enableBlend();
|
||||
|
||||
float PI = (float) Math.PI;
|
||||
|
||||
float sqrtSwingProg = (float) Math.sqrt(swingProgress);
|
||||
float sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
|
||||
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||
|
||||
var matrix0 = poseStack.last().pose();
|
||||
//Laser pointer
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, (float) (0.2f * Math.sin(sqrtSwingProg * PI * 2.0f)), (float) (-0.2f * Math.sin(swingProgress * PI)));
|
||||
poseStack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f);
|
||||
poseStack.mulPose(YP.rotationDegrees((float) (handSideSign * (45.0f - Math.sin(swingProgress * swingProgress * PI) * 20.0f))));
|
||||
poseStack.mulPose(ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f));
|
||||
poseStack.mulPose(XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
|
||||
poseStack.mulPose(YP.rotationDegrees(handSideSign * -30.0f));
|
||||
poseStack.translate(0.0f, 0.2f, 0.0f);
|
||||
poseStack.mulPose(XP.rotationDegrees(10.0f));
|
||||
poseStack.scale(1.0f / 16.0f, 1.0f / 16.0f, 1.0f / 16.0f);
|
||||
var matrix = poseStack.last().pose();
|
||||
|
||||
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
|
||||
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
|
||||
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 0.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 0.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
|
||||
bb.vertex(matrix, 1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 1.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
|
||||
bb.vertex(matrix, 0.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
bb.vertex(matrix, 0.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex();
|
||||
|
||||
if (isOn()) drawLineBetween(bb, matrix0, matrix, new Vec3(0.5f, -0.5f, 0.5f), new Vec3(-40.0f, 4000.5f, -100.0f));
|
||||
|
||||
t.end();
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.disableDepthTest();
|
||||
// RenderSystem.enableTexture(); //Fix for shitty minecraft fire
|
||||
RenderSystem.enableCull();
|
||||
poseStack.popPose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void drawLineBetween(BufferBuilder bb, Matrix4f matrix0, Matrix4f matrix, Vec3 local, Vec3 target) {
|
||||
//Calculate distance between points -> length of the line
|
||||
float distance = (float) local.distanceTo(target) / 2;
|
||||
float quarterWidth = 0.25f;
|
||||
float biggerWidth = 10;
|
||||
|
||||
bb.vertex(matrix, 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix, quarterWidth + 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix0, biggerWidth - 6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix0, -6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
|
||||
bb.vertex(matrix, 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix, 0.25f, -quarterWidth - 0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix0, -6f, -biggerWidth + 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix0, -6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
|
||||
bb.vertex(matrix, quarterWidth + 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix, quarterWidth + 0.25f, -quarterWidth - 0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix0, biggerWidth - 6f, -biggerWidth + 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
bb.vertex(matrix0, biggerWidth - 6f, 3f, -distance).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,132 +4,161 @@
|
|||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import com.cinemamod.mcef.MCEFBrowser;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.math.Matrix3f;
|
||||
import com.mojang.math.Matrix4f;
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.config.ClientConfig;
|
||||
import net.montoyo.wd.item.ItemMinePad2;
|
||||
|
||||
import static org.lwjgl.opengl.GL12.GL_RESCALE_NORMAL;
|
||||
import static com.mojang.math.Axis.*;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class MinePadRenderer implements IItemRenderer {
|
||||
|
||||
private static final float PI = (float) Math.PI;
|
||||
private final Minecraft mc = Minecraft.getInstance();
|
||||
private final ResourceLocation tex = new ResourceLocation("webdisplays", "textures/models/minepad.png");
|
||||
// private final ModelMinePad model = new ModelMinePad();
|
||||
private final ClientProxy clientProxy = (ClientProxy) WebDisplays.PROXY;
|
||||
|
||||
private float sinSqrtSwingProg1;
|
||||
private float sinSqrtSwingProg2;
|
||||
private float sinSwingProg1;
|
||||
private float sinSwingProg2;
|
||||
|
||||
// public static void drawAxis() {
|
||||
// glDisable(GL_TEXTURE_2D);
|
||||
// glBegin(GL_LINES);
|
||||
// glColor4f(1.f, 0.f, 0.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
|
||||
// glColor4f(1.f, 0.f, 0.f, 1.f); glVertex3d(5.0, 0.0, 0.0);
|
||||
// glColor4f(0.f, 1.f, 0.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
|
||||
// glColor4f(0.f, 1.f, 0.f, 1.f); glVertex3d(0.0, 5.0, 0.0);
|
||||
// glColor4f(0.f, 0.f, 1.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
|
||||
// glColor4f(0.f, 0.f, 1.f, 1.f); glVertex3d(0.0, 0.0, 5.0);
|
||||
// glEnd();
|
||||
// glEnable(GL_TEXTURE_2D);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public final void render(PoseStack stack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
|
||||
//Pre-compute values
|
||||
float sqrtSwingProg = (float) Math.sqrt(swingProgress);
|
||||
sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
|
||||
sinSqrtSwingProg2 = (float) Math.sin(sqrtSwingProg * PI * 2.0f);
|
||||
sinSwingProg1 = (float) Math.sin(swingProgress * PI);
|
||||
sinSwingProg2 = (float) Math.sin(swingProgress * swingProgress * PI);
|
||||
|
||||
RenderSystem.disableCull();
|
||||
// glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
//Render arm
|
||||
stack.pushPose();
|
||||
renderArmFirstPerson(stack, multiBufferSource, packedLight, equipProgress, handSideSign);
|
||||
stack.popPose();
|
||||
|
||||
//Prepare minePad transform
|
||||
stack.pushPose();
|
||||
stack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, 0.2f * sinSqrtSwingProg2, -0.2f * sinSwingProg1);
|
||||
stack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f);
|
||||
stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * (45.0f - sinSwingProg2 * 20.0f)));
|
||||
stack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f));
|
||||
stack.mulPose(Vector3f.XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
|
||||
stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -45.0f));
|
||||
|
||||
if(handSideSign >= 0.0f)
|
||||
stack.translate(-1.065f, 0.0f, 0.0f);
|
||||
else {
|
||||
stack.translate(0.0f, 0.0f, -0.2f);
|
||||
stack.mulPose(Vector3f.YP.rotationDegrees(20.0f));
|
||||
stack.translate(-0.475f, -0.1f, 0.0f);
|
||||
stack.mulPose(Vector3f.ZP.rotationDegrees(1.0f));
|
||||
}
|
||||
|
||||
//Render model
|
||||
stack.pushPose();
|
||||
stack.mulPose(Vector3f.XP.rotationDegrees(-90.0f));
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
RenderSystem.setShaderTexture(0, tex);
|
||||
// model.render(1.f / 16.f);
|
||||
stack.popPose();
|
||||
|
||||
//Render web view
|
||||
if(is.getTag() != null && is.getTag().contains("PadID")) {
|
||||
ClientProxy.PadData pd = clientProxy.getPadByID(is.getTag().getInt("PadID"));
|
||||
|
||||
if(pd != null) {
|
||||
stack.translate(0.063f, 0.28f, 0.001f);
|
||||
RenderSystem.disableTexture();
|
||||
pd.view.draw(stack,0.0, 0.0, 27.65 / 32.0 + 0.01, 14.0 / 32.0 + 0.002);
|
||||
}
|
||||
}
|
||||
|
||||
stack.popPose();
|
||||
// glDisable(GL_RESCALE_NORMAL);
|
||||
RenderSystem.enableCull();
|
||||
}
|
||||
|
||||
private void renderArmFirstPerson(PoseStack stack, MultiBufferSource buffer, int combinedLight, float equipProgress, float handSideSign) {
|
||||
float tx = -0.3f * sinSqrtSwingProg1;
|
||||
float ty = 0.4f * sinSqrtSwingProg2;
|
||||
float tz = -0.4f * sinSwingProg1;
|
||||
|
||||
stack.translate(handSideSign * (tx + 0.64000005f), ty - 0.6f - equipProgress * 0.6f, tz - 0.71999997f);
|
||||
stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * 45.0f));
|
||||
stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * 70.0f));
|
||||
stack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * sinSwingProg2 * -20.0f));
|
||||
stack.translate(-handSideSign, 3.6f, 3.5f);
|
||||
stack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * 120.0f));
|
||||
stack.mulPose(Vector3f.XP.rotationDegrees(200.0f));
|
||||
stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -135.0f));
|
||||
stack.translate(handSideSign * 5.6f, 0.0f, 0.0f);
|
||||
|
||||
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(mc.player);
|
||||
RenderSystem.setShaderTexture(0, mc.player.getSkinTextureLocation());
|
||||
|
||||
if(handSideSign >= 0.0f)
|
||||
playerRenderer.renderRightHand(stack, buffer, combinedLight, mc.player);
|
||||
else
|
||||
playerRenderer.renderLeftHand(stack, buffer, combinedLight, mc.player);
|
||||
}
|
||||
|
||||
private static final float PI = (float) Math.PI;
|
||||
private final Minecraft mc = Minecraft.getInstance();
|
||||
private final ResourceLocation tex = new ResourceLocation("webdisplays", "textures/item/model/minepad.png");
|
||||
private final ModelMinePad model = new ModelMinePad();
|
||||
private final ClientProxy clientProxy = (ClientProxy) WebDisplays.PROXY;
|
||||
|
||||
private float sinSqrtSwingProg1;
|
||||
private float sinSqrtSwingProg2;
|
||||
private float sinSwingProg1;
|
||||
private float sinSwingProg2;
|
||||
|
||||
public static boolean renderAtSide(float handSideSign) {
|
||||
float relSide = handSideSign;
|
||||
if (Minecraft.getInstance().player.getMainArm() == HumanoidArm.LEFT) relSide *= -1;
|
||||
|
||||
// by default, the player holds the device off to the side
|
||||
// if they are crouching, they hold it infront of them
|
||||
// however, if they are holding two at once, then it once again should just be held off to the side
|
||||
boolean sideHold = Minecraft.getInstance().player.isShiftKeyDown() != ClientConfig.sidePad;
|
||||
if (
|
||||
(relSide < 0 && Minecraft.getInstance().player.getItemInHand(InteractionHand.MAIN_HAND).getItem() instanceof ItemMinePad2) ||
|
||||
(relSide > 0 && Minecraft.getInstance().player.getItemInHand(InteractionHand.OFF_HAND).getItem() instanceof ItemMinePad2)
|
||||
) sideHold = true;
|
||||
|
||||
return sideHold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean render(PoseStack stack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
|
||||
//Pre-compute values
|
||||
float sqrtSwingProg = (float) Math.sqrt(swingProgress);
|
||||
sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
|
||||
sinSqrtSwingProg2 = (float) Math.sin(sqrtSwingProg * PI * 2.0f);
|
||||
sinSwingProg1 = (float) Math.sin(swingProgress * PI);
|
||||
sinSwingProg2 = (float) Math.sin(swingProgress * swingProgress * PI);
|
||||
|
||||
boolean sideHold = renderAtSide(handSideSign);
|
||||
|
||||
//Render arm
|
||||
stack.pushPose();
|
||||
renderArmFirstPerson(stack, multiBufferSource, packedLight, equipProgress, handSideSign);
|
||||
stack.popPose();
|
||||
// if (!sideHold && handSideSign == 1 && mc.player.getItemInHand(InteractionHand.OFF_HAND).isEmpty()) {
|
||||
// stack.pushPose();
|
||||
// renderArmFirstPerson(stack, multiBufferSource, packedLight, 0, -handSideSign);
|
||||
// stack.popPose();
|
||||
// }
|
||||
|
||||
//Prepare minePad transform
|
||||
stack.pushPose();
|
||||
stack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, 0.2f * sinSqrtSwingProg2, -0.2f * sinSwingProg1);
|
||||
stack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f);
|
||||
stack.mulPose(YP.rotationDegrees(handSideSign * (45.0f - sinSwingProg2 * 20.0f)));
|
||||
stack.mulPose(ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f));
|
||||
stack.mulPose(XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
|
||||
stack.mulPose(YP.rotationDegrees(handSideSign * -45.0f));
|
||||
|
||||
if (sideHold) {
|
||||
stack.translate(0.0f, 0.0f, -0.2f);
|
||||
stack.mulPose(YP.rotationDegrees(20.0f * -handSideSign));
|
||||
float total = 0.475f;
|
||||
float off = -0.025f; // gotta love magic numbers
|
||||
stack.translate(-(total - off) + (off * handSideSign), -0.1f, 0.0f);
|
||||
stack.mulPose(ZP.rotationDegrees(1.0f));
|
||||
} else if (handSideSign >= 0) // right hand
|
||||
stack.translate(-1.065f, 0.0f, 0.0f);
|
||||
else // left hand
|
||||
stack.translate(0.065f, 0.0f, 0.0f);
|
||||
|
||||
//Render model
|
||||
stack.translate(0.063f, 0.28f, 0.001f);
|
||||
model.render(multiBufferSource, stack);
|
||||
stack.translate(-0.063f, -0.28f, -0.001f);
|
||||
|
||||
// force draw so the browser can be drawn ontop of the model
|
||||
multiBufferSource.getBuffer(RenderType.LINES);
|
||||
|
||||
if (is.getTag() != null && is.getTag().contains("PadID")) {
|
||||
ClientProxy.PadData pd = clientProxy.getPadByID(is.getTag().getUUID("PadID"));
|
||||
|
||||
//Render web view
|
||||
if (pd != null) {
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x2 = 27.65 / 32.0 + 0.01;
|
||||
double y2 = 14.0 / 32.0 + 0.002;
|
||||
|
||||
stack.translate(0.063f, 0.28f, 0.001f);
|
||||
// RenderSystem.setShaderTexture(0, tex);
|
||||
|
||||
RenderSystem.disableDepthTest();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
|
||||
RenderSystem.setShaderTexture(0, ((MCEFBrowser) pd.view).getRenderer().getTextureID());
|
||||
Tesselator t = Tesselator.getInstance();
|
||||
BufferBuilder buffer = t.getBuilder();
|
||||
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
|
||||
buffer.vertex(stack.last().pose(), (float) x1, (float) y1, 0.0f).uv(0.0F, 1.0F).color(255, 255, 255, 255).endVertex();
|
||||
buffer.vertex(stack.last().pose(), (float) x2, (float) y1, 0.0f).uv(1.0F, 1.0F).color(255, 255, 255, 255).endVertex();
|
||||
buffer.vertex(stack.last().pose(), (float) x2, (float) y2, 0.0f).uv(1.0F, 0.0F).color(255, 255, 255, 255).endVertex();
|
||||
buffer.vertex(stack.last().pose(), (float) x1, (float) y2, 0.0f).uv(0.0F, 0.0F).color(255, 255, 255, 255).endVertex();
|
||||
t.end();
|
||||
RenderSystem.enableDepthTest();
|
||||
}
|
||||
}
|
||||
|
||||
stack.popPose();
|
||||
RenderSystem.enableCull();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void renderArmFirstPerson(PoseStack stack, MultiBufferSource buffer, int combinedLight, float equipProgress, float handSideSign) {
|
||||
float tx = -0.3f * sinSqrtSwingProg1;
|
||||
float ty = 0.4f * sinSqrtSwingProg2;
|
||||
float tz = -0.4f * sinSwingProg1;
|
||||
|
||||
stack.translate(handSideSign * (tx + 0.64000005f), ty - 0.6f - equipProgress * 0.6f, tz - 0.71999997f);
|
||||
stack.mulPose(YP.rotationDegrees(handSideSign * 45.0f));
|
||||
stack.mulPose(YP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * 70.0f));
|
||||
stack.mulPose(ZP.rotationDegrees(handSideSign * sinSwingProg2 * -20.0f));
|
||||
stack.translate(-handSideSign, 3.6f, 3.5f);
|
||||
stack.mulPose(ZP.rotationDegrees(handSideSign * 120.0f));
|
||||
stack.mulPose(XP.rotationDegrees(200.0f));
|
||||
stack.mulPose(YP.rotationDegrees(handSideSign * -135.0f));
|
||||
stack.translate(handSideSign * 5.6f, 0.0f, 0.0f);
|
||||
|
||||
PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(mc.player);
|
||||
RenderSystem.setShaderTexture(0, mc.player.getSkinTextureLocation());
|
||||
|
||||
if (handSideSign >= 0.0f)
|
||||
playerRenderer.renderRightHand(stack, buffer, combinedLight, mc.player);
|
||||
else
|
||||
playerRenderer.renderLeftHand(stack, buffer, combinedLight, mc.player);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,60 +4,70 @@
|
|||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
/*import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.model.Model;
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public final class ModelMinePad extends Model {
|
||||
public final class ModelMinePad {
|
||||
public void render(MultiBufferSource buffers, PoseStack stack) {
|
||||
// TODO: this needs completing
|
||||
// TODO: I'd like this to be able to load a model from a JSON if possible
|
||||
|
||||
double x1 = 0.0;
|
||||
double y1 = 0.0;
|
||||
double x2 = 27.65 / 32.0 + 0.01;
|
||||
double y2 = 14.0 / 32.0 + 0.002;
|
||||
|
||||
Matrix4f positionMatrix = stack.last().pose();
|
||||
Tesselator t = Tesselator.getInstance();
|
||||
BufferBuilder vb = t.getBuilder();
|
||||
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
vb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
vb.vertex(positionMatrix, (float) x1, (float) y1, 0.0f).color(0, 0, 0, 255).endVertex();
|
||||
vb.vertex(positionMatrix, (float) x2, (float) y1, 0.0f).color(0, 0, 0, 255).endVertex();
|
||||
vb.vertex(positionMatrix, (float) x2, (float) y2, 0.0f).color(0, 0, 0, 255).endVertex();
|
||||
vb.vertex(positionMatrix, (float) x1, (float) y2, 0.0f).color(0, 0, 0, 255).endVertex();
|
||||
t.end();
|
||||
|
||||
int width = 32;
|
||||
int height = 32;
|
||||
|
||||
float padding = 1f / 23;
|
||||
float padding1 = 1f / 21;
|
||||
|
||||
float z = 0;
|
||||
|
||||
VertexConsumer consumer = buffers.getBuffer(RenderType.entityCutout(new ResourceLocation("webdisplays:textures/item/model/minepad_item.png")));
|
||||
|
||||
consumer.vertex(positionMatrix, (float) x1, (float) y1 - padding, z).color(255, 255, 255, 255).uv(1f / width, 12f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
consumer.vertex(positionMatrix, (float) x2, (float) y1 - padding, z).color(255, 255, 255, 255).uv(19f / width, 12f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
consumer.vertex(positionMatrix, (float) x2, (float) y2 + padding, z).color(255, 255, 255, 255).uv(19f / width, 0).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
consumer.vertex(positionMatrix, (float) x1, (float) y2 + padding, z).color(255, 255, 255, 255).uv(1f / width, 0).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
|
||||
// fields
|
||||
private final ModelPart base;
|
||||
private final ModelPart left;
|
||||
private final ModelPart right;
|
||||
|
||||
public ModelMinePad() {
|
||||
super();
|
||||
textureWidth = 64;
|
||||
textureHeight = 32;
|
||||
|
||||
base = new ModelPart(this, 0, 0);
|
||||
base.addBox(0F, 0F, 0F, 14, 1, 9);
|
||||
base.setRotationPoint(1F, 0F, 3.5F);
|
||||
base.setTextureSize(64, 32);
|
||||
base.mirror = true;
|
||||
clearRotation(base);
|
||||
left = new ModelRenderer(this, 0, 10);
|
||||
left.addBox(0F, 0F, 0F, 1, 1, 7);
|
||||
left.setRotationPoint(0F, 0F, 4.5F);
|
||||
left.setTextureSize(64, 32);
|
||||
left.mirror = true;
|
||||
clearRotation(left);
|
||||
right = new ModelRenderer(this, 30, 10);
|
||||
right.addBox(0F, 0F, 0F, 1, 1, 7);
|
||||
right.setRotationPoint(15F, 0F, 4.5F);
|
||||
right.setTextureSize(64, 32);
|
||||
right.mirror = true;
|
||||
clearRotation(right);
|
||||
}
|
||||
|
||||
public final void render(float f5) {
|
||||
base.render(f5);
|
||||
left.render(f5);
|
||||
right.render(f5);
|
||||
}
|
||||
|
||||
private void clearRotation(ModelPart model) {
|
||||
model.rotateAngleX = 0.0f;
|
||||
model.rotateAngleY = 0.0f;
|
||||
model.rotateAngleZ = 0.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderToBuffer(PoseStack poseStack, VertexConsumer buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
|
||||
|
||||
}
|
||||
}*/
|
||||
consumer.vertex(positionMatrix, (float) x1 - padding1, (float) y1, z).color(255, 255, 255, 255).uv(0f / width, 10f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
consumer.vertex(positionMatrix, (float) x2 + padding1, (float) y1, z).color(255, 255, 255, 255).uv(20f / width, 10f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
consumer.vertex(positionMatrix, (float) x2 + padding1, (float) y2, z).color(255, 255, 255, 255).uv(20f / width, 1f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
consumer.vertex(positionMatrix, (float) x1 - padding1, (float) y2, z).color(255, 255, 255, 255).uv(0f / width, 1f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
|
||||
// consumer.vertex(positionMatrix, (float) x2, (float) y2 + padding, z - padding).color(255, 255, 255, 255).uv(0f / width, 1f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
// consumer.vertex(positionMatrix, (float) x2, (float) y2 + padding, z).color(255, 255, 255, 255).uv(1f / width, 1f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
// consumer.vertex(positionMatrix, (float) x2, (float) y1 - padding, z).color(255, 255, 255, 255).uv(1f / width, 2f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
// consumer.vertex(positionMatrix, (float) x2, (float) y1 - padding, z - padding).color(255, 255, 255, 255).uv(0f / width, 2f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
//
|
||||
// consumer.vertex(positionMatrix, (float) x1, (float) y1 - padding, z - padding).color(255, 255, 255, 255).uv(0f / width, 2f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
// consumer.vertex(positionMatrix, (float) x1, (float) y1 - padding, z).color(255, 255, 255, 255).uv(1f / width, 2f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
// consumer.vertex(positionMatrix, (float) x1, (float) y2 + padding, z).color(255, 255, 255, 255).uv(1f / width, 1f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
// consumer.vertex(positionMatrix, (float) x1, (float) y2 + padding, z - padding).color(255, 255, 255, 255).uv(0f / width, 1f / height).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(LightTexture.FULL_BRIGHT).normal(0.25f, 0.5f, 1).endVertex();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,164 +5,232 @@
|
|||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.ModelState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Vector3f;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
import net.minecraftforge.client.model.data.ModelData;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector3f;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ScreenBaker implements IModelBaker {
|
||||
|
||||
private static final List<BakedQuad> noQuads = ImmutableList.of();
|
||||
private final TextureAtlasSprite[] texs = new TextureAtlasSprite[16];
|
||||
private final BlockSide[] blockSides = BlockSide.values();
|
||||
private final Direction[] blockFacings = Direction.values();
|
||||
private final ModelState modelState;
|
||||
private final Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter;
|
||||
private final ItemOverrides overrides;
|
||||
private final ItemTransforms itemTransforms;
|
||||
|
||||
public ScreenBaker(ModelState modelState, Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter, ItemOverrides overrides, ItemTransforms itemTransforms) {
|
||||
this.modelState = modelState;
|
||||
this.spriteGetter = spriteGetter;
|
||||
this.overrides = overrides;
|
||||
this.itemTransforms = itemTransforms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTextures(TextureAtlas texMap) {
|
||||
for(int i = 0; i < texs.length; i++)
|
||||
texs[i] = texMap.getSprite(new ResourceLocation("webdisplays", "blocks/screen" + i));
|
||||
}
|
||||
|
||||
private void putVertex(int[] buf, int pos, Vector3f vpos, TextureAtlasSprite tex, Vector3f uv, Vector3i normal) {
|
||||
buf[pos * 7 + 0] = Float.floatToRawIntBits(vpos.x);
|
||||
buf[pos * 7 + 1] = Float.floatToRawIntBits(vpos.y);
|
||||
buf[pos * 7 + 2] = Float.floatToRawIntBits(vpos.z);
|
||||
buf[pos * 7 + 3] = 0xFFFFFFFF; //Color, let this white...
|
||||
buf[pos * 7 + 4] = Float.floatToRawIntBits(tex.getU(uv.x));
|
||||
buf[pos * 7 + 5] = Float.floatToRawIntBits(tex.getV(uv.y));
|
||||
|
||||
int nx = (normal.x * 127) & 0xFF;
|
||||
int ny = (normal.y * 127) & 0xFF;
|
||||
int nz = (normal.z * 127) & 0xFF;
|
||||
buf[pos * 7 + 6] = nx | (ny << 8) | (nz << 16);
|
||||
}
|
||||
|
||||
private Vector3f rotateVec(Vector3f vec, BlockSide side) {
|
||||
switch(side) {
|
||||
case BOTTOM: return new Vector3f(vec.x, 1.0f, 1.0f - vec.z);
|
||||
case TOP: return new Vector3f(vec.x, 0.0f, vec.z);
|
||||
case NORTH: return new Vector3f(vec.x, vec.z, 1.0f);
|
||||
case SOUTH: return new Vector3f(vec.x, 1.0f - vec.z, 0.0f);
|
||||
case WEST: return new Vector3f(1.f , vec.x, vec.z);
|
||||
case EAST: return new Vector3f(0.0f, 1.0f - vec.x, vec.z);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown block side " + side);
|
||||
}
|
||||
|
||||
private Vector3f rotateTex(BlockSide side, float u, float v) {
|
||||
switch(side) {
|
||||
case BOTTOM: return new Vector3f(u, 16.f - v, 0.0f);
|
||||
case TOP: return new Vector3f(u, v, 0.0f);
|
||||
case NORTH: return new Vector3f(16.f - u, 16.f - v, 0.0f);
|
||||
case SOUTH: return new Vector3f(u, v, 0.0f);
|
||||
case WEST: return new Vector3f(v, 16.f - u, 0.0f);
|
||||
case EAST: return new Vector3f(16.f - v, u, 0.0f);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unknown block side " + side);
|
||||
}
|
||||
|
||||
private BakedQuad bakeSide(BlockSide side, TextureAtlasSprite tex) {
|
||||
int[] data = new int[7 * 4];
|
||||
|
||||
putVertex(data, 3, rotateVec(new Vector3f(0.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 0.0f, 0.0f ), side.backward);
|
||||
putVertex(data, 2, rotateVec(new Vector3f(0.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 0.0f, 16.0f ), side.backward);
|
||||
putVertex(data, 1, rotateVec(new Vector3f(1.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 16.0f, 16.0f), side.backward);
|
||||
putVertex(data, 0, rotateVec(new Vector3f(1.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 16.0f, 0.0f ), side.backward);
|
||||
|
||||
return new BakedQuad(data, 0xFFFFFFFF, blockFacings[side.ordinal()], tex, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@org.jetbrains.annotations.Nullable BlockState state, @org.jetbrains.annotations.Nullable Direction side, @NotNull Random random, @NotNull IModelData iModelData) {
|
||||
if(side == null)
|
||||
return noQuads;
|
||||
BlockState bs = state;
|
||||
List<BakedQuad> ret = new ArrayList<>();
|
||||
|
||||
int sid = BlockSide.reverse(side.ordinal());
|
||||
BlockSide s = blockSides[sid];
|
||||
TextureAtlasSprite tex = texs[15];
|
||||
if(bs != null) {
|
||||
IntegerProperty[] sideFlags = new IntegerProperty[6];
|
||||
for(int i = 0; i < sideFlags.length; i++)
|
||||
sideFlags[i] = IntegerProperty.create("neighbor" + i, 0, 15);
|
||||
tex = texs[bs.getValue(sideFlags[sid])];
|
||||
}
|
||||
ret.add(bakeSide(s, tex));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomRenderer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public TextureAtlasSprite getParticleIcon() {
|
||||
return texs[15];
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemTransforms getTransforms() {
|
||||
return ItemTransforms.NO_TRANSFORMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemOverrides getOverrides() {
|
||||
return ItemOverrides.EMPTY;
|
||||
}
|
||||
|
||||
public class ScreenBaker implements BakedModel {
|
||||
|
||||
private static final List<BakedQuad> noQuads = ImmutableList.of();
|
||||
private final TextureAtlasSprite[] texs = new TextureAtlasSprite[16];
|
||||
private final BlockSide[] blockSides = BlockSide.values();
|
||||
private final Direction[] blockFacings = Direction.values();
|
||||
private final ModelState modelState;
|
||||
private final Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter;
|
||||
private final ItemOverrides overrides;
|
||||
private final ItemTransforms itemTransforms;
|
||||
|
||||
IntegerModelProperty[] TEXTURES = new IntegerModelProperty[6];
|
||||
|
||||
public ScreenBaker(ModelState modelState, Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter, ItemOverrides overrides, ItemTransforms itemTransforms) {
|
||||
this.modelState = modelState;
|
||||
this.spriteGetter = spriteGetter;
|
||||
this.overrides = overrides;
|
||||
this.itemTransforms = itemTransforms;
|
||||
|
||||
for (int i = 0; i < texs.length; i++) {
|
||||
texs[i] = spriteGetter.apply(ScreenModelLoader.MATERIALS_SIDES[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < TEXTURES.length; i++) {
|
||||
TEXTURES[i] = new IntegerModelProperty();
|
||||
}
|
||||
}
|
||||
|
||||
private void putVertex(int[] buf, int pos, Vector3f vpos, TextureAtlasSprite tex, Vector3f uv, Vector3i normal) {
|
||||
pos *= 8;
|
||||
|
||||
buf[pos] = Float.floatToRawIntBits(vpos.x);
|
||||
buf[pos + 1] = Float.floatToRawIntBits(vpos.y);
|
||||
buf[pos + 2] = Float.floatToRawIntBits(vpos.z);
|
||||
buf[pos + 3] = 0xFFFFFFFF; //Color, let this white...
|
||||
buf[pos + 4] = Float.floatToRawIntBits(tex.getU(uv.x));
|
||||
buf[pos + 5] = Float.floatToRawIntBits(tex.getV(uv.y));
|
||||
|
||||
int nx = (normal.x * 127) & 0xFF;
|
||||
int ny = (normal.y * 127) & 0xFF;
|
||||
int nz = (normal.z * 127) & 0xFF;
|
||||
buf[pos + 7] = nx | (ny << 8) | (nz << 16);
|
||||
}
|
||||
|
||||
private Vector3f rotateVec(Vector3f vec, BlockSide side) {
|
||||
return switch (side) {
|
||||
case BOTTOM -> new Vector3f(vec.x, 1.0f, 1.0f - vec.z);
|
||||
case TOP -> new Vector3f(vec.x, 0.0f, vec.z);
|
||||
case NORTH -> new Vector3f(vec.x, vec.z, 1.0f);
|
||||
case SOUTH -> new Vector3f(vec.x, 1.0f - vec.z, 0.0f);
|
||||
case WEST -> new Vector3f(1.f, vec.x, vec.z);
|
||||
case EAST -> new Vector3f(0.0f, 1.0f - vec.x, vec.z);
|
||||
//noinspection UnnecessaryDefault
|
||||
default -> throw new RuntimeException("Unknown block side " + side);
|
||||
};
|
||||
}
|
||||
|
||||
private Vector3f rotateTex(BlockSide side, float u, float v) {
|
||||
return switch (side) {
|
||||
case BOTTOM, NORTH -> new Vector3f(16.f - u, 16.f - v, 0.0f);
|
||||
case TOP -> new Vector3f(16.f - u, v, 0.0f);
|
||||
case SOUTH -> new Vector3f(u, v, 0.0f);
|
||||
case WEST -> new Vector3f(16.f - v, u, 0.0f);
|
||||
case EAST -> new Vector3f(v, 16.f - u, 0.0f);
|
||||
//noinspection UnnecessaryDefault
|
||||
default -> throw new RuntimeException("Unknown block side " + side);
|
||||
};
|
||||
}
|
||||
|
||||
private BakedQuad bakeSide(BlockSide side, TextureAtlasSprite tex) {
|
||||
int[] data = new int[8 * 4];
|
||||
|
||||
// I have no idea
|
||||
int rotation = switch (side) {
|
||||
case NORTH, TOP, BOTTOM -> 2;
|
||||
case SOUTH -> 0;
|
||||
case EAST -> 1;
|
||||
case WEST -> 3;
|
||||
//noinspection UnnecessaryDefault
|
||||
default -> throw new RuntimeException("Unknown block side " + side);
|
||||
};
|
||||
|
||||
putVertex(data, (rotation + 3) % 4, rotateVec(new Vector3f(0.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 16.0f, 0.0f), side.backward);
|
||||
putVertex(data, (rotation + 2) % 4, rotateVec(new Vector3f(0.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 16.0f, 16.0f), side.backward);
|
||||
putVertex(data, (rotation + 1) % 4, rotateVec(new Vector3f(1.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 0.0f, 16.0f), side.backward);
|
||||
putVertex(data, (rotation) % 4, rotateVec(new Vector3f(1.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 0.0f, 0.0f), side.backward);
|
||||
|
||||
return new BakedQuad(data, 0xFFFFFFFF, blockFacings[side.ordinal()].getOpposite(), tex, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource random) {
|
||||
return getQuads(state, side, random, ModelData.EMPTY, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @NotNull RandomSource rand, @NotNull ModelData data, @Nullable RenderType renderType) {
|
||||
if (side == null)
|
||||
return noQuads;
|
||||
|
||||
List<BakedQuad> ret = new ArrayList<>();
|
||||
|
||||
int sid = BlockSide.reverse(side.ordinal());
|
||||
BlockSide s = blockSides[sid];
|
||||
TextureAtlasSprite tex = texs[15];
|
||||
if (data.has(TEXTURES[side.ordinal()]))
|
||||
tex = texs[data.get(TEXTURES[side.ordinal()])];
|
||||
ret.add(bakeSide(s, tex));
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected byte check(BlockState state, BlockAndTintGetter level, BlockPos pos, Vector3i dir) {
|
||||
BlockState u = level.getBlockState(pos.offset(dir.x, dir.y, dir.z));
|
||||
BlockState d = level.getBlockState(pos.offset(-dir.x, -dir.y, -dir.z));
|
||||
if (
|
||||
u.getBlock() == state.getBlock() &&
|
||||
d.getBlock() != state.getBlock()
|
||||
) return (byte) 1; // away
|
||||
else if (
|
||||
d.getBlock() == state.getBlock() &&
|
||||
u.getBlock() != state.getBlock()
|
||||
) return (byte) 2; // to
|
||||
else if (
|
||||
d.getBlock() != state.getBlock() &&
|
||||
u.getBlock() != state.getBlock()
|
||||
) return (byte) 3; // both
|
||||
return (byte) 0; // none
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ModelData getModelData(@NotNull BlockAndTintGetter level, @NotNull BlockPos pos, @NotNull BlockState state, @NotNull ModelData modelData) {
|
||||
ModelData.Builder builder = ModelData.builder();
|
||||
|
||||
final int BAR_BOTTOM = 1;
|
||||
final int BAR_RIGHT = 2;
|
||||
final int BAR_TOP = 4;
|
||||
final int BAR_LEFT = 8;
|
||||
|
||||
for (int i = 0; i < TEXTURES.length; i++) {
|
||||
BlockSide side = blockSides[i];
|
||||
|
||||
// check up and down
|
||||
int res = switch (check(state, level, pos, side.up)) {
|
||||
case 1 -> BAR_BOTTOM;
|
||||
case 2 -> BAR_TOP;
|
||||
case 3 -> BAR_TOP | BAR_BOTTOM;
|
||||
default -> 0;
|
||||
};
|
||||
// check left and right
|
||||
res |= switch (check(state, level, pos, side.right)) {
|
||||
case 1 -> BAR_LEFT;
|
||||
case 2 -> BAR_RIGHT;
|
||||
case 3 -> BAR_LEFT | BAR_RIGHT;
|
||||
default -> 0;
|
||||
};
|
||||
|
||||
builder.with(TEXTURES[i], res);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomRenderer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public TextureAtlasSprite getParticleIcon() {
|
||||
return texs[15];
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemTransforms getTransforms() {
|
||||
return ItemTransforms.NO_TRANSFORMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemOverrides getOverrides() {
|
||||
return ItemOverrides.EMPTY;
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
public static final class IntegerModelProperty extends ModelProperty<Integer> {}
|
||||
//@formatter:on
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,56 +2,65 @@ package net.montoyo.wd.client.renderers;
|
|||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.*;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.model.IModelConfiguration;
|
||||
import net.minecraftforge.client.model.IModelLoader;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
||||
import net.minecraftforge.client.model.geometry.IGeometryBakingContext;
|
||||
import net.minecraftforge.client.model.geometry.IGeometryLoader;
|
||||
import net.minecraftforge.client.model.geometry.IUnbakedGeometry;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ScreenModelLoader implements IModelLoader<ScreenModelLoader.ScreenModelGeometry> {
|
||||
|
||||
public class ScreenModelLoader implements IGeometryLoader<ScreenModelLoader.ScreenModelGeometry> {
|
||||
public static final ResourceLocation SCREEN_LOADER = new ResourceLocation("webdisplays", "screen_loader");
|
||||
|
||||
public static final ResourceLocation SCREEN_SIDE = new ResourceLocation("webdisplays", "block/screen");
|
||||
|
||||
public static final Material MATERIAL_SIDE = ForgeHooksClient.getBlockMaterial(SCREEN_SIDE);
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(ResourceManager resourceManager) {
|
||||
private static final ResourceLocation[] SIDES = new ResourceLocation[16];
|
||||
public static final Material[] MATERIALS_SIDES = new Material[16];
|
||||
|
||||
static {
|
||||
for (int i = 0; i < SIDES.length; i++) {
|
||||
SIDES[i] = new ResourceLocation(SCREEN_SIDE.getNamespace(), SCREEN_SIDE.getPath() + i);
|
||||
MATERIALS_SIDES[i] = ForgeHooksClient.getBlockMaterial(SIDES[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ScreenModelGeometry read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
|
||||
public ScreenModelGeometry read(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
return new ScreenModelGeometry();
|
||||
}
|
||||
|
||||
|
||||
public static class ScreenModelGeometry implements IModelGeometry<ScreenModelGeometry> {
|
||||
public static class ScreenModelGeometry implements IUnbakedGeometry<ScreenModelGeometry> {
|
||||
|
||||
@Override
|
||||
public BakedModel bake(IModelConfiguration owner, ModelBakery modelBakery, Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter, ModelState modelState, ItemOverrides itemOverrides, ResourceLocation resourceLocation) {
|
||||
return new ScreenBaker(modelState, spriteGetter, itemOverrides, owner.getCameraTransforms());
|
||||
public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function<Material, TextureAtlasSprite> spriteGetter, ModelState modelState, ItemOverrides overrides, ResourceLocation modelLocation) {
|
||||
return new ScreenBaker(modelState, spriteGetter, overrides, context.getTransforms());
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void resolveParents(Function<ResourceLocation, UnbakedModel> modelGetter, IGeometryBakingContext context) {
|
||||
// IUnbakedGeometry.super.resolveParents(modelGetter, context);
|
||||
// }
|
||||
|
||||
// @Override
|
||||
// public Set<String> getConfigurableComponentNames() {
|
||||
// return IUnbakedGeometry.super.getConfigurableComponentNames();
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<net.minecraft.client.resources.model.Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, UnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
|
||||
return List.of(MATERIAL_SIDE);
|
||||
}
|
||||
// TODO: ?
|
||||
// @Override
|
||||
// public Collection<Material> getMaterials(IGeometryBakingContext iGeometryBakingContext, Function<ResourceLocation, UnbakedModel> function, Set<Pair<String, String>> set) {
|
||||
// return Arrays.asList(MATERIALS_SIDES);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,205 +4,186 @@
|
|||
|
||||
package net.montoyo.wd.client.renderers;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.cinemamod.mcef.MCEFBrowser;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.client.ClientProxy;
|
||||
import net.montoyo.wd.entity.TileEntityScreen;
|
||||
import net.montoyo.wd.utilities.Vector3f;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import net.montoyo.wd.utilities.math.Vector3f;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.mojang.math.Vector3f.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static com.mojang.math.Axis.*;
|
||||
|
||||
public class ScreenRenderer implements BlockEntityRenderer<TileEntityScreen> {
|
||||
public class ScreenRenderer implements BlockEntityRenderer<ScreenBlockEntity> {
|
||||
public ScreenRenderer() {
|
||||
}
|
||||
|
||||
public static class ScreenRendererProvider implements BlockEntityRendererProvider<ScreenBlockEntity> {
|
||||
@Override
|
||||
public @NotNull BlockEntityRenderer<ScreenBlockEntity> create(@NotNull Context arg) {
|
||||
return new ScreenRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
private final Vector3f mid = new Vector3f();
|
||||
private final Vector3i tmpi = new Vector3i();
|
||||
private final Vector3f tmpf = new Vector3f();
|
||||
|
||||
@Override
|
||||
public void render(ScreenBlockEntity te, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
|
||||
if (!te.isLoaded())
|
||||
return;
|
||||
|
||||
public static class ScreenRendererProvider implements BlockEntityRendererProvider<TileEntityScreen> {
|
||||
@Override
|
||||
public @NotNull BlockEntityRenderer<TileEntityScreen> create(@NotNull Context arg) {
|
||||
return new ScreenRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
private final Vector3f mid = new Vector3f();
|
||||
private final Vector3i tmpi = new Vector3i();
|
||||
private final Vector3f tmpf = new Vector3f();
|
||||
|
||||
@Override
|
||||
public void render(TileEntityScreen te, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
|
||||
if(!te.isLoaded())
|
||||
return;
|
||||
|
||||
//Disable lighting
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.disableBlend();
|
||||
|
||||
for(int i = 0; i < te.screenCount(); i++) {
|
||||
TileEntityScreen.Screen scr = te.getScreen(i);
|
||||
if(scr.browser == null) {
|
||||
scr.browser = ((ClientProxy) WebDisplays.PROXY).getMCEF().createBrowser(WebDisplays.applyBlacklist(scr.url));
|
||||
|
||||
if(scr.rotation.isVertical)
|
||||
scr.browser.resize(scr.resolution.y, scr.resolution.x);
|
||||
else
|
||||
scr.browser.resize(scr.resolution.x, scr.resolution.y);
|
||||
|
||||
scr.doTurnOnAnim = true;
|
||||
scr.turnOnTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
tmpi.set(scr.side.right);
|
||||
tmpi.mul(scr.size.x);
|
||||
tmpi.addMul(scr.side.up, scr.size.y);
|
||||
tmpf.set(tmpi);
|
||||
mid.set(0.5, 0.5, 0.5);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
tmpf.set(scr.side.left);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
tmpf.set(scr.side.down);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(mid.x, mid.y, mid.z);
|
||||
|
||||
switch(scr.side) {
|
||||
case BOTTOM:
|
||||
poseStack.mulPose(XP.rotation(90.f + 49.8f));
|
||||
break;
|
||||
|
||||
case TOP:
|
||||
poseStack.mulPose(XN.rotation(90.f + 49.8f));
|
||||
break;
|
||||
|
||||
case NORTH:
|
||||
poseStack.mulPose(YN.rotationDegrees(180.f));
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
poseStack.mulPose(YN.rotationDegrees(90.f));
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
poseStack.mulPose(YP.rotationDegrees(90.f));
|
||||
break;
|
||||
}
|
||||
|
||||
if(scr.doTurnOnAnim) {
|
||||
long lt = System.currentTimeMillis() - scr.turnOnTime;
|
||||
float ft = ((float) lt) / 100.0f;
|
||||
|
||||
if(ft >= 1.0f) {
|
||||
ft = 1.0f;
|
||||
scr.doTurnOnAnim = false;
|
||||
}
|
||||
|
||||
poseStack.scale(ft, ft, 1.0f);
|
||||
}
|
||||
|
||||
if(!scr.rotation.isNull)
|
||||
poseStack.mulPose(ZP.rotationDegrees(scr.rotation.angle));
|
||||
|
||||
float sw = ((float) scr.size.x) * 0.5f - 2.f / 16.f;
|
||||
float sh = ((float) scr.size.y) * 0.5f - 2.f / 16.f;
|
||||
|
||||
if(scr.rotation.isVertical) {
|
||||
float tmp = sw;
|
||||
sw = sh;
|
||||
sh = tmp;
|
||||
}
|
||||
|
||||
Tesselator tesselator = Tesselator.getInstance();
|
||||
BufferBuilder builder = tesselator.getBuilder();
|
||||
//TODO: Use tesselator
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
|
||||
RenderSystem._setShaderTexture(0, scr.browser.getTextureID());
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
|
||||
builder.vertex(poseStack.last().pose(),-sw, -sh, 0.505f).uv(0.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
builder.vertex(poseStack.last().pose(), sw, -sh, 0.505f).uv(1.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
builder.vertex(poseStack.last().pose(), sw, sh, 0.505f).uv(1.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
builder.vertex(poseStack.last().pose(),-sw, sh, 0.505f).uv(0.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
tesselator.end();//Minecraft does shit with mah texture otherwise...
|
||||
RenderSystem.disableDepthTest();
|
||||
poseStack.popPose();
|
||||
}
|
||||
//Disable lighting
|
||||
// RenderSystem.enableTexture();
|
||||
// RenderSystem.disableCull();
|
||||
RenderSystem.disableBlend();
|
||||
|
||||
for (int i = 0; i < te.screenCount(); i++) {
|
||||
ScreenData scr = te.getScreen(i);
|
||||
if (scr.browser == null) {
|
||||
double dist = WebDisplays.PROXY.distanceTo(te, Minecraft.getInstance().getEntityRenderDispatcher().camera.getPosition());
|
||||
if (dist <= WebDisplays.INSTANCE.loadDistance2 * 16)
|
||||
scr.createBrowser(te, true);
|
||||
else continue;
|
||||
}
|
||||
|
||||
// TODO: manually backface cull the screens
|
||||
|
||||
tmpi.set(scr.side.right);
|
||||
tmpi.mul(scr.size.x);
|
||||
tmpi.addMul(scr.side.up, scr.size.y);
|
||||
tmpf.set(tmpi);
|
||||
mid.set(0.5, 0.5, 0.5);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
tmpf.set(scr.side.left);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
tmpf.set(scr.side.down);
|
||||
mid.addMul(tmpf, 0.5f);
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(mid.x, mid.y, mid.z);
|
||||
|
||||
switch (scr.side) {
|
||||
case BOTTOM:
|
||||
poseStack.mulPose(XP.rotation(90.f + 49.8f));
|
||||
break;
|
||||
|
||||
case TOP:
|
||||
poseStack.mulPose(XN.rotation(90.f + 49.8f));
|
||||
break;
|
||||
|
||||
case NORTH:
|
||||
poseStack.mulPose(YN.rotationDegrees(180.f));
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
poseStack.mulPose(YN.rotationDegrees(90.f));
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
poseStack.mulPose(YP.rotationDegrees(90.f));
|
||||
break;
|
||||
}
|
||||
|
||||
if (scr.doTurnOnAnim) {
|
||||
long lt = System.currentTimeMillis() - scr.turnOnTime;
|
||||
float ft = ((float) lt) / 100.0f;
|
||||
|
||||
if (ft >= 1.0f) {
|
||||
ft = 1.0f;
|
||||
scr.doTurnOnAnim = false;
|
||||
}
|
||||
|
||||
poseStack.scale(ft, ft, 1.0f);
|
||||
}
|
||||
|
||||
if (!scr.rotation.isNull)
|
||||
poseStack.mulPose(ZP.rotationDegrees(scr.rotation.angle));
|
||||
|
||||
float sw = ((float) scr.size.x) * 0.5f - 2.f / 16.f;
|
||||
float sh = ((float) scr.size.y) * 0.5f - 2.f / 16.f;
|
||||
|
||||
if (scr.rotation.isVertical) {
|
||||
float tmp = sw;
|
||||
sw = sh;
|
||||
sh = tmp;
|
||||
}
|
||||
|
||||
Tesselator tesselator = Tesselator.getInstance();
|
||||
BufferBuilder builder = tesselator.getBuilder();
|
||||
//TODO: don't use tesselator
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
|
||||
RenderSystem._setShaderTexture(0, ((MCEFBrowser) scr.browser).getRenderer().getTextureID());
|
||||
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
|
||||
builder.vertex(poseStack.last().pose(), -sw, -sh, 0.505f).uv(0.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
builder.vertex(poseStack.last().pose(), sw, -sh, 0.505f).uv(1.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
builder.vertex(poseStack.last().pose(), sw, sh, 0.505f).uv(1.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
builder.vertex(poseStack.last().pose(), -sw, sh, 0.505f).uv(0.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
|
||||
tesselator.end();//Minecraft does shit with mah texture otherwise...
|
||||
RenderSystem.disableDepthTest();
|
||||
|
||||
// TODO: it'd be neat to draw a mouse cursor on the screen
|
||||
// // debug hit2pixels
|
||||
// HitResult result = Minecraft.getInstance().hitResult;
|
||||
// VertexConsumer consumer = bufferSource.getBuffer(RenderType.lines());
|
||||
// poseStack.translate(-sw, -sh, 0);
|
||||
// if (result instanceof BlockHitResult hit) {
|
||||
// BlockPos bpos = hit.getBlockPos();
|
||||
//
|
||||
// Vector3i pos = new Vector3i(hit.getBlockPos());
|
||||
// float hitX = ((float) result.getLocation().x) - (float) te.getBlockPos().getX();
|
||||
// float hitY = ((float) result.getLocation().y) - (float) te.getBlockPos().getY();
|
||||
// float hitZ = ((float) result.getLocation().z) - (float) te.getBlockPos().getZ();
|
||||
// Vector2i tmp = new Vector2i();
|
||||
//
|
||||
// if (BlockScreen.hit2pixels(scr.side, bpos, pos, scr, hitX, hitY, hitZ, tmp)) {
|
||||
// float x = tmp.x / (float) scr.resolution.x * scr.size.x;
|
||||
// float y = tmp.y / (float) scr.resolution.y * scr.size.y;
|
||||
// y = scr.size.y - y;
|
||||
//
|
||||
// x /= scr.size.x;
|
||||
// y /= scr.size.y;
|
||||
// x *= sw * 2;
|
||||
// y *= sh * 2;
|
||||
//
|
||||
// LevelRenderer.renderLineBox(
|
||||
// poseStack,
|
||||
// consumer, new AABB(
|
||||
// x - 0.01, y - 0.01, 0.5 - 0.01,
|
||||
// x + 0.01, y + 0.01, 0.5 + 0.01
|
||||
// ),
|
||||
// 1f, 0, 0, 1f
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
|
||||
//Bounding box debugging
|
||||
/*poseStack.pushPose();
|
||||
poseStack.translate(-te.getBlockPos().getX(), -te.getBlockPos().getY(), -te.getBlockPos().getZ());
|
||||
renderAABB(te.getRenderBoundingBox());
|
||||
poseStack.popPose();*/
|
||||
|
||||
//Re-enable lighting
|
||||
RenderSystem.enableCull();
|
||||
}
|
||||
|
||||
public void renderAABB(AABB bb) {
|
||||
RenderSystem.disableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.setShaderColor(0.f, 0.5f, 1.f, 0.75f);
|
||||
RenderSystem.depthMask(false);
|
||||
|
||||
Tesselator t = new Tesselator();
|
||||
BufferBuilder vb = t.getBuilder();
|
||||
VertexBuffer tb = new VertexBuffer();
|
||||
vb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
|
||||
|
||||
//Bottom
|
||||
vb.vertex(bb.minX, bb.minY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.minY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.minX, bb.minY, bb.maxZ).endVertex();
|
||||
|
||||
//Top
|
||||
vb.vertex(bb.minX, bb.maxY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.maxY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.minX, bb.maxY, bb.maxZ).endVertex();
|
||||
|
||||
//Left
|
||||
vb.vertex(bb.minX, bb.minY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.minX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.minX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.minX, bb.maxY, bb.minZ).endVertex();
|
||||
|
||||
//Right
|
||||
vb.vertex(bb.maxX, bb.minY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.maxY, bb.minZ).endVertex();
|
||||
|
||||
//Front
|
||||
vb.vertex(bb.minX, bb.minY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.minY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.maxY, bb.minZ).endVertex();
|
||||
vb.vertex(bb.minX, bb.maxY, bb.minZ).endVertex();
|
||||
|
||||
//Back
|
||||
vb.vertex(bb.minX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.minY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.maxX, bb.maxY, bb.maxZ).endVertex();
|
||||
vb.vertex(bb.minX, bb.maxY, bb.maxZ).endVertex();
|
||||
tb.draw();
|
||||
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
// //Bounding box debugging
|
||||
// poseStack.pushPose();
|
||||
// poseStack.translate(-te.getBlockPos().getX(), -te.getBlockPos().getY(), -te.getBlockPos().getZ());
|
||||
// LevelRenderer.renderLineBox(
|
||||
// poseStack, bufferSource.getBuffer(RenderType.LINES),
|
||||
// te.getRenderBoundingBox(), 1, 1, 1, 1f
|
||||
// );
|
||||
// poseStack.popPose();
|
||||
|
||||
//Re-enable lighting
|
||||
// RenderSystem.enableCull();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
133
src/main/java/net/montoyo/wd/config/ClientConfig.java
Normal file
133
src/main/java/net/montoyo/wd/config/ClientConfig.java
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
package net.montoyo.wd.config;
|
||||
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.config.annoconfg.AnnoCFG;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.format.*;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.Default;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.DoubleRange;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.IntRange;
|
||||
|
||||
@Config(type = ModConfig.Type.CLIENT)
|
||||
public class ClientConfig {
|
||||
@SuppressWarnings("unused")
|
||||
private static final AnnoCFG CFG = new AnnoCFG(FMLJavaModLoadingContext.get().getModEventBus(), ClientConfig.class);
|
||||
public static void init() {
|
||||
// loads the class
|
||||
}
|
||||
|
||||
@Name("load_distance")
|
||||
@Comment("How far (in blocks) you can be before a screen starts rendering")
|
||||
@Translation("config.webdisplays.load_distance")
|
||||
@DoubleRange(minV = 0, maxV = Double.MAX_VALUE)
|
||||
@Default(valueD = 30)
|
||||
public static double loadDistance = 30.0;
|
||||
|
||||
@Name("unload_distance")
|
||||
@Comment("How far you can be before a screen stops rendering")
|
||||
@Translation("config.webdisplays.unload_distance")
|
||||
@DoubleRange(minV = 0, maxV = Double.MAX_VALUE)
|
||||
@Default(valueD = 32)
|
||||
public static double unloadDistance = 32.0;
|
||||
|
||||
@Name("pad_resolution")
|
||||
@Comment({
|
||||
"The resolution that minePads should use",
|
||||
"Smaller values produce lower qualities, higher values produce higher qualities",
|
||||
"Due to how web browsers work however, the larger this value is, the smaller text is",
|
||||
"Also, higher values will invariably lag more",
|
||||
"A good goto value for this would be the height of your monitor, in pixels",
|
||||
"A standard monitor is (at least currently) 1080",
|
||||
})
|
||||
@Translation("config.webdisplays.pad_res")
|
||||
@IntRange(minV = 0, maxV = Integer.MAX_VALUE)
|
||||
@Default(valueI = 720)
|
||||
public static int padResolution = 720;
|
||||
|
||||
@Name("side_pad")
|
||||
@Comment({
|
||||
"When this is true, the minePad is placed off to the side of the screen when held, so it's visible but doesn't take up too much of the screen",
|
||||
"When this is false, the minePad is placed closer to the center of the screen, allow it to be seen better, but taking up more of your view",
|
||||
})
|
||||
@Translation("config.webdisplays.side_pad")
|
||||
@Default(valueBoolean = true)
|
||||
public static boolean sidePad = true;
|
||||
|
||||
@Comment({
|
||||
"Options relating to input handling"
|
||||
})
|
||||
@CFGSegment("input")
|
||||
public static class Input {
|
||||
@Name("keyboard_camera")
|
||||
@Comment({
|
||||
"If this is on, then the camera will try to focus on the selected element while a keyboard is in use",
|
||||
"Elsewise, it'll try to focus on the center of the screen",
|
||||
})
|
||||
@Translation("config.webdisplays.keyboard_camera")
|
||||
@Default(valueBoolean = true)
|
||||
public static boolean keyboardCamera = true;
|
||||
|
||||
@Name("switch_buttons")
|
||||
@Comment("If the left and right buttons should be swapped when using a laser")
|
||||
@Translation("config.webdisplays.switch_buttons")
|
||||
@DoubleRange(minV = 0, maxV = Double.MAX_VALUE)
|
||||
@Default(valueD = 30)
|
||||
public static boolean switchButtons = true;
|
||||
}
|
||||
|
||||
// @Comment({
|
||||
// "AutoVolume makes audio fade off based on distance",
|
||||
// "Currently, this seems to not work"
|
||||
// })
|
||||
// @CFGSegment("auto_volume")
|
||||
// public static class AutoVolumeControl {
|
||||
// @Name("enabled")
|
||||
// @Comment("Whether or not auto volume should be enabled")
|
||||
// @Translation("config.webdisplays.auto_vol")
|
||||
// @Default(valueBoolean = true)
|
||||
// public static boolean enableAutoVolume = true;
|
||||
//
|
||||
// @Name("youtube_volume")
|
||||
// @Comment("How loud youtube should be by default")
|
||||
// @Translation("config.webdisplays.yt_vol")
|
||||
// @DoubleRange(minV = 0, maxV = 100)
|
||||
// @Default(valueD = 100)
|
||||
// public static double ytVolume = 100.0;
|
||||
//
|
||||
// @Name("dist0")
|
||||
// @Comment("Distance after which you can't hear anything (in blocks)")
|
||||
// @Translation("config.webdisplays.d0")
|
||||
// @DoubleRange(minV = 0, maxV = Double.MAX_VALUE)
|
||||
// @Default(valueD = 30)
|
||||
// public static double dist0 = 30.0;
|
||||
//
|
||||
// @Name("dist100")
|
||||
// @Comment("Distance after which the sound starts dropping (in blocks)")
|
||||
// @Translation("config.webdisplays.d100")
|
||||
// @DoubleRange(minV = 0, maxV = Double.MAX_VALUE)
|
||||
// @Default(valueD = 10)
|
||||
// public static double dist100 = 10.0;
|
||||
// }
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void postLoad() {
|
||||
if (unloadDistance < loadDistance + 2.0)
|
||||
unloadDistance = loadDistance + 2.0;
|
||||
|
||||
// if (AutoVolumeControl.dist0 < AutoVolumeControl.dist100 + 0.1)
|
||||
// AutoVolumeControl.dist0 = AutoVolumeControl.dist100 + 0.1;
|
||||
|
||||
// cache pad resolution
|
||||
WebDisplays.INSTANCE.padResY = padResolution;
|
||||
WebDisplays.INSTANCE.padResX = WebDisplays.INSTANCE.padResY * WebDisplays.PAD_RATIO;
|
||||
|
||||
// cache unload/load distances
|
||||
WebDisplays.INSTANCE.unloadDistance2 = unloadDistance * unloadDistance;
|
||||
WebDisplays.INSTANCE.loadDistance2 = loadDistance * loadDistance;
|
||||
|
||||
// WebDisplays.INSTANCE.ytVolume = (float) AutoVolumeControl.ytVolume;
|
||||
// WebDisplays.INSTANCE.avDist100 = (float) AutoVolumeControl.dist100;
|
||||
// WebDisplays.INSTANCE.avDist0 = (float) AutoVolumeControl.dist0;
|
||||
}
|
||||
}
|
||||
127
src/main/java/net/montoyo/wd/config/CommonConfig.java
Normal file
127
src/main/java/net/montoyo/wd/config/CommonConfig.java
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
package net.montoyo.wd.config;
|
||||
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.config.annoconfg.AnnoCFG;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.format.*;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.Default;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.IntRange;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.LongRange;
|
||||
|
||||
@SuppressWarnings("DefaultAnnotationParam")
|
||||
@Config(type = ModConfig.Type.COMMON)
|
||||
public class CommonConfig {
|
||||
@SuppressWarnings("unused")
|
||||
private static final AnnoCFG CFG = new AnnoCFG(FMLJavaModLoadingContext.get().getModEventBus(), CommonConfig.class);
|
||||
|
||||
public static void init() {
|
||||
// loads the class
|
||||
}
|
||||
|
||||
@Name("hard_recipes")
|
||||
@Comment("If true, breaking the minePad is required to craft upgrades.")
|
||||
@Translation("config.webdisplays.hard_recipes")
|
||||
@Default(valueBoolean = true)
|
||||
public static boolean hardRecipes = true;
|
||||
|
||||
@Name("join_message")
|
||||
@Comment("Whether or not webdisplays should thank the user for using the mod")
|
||||
@Translation("config.webdisplays.join_message")
|
||||
@Default(valueBoolean = true)
|
||||
public static boolean joinMessage = true;
|
||||
|
||||
@Name("disable_ownership_thief")
|
||||
@Comment("If true, the ownership thief item will be disabled")
|
||||
@Translation("config.webdisplays.disable_thief")
|
||||
@Default(valueBoolean = false)
|
||||
public static boolean disableOwnershipThief = false;
|
||||
|
||||
@Comment("Options for the browsers (both the minePad and the screens)")
|
||||
@CFGSegment("browser_options")
|
||||
public static class Browser {
|
||||
@Name("blacklist")
|
||||
@Comment("The page which screens should open up to when turning on")
|
||||
@Translation("config.webdisplays.blacklist")
|
||||
@Default(valueStr = "")
|
||||
public static String[] blacklist = new String[0];
|
||||
|
||||
@Name("home_page")
|
||||
@Comment("The page which screens should open up to when turning on")
|
||||
@Translation("config.webdisplays.home_page")
|
||||
@Default(valueStr = "mod://webdisplays/main.html")
|
||||
public static String homepage = "mod://webdisplays/main.html";
|
||||
}
|
||||
|
||||
@Comment("Options for the in world screen blocks")
|
||||
@CFGSegment("screen_options")
|
||||
public static class Screen {
|
||||
@Name("max_resolution_x")
|
||||
@Comment("The maximum value screen's horizontal resolution, in pixels")
|
||||
@Translation("config.webdisplays.max_res_x")
|
||||
@IntRange(minV = 0, maxV = Integer.MAX_VALUE)
|
||||
@Default(valueI = 1920)
|
||||
public static int maxResolutionX = 1920;
|
||||
|
||||
@Name("max_resolution_y")
|
||||
@Comment("The maximum value screen's vertical resolution, in pixels")
|
||||
@Translation("config.webdisplays.max_res_y")
|
||||
@IntRange(minV = 0, maxV = Integer.MAX_VALUE)
|
||||
@Default(valueI = 1080)
|
||||
public static int maxResolutionY = 1080;
|
||||
|
||||
@Name("max_width")
|
||||
@Comment("The maximum width for the screen multiblock, in blocks")
|
||||
@Translation("config.webdisplays.max_width")
|
||||
@IntRange(minV = 0, maxV = Integer.MAX_VALUE)
|
||||
@Default(valueI = 16)
|
||||
public static int maxScreenSizeX = 16;
|
||||
|
||||
@Name("max_height")
|
||||
@Comment("The maximum height for the screen multiblock, in blocks")
|
||||
@Translation("config.webdisplays.max_height")
|
||||
@IntRange(minV = 0, maxV = Integer.MAX_VALUE)
|
||||
@Default(valueI = 16)
|
||||
public static int maxScreenSizeY = 16;
|
||||
}
|
||||
|
||||
@Comment("Options for the miniserver")
|
||||
@CFGSegment("mini_server")
|
||||
public static class MiniServ {
|
||||
@Name("miniserv_port")
|
||||
@Comment("The port used by miniserv. 0 to disable")
|
||||
@Translation("config.webdisplays.miniserv_port")
|
||||
@IntRange(minV = 0, maxV = Short.MAX_VALUE)
|
||||
@Default(valueI = 25566)
|
||||
public static int miniservPort = 25566;
|
||||
|
||||
@Name("miniserv_quota")
|
||||
@Comment("The amount of data that can be uploaded to miniserv, in KiB (so 1024 = 1 MiO)")
|
||||
@Translation("config.webdisplays.miniserv_quota")
|
||||
@LongRange(minV = 0, maxV = Long.MAX_VALUE)
|
||||
@Default(valueL = 1920)
|
||||
public static long miniservQuota = 1024; //It's stored as a string anyway
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void postLoad() {
|
||||
WebDisplays.INSTANCE.miniservPort = MiniServ.miniservPort;
|
||||
WebDisplays.INSTANCE.miniservQuota = MiniServ.miniservQuota * 1024L;
|
||||
}
|
||||
|
||||
// //Comments & shit
|
||||
// blacklist.setComment("An array of domain names you don't want to load.");
|
||||
// padHeight.setComment("The minePad Y resolution in pixels. padWidth = padHeight * " + PAD_RATIO);
|
||||
// hardRecipe.setComment("If true, breaking the minePad is required to craft upgrades.");
|
||||
// homePage.setComment("The URL that will be loaded each time you create a screen");
|
||||
// disableOT.setComment("If true, the ownership thief item will be disabled");
|
||||
// loadDistance.setComment("All screens outside this range will be unloaded");
|
||||
// unloadDistance.setComment("All unloaded screens inside this range will be loaded");
|
||||
// maxResX.setComment("Maximum horizontal screen resolution, in pixels");
|
||||
// maxResY.setComment("Maximum vertical screen resolution, in pixels");
|
||||
// miniservPort.setComment("The port used by miniserv. 0 to disable.");
|
||||
// miniservPort.setMaxValue(Short.MAX_VALUE);
|
||||
// miniservQuota.setComment("The amount of data that can be uploaded to miniserv, in KiB (so 1024 = 1 MiO)");
|
||||
// maxScreenX.setComment("Maximum screen width, in blocks. Resolution will be clamped by maxResolutionX.");
|
||||
// maxScreenY.setComment("Maximum screen height, in blocks. Resolution will be clamped by maxResolutionY.");
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
package net.montoyo.wd.config;
|
||||
|
||||
import me.shedaniel.autoconfig.ConfigData;
|
||||
import me.shedaniel.autoconfig.annotation.Config;
|
||||
import me.shedaniel.autoconfig.annotation.ConfigEntry;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.montoyo.mcef.easy_forge_compat.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Config(name = "webdisplays")
|
||||
public class ModConfig implements ConfigData {
|
||||
@ConfigEntry.Category("main")
|
||||
public Main main = new Main();
|
||||
|
||||
@ConfigEntry.Category("client")
|
||||
public Client client = new Client();
|
||||
|
||||
public static class Main {
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public List<String> blacklist = List.of();
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public int padHeight = 480;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public boolean hardRecipes = true;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public String homepage = "https://www.google.com";
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public boolean disableOwnershipThief = false;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public int maxResolutionX = 1920;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public int maxResolutionY = 1080;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
@ConfigEntry.BoundedDiscrete(max = Short.MAX_VALUE)
|
||||
public int miniservPort = 25566;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public long miniservQuota = 1024; //It's stored as a string anyway
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public int maxScreenSizeX = 16;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public int maxScreenSizeY = 16;
|
||||
}
|
||||
|
||||
public static class Client {
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public double loadDistance = 30.0;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public double unloadDistance = 32.0;
|
||||
|
||||
@ConfigEntry.Gui.CollapsibleObject()
|
||||
public AutoVolumeControl autoVolumeControl = new AutoVolumeControl();
|
||||
|
||||
public static class AutoVolumeControl {
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public boolean enableAutoVolume = true;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public double ytVolume = 100.0;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public double dist100 = 10.0;
|
||||
|
||||
@ConfigEntry.Gui.Tooltip
|
||||
public double dist0 = 30.0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validatePostLoad() throws ValidationException {
|
||||
ConfigData.super.validatePostLoad();
|
||||
|
||||
main.miniservPort = Mth.clamp(main.miniservPort, 0, Short.MAX_VALUE);
|
||||
client.autoVolumeControl.ytVolume = Mth.clamp(client.autoVolumeControl.ytVolume, 0.0, 100.0);
|
||||
client.autoVolumeControl.dist0 = Mth.clamp(client.autoVolumeControl.dist0, 0.0, Double.MAX_VALUE);
|
||||
client.autoVolumeControl.ytVolume = Mth.clamp(client.autoVolumeControl.dist100, 0.0, Double.MAX_VALUE);
|
||||
|
||||
if(client.unloadDistance < client.loadDistance + 2.0) {
|
||||
client.unloadDistance = client.loadDistance + 2.0;
|
||||
}
|
||||
|
||||
if(client.autoVolumeControl.dist0 < client.autoVolumeControl.dist100 + 0.1) {
|
||||
client.autoVolumeControl.dist0 = client.autoVolumeControl.dist100 + 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
// //Comments & shit
|
||||
// blacklist.setComment("An array of domain names you don't want to load.");
|
||||
// padHeight.setComment("The minePad Y resolution in pixels. padWidth = padHeight * " + PAD_RATIO);
|
||||
// hardRecipe.setComment("If true, breaking the minePad is required to craft upgrades.");
|
||||
// homePage.setComment("The URL that will be loaded each time you create a screen");
|
||||
// disableOT.setComment("If true, the ownership thief item will be disabled");
|
||||
// loadDistance.setComment("All screens outside this range will be unloaded");
|
||||
// unloadDistance.setComment("All unloaded screens inside this range will be loaded");
|
||||
// maxResX.setComment("Maximum horizontal screen resolution, in pixels");
|
||||
// maxResY.setComment("Maximum vertical screen resolution, in pixels");
|
||||
// miniservPort.setComment("The port used by miniserv. 0 to disable.");
|
||||
// miniservPort.setMaxValue(Short.MAX_VALUE);
|
||||
// miniservQuota.setComment("The amount of data that can be uploaded to miniserv, in KiB (so 1024 = 1 MiO)");
|
||||
// maxScreenX.setComment("Maximum screen width, in blocks. Resolution will be clamped by maxResolutionX.");
|
||||
// maxScreenY.setComment("Maximum screen height, in blocks. Resolution will be clamped by maxResolutionY.");
|
||||
// enableAutoVol.setComment("If true, the volume of YouTube videos will change depending on how far you are");
|
||||
// ytVolume.setComment("Volume for YouTube videos. This will have no effect if enableSoundDistance is set to false");
|
||||
// ytVolume.setMinValue(0.0);
|
||||
// ytVolume.setMaxValue(100.0);
|
||||
// dist100.setComment("Distance after which the sound starts dropping (in blocks)");
|
||||
// dist100.setMinValue(0.0);
|
||||
// dist0.setComment("Distance after which you can't hear anything (in blocks)");
|
||||
// dist0.setMinValue(0.0);
|
||||
}
|
||||
219
src/main/java/net/montoyo/wd/config/annoconfg/AnnoCFG.java
Normal file
219
src/main/java/net/montoyo/wd/config/annoconfg/AnnoCFG.java
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
package net.montoyo.wd.config.annoconfg;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import net.minecraftforge.fml.event.config.ModConfigEvent;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.format.*;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.Default;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.DoubleRange;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.IntRange;
|
||||
import net.montoyo.wd.config.annoconfg.annotation.value.LongRange;
|
||||
import net.montoyo.wd.config.annoconfg.handle.UnsafeHandle;
|
||||
import net.montoyo.wd.config.annoconfg.util.EnumType;
|
||||
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class AnnoCFG {
|
||||
private ForgeConfigSpec mySpec;
|
||||
|
||||
private final HashMap<String, ConfigEntry> handles = new HashMap<>();
|
||||
|
||||
private static final ArrayList<AnnoCFG> configs = new ArrayList<>();
|
||||
private final Method postInit;
|
||||
|
||||
public AnnoCFG(IEventBus bus, Class<?> clazz) {
|
||||
bus.addListener(this::onConfigChange);
|
||||
ForgeConfigSpec.Builder configBuilder = new ForgeConfigSpec.Builder();
|
||||
setup("", configBuilder, clazz);
|
||||
configs.add(this);
|
||||
|
||||
Method m = null;
|
||||
try {
|
||||
m = clazz.getDeclaredMethod("postLoad");
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
postInit = m;
|
||||
|
||||
Config configDescriptor = clazz.getAnnotation(Config.class);
|
||||
if (configDescriptor != null) {
|
||||
String pth = configDescriptor.path();
|
||||
if (!pth.isEmpty()) pth = pth + "/";
|
||||
switch (configDescriptor.type()) {
|
||||
case SERVER -> create(ModConfig.Type.SERVER, pth + ModLoadingContext.get().getActiveNamespace() + "_server.toml");
|
||||
case CLIENT -> create(ModConfig.Type.CLIENT, pth + ModLoadingContext.get().getActiveNamespace() + "_client.toml");
|
||||
case COMMON -> create(ModConfig.Type.COMMON, pth + ModLoadingContext.get().getActiveNamespace() + "_common.toml");
|
||||
default -> throw new RuntimeException("wat");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setupCommentsAndTranslations(AnnotatedElement element, ForgeConfigSpec.Builder builder, String... additionalLines) {
|
||||
Translation translation = element.getAnnotation(Translation.class);
|
||||
Comment comment = element.getAnnotation(Comment.class);
|
||||
|
||||
StringBuilder builder1 = new StringBuilder();
|
||||
if (comment != null) {
|
||||
for (int i = 0; i < comment.value().length; i++) {
|
||||
String s = comment.value()[i];
|
||||
builder1.append(s);
|
||||
if (i != comment.value().length - 1)
|
||||
builder1.append("\n");
|
||||
}
|
||||
}
|
||||
for (String additionalLine : additionalLines) builder1.append(additionalLine);
|
||||
if (!builder1.isEmpty())
|
||||
builder.comment(builder1.toString());
|
||||
|
||||
if (translation != null)
|
||||
builder.translation(translation.value());
|
||||
}
|
||||
|
||||
public void setup(String dir, ForgeConfigSpec.Builder builder, Class<?> clazz) {
|
||||
if (dir.startsWith(".")) dir = dir.substring(1);
|
||||
|
||||
for (Field field : clazz.getFields()) {
|
||||
if (field.canAccess(null)) {
|
||||
Skip skip = field.getAnnotation(Skip.class);
|
||||
if (skip != null) continue;
|
||||
|
||||
Name name = field.getAnnotation(Name.class);
|
||||
|
||||
String nameStr = field.getName();
|
||||
if (name != null) nameStr = name.value();
|
||||
|
||||
setupCommentsAndTranslations(field, builder);
|
||||
|
||||
Supplier<?> value;
|
||||
|
||||
Default defaultValue = field.getAnnotation(Default.class);
|
||||
try {
|
||||
switch (EnumType.forClass(field.getType())) {
|
||||
case INT -> {
|
||||
IntRange range = field.getAnnotation(IntRange.class);
|
||||
int v = defaultValue.valueI();
|
||||
if (range != null) {
|
||||
int min = range.minV();
|
||||
int max = range.maxV();
|
||||
|
||||
value = builder.defineInRange(nameStr, v, min, max);
|
||||
} else {
|
||||
value = builder.define(nameStr, v);
|
||||
}
|
||||
}
|
||||
case LONG -> {
|
||||
LongRange range = field.getAnnotation(LongRange.class);
|
||||
long v = defaultValue.valueL();
|
||||
if (range != null) {
|
||||
long min = range.minV();
|
||||
long max = range.maxV();
|
||||
|
||||
value = builder.defineInRange(nameStr, v, min, max);
|
||||
} else {
|
||||
value = builder.define(nameStr, v);
|
||||
}
|
||||
}
|
||||
case DOUBLE -> {
|
||||
DoubleRange range = field.getAnnotation(DoubleRange.class);
|
||||
double v = defaultValue.valueD();
|
||||
if (range != null) {
|
||||
double min = range.minV();
|
||||
double max = range.maxV();
|
||||
|
||||
value = builder.defineInRange(nameStr, v, min, max);
|
||||
} else {
|
||||
value = builder.define(nameStr, v);
|
||||
}
|
||||
}
|
||||
case BOOLEAN -> {
|
||||
boolean b = defaultValue.valueBoolean();
|
||||
value = builder.define(nameStr, b);
|
||||
}
|
||||
case OTHER -> {
|
||||
Class<?> fieldType = field.getType();
|
||||
if (fieldType.equals(String[].class)) {
|
||||
Supplier<String> sup = builder.define(nameStr, defaultValue.valueStr());
|
||||
value = () -> {
|
||||
String v = sup.get();
|
||||
return v.split(",");
|
||||
};
|
||||
} else if (fieldType.equals(String.class)) {
|
||||
value = builder.define(nameStr, defaultValue.valueStr());
|
||||
} else
|
||||
throw new RuntimeException("NYI " + field.getType());
|
||||
}
|
||||
default -> throw new RuntimeException("NYI " + field.getType());
|
||||
}
|
||||
} catch (NullPointerException npe) {
|
||||
String inf = "";
|
||||
if (npe.getMessage().contains("\"value.Default\""))
|
||||
inf = " this is likely due to a missing default.";
|
||||
throw new RuntimeException("A null pointer occurred on " + field.getName() + inf, npe);
|
||||
}
|
||||
|
||||
Object o;
|
||||
try {
|
||||
// without this line, this system freaks out due to using theUnsafe
|
||||
//noinspection UnusedAssignment
|
||||
o = field.get(null);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
UnsafeHandle handle = new UnsafeHandle(field);
|
||||
o = handle.get();
|
||||
handle.set(o);
|
||||
|
||||
//noinspection FunctionalExpressionCanBeFolded
|
||||
handles.put(dir + "." + nameStr, new ConfigEntry(
|
||||
handle, value::get
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check if the nested class is a direct nesting
|
||||
for (Class<?> nestMember : clazz.getClasses()) {
|
||||
if (nestMember == clazz) continue;
|
||||
if (!nestMember.getName().startsWith(clazz.getName())) continue;
|
||||
CFGSegment segment = nestMember.getAnnotation(CFGSegment.class);
|
||||
if (segment == null) {
|
||||
System.out.println(nestMember);
|
||||
throw new RuntimeException("NYI: default name");
|
||||
}
|
||||
String name = segment.value();
|
||||
|
||||
setupCommentsAndTranslations(nestMember, builder);
|
||||
|
||||
builder.push(name);
|
||||
setup(dir + "." + name, builder, nestMember);
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
mySpec = builder.build();
|
||||
}
|
||||
|
||||
public void onConfigChange(ModConfigEvent event) {
|
||||
if (
|
||||
event.getConfig().getSpec().equals(mySpec) ||
|
||||
event.getConfig().getSpec() == mySpec
|
||||
) {
|
||||
for (String s : handles.keySet()) {
|
||||
ConfigEntry entry = handles.get(s);
|
||||
entry.handle.set(entry.supplier.get());
|
||||
}
|
||||
}
|
||||
try {
|
||||
postInit.invoke(null);
|
||||
} catch (Throwable err) {
|
||||
err.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void create(ModConfig.Type type, String file) {
|
||||
ModLoadingContext.get().registerConfig(type, mySpec, file);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package net.montoyo.wd.config.annoconfg;
|
||||
|
||||
import net.montoyo.wd.config.annoconfg.handle.UnsafeHandle;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ConfigEntry {
|
||||
UnsafeHandle handle;
|
||||
Supplier<?> supplier;
|
||||
|
||||
public ConfigEntry(UnsafeHandle handle, Supplier<?> supplier) {
|
||||
this.handle = handle;
|
||||
this.supplier = supplier;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.format;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CFGSegment {
|
||||
String value();
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.format;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Comment {
|
||||
String[] value();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.format;
|
||||
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Config {
|
||||
ModConfig.Type type();
|
||||
String path() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.format;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Name {
|
||||
String value();
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.format;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Skip {
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.format;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Translation {
|
||||
String value();
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.value;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Default {
|
||||
byte valueB() default 0;
|
||||
short valueS() default 0;
|
||||
int valueI() default 0;
|
||||
long valueL() default 0;
|
||||
float valueF() default 0;
|
||||
double valueD() default 0;
|
||||
boolean valueBoolean() default false;
|
||||
String valueStr() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.value;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DoubleRange {
|
||||
double minV();
|
||||
double maxV();
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.value;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface IntRange {
|
||||
int minV();
|
||||
int maxV();
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package net.montoyo.wd.config.annoconfg.annotation.value;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface LongRange {
|
||||
long minV();
|
||||
long maxV();
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package net.montoyo.wd.config.annoconfg.handle;
|
||||
|
||||
import net.montoyo.wd.config.annoconfg.util.EnumType;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class UnsafeHandle {
|
||||
private static final Unsafe theUnsafe;
|
||||
|
||||
static {
|
||||
try {
|
||||
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
theUnsafe = (Unsafe) f.get(null);
|
||||
} catch (Throwable ignored) {
|
||||
throw new RuntimeException("AnnoConfg: Failed to acquire an instance of the unsafe.");
|
||||
}
|
||||
}
|
||||
|
||||
private final long offset;
|
||||
|
||||
private final Consumer<Object> uploader;
|
||||
private final Supplier<Object> getter;
|
||||
|
||||
public UnsafeHandle(Field f) {
|
||||
this(null, f);
|
||||
}
|
||||
|
||||
public UnsafeHandle(Object relative, Field f) {
|
||||
offset = theUnsafe.staticFieldOffset(f);
|
||||
if (relative == null) relative = theUnsafe.staticFieldBase(f);
|
||||
Object finalRelative = relative;
|
||||
if (f.getType().isPrimitive()) {
|
||||
switch (EnumType.forClass(f.getType())) {
|
||||
case BYTE -> {
|
||||
uploader = (v) -> theUnsafe.putByte(finalRelative, offset, (byte) v);
|
||||
getter = () -> theUnsafe.getByte(finalRelative, offset);
|
||||
}
|
||||
case SHORT -> {
|
||||
uploader = (v) -> theUnsafe.putShort(finalRelative, offset, (short) v);
|
||||
getter = () -> theUnsafe.getShort(finalRelative, offset);
|
||||
}
|
||||
case INT -> {
|
||||
uploader = (v) -> theUnsafe.putInt(finalRelative, offset, (int) v);
|
||||
getter = () -> theUnsafe.getInt(finalRelative, offset);
|
||||
}
|
||||
case LONG -> {
|
||||
uploader = (v) -> theUnsafe.putLong(finalRelative, offset, (long) v);
|
||||
getter = () -> theUnsafe.getLong(finalRelative, offset);
|
||||
}
|
||||
case FLOAT -> {
|
||||
uploader = (v) -> theUnsafe.putFloat(finalRelative, offset, (float) v);
|
||||
getter = () -> theUnsafe.getFloat(finalRelative, offset);
|
||||
}
|
||||
case DOUBLE -> {
|
||||
uploader = (v) -> theUnsafe.putDouble(finalRelative, offset, (double) v);
|
||||
getter = () -> theUnsafe.getDouble(finalRelative, offset);
|
||||
}
|
||||
case BOOLEAN -> {
|
||||
uploader = (v) -> theUnsafe.putBoolean(finalRelative, offset, (boolean) v);
|
||||
getter = () -> theUnsafe.getBoolean(finalRelative, offset);
|
||||
}
|
||||
default -> {
|
||||
// TODO: check that I have all primitives?
|
||||
uploader = null;
|
||||
getter = () -> null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uploader = (v) -> theUnsafe.putObject(finalRelative, offset, v);
|
||||
getter = () -> theUnsafe.getObject(finalRelative, offset);
|
||||
}
|
||||
}
|
||||
|
||||
public void set(Object o) {
|
||||
uploader.accept(o);
|
||||
// System.out.println(getter.get());
|
||||
}
|
||||
|
||||
public Object get() {
|
||||
return getter.get();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package net.montoyo.wd.config.annoconfg.util;
|
||||
|
||||
public enum EnumType {
|
||||
BYTE(byte.class),
|
||||
SHORT(short.class),
|
||||
INT(int.class),
|
||||
LONG(long.class),
|
||||
FLOAT(float.class),
|
||||
DOUBLE(double.class),
|
||||
BOOLEAN(boolean.class),
|
||||
OTHER(Object.class),
|
||||
;
|
||||
|
||||
Class<?> clazz;
|
||||
|
||||
EnumType(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public static EnumType forClass(Class<?> clazz) {
|
||||
for (EnumType value : EnumType.values())
|
||||
if (value.clazz.equals(clazz)) return value;
|
||||
return OTHER;
|
||||
}
|
||||
}
|
||||
38
src/main/java/net/montoyo/wd/controls/ScreenControl.java
Normal file
38
src/main/java/net/montoyo/wd/controls/ScreenControl.java
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package net.montoyo.wd.controls;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class ScreenControl {
|
||||
private final ResourceLocation id;
|
||||
|
||||
public ScreenControl(ResourceLocation id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public abstract void write(FriendlyByteBuf buf);
|
||||
public abstract void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException;
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public abstract void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx);
|
||||
|
||||
public void checkPerms(int perms, Function<Integer, Boolean> checker, ServerPlayer player) throws MissingPermissionException {
|
||||
if (!checker.apply(perms)) {
|
||||
throw new MissingPermissionException(perms, Objects.requireNonNull(player));
|
||||
}
|
||||
}
|
||||
|
||||
public final ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package net.montoyo.wd.controls;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.builtin.*;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.Log;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
|
||||
// TODO: enable deferred registry of these
|
||||
public class ScreenControlRegistry {
|
||||
private static final HashMap<ResourceLocation, ScreenControlType<?>> CONTROL_TYPES = new HashMap<>();
|
||||
|
||||
public static void register(ResourceLocation name, ScreenControlType<?> type) {
|
||||
if (CONTROL_TYPES.containsKey(name)) {
|
||||
Log.warning("ScreenControlRegistry#CONTROL_TYPES already contains an entry with name " + name);
|
||||
throw new IllegalArgumentException("Cannot have two entries with the same name.");
|
||||
}
|
||||
CONTROL_TYPES.put(name, type);
|
||||
|
||||
// lil thing for sanity
|
||||
// avoids the pain the dist cleaner causes, hopefully
|
||||
if (!FMLEnvironment.production) {
|
||||
if (FMLEnvironment.dist.isClient()) {
|
||||
boolean shouldThrow = false;
|
||||
try {
|
||||
Method m = type.clazz.getMethod("handleClient", BlockPos.class, BlockSide.class, ScreenBlockEntity.class, NetworkEvent.Context.class);
|
||||
OnlyIn onlyIn = m.getAnnotation(OnlyIn.class);
|
||||
if (onlyIn == null) shouldThrow = true;
|
||||
Dist d = onlyIn.value(); // idc if this throws, lol
|
||||
if (d != Dist.CLIENT) shouldThrow = true;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
if (shouldThrow) {
|
||||
Log.warning("handleClient on ScreenControl classes MUST be marked with `@OnlyIn(Dist.CLIENT)`, but it is not on " + type.clazz);
|
||||
throw new IllegalStateException(
|
||||
"handleClient on ScreenControl classes MUST be marked with `@OnlyIn(Dist.CLIENT)`, but it is not on " + type.clazz
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if needed, the old code
|
||||
// https://github.com/Mysticpasta1/webdisplays/blob/ff55cbf1b27773c15f44f17ad3364da3a16b6ed9/src/main/java/net/montoyo/wd/net/server/SMessageScreenCtrl.java#L281-L364
|
||||
// https://github.com/Mysticpasta1/webdisplays/blob/5ce9e4574df356910645b0382628f74d1401e26d/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageScreenUpdate.java#L261-L284
|
||||
static {
|
||||
register(SetURLControl.id, new ScreenControlType<>(SetURLControl.class, SetURLControl::new));
|
||||
register(KeyTypedControl.id, new ScreenControlType<>(KeyTypedControl.class, KeyTypedControl::new));
|
||||
register(AutoVolumeControl.id, new ScreenControlType<>(AutoVolumeControl.class, AutoVolumeControl::new));
|
||||
register(JSRequestControl.id, new ScreenControlType<>(JSRequestControl.class, JSRequestControl::new));
|
||||
register(LaserControl.id, new ScreenControlType<>(LaserControl.class, LaserControl::new));
|
||||
register(ScreenModifyControl.id, new ScreenControlType<>(ScreenModifyControl.class, ScreenModifyControl::new));
|
||||
register(ModifyFriendListControl.id, new ScreenControlType<>(ModifyFriendListControl.class, ModifyFriendListControl::new));
|
||||
register(ManageRightsAndUpdgradesControl.id, new ScreenControlType<>(ManageRightsAndUpdgradesControl.class, ManageRightsAndUpdgradesControl::new));
|
||||
register(ClickControl.id, new ScreenControlType<>(ClickControl.class, ClickControl::new));
|
||||
register(OwnerControl.id, new ScreenControlType<>(OwnerControl.class, OwnerControl::new));
|
||||
register(TurnOffControl.id, new ScreenControlType<>(TurnOffControl.class, (buf) -> TurnOffControl.INSTANCE));
|
||||
}
|
||||
|
||||
public static ScreenControl parse(FriendlyByteBuf buf) {
|
||||
return CONTROL_TYPES.get(new ResourceLocation(buf.readUtf()))
|
||||
.deserializer.apply(buf);
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
/* NO-OP: allows static init to run during mod init in dev env */
|
||||
}
|
||||
}
|
||||
15
src/main/java/net/montoyo/wd/controls/ScreenControlType.java
Normal file
15
src/main/java/net/montoyo/wd/controls/ScreenControlType.java
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
package net.montoyo.wd.controls;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ScreenControlType<T extends ScreenControl> {
|
||||
Class<T> clazz;
|
||||
Function<FriendlyByteBuf, ScreenControl> deserializer;
|
||||
|
||||
public ScreenControlType(Class<T> clazz, Function<FriendlyByteBuf, ScreenControl> deserializer) {
|
||||
this.clazz = clazz;
|
||||
this.deserializer = deserializer;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class AutoVolumeControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:auto_volume");
|
||||
|
||||
boolean autoVol;
|
||||
|
||||
public AutoVolumeControl(boolean autoVol) {
|
||||
super(id);
|
||||
this.autoVol = autoVol;
|
||||
}
|
||||
|
||||
public AutoVolumeControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
autoVol = buf.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeBoolean(autoVol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
// I feel like there's probably a better permission category
|
||||
checkPerms(ScreenRights.MANAGE_UPGRADES, permissionChecker, ctx.getSender());
|
||||
tes.setAutoVolume(side, autoVol);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
tes.setAutoVolume(side, autoVol);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector2i;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ClickControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:click");
|
||||
|
||||
public enum ControlType {
|
||||
CLICK, MOVE, DOWN, UP
|
||||
}
|
||||
|
||||
ControlType type;
|
||||
Vector2i coord;
|
||||
|
||||
public ClickControl(ControlType type, Vector2i coord) {
|
||||
this(type, coord, -1);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ClickControl(ControlType type, Vector2i coord, int button) {
|
||||
super(id);
|
||||
this.coord = coord;
|
||||
}
|
||||
|
||||
public ClickControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
type = ControlType.values()[buf.readByte()];
|
||||
coord = new Vector2i(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeByte(type.ordinal());
|
||||
coord.writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
throw new RuntimeException("Cannot call click control on server");
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
if (coord != null)
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.MOVE, coord, -1);
|
||||
|
||||
tes.handleMouseEvent(side, type, coord, 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.JSServerRequest;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class JSRequestControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:js_req");
|
||||
|
||||
int reqId;
|
||||
JSServerRequest reqType;
|
||||
Object[] data;
|
||||
|
||||
public JSRequestControl(int reqId, JSServerRequest reqType, Object[] data) {
|
||||
super(id);
|
||||
this.reqId = reqId;
|
||||
this.reqType = reqType;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public JSRequestControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
reqId = buf.readInt();
|
||||
reqType = JSServerRequest.fromID(buf.readByte());
|
||||
|
||||
if (reqType != null)
|
||||
data = reqType.deserialize(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeInt(reqId);
|
||||
buf.writeByte(reqType.ordinal());
|
||||
|
||||
if (!reqType.serialize(buf, data))
|
||||
throw new RuntimeException("Could not serialize CTRL_JS_REQUEST " + reqType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
ServerPlayer player = ctx.getSender();
|
||||
// if (reqType == null || data == null) Log.warning("Caught invalid JS request from player %s (UUID %s)", player.getName(), player.getGameProfile().getId().toString());
|
||||
// else tes.handleJSRequest(player, side, reqId, reqType, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class KeyTypedControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:type");
|
||||
|
||||
String text;
|
||||
BlockPos soundPos;
|
||||
|
||||
public KeyTypedControl(String text, BlockPos soundPos) {
|
||||
super(id);
|
||||
this.text = text;
|
||||
this.soundPos = soundPos;
|
||||
}
|
||||
|
||||
public KeyTypedControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
text = buf.readUtf();
|
||||
soundPos = buf.readBlockPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeUtf(text);
|
||||
buf.writeBlockPos(soundPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
checkPerms(ScreenRights.INTERACT, permissionChecker, ctx.getSender());
|
||||
tes.type(side, text, soundPos, ctx.getSender());
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
tes.type(side, text, soundPos);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector2i;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class LaserControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:laser");
|
||||
|
||||
public enum ControlType {
|
||||
MOVE, DOWN, UP
|
||||
}
|
||||
|
||||
ControlType type;
|
||||
Vector2i coord;
|
||||
int button;
|
||||
|
||||
public LaserControl(ControlType type, Vector2i coord) {
|
||||
this(type, coord, -1);
|
||||
}
|
||||
|
||||
public LaserControl(ControlType type, Vector2i coord, int button) {
|
||||
super(id);
|
||||
this.type = type;
|
||||
this.coord = coord;
|
||||
this.button = button;
|
||||
}
|
||||
|
||||
public LaserControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
type = ControlType.values()[buf.readByte()];
|
||||
if (!type.equals(ControlType.UP))
|
||||
coord = new Vector2i(buf);
|
||||
if (!type.equals(ControlType.MOVE))
|
||||
button = buf.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeByte(type.ordinal());
|
||||
if (coord != null) coord.writeTo(buf);
|
||||
if (type != ControlType.MOVE) buf.writeInt(button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
// feel like this makes sense, but I wanna get opinions first
|
||||
// checkPerms(ScreenRights.INTERACT, permissionChecker, ctx.getSender());
|
||||
ServerPlayer sender = ctx.getSender();
|
||||
switch (type) {
|
||||
case UP -> tes.laserUp(side, sender, button);
|
||||
case DOWN -> tes.laserDownMove(side, sender, coord, true, button);
|
||||
case MOVE -> tes.laserDownMove(side, sender, coord, false, button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
if (coord != null)
|
||||
tes.handleMouseEvent(side, ClickControl.ControlType.MOVE, coord, -1);
|
||||
|
||||
switch (type) {
|
||||
case UP -> tes.handleMouseEvent(side, ClickControl.ControlType.UP, coord, button);
|
||||
case DOWN -> tes.handleMouseEvent(side, ClickControl.ControlType.DOWN, coord, button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.ScreenData;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* TODO: I'm considering merging this with {@link ModifyFriendListControl} to make ManageScreenControl
|
||||
*/
|
||||
@Deprecated
|
||||
public class ManageRightsAndUpdgradesControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:mod_rights_upgrades");
|
||||
|
||||
public enum ControlType {
|
||||
RIGHTS, UPGRADES
|
||||
}
|
||||
|
||||
ControlType type;
|
||||
boolean adding;
|
||||
ItemStack toRemove;
|
||||
|
||||
private int friendRights;
|
||||
private int otherRights;
|
||||
|
||||
public ManageRightsAndUpdgradesControl(boolean adding, ItemStack toRemove) {
|
||||
super(id);
|
||||
this.adding = adding;
|
||||
type = ControlType.UPGRADES;
|
||||
this.toRemove = toRemove;
|
||||
}
|
||||
|
||||
public ManageRightsAndUpdgradesControl(int friendRights, int otherRights) {
|
||||
super(id);
|
||||
type = ControlType.RIGHTS;
|
||||
this.friendRights = friendRights;
|
||||
this.otherRights = otherRights;
|
||||
}
|
||||
|
||||
public ManageRightsAndUpdgradesControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
type = ControlType.values()[buf.readByte()];
|
||||
switch (type) {
|
||||
case UPGRADES -> {
|
||||
adding = buf.readBoolean();
|
||||
toRemove = buf.readItem();
|
||||
}
|
||||
case RIGHTS -> {
|
||||
friendRights = buf.readInt();
|
||||
otherRights = buf.readInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeByte(type.ordinal());
|
||||
switch (type) {
|
||||
case UPGRADES -> {
|
||||
buf.writeBoolean(adding);
|
||||
buf.writeItem(toRemove);
|
||||
}
|
||||
case RIGHTS -> {
|
||||
buf.writeInt(friendRights);
|
||||
buf.writeInt(otherRights);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
ServerPlayer player = ctx.getSender();
|
||||
switch (type) {
|
||||
case UPGRADES -> {
|
||||
checkPerms(ScreenRights.MANAGE_UPGRADES, permissionChecker, ctx.getSender());
|
||||
if (adding)
|
||||
throw new RuntimeException("Cannot add an upgrade from the client");
|
||||
else tes.removeUpgrade(side, toRemove, player);
|
||||
}
|
||||
case RIGHTS -> {
|
||||
ScreenData scr = tes.getScreen(side);
|
||||
|
||||
int fr = scr.owner.uuid.equals(player.getGameProfile().getId()) ? friendRights : scr.friendRights;
|
||||
int or = (scr.rightsFor(player) & ScreenRights.MANAGE_OTHER_RIGHTS) == 0 ? scr.otherRights : otherRights;
|
||||
|
||||
if(scr.friendRights != fr || scr.otherRights != or)
|
||||
tes.setRights(player, side, fr, or);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
ServerPlayer player = ctx.getSender();
|
||||
switch (type) {
|
||||
case UPGRADES -> {
|
||||
if (adding)
|
||||
tes.addUpgrade(side, toRemove, player, true);
|
||||
else tes.removeUpgrade(side, toRemove, player);
|
||||
}
|
||||
case RIGHTS -> {
|
||||
ScreenData scr = tes.getScreen(side);
|
||||
|
||||
int fr = friendRights;
|
||||
int or = otherRights;
|
||||
|
||||
if(scr.friendRights != fr || scr.otherRights != or)
|
||||
tes.setRights(player, side, fr, or);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.serialization.NameUUIDPair;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ModifyFriendListControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:mod_friend_list");
|
||||
|
||||
boolean adding;
|
||||
NameUUIDPair friend;
|
||||
|
||||
public ModifyFriendListControl(NameUUIDPair pair, boolean adding) {
|
||||
super(id);
|
||||
this.adding = adding;
|
||||
this.friend = pair;
|
||||
}
|
||||
|
||||
public ModifyFriendListControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
adding = buf.readBoolean();
|
||||
friend = new NameUUIDPair(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeBoolean(adding);
|
||||
friend.writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
ServerPlayer player = ctx.getSender();
|
||||
checkPerms(ScreenRights.MANAGE_FRIEND_LIST, permissionChecker, ctx.getSender());
|
||||
if (adding) tes.addFriend(player, side, friend);
|
||||
else tes.removeFriend(player, side, friend);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
throw new RuntimeException("TODO");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.serialization.NameUUIDPair;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class OwnerControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:set_owner");
|
||||
|
||||
NameUUIDPair owner;
|
||||
|
||||
public OwnerControl(NameUUIDPair pair) {
|
||||
super(id);
|
||||
this.owner = pair;
|
||||
}
|
||||
|
||||
public OwnerControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
owner = new NameUUIDPair(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
owner.writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
throw new RuntimeException("Cannot handle ownership theft packet from server");
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
tes.getScreen(side).owner = owner;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.data.Rotation;
|
||||
import net.montoyo.wd.utilities.math.Vector2i;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ScreenModifyControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:mod_screen");
|
||||
|
||||
public enum ControlType {
|
||||
RESOLUTION, ROTATION
|
||||
}
|
||||
|
||||
ControlType type;
|
||||
Vector2i res;
|
||||
Rotation rotation;
|
||||
|
||||
public ScreenModifyControl(Vector2i res) {
|
||||
super(id);
|
||||
this.type = ControlType.RESOLUTION;
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
public ScreenModifyControl(Rotation rotation) {
|
||||
super(id);
|
||||
this.type = ControlType.ROTATION;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public ScreenModifyControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
type = ControlType.values()[buf.readByte()];
|
||||
if (type.equals(ControlType.RESOLUTION))
|
||||
res = new Vector2i(buf);
|
||||
else rotation = Rotation.values()[buf.readByte()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeByte(type.ordinal());
|
||||
if (res != null) res.writeTo(buf);
|
||||
else if (rotation != null) buf.writeByte(rotation.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
checkPerms(ScreenRights.MODIFY_SCREEN, permissionChecker, ctx.getSender());
|
||||
switch (type) {
|
||||
case RESOLUTION -> tes.setResolution(side, res);
|
||||
case ROTATION -> tes.setRotation(side, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
switch (type) {
|
||||
case RESOLUTION -> tes.setResolution(side, res);
|
||||
case ROTATION -> tes.setRotation(side, rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.core.ScreenRights;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class SetURLControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:set_url");
|
||||
|
||||
String url;
|
||||
Vector3i remoteLocation;
|
||||
|
||||
public SetURLControl(String url, Vector3i remoteLocation) {
|
||||
super(id);
|
||||
this.url = url;
|
||||
this.remoteLocation = remoteLocation;
|
||||
}
|
||||
|
||||
public SetURLControl(FriendlyByteBuf buf) {
|
||||
super(id);
|
||||
url = buf.readUtf();
|
||||
if (buf.readBoolean()) remoteLocation = new Vector3i(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeUtf(url);
|
||||
buf.writeBoolean(remoteLocation != null);
|
||||
if (remoteLocation != null) remoteLocation.writeTo(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
// TODO: deal with remote
|
||||
checkPerms(ScreenRights.CHANGE_URL, permissionChecker, ctx.getSender());
|
||||
try {
|
||||
tes.setScreenURL(side, url);
|
||||
} catch (Throwable err) {
|
||||
err.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
try {
|
||||
tes.setScreenURL(side, url);
|
||||
} catch (Throwable err) {
|
||||
err.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package net.montoyo.wd.controls.builtin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.controls.ScreenControl;
|
||||
import net.montoyo.wd.core.MissingPermissionException;
|
||||
import net.montoyo.wd.entity.ScreenBlockEntity;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TurnOffControl extends ScreenControl {
|
||||
public static final ResourceLocation id = new ResourceLocation("webdisplays:deactivate");
|
||||
|
||||
public static final TurnOffControl INSTANCE = new TurnOffControl();
|
||||
|
||||
public TurnOffControl() {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServer(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx, Function<Integer, Boolean> permissionChecker) throws MissingPermissionException {
|
||||
throw new RuntimeException("Cannot handle deactivation packet from server");
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handleClient(BlockPos pos, BlockSide side, ScreenBlockEntity tes, NetworkEvent.Context ctx) {
|
||||
if (side != null) {
|
||||
WebDisplays.PROXY.closeGui(pos, side);
|
||||
tes.disableScreen(side);
|
||||
} else {
|
||||
for (BlockSide value : BlockSide.values()) {
|
||||
WebDisplays.PROXY.closeGui(pos, value);
|
||||
tes.disableScreen(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 BARBOTIN Nicolas
|
||||
*/
|
||||
|
||||
package net.montoyo.wd.core;
|
||||
|
||||
public enum AdvancementIcon {
|
||||
|
||||
WEB_DISPLAYS("wd"),
|
||||
BROKEN_PAD("brokenpad"),
|
||||
PIGEON("pigeon");
|
||||
|
||||
private final String name;
|
||||
|
||||
AdvancementIcon(String n) {
|
||||
name = n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ package net.montoyo.wd.core;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
// TODO: bring this back when SSR is implemented
|
||||
public class CCArguments implements IComputerArgs {
|
||||
|
||||
private final Object[] args;
|
||||
|
|
|
|||
|
|
@ -5,20 +5,18 @@
|
|||
package net.montoyo.wd.core;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.init.ItemInit;
|
||||
import net.montoyo.wd.registry.ItemRegistry;
|
||||
|
||||
public enum CraftComponent {
|
||||
|
||||
STONE_KEY("stonekey", "Stone_Key"),
|
||||
BLANK_UPGRADE("upgrade", "Blank_Upgrade"),
|
||||
PERIPHERAL_BASE("peripheral", "Peripheral_Base"),
|
||||
BATTERY_CELL("batcell", "Battery_Cell"),
|
||||
BATTERY_PACK("batpack", "Battery_Pack"),
|
||||
LASER_DIODE("laserdiode", "Laser_Diode"),
|
||||
STONEKEY("stonekey", "StoneKey"),
|
||||
UPGRADE("upgrade", "Upgrade"),
|
||||
PERIPHERAL("peripheral", "Peripheral"),
|
||||
BATCELL("batcell", "BatCell"),
|
||||
BATPACK("batpack", "BatPack"),
|
||||
LASERDIODE("laserdiode", "LaserDiode"),
|
||||
BACKLIGHT("backlight", "Backlight"),
|
||||
EXTENSION_CARD("extcard", "Blank_Upgrade"),
|
||||
BAD_EXTENSION_CARD("badextcard", "Bad_Extension_Card");
|
||||
EXTCARD("extcard", "ExtCard"),
|
||||
BADEXTCARD("badextcard", "BadExtCard");
|
||||
|
||||
private final String name;
|
||||
private final String wikiName;
|
||||
|
|
@ -34,7 +32,6 @@ public enum CraftComponent {
|
|||
}
|
||||
|
||||
public ItemStack makeItemStack() {
|
||||
return new ItemStack(ItemInit.itemCraftComp.get(), 1);
|
||||
return new ItemStack(ItemRegistry.getComputerCraftItem(ordinal()).get(), 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package net.montoyo.wd.core;
|
|||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.advancements.CriterionTrigger;
|
||||
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance;
|
||||
import net.minecraft.advancements.critereon.ContextAwarePredicate;
|
||||
import net.minecraft.advancements.critereon.DeserializationContext;
|
||||
import net.minecraft.advancements.critereon.EntityPredicate;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
|
@ -19,10 +20,8 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
|
||||
public class Criterion implements CriterionTrigger<Criterion.Instance> {
|
||||
|
||||
public static class Instance extends AbstractCriterionTriggerInstance {
|
||||
|
||||
public Instance(ResourceLocation id, EntityPredicate.Composite arg2) {
|
||||
public Instance(ResourceLocation id, ContextAwarePredicate arg2) {
|
||||
super(id, arg2);
|
||||
}
|
||||
}
|
||||
|
|
@ -60,16 +59,15 @@ public class Criterion implements CriterionTrigger<Criterion.Instance> {
|
|||
|
||||
@Override
|
||||
public @NotNull Instance createInstance(JsonObject json, DeserializationContext context) {
|
||||
return new Instance(id, EntityPredicate.Composite.fromJson(json, "instance", context));
|
||||
return new Instance(id, EntityPredicate.fromJson(json, "instance", context));
|
||||
}
|
||||
|
||||
public void trigger(PlayerAdvancements ply) {
|
||||
ArrayList<Listener<Instance>> listeners = map.get(ply);
|
||||
|
||||
if(listeners != null) {
|
||||
if (listeners != null) {
|
||||
Listener[] copy = listeners.toArray(new Listener[0]); //We need to make a copy, otherwise we get a ConcurrentModificationException
|
||||
Arrays.stream(copy).forEach(l -> l.run(ply));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,22 +8,22 @@ import net.minecraft.util.StringRepresentable;
|
|||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.montoyo.wd.entity.TileEntityKeyboard;
|
||||
import net.montoyo.wd.entity.TileEntityRCtrl;
|
||||
import net.montoyo.wd.entity.TileEntityRedCtrl;
|
||||
import net.montoyo.wd.entity.TileEntityServer;
|
||||
import net.montoyo.wd.entity.KeyboardBlockEntity;
|
||||
import net.montoyo.wd.entity.RemoteControlBlockEntity;
|
||||
import net.montoyo.wd.entity.RedstoneControlBlockEntity;
|
||||
import net.montoyo.wd.entity.ServerBlockEntity;
|
||||
import net.montoyo.wd.registry.BlockRegistry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum DefaultPeripheral implements StringRepresentable {
|
||||
|
||||
KEYBOARD("keyboard", "Keyboard", TileEntityKeyboard::new, TileEntityKeyboard::getBlockFromTE), //WITH FACING (< 3)
|
||||
KEYBOARD("keyboard", "Keyboard", KeyboardBlockEntity::new, BlockRegistry.KEYBOARD_BLOCK), //WITH FACING (< 3)
|
||||
// CC_INTERFACE("ccinterface", "ComputerCraft_Interface", TileEntityCCInterface.class),
|
||||
// OC_INTERFACE("cointerface", "OpenComputers_Interface", TileEntityOCInterface.class),
|
||||
REMOTE_CONTROLLER("remotectrl", "Remote_Controller", TileEntityRCtrl::new ,TileEntityRCtrl::getBlockFromTE), //WITHOUT FACING (>= 3)
|
||||
REDSTONE_CONTROLLER("redstonectrl", "Redstone_Controller", TileEntityRedCtrl::new ,TileEntityRedCtrl::getBlockFromTE),
|
||||
SERVER("server", "Server", TileEntityServer::new, TileEntityServer::getBlockFromTE);
|
||||
REMOTE_CONTROLLER("remotectrl", "Remote_Controller", RemoteControlBlockEntity::new , BlockRegistry.REMOTE_CONTROLLER_BLOCK), //WITHOUT FACING (>= 3)
|
||||
REDSTONE_CONTROLLER("redstonectrl", "Redstone_Controller", RedstoneControlBlockEntity::new , BlockRegistry.REDSTONE_CONTROL_BLOCK),
|
||||
SERVER("server", "Server", ServerBlockEntity::new, BlockRegistry.SERVER_BLOCK);
|
||||
|
||||
private final String name;
|
||||
private final String wikiName;
|
||||
|
|
|
|||
|
|
@ -5,19 +5,16 @@
|
|||
package net.montoyo.wd.core;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.montoyo.wd.WebDisplays;
|
||||
import net.montoyo.wd.config.ModConfig;
|
||||
import net.montoyo.wd.init.ItemInit;
|
||||
import net.montoyo.wd.item.ItemUpgrade;
|
||||
|
||||
public enum DefaultUpgrade {
|
||||
|
||||
LASER_MOUSE("lasermouse", "Laser_Sensor"),
|
||||
REDSTONE_INPUT("redinput", "Redstone_Input_Port"),
|
||||
REDSTONE_OUTPUT("redoutput", "Redstone_Output_Port"),
|
||||
GPS("gps", "GPS_Module");
|
||||
|
||||
private final String name;
|
||||
private final String wikiName;
|
||||
LASERMOUSE("lasermouse", "LaserMouse"),
|
||||
REDINPUT("redinput", "RedInput"),
|
||||
REDOUTPUT("redoutput", "RedOutput"),
|
||||
GPS("gps", "GPS");
|
||||
|
||||
public final String name;
|
||||
public final String wikiName;
|
||||
|
||||
DefaultUpgrade(String n, String wn) {
|
||||
name = n;
|
||||
|
|
@ -29,7 +26,25 @@ public enum DefaultUpgrade {
|
|||
return name;
|
||||
}
|
||||
|
||||
public boolean matches(ItemStack is) {
|
||||
return is.getItem() == ItemInit.itemUpgrade.get();
|
||||
protected static boolean matches(ItemStack stack, DefaultUpgrade upgrade) {
|
||||
if (stack.getItem() instanceof ItemUpgrade upgrade1)
|
||||
return upgrade1.type == upgrade;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean matchesLaserMouse(ItemStack is) {
|
||||
return matches(is, LASERMOUSE);
|
||||
}
|
||||
|
||||
public boolean matchesRedInput(ItemStack is) {
|
||||
return matches(is, REDINPUT);
|
||||
}
|
||||
|
||||
public boolean matchesRedOutput(ItemStack is) {
|
||||
return matches(is, REDOUTPUT);
|
||||
}
|
||||
|
||||
public boolean matchesGps(ItemStack is) {
|
||||
return matches(is, GPS);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@
|
|||
package net.montoyo.wd.core;
|
||||
|
||||
public enum HasAdvancement {
|
||||
|
||||
DONT_KNOW,
|
||||
YES,
|
||||
NO
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ package net.montoyo.wd.core;
|
|||
import java.util.Map;
|
||||
|
||||
public interface IComputerArgs {
|
||||
|
||||
String checkString(int i);
|
||||
int checkInteger(int i);
|
||||
Map checkTable(int i);
|
||||
int count();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,9 @@ package net.montoyo.wd.core;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.montoyo.wd.utilities.BlockSide;
|
||||
import net.montoyo.wd.utilities.Vector3i;
|
||||
import net.montoyo.wd.utilities.data.BlockSide;
|
||||
import net.montoyo.wd.utilities.math.Vector3i;
|
||||
|
||||
public interface IPeripheral {
|
||||
|
||||
boolean connect(Level world, BlockPos blockPos, BlockState blockState, Vector3i screenPos, BlockSide screenSide);
|
||||
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user