Compare commits

..

No commits in common. "1.20" and "1.19.2-forge-windows-only" have entirely different histories.

375 changed files with 11135 additions and 12291 deletions

22
LICENSE
View File

@ -1,21 +1 @@
MIT License 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!
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.

View File

@ -1,25 +1,18 @@
# WebDisplays # WebDisplays for Minecraft 1.12.2
WebDisplays is a mod for creating and interacting with web browsers in Minecraft. You can create screens in your world and browse the internet. 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 was originally written by montoyo. It is currently maintained by CinemaMod Group. ### Wiki
* The Wiki that details all blocks/items can be found on my website https://montoyo.net/wdwiki/
Discussion: https://discord.gg/rNrh5kW8Ty ### Things before release
* Release ready. Targeted release date: 17/02/2018.
## Install ### Delayed things
Download WebDisplays from either: * Plugin API
- CurseForge: https://legacy.curseforge.com/minecraft/mc-mods/webdisplays * The Shop
- Modrinth: https://modrinth.com/mod/webdisplays * CC Interface, if CC gets updated...
* Center camera to screen when using keyboard
**WebDisplays Requires MCEF!** You must install MCEF in order for WebDisplays to work. * minePad management: check GuiContainer.draggedStack for minePad
* In-game command to add/remove blacklisted domains
Download MCEF from either: * Config: RPMP (Real pixels per Minecraft pixels)
- CurseForge: https://legacy.curseforge.com/minecraft/mc-mods/mcef * Disable miniserv in solo
- 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
View File

@ -1,12 +0,0 @@
### 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

View File

@ -1,179 +1,101 @@
plugins { plugins {
id 'java' id 'dev.architectury.loom' version '0.12.0-SNAPSHOT'
id 'idea' id 'io.github.juuxel.loom-quiltflower' version '1.6.0'
id 'maven-publish' id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'net.neoforged.moddev.legacyforge' version '2.0.103'
} }
// Only add ProGuard if building with it sourceCompatibility = JavaVersion.VERSION_17
def enableProguard = project.hasProperty("enableProguard") && project.enableProguard.toBoolean() targetCompatibility = JavaVersion.VERSION_17
if (enableProguard) {
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.guardsquare:proguard-gradle:7.7.0'
}
}
}
base { archivesBaseName = project.archives_base_name
archivesName = mod_id version = project.mod_version
} group = project.maven_group
group = mod_group_id
version = "${minecraft_version}-${mod_version}"
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
println "Java: ${System.getProperty 'java.version'}"
repositories { repositories {
mavenCentral() // Add repositories to retrieve artifacts from in here.
maven { url = "https://libraries.minecraft.net/" } // You should only use this when depending on other mods because
maven { url = "https://cursemaven.com" } // Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
maven { url = "https://maven.parchmentmc.org" } // See https://docs.gradle.org/current/userguide/declaring_repositories.html
maven { url = 'https://mcef-download.cinemamod.com/repositories/releases/' } // for more information about repositories.
maven { url = "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/" } maven { url "https://maven.shedaniel.me/" }
maven { url = "https://maven.theillusivec4.top/" } maven { url 'https://jitpack.io' }
maven { url = "https://repo.lucko.me/" } maven {
maven { url = "https://maven.kosmx.dev/" } url = "https://maven.parchmentmc.org"
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 {
runs { name = "cursemaven"
configureEach { url = "https://www.cursemaven.com"
systemProperty 'forge.logging.console.level', 'debug'
logLevel = org.slf4j.event.Level.DEBUG
}
client {
client()
programArgument "-mixin.config=${mod_id}.mixins.json"
systemProperty 'mixin.debug.export', 'true'
}
server {
server()
programArgument "-mixin.config=${mod_id}.mixins.json"
}
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 { loom {
srcDir 'src/generated/resources' accessWidenerPath = file("src/main/resources/webdisplays.accesswidener")
} }
dependencies { dependencies {
// MCEF dependency // To change the versions see the gradle.properties file
modImplementation("com.cinemamod:mcef-forge:2.1.1-1.20.1") { minecraft "com.mojang:minecraft:${project.minecraft_version}"
transitive = false mappings loom.layered() {
officialMojangMappings()
parchment("org.parchmentmc.data:parchment-1.18.2:2022.05.02@zip")
} }
forge "net.minecraftforge:forge:${project.forge_version}"
// Optional mods (make sure versions exist) modImplementation "com.github.Mysticpasta1:mcef-forge:11826a2d11"
modRuntimeOnly "curse.maven:spark-361579:4738952" modImplementation "curse.maven:cloth_config_forge-348521:3546623"
modCompileOnly "curse.maven:vivecraft-667903:4794431" // Uncomment the following line to enable the deprecated Fabric API modules.
modImplementation "software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}" // 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.
modCompileOnly "top.theillusivec4.curios:curios-forge:${curios_version}:api"
modRuntimeOnly "top.theillusivec4.curios:curios-forge:${curios_version}"
// Mixin Extras // modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}"
compileOnly annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")
modImplementation "io.github.llamalad7:mixinextras-forge:0.4.1"
} }
tasks.named('jar', Jar) { loom {
manifest { forge {
attributes([ mixinConfigs = [
'Specification-Title': mod_name, "webdisplays.mixin.json"
'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 processResources {
tasks.register('sourcesJar', Jar) { inputs.property "version", project.version
dependsOn classes
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
// Reobfuscation handling filesMatching("fabric.mod.json") {
tasks.named('reobfJar') { expand "version": project.version
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) tasks.withType(JavaCompile).configureEach {
if (enableProguard) { // Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
tasks.register('proguard', proguard.gradle.ProGuardTask) { it.options.release = 17
dependsOn tasks.jar }
configuration 'proguard.pro'
libraryjars "${System.getProperty('java.home')}/jmods" 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()
}
def inputJar = tasks.jar.archiveFile.get().asFile jar {
injars inputJar from("LICENSE") {
outjars "${buildDir}/libs/${mod_id}-${minecraft_version}-${mod_version}-proguard.jar" rename { "${it}_${project.archivesBaseName}"}
} }
} }
// configure the maven publication
publishing { publishing {
publications { publications {
mavenJava(MavenPublication) { mavenJava(MavenPublication) {
artifactId = mod_id from components.java
artifact reobfJar
artifact sourcesJar
} }
} }
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories { repositories {
maven { // Add repositories to publish to here.
name = "local" // Notice: This block does NOT have the same function as the block in the top level.
url = layout.buildDirectory.dir("repo") // The repositories here will be used for publishing your artifact, not for
} // retrieving dependencies.
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -1,36 +1,17 @@
# Gradle settings # Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false loom.platform=forge
org.gradle.parallel=true
org.gradle.caching=true
# ProGuard # Fabric Properties
enableProguard=false # check these on https://fabricmc.net/develop
minecraft_version=1.18.2
yarn_mappings=1.18.2+build.3
loader_version=0.14.8
# Mod properties # Mod Properties
mod_id=webdisplays mod_version = 1.0.0
mod_name=WebDisplays maven_group = net.montoyo.wd
mod_version=2.0.3 archives_base_name = webdisplays
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
# Minecraft/Forge versions # Dependencies
minecraft_version=1.20.1 forge_version=1.18.2-40.1.52
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

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip

0
gradlew vendored Executable file → Normal file
View File

View File

@ -1,11 +1,23 @@
pluginManagement { pluginManagement {
repositories { repositories {
mavenLocal() 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()
gradlePluginPortal() 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'
} }

View File

@ -4,59 +4,40 @@
package net.montoyo.wd; package net.montoyo.wd;
import com.cinemamod.mcef.MCEF;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.player.Player; 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.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.level.dimension.DimensionType;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.server.ServerLifecycleHooks; import net.minecraftforge.server.ServerLifecycleHooks;
import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.core.HasAdvancement; import net.montoyo.wd.core.HasAdvancement;
import net.montoyo.wd.core.JSServerRequest; import net.montoyo.wd.core.JSServerRequest;
import net.montoyo.wd.data.GuiData; import net.montoyo.wd.data.GuiData;
import net.montoyo.wd.entity.ScreenBlockEntity; import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.entity.ScreenData;
import net.montoyo.wd.utilities.*; 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 javax.annotation.Nonnull;
import java.util.UUID;
import static net.minecraftforge.api.distmarker.Dist.CLIENT;
public class SharedProxy { public class SharedProxy {
public void preInit() { public void preInit() {
} }
public void init() { public void init() {
MCEF.scheduleForInit((cef) -> onCefInit());
} }
public void postInit() { public void postInit() {
} }
public void onCefInit() {
}
@Deprecated(forRemoval = true)
public Level getWorld(ResourceKey<Level> dim) { public Level getWorld(ResourceKey<Level> dim) {
return getServer().getLevel(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) { public void enqueue(Runnable r) {
ServerLifecycleHooks.getCurrentServer().addTickable(r); ServerLifecycleHooks.getCurrentServer().addTickable(r);
} }
@ -65,7 +46,7 @@ public class SharedProxy {
Log.error("Called SharedProxy.displayGui() on server side..."); Log.error("Called SharedProxy.displayGui() on server side...");
} }
public void trackScreen(ScreenBlockEntity tes, boolean track) { public void trackScreen(TileEntityScreen tes, boolean track) {
} }
public void onAutocompleteResult(NameUUIDPair pairs[]) { public void onAutocompleteResult(NameUUIDPair pairs[]) {
@ -84,11 +65,11 @@ public class SharedProxy {
public void screenUpdateAutoVolumeInGui(Vector3i pos, BlockSide side, boolean av) { public void screenUpdateAutoVolumeInGui(Vector3i pos, BlockSide side, boolean av) {
} }
public void displaySetPadURLGui(ItemStack is, String padURL) { public void displaySetPadURLGui(String padURL) {
Log.error("Called SharedProxy.displaySetPadURLGui() on server side..."); Log.error("Called SharedProxy.displaySetPadURLGui() on server side...");
} }
public void openMinePadGui(UUID padId) { public void openMinePadGui(int padId) {
Log.error("Called SharedProxy.openMinePadGui() on server side..."); Log.error("Called SharedProxy.openMinePadGui() on server side...");
} }
@ -129,20 +110,4 @@ public class SharedProxy {
return false; 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;
}
} }

View File

@ -5,11 +5,13 @@
package net.montoyo.wd; package net.montoyo.wd;
import com.google.gson.Gson; 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.ChatFormatting;
import net.minecraft.advancements.Advancement; import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
@ -18,55 +20,59 @@ import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player; 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.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraftforge.client.event.ClientChatEvent; import net.minecraftforge.client.event.ClientChatEvent;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.item.ItemTossEvent;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.level.LevelEvent;
import net.minecraftforge.event.server.ServerStoppingEvent; import net.minecraftforge.event.server.ServerStoppingEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.registries.DeferredRegister; import net.montoyo.wd.block.WDBlockContainer;
import net.minecraftforge.registries.ForgeRegistries;
import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.client.gui.camera.KeyboardCamera; import net.montoyo.wd.client.gui.controls.*;
import net.montoyo.wd.config.ClientConfig; import net.montoyo.wd.config.ModConfig;
import net.montoyo.wd.config.CommonConfig;
import net.montoyo.wd.controls.ScreenControlRegistry;
import net.montoyo.wd.core.*; 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.miniserv.server.Server;
import net.montoyo.wd.net.WDNetworkRegistry; import net.montoyo.wd.net.Messages;
import net.montoyo.wd.net.client_bound.S2CMessageServerInfo; import net.montoyo.wd.net.client.CMessageServerInfo;
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.Log;
import net.montoyo.wd.utilities.serialization.Util; import net.montoyo.wd.utilities.Util;
import java.io.*; import java.io.*;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@Mod("webdisplays") @Mod("webdisplays")
public class WebDisplays { public class WebDisplays {
public static final String MOD_VERSION = "1.1";
public static WebDisplays INSTANCE; public static WebDisplays INSTANCE;
public static SharedProxy PROXY = null; public static SharedProxy PROXY = DistExecutor.<SharedProxy>runForDist(() -> ClientProxy::new, () -> SharedProxy::new);
public static WDCreativeTab CREATIVE_TAB;
public static final ResourceLocation ADV_PAD_BREAK = new ResourceLocation("webdisplays", "webdisplays/pad_break"); 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 String BLACKLIST_URL = "mod://webdisplays/blacklisted.html";
public static final Gson GSON = new Gson(); public static final Gson GSON = new Gson();
@ -88,40 +94,54 @@ public class WebDisplays {
//Config //Config
public static final double PAD_RATIO = 59.0 / 30.0; public static final double PAD_RATIO = 59.0 / 30.0;
public String homePage;
public double padResX; public double padResX;
public double padResY; public double padResY;
private int lastPadId = 0; 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 unloadDistance2;
public double loadDistance2; public double loadDistance2;
public int maxResX;
public int maxResY;
public int maxScreenX;
public int maxScreenY;
public int miniservPort; public int miniservPort;
public long miniservQuota; public long miniservQuota;
public boolean enableSoundDistance;
public float ytVolume; public float ytVolume;
public float avDist100; public float avDist100;
public float avDist0; public float avDist0;
// mod detection
private boolean hasOC;
private boolean hasCC;
public WebDisplays() { public WebDisplays() {
INSTANCE = this; INSTANCE = this;
if(FMLEnvironment.dist.isClient()) { AutoConfig.register(ModConfig.class, Toml4jConfigSerializer::new);
PROXY = DistSafety.createProxy(); ConfigHolder<ModConfig> configHolder = AutoConfig.getConfigHolder(ModConfig.class);
} else { ModConfig config = configHolder.getConfig();
PROXY = new SharedProxy(); configHolder.save();
}
this.blacklist = config.main.blacklist;
if (FMLEnvironment.dist.isClient()) { doHardRecipe = config.main.hardRecipes;
// proxies are annoying, so from now on, I'mma be just registering stuff in here this.homePage = config.main.homepage;
FMLJavaModLoadingContext.get().getModEventBus().addListener(ClientProxy::onKeybindRegistry); disableOwnershipThief = config.main.disableOwnershipThief;
MinecraftForge.EVENT_BUS.addListener(ClientProxy::onDrawSelection); unloadDistance2 = config.client.unloadDistance * config.client.unloadDistance;
MinecraftForge.EVENT_BUS.addListener(KeyboardCamera::updateCamera); loadDistance2 = config.client.loadDistance * config.client.loadDistance;
MinecraftForge.EVENT_BUS.addListener(KeyboardCamera::gameTick); this.maxResX = config.main.maxResolutionX;
ClientConfig.init(); this.maxResY = config.main.maxResolutionY;
} this.miniservPort = config.main.miniservPort;
this.miniservQuota = config.main.miniservQuota * 1024L;
CommonConfig.init(); 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();
//Criterions //Criterions
criterionPadBreak = new Criterion("pad_break"); criterionPadBreak = new Criterion("pad_break");
criterionUpgradeScreen = new Criterion("upgrade_screen"); criterionUpgradeScreen = new Criterion("upgrade_screen");
@ -129,19 +149,23 @@ public class WebDisplays {
criterionKeyboardCat = new Criterion("keyboard_cat"); criterionKeyboardCat = new Criterion("keyboard_cat");
registerTrigger(criterionPadBreak, criterionUpgradeScreen, criterionLinkPeripheral, criterionKeyboardCat); registerTrigger(criterionPadBreak, criterionUpgradeScreen, criterionLinkPeripheral, criterionKeyboardCat);
//Read configuration
padResY = config.main.padHeight;
padResX = padResY * PAD_RATIO;
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
WDNetworkRegistry.init(); bus.addListener(Messages::registryNetworkPackets);
SOUNDS.register(bus); BlockInit.init(bus);
onRegisterSounds(); ItemInit.init(bus);
WDTabs.init(bus); ItemInit.registerUpgrade();
BlockRegistry.init(bus); ItemInit.registerComponents();
ItemRegistry.init(bus); TileInit.init(bus);
TileRegistry.init(bus);
PROXY.preInit(); PROXY.preInit();
MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(this);
//Other things //Other things
PROXY.init(); PROXY.init();
@ -158,10 +182,6 @@ public class WebDisplays {
t.printStackTrace(); t.printStackTrace();
} }
} */ } */
if (!FMLEnvironment.production) {
ScreenControlRegistry.init();
}
} }
@SubscribeEvent @SubscribeEvent
@ -171,24 +191,23 @@ public class WebDisplays {
} }
} }
public void onRegisterSounds() { @SubscribeEvent
soundTyping = registerSound("keyboard_type"); public void onRegisterSounds(RegistryEvent.Register<SoundEvent> ev) {
soundUpgradeAdd = registerSound("upgrade_add"); soundTyping = registerSound(ev, "keyboardType");
soundUpgradeDel = registerSound("upgrade_del"); soundUpgradeAdd = registerSound(ev, "upgradeAdd");
soundScreenCfg = registerSound("screencfg_open"); soundUpgradeDel = registerSound(ev, "upgradeDel");
soundServer = registerSound("server"); soundScreenCfg = registerSound(ev, "screencfgOpen");
soundIronic = registerSound("ironic"); soundServer = registerSound(ev, "server");
soundIronic = registerSound(ev, "ironic");
} }
ArrayList<ResourceKey<Level>> serverStartedDimensions = new ArrayList<>();
@SubscribeEvent @SubscribeEvent
public void onWorldLoad(LevelEvent.Load ev) { public void onWorldLoad(WorldEvent.Load ev) {
if (ev.getLevel() instanceof Level level) { if (ev.getWorld() instanceof Level level) {
if (ev.getLevel().isClientSide() || level.dimension() != Level.OVERWORLD) if (ev.getWorld().isClientSide() || level.dimension() != Level.OVERWORLD)
return; return;
File worldDir = Objects.requireNonNull(ev.getLevel().getServer()).getServerDirectory(); File worldDir = Objects.requireNonNull(ev.getWorld().getServer()).getServerDirectory();
File f = new File(worldDir, "wd_next.txt"); File f = new File(worldDir, "wd_next.txt");
if (f.exists()) { if (f.exists()) {
@ -212,34 +231,29 @@ public class WebDisplays {
if (miniservPort != 0) { if (miniservPort != 0) {
Server sv = Server.getInstance(); Server sv = Server.getInstance();
sv.setPort(miniservPort);
if(!serverStartedDimensions.contains(level.dimension())) { sv.setDirectory(new File(worldDir, "wd_filehost"));
sv.setPort(miniservPort); sv.start();
sv.setDirectory(new File(worldDir, "wd_filehost"));
sv.start();
serverStartedDimensions.add(level.dimension());
}
} }
} }
} }
@SubscribeEvent @SubscribeEvent
public void onWorldLeave(LevelEvent.Unload ev) throws IOException { public void onWorldLeave(WorldEvent.Unload ev) throws IOException {
if(ev.getLevel() instanceof Level level) { if(ev.getWorld() instanceof Level level) {
if (ev.getLevel().isClientSide() || level.dimension() != Level.OVERWORLD) if (ev.getWorld().isClientSide() || level.dimension() != Level.OVERWORLD)
return; return;
Server sw = Server.getInstance(); Server sw = Server.getInstance();
sw.stopServer(); sw.stopServer();
serverStartedDimensions.remove(level.dimension());
} }
} }
@SubscribeEvent @SubscribeEvent
public void onWorldSave(LevelEvent.Save ev) { public void onWorldSave(WorldEvent.Save ev) {
if(ev.getLevel() instanceof Level level) { if(ev.getWorld() instanceof Level level) {
if (ev.getLevel().isClientSide() || level.dimension() != Level.OVERWORLD) if (ev.getWorld().isClientSide() || level.dimension() != Level.OVERWORLD)
return; return;
File f = new File(Objects.requireNonNull(ev.getLevel().getServer()).getServerDirectory(), "wd_next.txt"); File f = new File(Objects.requireNonNull(ev.getWorld().getServer()).getServerDirectory(), "wd_next.txt");
try { try {
BufferedWriter bw = new BufferedWriter(new FileWriter(f)); BufferedWriter bw = new BufferedWriter(new FileWriter(f));
@ -253,10 +267,10 @@ public class WebDisplays {
@SubscribeEvent @SubscribeEvent
public void onToss(ItemTossEvent ev) { public void onToss(ItemTossEvent ev) {
if(!ev.getEntity().level().isClientSide) { if(!ev.getEntityItem().getLevel().isClientSide) {
ItemStack is = ev.getEntity().getItem(); ItemStack is = ev.getEntityItem().getItem();
if(is.getItem() == ItemRegistry.MINEPAD.get()) { if(is.getItem() == ItemInit.itemMinePad.get()) {
CompoundTag tag = is.getTag(); CompoundTag tag = is.getTag();
if(tag == null) { if(tag == null) {
@ -274,12 +288,12 @@ public class WebDisplays {
@SubscribeEvent @SubscribeEvent
public void onPlayerCraft(PlayerEvent.ItemCraftedEvent ev) { public void onPlayerCraft(PlayerEvent.ItemCraftedEvent ev) {
if(CommonConfig.hardRecipes && ItemRegistry.isCompCraftItem(ev.getCrafting().getItem()) && (CraftComponent.EXTCARD.makeItemStack().is(ev.getCrafting().getItem()))) { if(doHardRecipe && ev.getCrafting().getItem() == ItemInit.itemCraftComp.get() && (CraftComponent.EXTENSION_CARD.makeItemStack().is(ev.getCrafting().getItem()))) {
if((ev.getEntity() instanceof ServerPlayer && !hasPlayerAdvancement((ServerPlayer) ev.getEntity(), ADV_PAD_BREAK)) || PROXY.hasClientPlayerAdvancement(ADV_PAD_BREAK) != HasAdvancement.YES) { if((ev.getPlayer() instanceof ServerPlayer && !hasPlayerAdvancement((ServerPlayer) ev.getPlayer(), ADV_PAD_BREAK)) || PROXY.hasClientPlayerAdvancement(ADV_PAD_BREAK) != HasAdvancement.YES) {
ev.getCrafting().setDamageValue(CraftComponent.BADEXTCARD.ordinal()); ev.getCrafting().setDamageValue(CraftComponent.BAD_EXTENSION_CARD.ordinal());
if(!ev.getEntity().level().isClientSide) if(!ev.getPlayer().getLevel().isClientSide)
ev.getEntity().level().playSound(null, ev.getEntity().getX(), ev.getEntity().getY(), ev.getEntity().getZ(), SoundEvents.ITEM_BREAK, SoundSource.MASTER, 1.0f, 1.0f); ev.getPlayer().getLevel().playSound(null, ev.getPlayer().getX(), ev.getPlayer().getY(), ev.getPlayer().getZ(), SoundEvents.ITEM_BREAK, SoundSource.MASTER, 1.0f, 1.0f);
} }
} }
} }
@ -291,35 +305,35 @@ public class WebDisplays {
@SubscribeEvent @SubscribeEvent
public void onLogIn(PlayerEvent.PlayerLoggedInEvent ev) { public void onLogIn(PlayerEvent.PlayerLoggedInEvent ev) {
if (!CommonConfig.joinMessage) { if(!ev.getPlayer().getLevel().isClientSide && ev.getPlayer() instanceof ServerPlayer) {
return; IWDDCapability cap =
} ev.getPlayer().getCapability(WDDCapability.Provider.cap, null).orElseThrow(RuntimeException::new);
if(!ev.getEntity().level().isClientSide && ev.getEntity() instanceof ServerPlayer) { if(cap == null)
IWDDCapability cap = ev.getEntity().getCapability(WDDCapability.Provider.cap, null).orElseThrow(RuntimeException::new); Log.warning("Player %s (%s) has null IWDDCapability!", ev.getPlayer().getName(), ev.getPlayer().getGameProfile().getId().toString());
else if(cap.isFirstRun()) {
if(cap.isFirstRun()) { Util.toast(ev.getPlayer(), ChatFormatting.LIGHT_PURPLE, "welcome1");
Util.toast(ev.getEntity(), ChatFormatting.LIGHT_PURPLE, "welcome1"); Util.toast(ev.getPlayer(), ChatFormatting.LIGHT_PURPLE, "welcome2");
Util.toast(ev.getEntity(), ChatFormatting.LIGHT_PURPLE, "welcome2"); Util.toast(ev.getPlayer(), ChatFormatting.LIGHT_PURPLE, "welcome3");
Util.toast(ev.getEntity(), ChatFormatting.LIGHT_PURPLE, "welcome3");
cap.clearFirstRun(); cap.clearFirstRun();
} }
PacketDistributor.PacketTarget packetDistrutor = PacketDistributor.PLAYER.with( PacketDistributor.PacketTarget packetDistrutor = PacketDistributor.PLAYER
() -> (ServerPlayer) ev.getEntity() .with(
); () ->
(ServerPlayer) ev.getPlayer());
S2CMessageServerInfo message = new S2CMessageServerInfo(miniservPort); CMessageServerInfo message = new CMessageServerInfo(miniservPort);
WDNetworkRegistry.INSTANCE.send(packetDistrutor, message); Messages.INSTANCE.send(packetDistrutor, message);
} }
} }
@SubscribeEvent @SubscribeEvent
public void onLogOut(PlayerEvent.PlayerLoggedOutEvent ev) { public void onLogOut(PlayerEvent.PlayerLoggedOutEvent ev) {
if(!ev.getEntity().level().isClientSide) if(!ev.getPlayer().getLevel().isClientSide)
Server.getInstance().getClientManager().revokeClientKey(ev.getEntity().getGameProfile().getId()); Server.getInstance().getClientManager().revokeClientKey(ev.getPlayer().getGameProfile().getId());
} }
@SubscribeEvent @SubscribeEvent
@ -331,7 +345,7 @@ public class WebDisplays {
@SubscribeEvent @SubscribeEvent
public void onPlayerClone(PlayerEvent.Clone ev) { public void onPlayerClone(PlayerEvent.Clone ev) {
IWDDCapability src = ev.getOriginal().getCapability(WDDCapability.Provider.cap, null).orElse(new WDDCapability.Factory().call()); IWDDCapability src = ev.getOriginal().getCapability(WDDCapability.Provider.cap, null).orElse(new WDDCapability.Factory().call());
IWDDCapability dst = ev.getEntity().getCapability(WDDCapability.Provider.cap, null).orElse(new WDDCapability.Factory().call()); IWDDCapability dst = ev.getPlayer().getCapability(WDDCapability.Provider.cap, null).orElse(new WDDCapability.Factory().call());
if(src == null) { if(src == null) {
Log.error("src is null"); Log.error("src is null");
@ -348,7 +362,7 @@ public class WebDisplays {
@SubscribeEvent @SubscribeEvent
public void onServerChat(ServerChatEvent ev) { public void onServerChat(ServerChatEvent ev) {
String msg = ev.getMessage().getString().replaceAll("\\s+", " ").toLowerCase(); String msg = ev.getMessage().trim().replaceAll("\\s+", " ").toLowerCase();
StringBuilder sb = new StringBuilder(msg.length()); StringBuilder sb = new StringBuilder(msg.length());
for(int i = 0; i < msg.length(); i++) { for(int i = 0; i < msg.length(); i++) {
char chr = msg.charAt(i); char chr = msg.charAt(i);
@ -359,7 +373,7 @@ public class WebDisplays {
if(sb.toString().equals("ironic he could save others from death but not himself")) { if(sb.toString().equals("ironic he could save others from death but not himself")) {
Player ply = ev.getPlayer(); Player ply = ev.getPlayer();
ply.level().playSound(null, ply.getX(), ply.getY(), ply.getZ(), soundIronic, SoundSource.PLAYERS, 1.0f, 1.0f); ply.getLevel().playSound(null, ply.getX(), ply.getY(), ply.getZ(), soundIronic, SoundSource.PLAYERS, 1.0f, 1.0f);
} }
} }
@ -382,13 +396,12 @@ public class WebDisplays {
return new WebDisplays().lastPadId++; return new WebDisplays().lastPadId++;
} }
public static DeferredRegister<SoundEvent> SOUNDS = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, "webdisplays"); private static SoundEvent registerSound(RegistryEvent.Register<SoundEvent> ev, String resName) {
private static SoundEvent registerSound(String resName) {
ResourceLocation resLoc = new ResourceLocation("webdisplays", resName); ResourceLocation resLoc = new ResourceLocation("webdisplays", resName);
SoundEvent ret = SoundEvent.createVariableRangeEvent(resLoc); SoundEvent ret = new SoundEvent(resLoc);
ret.setRegistryName(resLoc);
SOUNDS.register(resName, () -> ret); ev.getRegistry().register(ret);
return ret; return ret;
} }
@ -408,9 +421,7 @@ public class WebDisplays {
public static boolean isSiteBlacklisted(String url) { public static boolean isSiteBlacklisted(String url) {
try { try {
URL url2 = new URL(Util.addProtocol(url)); URL url2 = new URL(Util.addProtocol(url));
for (String str : CommonConfig.Browser.blacklist) return new ModConfig.Main().blacklist.stream().anyMatch(str -> str.equalsIgnoreCase(url2.getHost()));
if (str.equalsIgnoreCase(url2.getHost())) return true;
return false;
} catch(MalformedURLException ex) { } catch(MalformedURLException ex) {
return false; return false;
} }
@ -419,5 +430,6 @@ public class WebDisplays {
public static String applyBlacklist(String url) { public static String applyBlacklist(String url) {
return isSiteBlacklisted(url) ? BLACKLIST_URL : url; return isSiteBlacklisted(url) ? BLACKLIST_URL : url;
} }
} }

View File

@ -0,0 +1,279 @@
/*
* 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());
}
}

View File

@ -0,0 +1,208 @@
/*
* 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;
}
}

View File

@ -0,0 +1,283 @@
/*
* 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());
}
}

View File

@ -0,0 +1,225 @@
/*
* 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());
}
}

View File

@ -0,0 +1,225 @@
/*
* 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());
}
}

View File

@ -12,158 +12,196 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.BaseEntityBlock;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition; 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.BooleanProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.montoyo.wd.WebDisplays; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.config.CommonConfig; import net.montoyo.wd.config.ModConfig;
import net.montoyo.wd.core.DefaultUpgrade; import net.montoyo.wd.core.DefaultUpgrade;
import net.montoyo.wd.core.IUpgrade; import net.montoyo.wd.core.IUpgrade;
import net.montoyo.wd.core.ScreenRights; import net.montoyo.wd.core.ScreenRights;
import net.montoyo.wd.data.SetURLData; import net.montoyo.wd.data.SetURLData;
import net.montoyo.wd.entity.ScreenData; import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.entity.ScreenBlockEntity; import net.montoyo.wd.init.BlockInit;
import net.montoyo.wd.item.ItemLaserPointer; import net.montoyo.wd.item.WDItem;
import net.montoyo.wd.utilities.*; 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 org.jetbrains.annotations.NotNull;
public class ScreenBlock extends BaseEntityBlock { import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class BlockScreen extends BaseEntityBlock {
public static final BooleanProperty hasTE = BooleanProperty.create("haste"); public static final BooleanProperty hasTE = BooleanProperty.create("haste");
public static final BooleanProperty emitting = BooleanProperty.create("emitting"); public static final BooleanProperty emitting = BooleanProperty.create("emitting");
private static final Property<?>[] properties = new Property<?>[]{hasTE, emitting}; private static final Property<?>[] properties = new Property<?>[] { hasTE, emitting };
public static final DirectionProperty FACING = BlockStateProperties.FACING;
public ScreenBlock(Properties properties) { 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) {
super(properties.strength(1.5f, 10.f)); super(properties.strength(1.5f, 10.f));
// setCreativeTab(WebDisplays.CREATIVE_TAB);
// setName("screen");
this.registerDefaultState(this.defaultBlockState().setValue(hasTE, false).setValue(emitting, false)); this.registerDefaultState(this.defaultBlockState().setValue(hasTE, false).setValue(emitting, false));
} }
@Override @Override
public void onRemove(BlockState p_60515_, Level p_60516_, BlockPos p_60517_, BlockState p_60518_, boolean p_60519_) { protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
// TODO: make this also get called on client? builder.add(properties).add(FACING);
if (p_60518_.getBlock() == p_60515_.getBlock()) return; }
for (BlockSide value : BlockSide.values()) { @Override
Vector3i vec = new Vector3i(p_60517_.getX(), p_60517_.getY(), p_60517_.getZ()); public RenderShape getRenderShape(BlockState state) {
Multiblock.findOrigin(p_60516_, vec, value, null); return RenderShape.MODEL;
BlockPos bp = new BlockPos(vec.x, vec.y, vec.z); }
if (!bp.equals(p_60517_)) {
p_60516_.removeBlockEntity(bp); public static boolean isntScreenBlock(Level world, Vector3i pos) {
p_60516_.setBlock( return world.getBlockState(pos.toBlock()).getBlock() != BlockInit.blockScreen.get();
bp, p_60516_.getBlockState(bp).setValue(hasTE, false), }
11
);
} @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);
} }
super.onRemove(p_60515_, p_60516_, p_60517_, p_60518_, p_60519_); 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;
} }
@Override @Override
public InteractionResult use(BlockState state, Level world, BlockPos position, Player player, InteractionHand hand, BlockHitResult hit) { public InteractionResult use(BlockState state, Level world, BlockPos position, Player player, InteractionHand hand, BlockHitResult hit) {
ItemStack heldItem = player.getItemInHand(hand); ItemStack heldItem = player.getItemInHand(hand);
boolean isUpgrade = false; if(heldItem.isEmpty())
if (heldItem.isEmpty())
heldItem = null; //Easier to work with heldItem = null; //Easier to work with
else if (!(isUpgrade = heldItem.getItem() instanceof IUpgrade)) else if(!(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; return InteractionResult.FAIL;
if (world.isClientSide) if(world.isClientSide)
return InteractionResult.FAIL; return InteractionResult.FAIL;
boolean sneaking = player.isShiftKeyDown(); boolean sneaking = player.isShiftKeyDown();
Vector3i pos = new Vector3i(position); Vector3i pos = new Vector3i(position);
BlockSide side = BlockSide.values()[hit.getDirection().ordinal()]; BlockSide side = BlockSide.values()[hit.getDirection().ordinal()];
Multiblock.findOrigin(world, pos, side, null); Multiblock.findOrigin(world, pos, side, null);
ScreenBlockEntity te = (ScreenBlockEntity) world.getBlockEntity(pos.toBlock()); TileEntityScreen te = (TileEntityScreen) world.getBlockEntity(pos.toBlock());
if (te != null && te.getScreen(side) != null) { if(te != null && te.getScreen(side) != null) {
ScreenData scr = te.getScreen(side); TileEntityScreen.Screen scr = te.getScreen(side);
if (sneaking) { //Right Click if(sneaking) { //Set URL
if ((scr.rightsFor(player) & ScreenRights.CHANGE_URL) == 0) if((scr.rightsFor(player) & ScreenRights.CHANGE_URL) == 0)
Util.toast(player, "restrictions"); Util.toast(player, "restrictions");
else else
(new SetURLData(pos, scr.side, scr.url)).sendTo((ServerPlayer) player); (new SetURLData(pos, scr.side, scr.url)).sendTo((ServerPlayer) player);
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} else if (heldItem != null) { } else if(heldItem != null && !te.hasUpgrade(side, heldItem)) { //Add upgrade
if (!te.hasUpgrade(side, heldItem)) { if((scr.rightsFor(player) & ScreenRights.MANAGE_UPGRADES) == 0) {
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;
}
} else {
if ((scr.rightsFor(player) & ScreenRights.INTERACT) == 0) {
Util.toast(player, "restrictions"); Util.toast(player, "restrictions");
return InteractionResult.CONSUME; return InteractionResult.SUCCESS;
}
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) {
Util.toast(player, "restrictions");
return InteractionResult.SUCCESS;
} }
Vector2i tmp = new Vector2i(); Vector2i tmp = new Vector2i();
if(hit2pixels(side, hit.getBlockPos(), pos, scr, (float) hit.getLocation().x, (float) hit.getLocation().y, (float) hit.getLocation().z, tmp))
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); te.click(side, tmp);
return InteractionResult.CONSUME;
return InteractionResult.SUCCESS;
} }
} 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); 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"); Util.toast(player, "tooSmall");
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
if (size.x > CommonConfig.Screen.maxScreenSizeX || size.y > CommonConfig.Screen.maxScreenSizeY) { if(size.x > WebDisplays.INSTANCE.maxScreenX || size.y > WebDisplays.INSTANCE.maxScreenY) {
Util.toast(player, "tooBig", CommonConfig.Screen.maxScreenSizeX, CommonConfig.Screen.maxScreenSizeY); Util.toast(player, "tooBig", WebDisplays.INSTANCE.maxScreenX, WebDisplays.INSTANCE.maxScreenY);
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
Vector3i err = Multiblock.check(world, pos, size, side); Vector3i err = Multiblock.check(world, pos, size, side);
if (err != null) { if(err != null) {
Util.toast(player, "invalid", err.toString()); Util.toast(player, "invalid", err.toString());
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
@ -171,58 +209,60 @@ public class ScreenBlock extends BaseEntityBlock {
boolean created = false; 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); 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(); BlockPos bp = pos.toBlock();
world.setBlockAndUpdate(bp, world.getBlockState(bp).setValue(hasTE, true)); world.setBlockAndUpdate(bp, world.getBlockState(bp).setValue(hasTE, true));
te = (ScreenBlockEntity) world.getBlockEntity(bp); te = (TileEntityScreen) world.getBlockEntity(bp);
created = true; created = true;
} }
te.addScreen(side, size, null, player, true); te.addScreen(side, size, null, player, !created);
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
@Override @Override
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos source, public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos source, boolean isMoving) {
boolean isMoving) { if(block != this && !world.isClientSide && !state.getValue(emitting)) {
if (block != this && !world.isClientSide && !state.getValue(emitting)) { for(BlockSide side: BlockSide.values()) {
for (BlockSide side : BlockSide.values()) {
Vector3i vec = new Vector3i(pos); Vector3i vec = new Vector3i(pos);
Multiblock.findOrigin(world, vec, side, null); Multiblock.findOrigin(world, vec, side, null);
ScreenBlockEntity tes = (ScreenBlockEntity) world.getBlockEntity(vec.toBlock()); TileEntityScreen tes = (TileEntityScreen) world.getBlockEntity(vec.toBlock());
if (tes != null && tes.hasUpgrade(side, DefaultUpgrade.REDINPUT)) { if(tes != null && tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_INPUT)) {
Direction facing = Direction.from2DDataValue(side.reverse().ordinal()); //Opposite face Direction facing = Direction.from2DDataValue(side.reverse().ordinal()); //Opposite face
vec.sub(pos.getX(), pos.getY(), pos.getZ()).neg(); 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, ScreenData scr, float hitX, float hitY, float hitZ, Vector2i dst) { public static boolean hit2pixels(BlockSide side, BlockPos bpos, Vector3i pos, TileEntityScreen.Screen scr, float hitX, float hitY, float hitZ, Vector2i dst) {
if(side.right.x < 0) if(side.right.x < 0)
hitX -= 1.f; hitX -= 1.f;
if(side.right.z < 0 || side == BlockSide.TOP || side == BlockSide.BOTTOM) if(side.right.z < 0 || side == BlockSide.TOP || side == BlockSide.BOTTOM)
hitZ -= 1.f; hitZ -= 1.f;
Vector3f rel = new Vector3f(hitX, hitY, hitZ); Vector3f rel = new Vector3f(pos.toBlock().getX(), pos.toBlock().getY(), pos.toBlock().getZ());
rel.sub(hitX, hitY, hitZ);
// this dot is acting as a "get distance from plane" where the plane is the edge of the screen float cx = Math.abs(rel.dot(side.right.toFloat()) - 2.f / 16.f);
float cx = rel.dot(side.right.toFloat()) - 2.f / 16.f; float cy = Math.abs(rel.dot(side.up.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 sw = ((float) scr.size.x) - 4.f / 16.f;
float sh = ((float) scr.size.y) - 4.f / 16.f; float sh = ((float) scr.size.y) - 4.f / 16.f;
cx /= sw; cx /= sw;
cy /= sh; cy /= sh;
if (cx >= 0.f && cx <= 1.0 && cy >= 0.f && cy <= 1.f) { cx = cx - 0.05f;
if (side != BlockSide.BOTTOM) cy = cy - 0.05f;
if(cx >= 0 && cx <= 1 && cy >= 0 && cy <= 1) {
if(side != BlockSide.BOTTOM)
cy = 1.f - cy; cy = 1.f - cy;
switch (scr.rotation) { switch(scr.rotation) {
case ROT_90: case ROT_90:
cy = 1.0f - cy; cy = 1.0f - cy;
break; break;
@ -235,12 +275,15 @@ public class ScreenBlock extends BaseEntityBlock {
case ROT_270: case ROT_270:
cx = 1.0f - cx; cx = 1.0f - cx;
break; break;
default:
break;
} }
cx *= (float) scr.resolution.x; cx *= (float) scr.resolution.x;
cy *= (float) scr.resolution.y; cy *= (float) scr.resolution.y;
if (scr.rotation.isVertical) { if(scr.rotation.isVertical) {
dst.x = (int) cy; dst.x = (int) cy;
dst.y = (int) cx; dst.y = (int) cx;
} else { } else {
@ -254,41 +297,49 @@ public class ScreenBlock extends BaseEntityBlock {
return false; 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 *************************************************/ /************************************************* DESTRUCTION HANDLING *************************************************/
private void onDestroy(Level world, BlockPos pos, Player ply) { private void onDestroy(Level world, BlockPos pos, Player ply) {
if (!world.isClientSide) { if(!world.isClientSide) {
Vector3i bp = new Vector3i(pos); Vector3i bp = new Vector3i(pos);
Multiblock.BlockOverride override = new Multiblock.BlockOverride(bp, Multiblock.OverrideAction.SIMULATE); 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); destroySide(world, bp.clone(), bs, override, ply);
} }
} }
private void destroySide(Level world, Vector3i pos, BlockSide side, Multiblock.BlockOverride override, Player private void destroySide(Level world, Vector3i pos, BlockSide side, Multiblock.BlockOverride override, Player source) {
source) {
Multiblock.findOrigin(world, pos, side, override); Multiblock.findOrigin(world, pos, side, override);
BlockPos bp = pos.toBlock(); BlockPos bp = pos.toBlock();
BlockEntity te = world.getBlockEntity(bp); BlockEntity te = world.getBlockEntity(bp);
if (te instanceof ScreenBlockEntity) { if(te != null && te instanceof TileEntityScreen) {
((ScreenBlockEntity) te).onDestroy(source); ((TileEntityScreen) te).onDestroy(source);
world.setBlock(bp, world.getBlockState(bp).setValue(hasTE, false), Block.UPDATE_ALL_IMMEDIATE); //Destroy tile entity. world.setBlock(bp, world.getBlockState(bp).setValue(hasTE, false), Block.UPDATE_ALL_IMMEDIATE); //Destroy tile entity.
} }
} }
@Override @Override
public boolean onDestroyedByPlayer(BlockState state, Level level, BlockPos pos, Player player, public boolean onDestroyedByPlayer(BlockState state, Level level, BlockPos pos, Player player, boolean willHarvest, FluidState fluid) {
boolean willHarvest, FluidState fluid) {
onDestroy(level, pos, player); onDestroy(level, pos, player);
return super.onDestroyedByPlayer(state, level, pos, player, willHarvest, fluid); return super.onDestroyedByPlayer(state, level, pos, player, willHarvest, fluid);
} }
@Override @Override
public void setPlacedBy(Level world, @NotNull BlockPos pos, @NotNull BlockState public void setPlacedBy(Level world, @NotNull BlockPos pos, @NotNull BlockState state, @org.jetbrains.annotations.Nullable LivingEntity whoDidThisShit, @NotNull ItemStack stack) {
state, @org.jetbrains.annotations.Nullable LivingEntity whoDidThisShit, @NotNull ItemStack stack) { if(world.isClientSide)
if (world.isClientSide)
return; return;
Multiblock.BlockOverride override = new Multiblock.BlockOverride(new Vector3i(pos), Multiblock.OverrideAction.IGNORE); Multiblock.BlockOverride override = new Multiblock.BlockOverride(new Vector3i(pos), Multiblock.OverrideAction.IGNORE);
@ -301,16 +352,14 @@ public class ScreenBlock extends BaseEntityBlock {
neighbors[4] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() + 1); neighbors[4] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() + 1);
neighbors[5] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() - 1); neighbors[5] = new Vector3i(pos.getX(), pos.getY(), pos.getZ() - 1);
for (Vector3i neighbor : neighbors) { for(Vector3i neighbor: neighbors) {
if (world.getBlockState(neighbor.toBlock()).getBlock() instanceof ScreenBlock) { if(world.getBlockState(neighbor.toBlock()).getBlock() instanceof BlockScreen) {
for (BlockSide bs : BlockSide.values()) for(BlockSide bs: BlockSide.values())
destroySide(world, neighbor.clone(), bs, override, (whoDidThisShit instanceof Player) ? ((Player) whoDidThisShit) : null); 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 @Override
public @NotNull PushReaction getPistonPushReaction(BlockState state) { public @NotNull PushReaction getPistonPushReaction(BlockState state) {
return PushReaction.IGNORE; return PushReaction.IGNORE;
@ -326,18 +375,23 @@ public class ScreenBlock extends BaseEntityBlock {
return state.getValue(emitting); return state.getValue(emitting);
} }
@Override // @Override //TODO: Add this
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { // protected BlockItem createItemBlock() {
return state.getValue(hasTE) ? new ScreenBlockEntity(pos, state) : null; // 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 RenderShape getRenderShape(BlockState state) {
return RenderShape.MODEL;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(properties);
}
} }

View File

@ -0,0 +1,226 @@
/*
* 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());
}
}

View File

@ -1,142 +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.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);
}
}

View File

@ -1,116 +0,0 @@
/*
* 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();
}
}

View File

@ -1,141 +0,0 @@
/*
* 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());
}
}

View File

@ -0,0 +1,35 @@
/*
* 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;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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;
}
}

View File

@ -1,22 +0,0 @@
/*
* 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;
}
}

View File

@ -1,54 +0,0 @@
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

View File

@ -1,370 +1,371 @@
///* /*
// * Copyright (C) 2018 BARBOTIN Nicolas * Copyright (C) 2018 BARBOTIN Nicolas
// */ */
//
//package net.montoyo.wd.client; package net.montoyo.wd.client;
//
//import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
//import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
//import net.minecraft.core.Direction; import net.minecraft.core.Direction;
//import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
//import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
//import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
//import net.montoyo.wd.block.BlockScreen; import net.montoyo.mcef.api.IBrowser;
//import net.montoyo.wd.core.DefaultUpgrade; import net.montoyo.mcef.api.IJSQueryCallback;
//import net.montoyo.wd.core.IScreenQueryHandler; import net.montoyo.wd.WebDisplays;
//import net.montoyo.wd.core.IUpgrade; import net.montoyo.wd.block.BlockScreen;
//import net.montoyo.wd.core.JSServerRequest; import net.montoyo.wd.core.DefaultUpgrade;
//import net.montoyo.wd.entity.TileEntityScreen; import net.montoyo.wd.core.IScreenQueryHandler;
//import net.montoyo.wd.net.WDNetworkRegistry; import net.montoyo.wd.core.IUpgrade;
//import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl; import net.montoyo.wd.core.JSServerRequest;
//import net.montoyo.wd.utilities.*; import net.montoyo.wd.entity.TileEntityScreen;
// import net.montoyo.wd.net.Messages;
//import java.util.*; import net.montoyo.wd.net.server.SMessageScreenCtrl;
// import net.montoyo.wd.utilities.*;
//@OnlyIn(Dist.CLIENT)
//public final class JSQueryDispatcher { import java.util.*;
//
// private static final class QueryData { @OnlyIn(Dist.CLIENT)
// public final class JSQueryDispatcher {
// private final IBrowser browser;
// private final String query; private static final class QueryData {
// private final String args;
// private final IJSQueryCallback callback; private final IBrowser browser;
// private final String query;
// private QueryData(IBrowser b, String q, String a, IJSQueryCallback cb) { private final String args;
// browser = b; private final IJSQueryCallback callback;
// query = q;
// args = a; private QueryData(IBrowser b, String q, String a, IJSQueryCallback cb) {
// callback = cb; browser = b;
// } query = q;
// args = a;
// } callback = cb;
// }
// public static final class ServerQuery {
// }
// private static int lastId = 0;
// public static final class ServerQuery {
// private final TileEntityScreen tes;
// private final BlockSide side; private static int lastId = 0;
// private final IJSQueryCallback callback;
// private final int id; private final TileEntityScreen tes;
// private final BlockSide side;
// private ServerQuery(TileEntityScreen t, BlockSide s, IJSQueryCallback cb) { private final IJSQueryCallback callback;
// tes = t; private final int id;
// side = s;
// callback = cb; private ServerQuery(TileEntityScreen t, BlockSide s, IJSQueryCallback cb) {
// id = lastId++; tes = t;
// } side = s;
// callback = cb;
// public TileEntityScreen getTileEntity() { id = lastId++;
// return tes; }
// }
// public TileEntityScreen getTileEntity() {
// public BlockSide getSide() { return tes;
// return side; }
// }
// public BlockSide getSide() {
// public TileEntityScreen.Screen getScreen() { return side;
// return tes.getScreen(side); }
// }
// public TileEntityScreen.Screen getScreen() {
// public void success(String resp) { return tes.getScreen(side);
// callback.success(resp); }
// }
// public void success(String resp) {
// public void error(int errId, String errStr) { callback.success(resp);
// callback.failure(errId, errStr); }
// }
// 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 ClientProxy proxy;
// private final ArrayList<ServerQuery> serverQueries = new ArrayList<>(); private final ArrayDeque<QueryData> queue = new ArrayDeque<>();
// private final Minecraft mc = Minecraft.getInstance(); private final ClientProxy.ScreenSidePair lookupResult = new ClientProxy.ScreenSidePair();
// private final HashMap<String, IScreenQueryHandler> handlers = new HashMap<>();
// public JSQueryDispatcher(ClientProxy proxy) { private final ArrayList<ServerQuery> serverQueries = new ArrayList<>();
// this.proxy = proxy; private final Minecraft mc = Minecraft.getInstance();
// registerDefaults();
// } public JSQueryDispatcher(ClientProxy proxy) {
// this.proxy = proxy;
// public void enqueueQuery(IBrowser b, String q, String a, IJSQueryCallback cb) { registerDefaults();
// synchronized(queue) { }
// queue.offer(new QueryData(b, q, a, cb));
// } 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) { public void handleQueries() {
// next = queue.poll(); while(true) {
// } QueryData next;
// synchronized(queue) {
// if(next == null) next = queue.poll();
// break; }
//
// if(proxy.findScreenFromBrowser(next.browser, lookupResult)) { if(next == null)
// Object[] args = (next.args == null) ? new Object[0] : parseArgs(next.args); break;
//
// if(args == null) if(proxy.findScreenFromBrowser(next.browser, lookupResult)) {
// next.callback.failure(400, "Malformed request parameters"); Object[] args = (next.args == null) ? new Object[0] : parseArgs(next.args);
// else {
// try { if(args == null)
// handlers.get(next.query).handleQuery(next.callback, lookupResult.tes, lookupResult.side, args); next.callback.failure(400, "Malformed request parameters");
// } catch(Throwable t) { else {
// Log.warningEx("Could not execute JS query %s(%s)", t, next.query, (next.args == null) ? "" : next.args); try {
// next.callback.failure(500, "Internal error"); 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);
// } else next.callback.failure(500, "Internal error");
// next.callback.failure(403, "A screen is required"); }
// } }
// } } else
// next.callback.failure(403, "A screen is required");
// public boolean canHandleQuery(String q) { }
// return handlers.containsKey(q); }
// }
// public boolean canHandleQuery(String q) {
// private static Object[] parseArgs(String args) { return handlers.containsKey(q);
// ArrayList<String> array = new ArrayList<>(); }
// int lastIdx = 0;
// boolean inString = false; private static Object[] parseArgs(String args) {
// boolean escape = false; ArrayList<String> array = new ArrayList<>();
// boolean hadString = false; int lastIdx = 0;
// boolean inString = false;
// for(int i = 0; i < args.length(); i++) { boolean escape = false;
// char chr = args.charAt(i); boolean hadString = false;
//
// if(inString) { for(int i = 0; i < args.length(); i++) {
// if(escape) char chr = args.charAt(i);
// escape = false;
// else { if(inString) {
// if(chr == '\"') if(escape)
// inString = false; escape = false;
// else if(chr == '\\') else {
// escape = true; if(chr == '\"')
// } inString = false;
// } else if(chr == '\"') { else if(chr == '\\')
// if(hadString) escape = true;
// return null; }
// } else if(chr == '\"') {
// inString = true; if(hadString)
// hadString = true; return null;
// } else if(chr == ',') {
// array.add(args.substring(lastIdx, i).trim()); inString = true;
// lastIdx = i + 1; hadString = true;
// hadString = false; } 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()); if(inString)
// Object[] ret = new Object[array.size()]; return null; //Non terminated string
//
// for(int i = 0; i < ret.length; i++) { array.add(args.substring(lastIdx).trim());
// String str = array.get(i); Object[] ret = new Object[array.size()];
// if(str.isEmpty())
// return null; //Nah... for(int i = 0; i < ret.length; i++) {
// String str = array.get(i);
// if(str.charAt(0) == '\"') //String if(str.isEmpty())
// ret[i] = str.substring(1, str.length() - 1); return null; //Nah...
// else {
// try { if(str.charAt(0) == '\"') //String
// ret[i] = Double.parseDouble(str); ret[i] = str.substring(1, str.length() - 1);
// } catch(NumberFormatException ex) { else {
// return null; try {
// } ret[i] = Double.parseDouble(str);
// } } catch(NumberFormatException ex) {
// } return null;
// }
// return ret; }
// } }
//
// public void register(String query, IScreenQueryHandler handler) { return ret;
// handlers.put(query.toLowerCase(), handler); }
// }
// public void register(String query, IScreenQueryHandler handler) {
// public ServerQuery fulfillQuery(int id) { handlers.put(query.toLowerCase(), handler);
// int toRemove = -1; }
//
// for(int i = 0; i < serverQueries.size(); i++) { public ServerQuery fulfillQuery(int id) {
// ServerQuery sq = serverQueries.get(i); int toRemove = -1;
//
// if(sq.id == id) { for(int i = 0; i < serverQueries.size(); i++) {
// toRemove = i; ServerQuery sq = serverQueries.get(i);
// break;
// } if(sq.id == id) {
// } toRemove = i;
// break;
// if(toRemove < 0) }
// return null; }
// else
// return serverQueries.remove(toRemove); if(toRemove < 0)
// } return null;
// else
// private void makeServerQuery(TileEntityScreen tes, BlockSide side, IJSQueryCallback cb, JSServerRequest type, Object ... data) { return serverQueries.remove(toRemove);
// ServerQuery ret = new ServerQuery(tes, side, cb); }
// serverQueries.add(ret);
// private void makeServerQuery(TileEntityScreen tes, BlockSide side, IJSQueryCallback cb, JSServerRequest type, Object ... data) {
// WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.jsRequest(tes, side, ret.id, type, data)); ServerQuery ret = new ServerQuery(tes, side, cb);
// } serverQueries.add(ret);
//
// private void registerDefaults() { Messages.INSTANCE.sendToServer(SMessageScreenCtrl.jsRequest(tes, side, ret.id, type, data));
// VideoType.registerQueries(this); }
//
// register("GetSize", (cb, tes, side, args) -> { private void registerDefaults() {
// Vector2i size = tes.getScreen(side).size; register("GetSize", (cb, tes, side, args) -> {
// cb.success("{\"x\":" + size.x + ",\"y\":" + size.y + "}"); 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)) { register("GetRedstoneAt", (cb, tes, side, args) -> {
// cb.failure(403, "Missing upgrade"); if(!tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_INPUT)) {
// return; cb.failure(403, "Missing upgrade");
// } return;
// }
// if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
// TileEntityScreen.Screen scr = tes.getScreen(side); if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
// int x = ((Double) args[0]).intValue(); TileEntityScreen.Screen scr = tes.getScreen(side);
// int y = ((Double) args[1]).intValue(); 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"); if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y)
// else { cb.failure(403, "Out of range");
// BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock(); else {
// int level = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting) ? 0 : tes.getLevel().getSignal(bpos, Direction.values()[side.reverse().ordinal()]); BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock();
// cb.success("{\"level\":" + level + "}"); 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"); } else
// }); cb.failure(400, "Wrong arguments");
// });
// register("GetRedstoneArray", (cb, tes, side, args) -> {
// if(tes.hasUpgrade(side, DefaultUpgrade.REDINPUT)) { register("GetRedstoneArray", (cb, tes, side, args) -> {
// final Direction facing = Direction.values()[side.reverse().ordinal()]; if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_INPUT)) {
// final StringJoiner resp = new StringJoiner(",", "{\"levels\":[", "]}"); 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)) tes.forEachScreenBlocks(side, bp -> {
// resp.add("0"); if(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting))
// else resp.add("0");
// resp.add("" + tes.getLevel().getSignal(bp, facing)); else
// }); resp.add("" + tes.getLevel().getSignal(bp, facing));
// });
// cb.success(resp.toString());
// } else cb.success(resp.toString());
// cb.failure(403, "Missing upgrade"); } else
// }); cb.failure(403, "Missing upgrade");
// });
// register("ClearRedstone", (cb, tes, side, args) -> {
// if(tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) { register("ClearRedstone", (cb, tes, side, args) -> {
// if(tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())) if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
// makeServerQuery(tes, side, cb, JSServerRequest.CLEAR_REDSTONE); if(tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId()))
// else makeServerQuery(tes, side, cb, JSServerRequest.CLEAR_REDSTONE);
// cb.success("{\"status\":\"notOwner\"}"); else
// } else cb.success("{\"status\":\"notOwner\"}");
// cb.failure(403, "Missing upgrade"); } else
// }); cb.failure(403, "Missing upgrade");
// });
// register("SetRedstoneAt", (cb, tes, side, args) -> {
// if(args.length != 3 || !Arrays.stream(args).allMatch((obj) -> obj instanceof Double)) { register("SetRedstoneAt", (cb, tes, side, args) -> {
// cb.failure(400, "Wrong arguments"); if(args.length != 3 || !Arrays.stream(args).allMatch((obj) -> obj instanceof Double)) {
// return; cb.failure(400, "Wrong arguments");
// } return;
// }
// if(!tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) {
// cb.failure(403, "Missing upgrade"); if(!tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
// return; cb.failure(403, "Missing upgrade");
// } return;
// }
// if(!tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())) {
// cb.success("{\"status\":\"notOwner\"}"); if(!tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())) {
// return; cb.success("{\"status\":\"notOwner\"}");
// } return;
// }
// int x = ((Double) args[0]).intValue();
// int y = ((Double) args[1]).intValue(); int x = ((Double) args[0]).intValue();
// boolean state = ((Double) args[2]) > 0.0; 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) { Vector2i size = tes.getScreen(side).size;
// cb.failure(403, "Out of range"); if(x < 0 || x >= size.x || y < 0 || y >= size.y) {
// return; cb.failure(403, "Out of range");
// } return;
// }
// makeServerQuery(tes, side, cb, JSServerRequest.SET_REDSTONE_AT, x, y, state);
// }); makeServerQuery(tes, side, cb, JSServerRequest.SET_REDSTONE_AT, x, y, state);
// });
// register("IsEmitting", (cb, tes, side, args) -> {
// if(!tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) { register("IsEmitting", (cb, tes, side, args) -> {
// cb.failure(403, "Missing upgrade"); if(!tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
// return; cb.failure(403, "Missing upgrade");
// } return;
// }
// if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
// TileEntityScreen.Screen scr = tes.getScreen(side); if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) {
// int x = ((Double) args[0]).intValue(); TileEntityScreen.Screen scr = tes.getScreen(side);
// int y = ((Double) args[1]).intValue(); 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"); if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y)
// else { cb.failure(403, "Out of range");
// BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock(); else {
// boolean e = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting); BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock();
// cb.success("{\"emitting\":" + (e ? "true" : "false") + "}"); boolean e = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting);
// } cb.success("{\"emitting\":" + (e ? "true" : "false") + "}");
// } else }
// cb.failure(400, "Wrong arguments"); } else
// }); cb.failure(400, "Wrong arguments");
// });
// register("GetEmissionArray", (cb, tes, side, args) -> {
// if(tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) { register("GetEmissionArray", (cb, tes, side, args) -> {
// final StringJoiner resp = new StringJoiner(",", "{\"emission\":[", "]}"); if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) {
// tes.forEachScreenBlocks(side, bp -> resp.add(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting) ? "1" : "0")); final StringJoiner resp = new StringJoiner(",", "{\"emission\":[", "]}");
// cb.success(resp.toString()); tes.forEachScreenBlocks(side, bp -> resp.add(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting) ? "1" : "0"));
// } else cb.success(resp.toString());
// cb.failure(403, "Missing upgrade"); } else
// }); cb.failure(403, "Missing upgrade");
// });
// register("GetLocation", (cb, tes, side, args) -> {
// if(!tes.hasUpgrade(side, DefaultUpgrade.GPS)) { register("GetLocation", (cb, tes, side, args) -> {
// cb.failure(403, "Missing upgrade"); if(!tes.hasUpgrade(side, DefaultUpgrade.GPS)) {
// return; cb.failure(403, "Missing upgrade");
// } return;
// }
// BlockPos bp = tes.getBlockPos();
// cb.success("{\"x\":" + bp.getX() + ",\"y\":" + bp.getY() + ",\"z\":" + bp.getZ() + ",\"side\":\"" + side + "\"}"); 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\":["); register("GetUpgrades", (cb, tes, side, args) -> {
// final ArrayList<ItemStack> upgrades = tes.getScreen(side).upgrades; 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) for(int i = 0; i < upgrades.size(); i++) {
// sb.append(','); if(i > 0)
// sb.append(',');
// sb.append('\"');
// sb.append(Util.addSlashes(((IUpgrade) upgrades.get(i).getItem()).getJSName(upgrades.get(i)))); sb.append('\"');
// sb.append('\"'); sb.append(Util.addSlashes(((IUpgrade) upgrades.get(i).getItem()).getJSName(upgrades.get(i))));
// } sb.append('\"');
// }
// cb.success(sb.append("]}").toString());
// }); 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())); register("IsOwner", (cb, tes, side, args) -> {
// cb.success("{\"isOwner\":" + (res ? "true}" : "false}")); 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() + "}")); 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() + "}"));
// }
//}
}

View File

@ -0,0 +1,28 @@
/*
* 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;
}
}

View File

@ -0,0 +1,27 @@
/*
* 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;
}
} */

View File

@ -4,127 +4,103 @@
package net.montoyo.wd.client; 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.Constants;
import net.montoyo.wd.miniserv.client.Client; import net.montoyo.wd.miniserv.client.Client;
import net.montoyo.wd.miniserv.client.ClientTaskGetFile; import net.montoyo.wd.miniserv.client.ClientTaskGetFile;
import net.montoyo.wd.utilities.Log; import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.utilities.serialization.Util; import net.montoyo.wd.utilities.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.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID; import java.util.UUID;
public class WDScheme implements CefResourceHandler { public class WDScheme implements IScheme {
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 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 ClientTaskGetFile task;
private boolean isErrorPage; private boolean isErrorPage;
String url;
boolean onlyError = false;
public WDScheme(String url) {
this.url = url;
}
@Override @Override
public boolean processRequest(CefRequest cefRequest, CefCallback cefCallback) { public SchemePreResponse processRequest(String url) {
url = cefRequest.getURL(); url = url.substring("wd://".length());
url = url.substring("webdisplays://".length());
int pos = url.indexOf('/'); int pos = url.indexOf('/');
if (pos < 0) if(pos < 0)
return false; return SchemePreResponse.NOT_HANDLED;
String uuidStr = url.substring(0, pos); String uuidStr = url.substring(0, pos);
String fileStr = url.substring(pos + 1); String fileStr = url.substring(pos + 1);
fileStr = URLDecoder.decode(fileStr, StandardCharsets.UTF_8); try {
fileStr = URLDecoder.decode(fileStr, "UTF-8");
if (uuidStr.isEmpty() || Util.isFileNameInvalid(fileStr)) { } catch(UnsupportedEncodingException ex) {
// invalid URL or no UUID Log.warningEx("UTF-8 isn't supported... yeah... and I'm a billionaire...", ex);
onlyError = true;
cefCallback.Continue();
return true;
} }
if(uuidStr.isEmpty() || Util.isFileNameInvalid(fileStr))
return SchemePreResponse.NOT_HANDLED;
UUID uuid; UUID uuid;
try { try {
uuid = UUID.fromString(uuidStr); uuid = UUID.fromString(uuidStr);
} catch (IllegalArgumentException ex) { } catch(IllegalArgumentException ex) {
// invalid UUID return SchemePreResponse.NOT_HANDLED; //Invalid UUID
onlyError = true;
cefCallback.Continue();
return true;
} }
task = new ClientTaskGetFile(uuid, fileStr); task = new ClientTaskGetFile(uuid, fileStr);
boolean doContinue = Client.getInstance().addTask(task); return Client.getInstance().addTask(task) ? SchemePreResponse.HANDLED_CONTINUE : SchemePreResponse.NOT_HANDLED;
if (doContinue) cefCallback.Continue();
return doContinue;
} }
@Override @Override
public void getResponseHeaders(CefResponse cefResponse, IntRef contentLength, StringRef redir) { public void getResponseHeaders(ISchemeResponseHeaders resp) {
int status; Log.info("Waiting for response...");
if (onlyError) { int status = task.waitForResponse();
status = Constants.GETF_STATUS_BAD_NAME; Log.info("Got response %d", status);
} else {
Log.info("Waiting for response...");
status = task.waitForResponse();
Log.info("Got response %d", status);
if (status == 0) { if(status == 0) {
//OK //OK
int extPos = task.getFileName().lastIndexOf('.'); int extPos = task.getFileName().lastIndexOf('.');
if (extPos >= 0) { if(extPos >= 0) {
String mime = mapMime(task.getFileName().substring(extPos + 1)); String mime = ((ClientProxy) WebDisplays.PROXY).getMCEF().mimeTypeFromExtension(task.getFileName().substring(extPos + 1));
if (mime != null) if(mime != null)
cefResponse.setMimeType(mime); resp.setMimeType(mime);
}
cefResponse.setStatus(200);
cefResponse.setStatusText("OK");
contentLength.set(0);
return;
} }
resp.setStatus(200);
resp.setStatusText("OK");
resp.setResponseLength(-1);
return;
} }
int errCode; int errCode;
String errStr; String errStr;
if (status == Constants.GETF_STATUS_NOT_FOUND) { if(status == Constants.GETF_STATUS_NOT_FOUND) {
errCode = 404; errCode = 404;
errStr = "Not Found"; 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 { } else {
errCode = 500; errCode = 500;
errStr = "Internal Server Error"; errStr = "Internal Server Error";
} }
// reporting the actual status and text makes CEF not display the page resp.setStatus(errCode);
cefResponse.setStatus(200); resp.setStatusText(errStr);
cefResponse.setStatusText("OK");
cefResponse.setMimeType("text/html");
dataToWrite = String.format(ERROR_PAGE, errCode, errStr).getBytes(StandardCharsets.UTF_8); try {
dataOffset = 0; dataToWrite = String.format(ERROR_PAGE, errCode, errStr).getBytes("UTF-8");
amountToWrite = dataToWrite.length; dataOffset = 0;
isErrorPage = true; amountToWrite = dataToWrite.length;
contentLength.set(0); isErrorPage = true;
resp.setResponseLength(amountToWrite);
} catch(UnsupportedEncodingException ex) {
resp.setResponseLength(0);
}
} }
private byte[] dataToWrite; private byte[] dataToWrite;
@ -132,10 +108,10 @@ public class WDScheme implements CefResourceHandler {
private int amountToWrite; private int amountToWrite;
@Override @Override
public boolean readResponse(byte[] output, int bytesToRead, IntRef bytesRead, CefCallback cefCallback) { public boolean readResponse(ISchemeResponseData data) {
if (dataToWrite == null) { if(dataToWrite == null) {
if (isErrorPage) { if(isErrorPage) {
bytesRead.set(0); data.setAmountRead(0);
return false; return false;
} }
@ -143,25 +119,25 @@ public class WDScheme implements CefResourceHandler {
dataOffset = 3; //packet ID + size dataOffset = 3; //packet ID + size
amountToWrite = task.getDataLength(); amountToWrite = task.getDataLength();
if (amountToWrite <= 0) { if(amountToWrite <= 0) {
dataToWrite = null; dataToWrite = null;
bytesRead.set(0); data.setAmountRead(0);
return false; return false;
} }
} }
int toWrite = bytesToRead; int toWrite = data.getBytesToRead();
if (toWrite > amountToWrite) if(toWrite > amountToWrite)
toWrite = amountToWrite; toWrite = amountToWrite;
System.arraycopy(dataToWrite, dataOffset, output, 0, toWrite); System.arraycopy(dataToWrite, dataOffset, data.getDataArray(), 0, toWrite);
bytesRead.set(toWrite); data.setAmountRead(toWrite);
dataOffset += toWrite; dataOffset += toWrite;
amountToWrite -= toWrite; amountToWrite -= toWrite;
if (amountToWrite <= 0) { if(amountToWrite <= 0) {
if (!isErrorPage) if(!isErrorPage)
task.nextData(); task.nextData();
dataToWrite = null; dataToWrite = null;
@ -170,46 +146,4 @@ public class WDScheme implements CefResourceHandler {
return true; 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;
}
}
} }

View File

@ -1,116 +0,0 @@
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;
}
}

View File

@ -4,59 +4,53 @@
package net.montoyo.wd.client.gui; package net.montoyo.wd.client.gui;
import com.cinemamod.mcef.MCEFBrowser; import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.vertex.PoseStack; import com.sun.jna.platform.unix.X11;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity; import net.minecraft.util.Mth;
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.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.ModList; import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.loading.FMLPaths;
import net.montoyo.wd.WebDisplays; 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.Button;
import net.montoyo.wd.client.gui.controls.Control; import net.montoyo.wd.client.gui.controls.Control;
import net.montoyo.wd.client.gui.controls.Label; import net.montoyo.wd.client.gui.controls.Label;
import net.montoyo.wd.client.gui.loading.FillControl; import net.montoyo.wd.client.gui.loading.FillControl;
import net.montoyo.wd.controls.builtin.ClickControl; import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.entity.ScreenBlockEntity; import net.montoyo.wd.net.Messages;
import net.montoyo.wd.entity.ScreenData; import net.montoyo.wd.net.server.SMessageScreenCtrl;
import net.montoyo.wd.net.WDNetworkRegistry; import net.montoyo.wd.utilities.BlockSide;
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl;
import net.montoyo.wd.utilities.Log; import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.utilities.TypeData;
import net.montoyo.wd.utilities.math.Vector2i; import net.montoyo.wd.utilities.Util;
import net.montoyo.wd.utilities.serialization.TypeData; import org.apache.commons.lang3.CharUtils;
import net.montoyo.wd.utilities.serialization.Util; import org.cef.browser.CefBrowserOsr;
import org.cef.browser.CefBrowser; import org.jline.utils.Display;
import org.cef.misc.CefCursorType;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import org.lwjgl.glfw.GLFW; 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.io.*;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
import static com.mojang.blaze3d.platform.InputConstants.*;
import static java.awt.event.KeyEvent.*;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class GuiKeyboard extends WDScreen { public class GuiKeyboard extends WDScreen {
private static final String WARNING_FNAME = "wd_keyboard_warning.txt"; private static final String WARNING_FNAME = "wd_keyboard_warning.txt";
private ScreenBlockEntity tes; private TileEntityScreen tes;
private BlockSide side; private BlockSide side;
private ScreenData data;
private final ArrayList<TypeData> evStack = new ArrayList<>(); private final ArrayList<TypeData> evStack = new ArrayList<>();
private BlockPos kbPos; private BlockPos kbPos;
private boolean showWarning = true; private boolean showWarning = true;
@ -71,7 +65,7 @@ public class GuiKeyboard extends WDScreen {
super(Component.nullToEmpty(null)); super(Component.nullToEmpty(null));
} }
public GuiKeyboard(ScreenBlockEntity tes, BlockSide side, BlockPos kbPos) { public GuiKeyboard(TileEntityScreen tes, BlockSide side, BlockPos kbPos) {
this(); this();
this.tes = tes; this.tes = tes;
this.side = side; this.side = side;
@ -83,30 +77,6 @@ public class GuiKeyboard extends WDScreen {
vars.put("showWarning", showWarning ? 1.0 : 0.0); 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 @Override
public void init() { public void init() {
super.init(); super.init();
@ -152,77 +122,64 @@ public class GuiKeyboard extends WDScreen {
defaultBackground = showWarning; defaultBackground = showWarning;
syncTicks = 5; 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 @Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) { public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (quitOnEscape && keyCode == GLFW.GLFW_KEY_ESCAPE) { key(keyCode, scanCode, true, modifiers);
onClose();
return true;
}
addKey(new TypeData(TypeData.Action.PRESS, keyCode, modifiers, scanCode));
return super.keyPressed(keyCode, scanCode, modifiers); 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 @Override
public boolean keyReleased(int keyCode, int scanCode, int modifiers) { public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
addKey(new TypeData(TypeData.Action.RELEASE, keyCode, modifiers, scanCode)); key(keyCode, scanCode, false, modifiers);
return super.keyPressed(keyCode, scanCode, modifiers); return super.keyPressed(keyCode, scanCode, modifiers);
} }
void addKey(TypeData data) { public void key(int keyCode, int scanCode, boolean pressed, int mod) {
tes.type(side, "[" + WebDisplays.GSON.toJson(data) + "]", kbPos); if (pressed) {
if(quitOnEscape && keyCode == GLFW.GLFW_KEY_ESCAPE) {
Minecraft.getInstance().setScreen(null);
}
evStack.add(data); int chr = getChar(keyCode, scanCode);
if (!evStack.isEmpty() && !syncRequested()) evStack.add(new TypeData(TypeData.Action.PRESS, chr, mod));
requestSync(); 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));
}
} }
@Override @Override
protected void sync() { protected void sync() {
if(!evStack.isEmpty()) { if(!evStack.isEmpty()) {
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.type(tes, side, WebDisplays.GSON.toJson(evStack), kbPos)); Messages.INSTANCE.sendToServer(SMessageScreenCtrl.type(tes, side, WebDisplays.GSON.toJson(evStack), kbPos));
evStack.clear(); evStack.clear();
} }
} }
@ -250,7 +207,7 @@ public class GuiKeyboard extends WDScreen {
private boolean hasUserReadWarning() { private boolean hasUserReadWarning() {
try { try {
File f = new File(FMLPaths.GAMEDIR.get().toString(), WARNING_FNAME); File f = new File(FMLPaths.GAMEDIR.name(), WARNING_FNAME);
if(f.exists()) { if(f.exists()) {
BufferedReader br = new BufferedReader(new FileReader(f)); BufferedReader br = new BufferedReader(new FileReader(f));
@ -268,7 +225,7 @@ public class GuiKeyboard extends WDScreen {
private void writeUserAcknowledge() { private void writeUserAcknowledge() {
try { try {
File f = new File(FMLPaths.GAMEDIR.get().toString(), WARNING_FNAME); File f = new File(FMLPaths.GAMEDIR.name(), WARNING_FNAME);
BufferedWriter bw = new BufferedWriter(new FileWriter(f)); BufferedWriter bw = new BufferedWriter(new FileWriter(f));
bw.write("read\n"); bw.write("read\n");
@ -283,89 +240,4 @@ public class GuiKeyboard extends WDScreen {
return bp.equals(kbPos) || (bp.equals(tes.getBlockPos()) && side == this.side); 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();
}
} }

View File

@ -4,354 +4,180 @@
package net.montoyo.wd.client.gui; 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.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.*;
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.core.BlockPos;
import net.minecraft.locale.Language;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.montoyo.wd.WebDisplays; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.utilities.browser.WDBrowser; import net.montoyo.wd.utilities.BlockSide;
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 org.lwjgl.glfw.GLFW;
import java.util.Optional; import java.util.Optional;
import static net.minecraftforge.api.distmarker.Dist.CLIENT; import static net.minecraftforge.api.distmarker.Dist.CLIENT;
import static org.lwjgl.opengl.GL11.glColor4f;
@OnlyIn(CLIENT) @OnlyIn(CLIENT)
public class GuiMinePad extends WDScreen { public class GuiMinePad extends WDScreen {
private ClientProxy.PadData pad; private ClientProxy.PadData pad;
private double vx; private double vx;
private double vy; private double vy;
private double vw; private double vw;
private double vh; private double vh;
public GuiMinePad() { public GuiMinePad() {
super(Component.nullToEmpty(null)); super(Component.nullToEmpty(null));
} }
public GuiMinePad(ClientProxy.PadData pad) { public GuiMinePad(ClientProxy.PadData pad) {
this(); this();
this.pad = pad; this.pad = pad;
} }
int trueWidth, trueHeight; @Override
public void init() {
super.init();
@Override vw = ((double) width) - 32.0f;
public void init() { vh = vw / WebDisplays.PAD_RATIO;
vw = ((double) width) - 32.0f; vx = 16.0f;
vh = vw / WebDisplays.PAD_RATIO; vy = (((double) height) - vh) / 2.0f;
vx = 16.0f; }
vy = (((double) height) - vh) / 2.0f;
trueWidth = width; private static void addRect(BufferBuilder bb, double x, double y, double w, double h) {
trueHeight = height; 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();
}
this.width = (int) vw; @Override
this.height = (int) vh; public void render(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
renderBackground(poseStack);
super.init(); RenderSystem.disableTexture();
RenderSystem.disableCull();
RenderSystem.setShaderColor(0.73f, 0.73f, 0.73f, 1.0f);
((MCEFBrowser) pad.view).setCursor(CefCursorType.fromId(pad.activeCursor)); Tesselator t = Tesselator.getInstance();
((MCEFBrowser) pad.view).setCursorChangeListener((id) -> { BufferBuilder bb = t.getBuilder();
pad.activeCursor = id; bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
((MCEFBrowser) pad.view).setCursor(CefCursorType.fromId(id)); 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();
private static void addRect(BufferBuilder bb, double x, double y, double w, double h) { RenderSystem.enableTexture();
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();
}
@Override if (pad.view != null) {
public void render(GuiGraphics graphics, int mouseX, int mouseY, float ptt) { glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
width = trueWidth; pad.view.draw(poseStack, vx, vy + vh, vx + vw, vy);
height = trueHeight; }
renderBackground(graphics);
width = (int) vw;
height = (int) vh;
RenderSystem.disableCull(); RenderSystem.enableCull();
RenderSystem.setShaderColor(0.73f, 0.73f, 0.73f, 1.0f); }
Tesselator t = Tesselator.getInstance(); @Override
BufferBuilder bb = t.getBuilder(); public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); key(keyCode, scanCode, true);
addRect(bb, vx, vy - 16, vw, 16); return super.keyPressed(keyCode, scanCode, modifiers);
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();
graphics.drawString( @Override
minecraft.font, Language.getInstance().getOrDefault( public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
"webdisplays.gui.minepad.close" key(keyCode, scanCode, false);
), (int) vx + 4, (int) vy - minecraft.font.lineHeight - 3, 16777215, true return super.keyPressed(keyCode, scanCode, modifiers);
); }
}
@Override public void key(int keyCode, int scanCode, boolean pressed) {
public boolean keyPressed(int keyCode, int scanCode, int modifiers) { Optional<Character> key = getChar(keyCode, scanCode);
return this.keyChanged(keyCode, scanCode, modifiers, true) || super.keyPressed(keyCode, scanCode, modifiers);
}
@Override if (pad.view != null && key.isPresent()) {
public boolean keyReleased(int keyCode, int scanCode, int modifiers) { char c = key.get();
return this.keyChanged(keyCode, scanCode, modifiers, false) || super.keyReleased(keyCode, scanCode, modifiers);
}
@Override if (pressed)
public boolean charTyped(char codePoint, int modifiers) { pad.view.injectKeyPressedByKeyCode(keyCode, c, 0);
if (pad.view != null) { else
((MCEFBrowser) pad.view).sendKeyTyped(codePoint, modifiers); pad.view.injectKeyReleasedByKeyCode(keyCode, c, 0);
return true;
} else {
return super.charTyped(codePoint, modifiers);
}
}
/* copied from MCEF */ if (c != 0)
public boolean keyChanged(int keyCode, int scanCode, int modifiers, boolean pressed) { pad.view.injectKeyTyped(c, 0);
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;
char key = keystr.charAt(keystr.length() - 1); @Override
public void mouseMoved(double mouseX, double mouseY) {
super.mouseMoved(mouseX, mouseY);
mouse(-1, false, (int) mouseX, (int) mouseY);
}
if (keystr.equals("Enter")) { @Override
keyCode = 10; public boolean mouseClicked(double mouseX, double mouseY, int button) {
key = '\n'; mouse(button, true, (int) mouseX, (int) mouseY);
} return super.mouseClicked(mouseX, mouseY, button);
}
if (pad.view != null) { @Override
if (pressed) public boolean mouseReleased(double mouseX, double mouseY, int button) {
((MCEFBrowser) pad.view).sendKeyPress(keyCode, scanCode, modifiers); mouse(button, false, (int) mouseX, (int) mouseY);
else return super.mouseReleased(mouseX, mouseY, button);
((MCEFBrowser) pad.view).sendKeyRelease(keyCode, scanCode, modifiers); }
if (pressed && key == '\n') public void mouse(int btn, boolean pressed, int sx, int sy) {
if (modifiers != 0) ((MCEFBrowser) pad.view).sendKeyTyped('\r', modifiers);
return true;
}
return false; int vx = screen2DisplayX((int) this.vx);
} int vy = screen2DisplayY((int) this.vy);
int vh = screen2DisplayX((int) this.vh);
int vw = screen2DisplayY((int) this.vw);
@Override if (pad.view != null && sx >= vx && sx <= vx + vw && sy >= vy && sy <= vy + vh) {
public void mouseMoved(double mouseX, double mouseY) { sx -= vx;
super.mouseMoved(mouseX, mouseY); sy -= vy;
mouse(-1, false, (int) mouseX, (int) mouseY, 0); sy = vh - sy;
}
@Override //Scale again according to the webview
public boolean mouseClicked(double mouseX, double mouseY, int button) { sx = (int) (((double) sx) / ((double) vw) * WebDisplays.INSTANCE.padResX);
mouse(button, true, (int) mouseX, (int) mouseY, 0); sy = (int) (((double) sy) / ((double) vh) * WebDisplays.INSTANCE.padResY);
return super.mouseClicked(mouseX, mouseY, button);
}
@Override if (btn == -1)
public boolean mouseReleased(double mouseX, double mouseY, int button) { pad.view.injectMouseMove(sx, sy, 0, false);
mouse(button, false, (int) mouseX, (int) mouseY, 0); else
return super.mouseReleased(mouseX, mouseY, button); pad.view.injectMouseButton(sx, sy, 0, btn + 1, pressed, 1);
}
@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);
return super.mouseScrolled(mouseX, mouseY, amount); 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();
}
public void capturedMouse(double scaledX, double scaledY, int sx, int sy) { return Optional.of(keystr.charAt(keystr.length() - 1));
double centerX = (int) (0.5 * (double) this.minecraft.getWindow().getGuiScaledWidth()); }
double centerY = (int) (0.5 * (double) this.minecraft.getWindow().getGuiScaledHeight());
if (sx == (int) centerX && sy == (int) centerY) return; @Override
public void tick() {
if(pad.view == null)
minecraft.setScreen(null); //In case the user dies with the pad in the hand
}
double mx = (centerX - vx) / vw; @Override
double my = (centerY - vy) / vh; public boolean isForBlock(BlockPos bp, BlockSide side) {
double scaledCentX = (mx * WebDisplays.INSTANCE.padResX); return false;
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);
}
}
} }

View File

@ -7,11 +7,17 @@ package net.montoyo.wd.client.gui;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; 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.Button;
import net.montoyo.wd.client.gui.controls.TextField; import net.montoyo.wd.client.gui.controls.TextField;
import net.montoyo.wd.client.gui.loading.FillControl; import net.montoyo.wd.client.gui.loading.FillControl;
import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.net.Messages;
import net.montoyo.wd.utilities.math.Vector3i; 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 javax.annotation.Nullable; import javax.annotation.Nullable;
@ -47,18 +53,18 @@ public class GuiRedstoneCtrl extends WDScreen {
tfFallingEdge.setText(fallingEdgeURL); tfFallingEdge.setText(fallingEdgeURL);
} }
// @GuiSubscribe @GuiSubscribe
// public void onClick(Button.ClickEvent ev) { public void onClick(Button.ClickEvent ev) {
// if(ev.getSource() == btnOk) { if(ev.getSource() == btnOk) {
// API mcef = ((ClientProxy) WebDisplays.PROXY).getMCEF(); API mcef = ((ClientProxy) WebDisplays.PROXY).getMCEF();
//
// String rising = mcef.punycode(Util.addProtocol(tfRisingEdge.getText())); String rising = mcef.punycode(Util.addProtocol(tfRisingEdge.getText()));
// String falling = mcef.punycode(Util.addProtocol(tfFallingEdge.getText())); String falling = mcef.punycode(Util.addProtocol(tfFallingEdge.getText()));
// WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageRedstoneCtrl(pos, rising, falling)); Messages.INSTANCE.sendToServer(new SMessageRedstoneCtrl(dimension, pos, rising, falling));
// } }
//
// minecraft.setScreen(null); minecraft.setScreen(null);
// } }
@Override @Override
public boolean isForBlock(BlockPos bp, BlockSide side) { public boolean isForBlock(BlockPos bp, BlockSide side) {

View File

@ -15,17 +15,11 @@ import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.gui.controls.*; import net.montoyo.wd.client.gui.controls.*;
import net.montoyo.wd.client.gui.loading.FillControl; import net.montoyo.wd.client.gui.loading.FillControl;
import net.montoyo.wd.core.ScreenRights; import net.montoyo.wd.core.ScreenRights;
import net.montoyo.wd.entity.ScreenData; import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.entity.ScreenBlockEntity;
import net.montoyo.wd.item.WDItem; import net.montoyo.wd.item.WDItem;
import net.montoyo.wd.net.WDNetworkRegistry; import net.montoyo.wd.net.Messages;
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl; import net.montoyo.wd.net.server.SMessageScreenCtrl;
import net.montoyo.wd.utilities.*; 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 javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -35,7 +29,7 @@ import java.util.UUID;
public class GuiScreenConfig extends WDScreen { public class GuiScreenConfig extends WDScreen {
//Screen data //Screen data
private final ScreenBlockEntity tes; private final TileEntityScreen tes;
private final BlockSide side; private final BlockSide side;
private NameUUIDPair owner; private NameUUIDPair owner;
private NameUUIDPair[] friends; private NameUUIDPair[] friends;
@ -124,7 +118,7 @@ public class GuiScreenConfig extends WDScreen {
private CheckBox[] friendBoxes; private CheckBox[] friendBoxes;
private CheckBox[] otherBoxes; private CheckBox[] otherBoxes;
public GuiScreenConfig(Component component, ScreenBlockEntity tes, BlockSide side, NameUUIDPair[] friends, int fr, int or) { public GuiScreenConfig(Component component, TileEntityScreen tes, BlockSide side, NameUUIDPair[] friends, int fr, int or) {
super(component); super(component);
this.tes = tes; this.tes = tes;
this.side = side; this.side = side;
@ -139,20 +133,20 @@ public class GuiScreenConfig extends WDScreen {
loadFrom(new ResourceLocation("webdisplays", "gui/screencfg.json")); loadFrom(new ResourceLocation("webdisplays", "gui/screencfg.json"));
friendBoxes = new CheckBox[] { boxFResolution, boxFUpgrades, boxFOthers, boxFFriends, boxFClick, boxFSetUrl }; friendBoxes = new CheckBox[] { boxFResolution, boxFUpgrades, boxFOthers, boxFFriends, boxFClick, boxFSetUrl };
boxFResolution.setUserdata(ScreenRights.MODIFY_SCREEN); boxFResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION);
boxFUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES); boxFUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES);
boxFOthers.setUserdata(ScreenRights.MANAGE_OTHER_RIGHTS); boxFOthers.setUserdata(ScreenRights.MANAGE_OTHER_RIGHTS);
boxFFriends.setUserdata(ScreenRights.MANAGE_FRIEND_LIST); boxFFriends.setUserdata(ScreenRights.MANAGE_FRIEND_LIST);
boxFClick.setUserdata(ScreenRights.INTERACT); boxFClick.setUserdata(ScreenRights.CLICK);
boxFSetUrl.setUserdata(ScreenRights.CHANGE_URL); boxFSetUrl.setUserdata(ScreenRights.CHANGE_URL);
otherBoxes = new CheckBox[] { boxOResolution, boxOUpgrades, boxOClick, boxOSetUrl }; otherBoxes = new CheckBox[] { boxOResolution, boxOUpgrades, boxOClick, boxOSetUrl };
boxOResolution.setUserdata(ScreenRights.MODIFY_SCREEN); boxOResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION);
boxOUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES); boxOUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES);
boxOClick.setUserdata(ScreenRights.INTERACT); boxOClick.setUserdata(ScreenRights.CLICK);
boxOSetUrl.setUserdata(ScreenRights.CHANGE_URL); boxOSetUrl.setUserdata(ScreenRights.CHANGE_URL);
ScreenData scr = tes.getScreen(side); TileEntityScreen.Screen scr = tes.getScreen(side);
if(scr != null) { if(scr != null) {
owner = scr.owner; owner = scr.owner;
rotation = scr.rotation; rotation = scr.rotation;
@ -196,7 +190,7 @@ public class GuiScreenConfig extends WDScreen {
} }
private void clickSetRes() { private void clickSetRes() {
ScreenData scr = tes.getScreen(side); TileEntityScreen.Screen scr = tes.getScreen(side);
if(scr == null) if(scr == null)
return; //WHATDAFUQ? return; //WHATDAFUQ?
@ -207,7 +201,7 @@ public class GuiScreenConfig extends WDScreen {
throw new NumberFormatException(); //I'm lazy throw new NumberFormatException(); //I'm lazy
if(x != scr.resolution.x || y != scr.resolution.y) if(x != scr.resolution.x || y != scr.resolution.y)
WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.resolution(tes, side, new Vector2i(x, y))); Messages.INSTANCE.sendToServer(SMessageScreenCtrl.vec2(tes, side, SMessageScreenCtrl.CTRL_SET_RESOLUTION, new Vector2i(x, y)));
} catch(NumberFormatException ex) { } catch(NumberFormatException ex) {
//Roll back //Roll back
tfResX.setText("" + scr.resolution.x); tfResX.setText("" + scr.resolution.x);
@ -225,7 +219,7 @@ public class GuiScreenConfig extends WDScreen {
clickSetRes(); clickSetRes();
else if(ev.getSource() == btnChangeRot) { else if(ev.getSource() == btnChangeRot) {
Rotation[] rots = Rotation.values(); Rotation[] rots = Rotation.values();
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, rots[(rotation.ordinal() + 1) % rots.length])); Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, rots[(rotation.ordinal() + 1) % rots.length]));
} }
} }
@ -288,7 +282,7 @@ public class GuiScreenConfig extends WDScreen {
@GuiSubscribe @GuiSubscribe
public void onRemovePlayer(List.EntryClick ev) { public void onRemovePlayer(List.EntryClick ev) {
if(ev.getSource() == lstFriends) if(ev.getSource() == lstFriends)
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, (NameUUIDPair) ev.getUserdata(), true)); Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, (NameUUIDPair) ev.getUserdata(), true));
} }
@GuiSubscribe @GuiSubscribe
@ -318,12 +312,13 @@ public class GuiScreenConfig extends WDScreen {
} catch(NumberFormatException ex) { } catch(NumberFormatException ex) {
cbLockRatio.setChecked(false); cbLockRatio.setChecked(false);
} }
} else if(ev.getSource() == cbAutoVolume) WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.autoVol(tes, side, ev.isChecked())); } else if(ev.getSource() == cbAutoVolume)
Messages.INSTANCE.sendToServer(SMessageScreenCtrl.autoVol(tes, side, ev.isChecked()));
} }
@GuiSubscribe @GuiSubscribe
public void onRemoveUpgrade(UpgradeGroup.ClickEvent ev) { public void onRemoveUpgrade(UpgradeGroup.ClickEvent ev) {
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, ev.getMouseOverStack())); Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, ev.getMouseOverStack()));
} }
public boolean isFriendCheckbox(CheckBox cb) { public boolean isFriendCheckbox(CheckBox cb) {
@ -344,7 +339,7 @@ public class GuiScreenConfig extends WDScreen {
if(adding) { if(adding) {
if(!hasFriend(pairs[0])) if(!hasFriend(pairs[0]))
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, pairs[0], false)); Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, pairs[0], false));
tfFriend.setDisabled(false); tfFriend.setDisabled(false);
tfFriend.clear(); tfFriend.clear();
@ -433,7 +428,7 @@ public class GuiScreenConfig extends WDScreen {
@Override @Override
protected void sync() { protected void sync() {
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageScreenCtrl(tes, side, friendRights, otherRights)); Messages.INSTANCE.sendToServer(new SMessageScreenCtrl(tes, side, friendRights, otherRights));
Log.info("Sent sync packet"); Log.info("Sent sync packet");
} }
@ -461,7 +456,7 @@ public class GuiScreenConfig extends WDScreen {
flag = (myRights & ScreenRights.MANAGE_OTHER_RIGHTS) == 0; flag = (myRights & ScreenRights.MANAGE_OTHER_RIGHTS) == 0;
grpOthers.setDisabled(flag); grpOthers.setDisabled(flag);
flag = (myRights & ScreenRights.MODIFY_SCREEN) == 0; flag = (myRights & ScreenRights.CHANGE_RESOLUTION) == 0;
tfResX.setDisabled(flag); tfResX.setDisabled(flag);
tfResY.setDisabled(flag); tfResY.setDisabled(flag);
btnChangeRot.setDisabled(flag); btnChangeRot.setDisabled(flag);
@ -508,16 +503,5 @@ public class GuiScreenConfig extends WDScreen {
return "Screen_Configurator"; 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

View File

@ -7,147 +7,125 @@ package net.montoyo.wd.client.gui;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.montoyo.wd.WebDisplays; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.client.gui.controls.Button; 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.controls.TextField;
import net.montoyo.wd.client.gui.loading.FillControl; import net.montoyo.wd.client.gui.loading.FillControl;
import net.montoyo.wd.entity.ScreenBlockEntity; import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.item.ItemMinePad2; import net.montoyo.wd.init.ItemInit;
import net.montoyo.wd.net.WDNetworkRegistry; import net.montoyo.wd.net.Messages;
import net.montoyo.wd.net.server_bound.C2SMessageMinepadUrl; import net.montoyo.wd.net.server.SMessagePadCtrl;
import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl; import net.montoyo.wd.net.server.SMessageScreenCtrl;
import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.utilities.BlockSide;
import net.montoyo.wd.utilities.serialization.Util; import net.montoyo.wd.utilities.Util;
import net.montoyo.wd.utilities.math.Vector3i; import net.montoyo.wd.utilities.Vector3i;
import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.UUID;
@Mod.EventBusSubscriber(Dist.CLIENT) @Mod.EventBusSubscriber
public class GuiSetURL2 extends WDScreen { public class GuiSetURL2 extends WDScreen {
//Screen data //Screen data
private ScreenBlockEntity tileEntity; private TileEntityScreen tileEntity;
private BlockSide screenSide; private BlockSide screenSide;
private Vector3i remoteLocation; private Vector3i remoteLocation;
//Pad data //Pad data
private ItemStack stack; private final boolean isPad;
private final boolean isPad;
//Common
//Common private final String screenURL;
private final String screenURL;
@FillControl
@FillControl private TextField tfURL;
private TextField tfURL;
@FillControl
@FillControl private Button btnShutDown;
private Button btnShutDown;
@FillControl
@FillControl private Button btnCancel;
private Button btnCancel;
@FillControl
@FillControl private Button btnOk;
private Button btnOk;
public GuiSetURL2(TileEntityScreen tes, BlockSide side, String url, Vector3i rl) {
public GuiSetURL2(ScreenBlockEntity tes, BlockSide side, String url, Vector3i rl) { super(Component.nullToEmpty(null));
super(Component.nullToEmpty(null)); tileEntity = tes;
tileEntity = tes; screenSide = side;
screenSide = side; remoteLocation = rl;
remoteLocation = rl; isPad = false;
isPad = false; screenURL = url;
screenURL = url; }
}
public GuiSetURL2(String url) {
public GuiSetURL2(ItemStack is, String url) { super(Component.nullToEmpty(null));
super(Component.nullToEmpty(null)); isPad = true;
isPad = true; screenURL = url;
stack = is; }
screenURL = url;
} @Override
public void init() {
@Override super.init();
public void init() { loadFrom(new ResourceLocation("webdisplays", "gui/seturl.json"));
super.init(); tfURL.setText(screenURL);
loadFrom(new ResourceLocation("webdisplays", "gui/seturl.json")); }
tfURL.setText(screenURL);
} @Override
protected void addLoadCustomVariables(Map<String, Double> vars) {
@Override vars.put("isPad", isPad ? 1.0 : 0.0);
protected void addLoadCustomVariables(Map<String, Double> vars) { }
vars.put("isPad", isPad ? 1.0 : 0.0);
} @GuiSubscribe
public void onButtonClicked(Button.ClickEvent ev) {
protected UUID getUUID() { if(ev.getSource() == btnCancel)
if (stack == null || !(stack.getItem() instanceof ItemMinePad2)) minecraft.setScreen(null);
throw new RuntimeException("Get UUID is being called for a non-minepad UI"); else if(ev.getSource() == btnOk)
if (!stack.hasTag() || !stack.getTag().contains("PadID")) validate(tfURL.getText());
stack.getOrCreateTag().putUUID("PadID", UUID.randomUUID()); else if(ev.getSource() == btnShutDown) {
if(isPad)
return stack.getTag().getUUID("PadID"); Messages.INSTANCE.sendToServer(new SMessagePadCtrl(""));
}
minecraft.setScreen(null);
@GuiSubscribe }
public void onButtonClicked(Button.ClickEvent ev) { }
if (ev.getSource() == btnCancel)
minecraft.setScreen(null); @GuiSubscribe
else if (ev.getSource() == btnOk) public void onEnterPressed(TextField.EnterPressedEvent ev) {
validate(tfURL.getText()); validate(ev.getText());
else if (ev.getSource() == btnShutDown) { }
if (isPad) {
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageMinepadUrl( private void validate(String url) {
getUUID(), if(!url.isEmpty()) {
"" url = Util.addProtocol(url);
)); url = ((ClientProxy) WebDisplays.PROXY).getMCEF().punycode(url);
stack.getTag().remove("PadID");
} if(isPad) {
Messages.INSTANCE.sendToServer(new SMessagePadCtrl(url));
minecraft.setScreen(null); 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"));
@GuiSubscribe
public void onEnterPressed(TextField.EnterPressedEvent ev) { if(pd != null && pd.view != null)
validate(ev.getText()); pd.view.loadURL(WebDisplays.applyBlacklist(url));
} }
} else
private void validate(String url) { Messages.INSTANCE.sendToServer(SMessageScreenCtrl.setURL(tileEntity, screenSide, url, remoteLocation));
if (!url.isEmpty()) { }
try { minecraft.setScreen(null);
ScreenBlockEntity.url(url); }
} catch (IOException e) {
throw new RuntimeException(e); @Override
} public boolean isForBlock(BlockPos bp, BlockSide side) {
return (remoteLocation != null && remoteLocation.equalsBlockPos(bp)) || (bp.equals(tileEntity.getBlockPos()) && side == screenSide);
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);
}
} }

View File

@ -7,7 +7,6 @@ package net.montoyo.wd.client.gui;
import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.platform.Lighting;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.language.I18n;
@ -78,16 +77,15 @@ public class RenderRecipe extends Screen {
Log.info("Loaded %d recipes", recipes.size()); Log.info("Loaded %d recipes", recipes.size());
nextRecipe(); nextRecipe();
} }
@Override @Override
public void render(GuiGraphics context, int mouseX, int mouseY, float partialTick) { public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTick) {
// renderBackground(poseStack); renderBackground(poseStack);
renderBackground(context);
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
RenderSystem.setShaderTexture(0, CRAFTING_TABLE_GUI_TEXTURES); RenderSystem.setShaderTexture(0, CRAFTING_TABLE_GUI_TEXTURES);
// context.blit(x, y, 0, 0, SIZE_X, SIZE_Y); blit(poseStack, x, y, 0, 0, SIZE_X, SIZE_Y);
// font.draw(poseStack, I18n.get("container.crafting"), x + 28, y + 6, 0x404040); font.draw(poseStack, I18n.get("container.crafting"), x + 28, y + 6, 0x404040);
Lighting.setupForFlatItems(); Lighting.setupForFlatItems();
// RenderSystem.disableLighting(); //TODO: Need this? // RenderSystem.disableLighting(); //TODO: Need this?
@ -100,15 +98,15 @@ public class RenderRecipe extends Screen {
int x = this.x + 30 + sx * 18; int x = this.x + 30 + sx * 18;
int y = this.y + 17 + sy * 18; int y = this.y + 17 + sy * 18;
context.renderItem(is, x, y); renderItem.renderAndDecorateItem(minecraft.player, is, x, y, 0);
context.renderItemDecorations(font, is, x, y); renderItem.renderGuiItemDecorations(font, is, x, y, null);
} }
} }
} }
if(recipeResult != null) { if(recipeResult != null) {
context.renderItem(recipeResult, x, y); renderItem.renderAndDecorateItem(minecraft.player, recipeResult, x + 124, y + 35, 0);
context.renderItemDecorations(font, recipeResult, x, y); renderItem.renderGuiItemDecorations(font, recipeResult, x + 124, y + 35, null);
} }
// GlStateManager.enableLighting(); // GlStateManager.enableLighting();
@ -129,7 +127,7 @@ public class RenderRecipe extends Screen {
} }
} }
// recipeResult = recipe.getResultItem(); recipeResult = recipe.getResultItem();
} }
private void nextRecipe() { private void nextRecipe() {

View File

@ -7,12 +7,12 @@ package net.montoyo.wd.client.gui;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.network.chat.Style; import net.minecraft.network.chat.Style;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.FormattedCharSequence; import net.minecraft.util.FormattedCharSequence;
@ -23,13 +23,10 @@ import net.montoyo.wd.client.gui.controls.Event;
import net.montoyo.wd.client.gui.loading.FillControl; import net.montoyo.wd.client.gui.loading.FillControl;
import net.montoyo.wd.client.gui.loading.GuiLoader; import net.montoyo.wd.client.gui.loading.GuiLoader;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
import net.montoyo.wd.net.WDNetworkRegistry; import net.montoyo.wd.net.Messages;
import net.montoyo.wd.net.server_bound.C2SMessageACQuery; import net.montoyo.wd.net.server.SMessageACQuery;
import net.montoyo.wd.utilities.*; import net.montoyo.wd.utilities.*;
import net.montoyo.wd.utilities.data.Bounds; import org.lwjgl.glfw.GLFW;
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 javax.annotation.Nullable;
import java.io.IOException; import java.io.IOException;
@ -116,19 +113,17 @@ public abstract class WDScreen extends Screen {
} }
@Override @Override
public void render(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void render(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(defaultBackground) if(defaultBackground)
renderBackground(poseStack); renderBackground(poseStack);
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
for(Control ctrl: controls) for(Control ctrl: controls)
ctrl.draw(poseStack, mouseX, mouseY, ptt); ctrl.draw(poseStack, mouseX, mouseY, ptt);
for(Control ctrl: postDrawList) for(Control ctrl: postDrawList)
ctrl.postDraw(poseStack, mouseX, mouseY, ptt); ctrl.postDraw(poseStack, mouseX, mouseY, ptt);
} }
@Override @Override
public boolean charTyped(char codePoint, int modifiers) { public boolean charTyped(char codePoint, int modifiers) {
boolean typed = false; boolean typed = false;
@ -143,21 +138,8 @@ public abstract class WDScreen extends Screen {
public boolean mouseClicked(double mouseX, double mouseY, int button) { public boolean mouseClicked(double mouseX, double mouseY, int button) {
boolean clicked = false; boolean clicked = false;
Control clickedEl = null; for(Control ctrl: controls)
for(Control ctrl: controls) { clicked = clicked || ctrl.mouseClicked(mouseX, mouseY, button);
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; return clicked;
} }
@ -169,7 +151,7 @@ public abstract class WDScreen extends Screen {
for(Control ctrl: controls) for(Control ctrl: controls)
mouseReleased = mouseReleased || ctrl.mouseReleased(mouseX, mouseY, button); mouseReleased = mouseReleased || ctrl.mouseReleased(mouseX, mouseY, button);
return mouseReleased; return mouseReleased || mouseClicked(mouseX, mouseY, button);
} }
@Override @Override
@ -185,7 +167,7 @@ public abstract class WDScreen extends Screen {
@Override @Override
protected void init() { protected void init() {
CURRENT_SCREEN = this; CURRENT_SCREEN = this;
// minecraft.keyboardHandler.setSendRepeatsToGui(true); minecraft.keyboardHandler.setSendRepeatsToGui(true);
} }
@Override @Override
@ -198,7 +180,7 @@ public abstract class WDScreen extends Screen {
for(Control ctrl : controls) for(Control ctrl : controls)
ctrl.destroy(); ctrl.destroy();
// Minecraft.getInstance().keyboardHandler.setSendRepeatsToGui(false); Minecraft.getInstance().keyboardHandler.setSendRepeatsToGui(false);
CURRENT_SCREEN = null; CURRENT_SCREEN = null;
} }
@ -227,9 +209,9 @@ public abstract class WDScreen extends Screen {
boolean down = false; boolean down = false;
for (Control ctrl : controls) for (Control ctrl : controls)
down = down || ctrl.keyDown(keyCode, scanCode, modifiers); down = down || ctrl.keyDown(keyCode);
if (this instanceof GuiKeyboard) { if (Minecraft.getInstance().screen instanceof GuiKeyboard) {
return down; return down;
} else { } else {
return new GuiServer(new Vector3i(), new NameUUIDPair()).keyPressed(keyCode, scanCode, modifiers); return new GuiServer(new Vector3i(), new NameUUIDPair()).keyPressed(keyCode, scanCode, modifiers);
@ -241,7 +223,7 @@ public abstract class WDScreen extends Screen {
boolean up = false; boolean up = false;
for(Control ctrl : controls) for(Control ctrl : controls)
up = up || ctrl.keyUp(keyCode, scanCode, modifiers); up = up || ctrl.keyUp(keyCode);
return up || super.keyReleased(keyCode, scanCode, modifiers); return up || super.keyReleased(keyCode, scanCode, modifiers);
} }
@ -282,9 +264,7 @@ public abstract class WDScreen extends Screen {
} }
public void loadFrom(ResourceLocation resLoc) { public void loadFrom(ResourceLocation resLoc) {
try { JsonObject root = GuiLoader.getJson(resLoc);
JsonObject root = GuiLoader.getJson(resLoc);
if(root == null) if(root == null)
throw new RuntimeException("Could not load GUI file " + resLoc.toString()); throw new RuntimeException("Could not load GUI file " + resLoc.toString());
@ -332,10 +312,6 @@ public abstract class WDScreen extends Screen {
if(root.has("center") && root.get("center").getAsBoolean()) if(root.has("center") && root.get("center").getAsBoolean())
centerControls(); centerControls();
} catch (IOException e) {
e.printStackTrace();
}
} }
@Override @Override
@ -348,7 +324,7 @@ public abstract class WDScreen extends Screen {
} }
protected void requestAutocomplete(String beginning, boolean matchExact) { protected void requestAutocomplete(String beginning, boolean matchExact) {
WDNetworkRegistry.INSTANCE.sendToServer(new C2SMessageACQuery(beginning, matchExact)); Messages.INSTANCE.sendToServer(new SMessageACQuery(beginning, matchExact));
} }
public void onAutocompleteResult(NameUUIDPair pairs[]) { public void onAutocompleteResult(NameUUIDPair pairs[]) {
@ -380,12 +356,12 @@ public abstract class WDScreen extends Screen {
} }
} }
public void drawItemStackTooltip(GuiGraphics poseStack, ItemStack is, int x, int y) { public void drawItemStackTooltip(PoseStack poseStack, ItemStack is, int x, int y) {
poseStack.renderTooltip(Minecraft.getInstance().font, is, x, y); //Since it's protected... renderTooltip(poseStack, is, x, y); //Since it's protected...
} }
public void drawTooltip(GuiGraphics poseStack, List<String> lines, int x, int y) { public void drawTooltip(PoseStack 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... renderTooltip(poseStack, lines.stream().map(a -> FormattedCharSequence.forward(a, Style.EMPTY)).collect(Collectors.toList()), x, y, font); //This is also protected...
} }
public void requirePostDraw(Control ctrl) { public void requirePostDraw(Control ctrl) {

View File

@ -1,273 +0,0 @@
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);
}
}
}

View File

@ -5,16 +5,10 @@
package net.montoyo.wd.client.gui.controls; package net.montoyo.wd.client.gui.controls;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component; 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 net.montoyo.wd.client.gui.loading.JsonOWrapper;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.function.Supplier;
public class Button extends Control { public class Button extends Control {
protected final net.minecraft.client.gui.components.Button btn; protected final net.minecraft.client.gui.components.Button btn;
@ -37,23 +31,17 @@ public class Button extends Control {
} }
} }
public Button() { public Button() {
btn = net.minecraft.client.gui.components.Button.builder(Component.nullToEmpty(""), a -> {}) btn = new net.minecraft.client.gui.components.Button(0,0, 0, 0, Component.nullToEmpty(null), a -> {});
.bounds(0, 0, 0, 0)
.build();
} }
public Button(String text, int x, int y, int width) { public Button(String text, int x, int y, int width) {
btn = net.minecraft.client.gui.components.Button.builder(Component.nullToEmpty(text), a -> {}) btn = new net.minecraft.client.gui.components.Button(x, y, width, 20, Component.nullToEmpty(text), a -> {});
.bounds(x, y, width, 20)
.build();
} }
public Button(String text, int x, int y) { public Button(String text, int x, int y) {
btn = net.minecraft.client.gui.components.Button.builder(Component.nullToEmpty(text), a -> {}) btn = new net.minecraft.client.gui.components.Button(0, 0, x, y, Component.nullToEmpty(text), a -> {});
.bounds(0, 0, x, y)
.build();
} }
@Override @Override
@ -83,8 +71,7 @@ public class Button extends Control {
} }
@Override @Override
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
btn.setFGColor(16777215);
btn.render(poseStack, mouseX, mouseY, ptt); btn.render(poseStack, mouseX, mouseY, ptt);
} }
@ -116,17 +103,18 @@ public class Button extends Control {
@Override @Override
public void setPos(int x, int y) { public void setPos(int x, int y) {
btn.setPosition(x, y); btn.x = x;
btn.y = y;
} }
@Override @Override
public int getX() { public int getX() {
return btn.getX(); return btn.x;
} }
@Override @Override
public int getY() { public int getY() {
return btn.getY(); return btn.y;
} }
public net.minecraft.client.gui.components.Button getMcButton() { public net.minecraft.client.gui.components.Button getMcButton() {
@ -170,7 +158,7 @@ public class Button extends Control {
} }
@Override @Override
public boolean keyUp(int key, int scanCode, int modifiers) { public boolean keyUp(int key) {
if(key == GLFW.GLFW_KEY_LEFT_SHIFT || key == GLFW.GLFW_KEY_RIGHT_SHIFT) { if(key == GLFW.GLFW_KEY_LEFT_SHIFT || key == GLFW.GLFW_KEY_RIGHT_SHIFT) {
shiftDown = false; shiftDown = false;
btn.setFGColor(originalColor); btn.setFGColor(originalColor);
@ -182,7 +170,7 @@ public class Button extends Control {
} }
@Override @Override
public boolean keyDown(int key, int scanCode, int modifiers) { public boolean keyDown(int key) {
if(key == GLFW.GLFW_KEY_LEFT_SHIFT || key == GLFW.GLFW_KEY_RIGHT_SHIFT) { if(key == GLFW.GLFW_KEY_LEFT_SHIFT || key == GLFW.GLFW_KEY_RIGHT_SHIFT) {
shiftDown = true; shiftDown = true;
btn.setFGColor(shiftColor); btn.setFGColor(shiftColor);
@ -216,13 +204,11 @@ public class Button extends Control {
@Override @Override
public void load(JsonOWrapper json) { public void load(JsonOWrapper json) {
super.load(json); super.load(json);
btn.setPosition( btn.x = json.getInt("x", 0);
json.getInt("x", 0), btn.y = json.getInt("y", 0);
json.getInt("y", 0)
);
btn.setWidth(json.getInt("width", 200)); btn.setWidth(json.getInt("width", 200));
btn.setHeight(json.getInt("height", 20)); btn.setHeight(json.getInt("height", 20));
btn.setMessage(Component.nullToEmpty(tr(json.getString("label", btn.getMessage().getContents().toString())))); btn.setMessage(Component.nullToEmpty(tr(json.getString("label", btn.getMessage().getContents()))));
btn.active = json.getBool("active", btn.active); btn.active = json.getBool("active", btn.active);
btn.visible = json.getBool("visible", btn.visible); btn.visible = json.getBool("visible", btn.visible);

View File

@ -7,14 +7,17 @@ package net.montoyo.wd.client.gui.controls;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; 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.client.resources.sounds.SimpleSoundInstance;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents; 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 net.montoyo.wd.client.gui.loading.JsonOWrapper;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CheckBox extends BasicControl { public class CheckBox extends BasicControl {
private static final ResourceLocation texUnchecked = new ResourceLocation("webdisplays", "textures/gui/checkbox.png"); private static final ResourceLocation texUnchecked = new ResourceLocation("webdisplays", "textures/gui/checkbox.png");
@ -69,28 +72,29 @@ public class CheckBox extends BasicControl {
checked = !checked; checked = !checked;
mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); mc.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
parent.actionPerformed(new CheckedEvent(this)); parent.actionPerformed(new CheckedEvent(this));
return true;
} }
return true;
} }
return false; return false;
} }
@Override @Override
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(visible) { if(visible) {
// GlStateManager.disableAlpha(); // GlStateManager.disableAlpha();
poseStack.pose().pushPose(); poseStack.pushPose();
RenderSystem.setShaderTexture(2, checked ? texChecked : texUnchecked);
RenderSystem.bindTexture(2);
RenderSystem.enableBlend(); RenderSystem.enableBlend();
poseStack.blit( fillTexturedRect(poseStack, x, y, WIDTH, HEIGHT, 0.0, 0.0, 1.0, 1.0);
checked ? texChecked : texUnchecked, x, y, 0, 0, 0, WIDTH, HEIGHT, WIDTH, HEIGHT
);
RenderSystem.disableBlend(); RenderSystem.disableBlend();
RenderSystem.bindTexture(-1);
poseStack.pose().popPose(); poseStack.popPose();
boolean inside = (!disabled && mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT); boolean inside = (!disabled && mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT);
poseStack.drawString(Minecraft.getInstance().font, label, x + WIDTH + 2, y + 4, inside ? 0xFF0080FF : COLOR_WHITE, false); font.draw(poseStack, label, x + WIDTH + 2, y + 4, inside ? 0xFF0080FF : COLOR_WHITE);
} }
} }
@ -136,7 +140,7 @@ public class CheckBox extends BasicControl {
} }
@Override @Override
public void postDraw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void postDraw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(tooltip != null && !disabled && mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT) if(tooltip != null && !disabled && mouseX >= x && mouseX <= x + WIDTH + 2 + labelW && mouseY >= y && mouseY < y + HEIGHT)
parent.drawTooltip(poseStack, tooltip, mouseX, mouseY); parent.drawTooltip(poseStack, tooltip, mouseX, mouseY);
} }

View File

@ -5,10 +5,10 @@
package net.montoyo.wd.client.gui.controls; package net.montoyo.wd.client.gui.controls;
import com.mojang.blaze3d.vertex.PoseStack; 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.GuiLoader;
import net.montoyo.wd.client.gui.loading.JsonAWrapper; import net.montoyo.wd.client.gui.loading.JsonAWrapper;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
import org.lwjgl.opengl.GL11;
import java.util.ArrayList; import java.util.ArrayList;
@ -36,24 +36,24 @@ public abstract class Container extends BasicControl {
} }
@Override @Override
public boolean keyUp(int key, int scanCode, int modifiers) { public boolean keyUp(int key) {
boolean up = false; boolean up = false;
if(!disabled) { if(!disabled) {
for(Control ctrl : childs) for(Control ctrl : childs)
up = up || ctrl.keyUp(key, scanCode, modifiers); up = up || ctrl.keyUp(key);
} }
return up; return up;
} }
@Override @Override
public boolean keyDown(int key, int scanCode, int modifiers) { public boolean keyDown(int key) {
boolean down = false; boolean down = false;
if(!disabled) { if(!disabled) {
for(Control ctrl : childs) for(Control ctrl : childs)
down = down || ctrl.keyDown(key, scanCode, modifiers); down = down || ctrl.keyDown(key);
} }
return down; return down;
@ -67,10 +67,8 @@ public abstract class Container extends BasicControl {
mouseX -= x + paddingX; mouseX -= x + paddingX;
mouseY -= y + paddingY; mouseY -= y + paddingY;
for(Control ctrl : childs) { for(Control ctrl : childs)
clicked = ctrl.mouseClicked(mouseX, mouseY, mouseButton); clicked = clicked || ctrl.mouseClicked(mouseX, mouseY, mouseButton);
if (clicked) break; // don't assume compiler optimizations
}
} }
return clicked; return clicked;
@ -138,13 +136,13 @@ public abstract class Container extends BasicControl {
} }
@Override @Override
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(visible) { if(visible) {
mouseX -= x + paddingX; mouseX -= x + paddingX;
mouseY -= y + paddingY; mouseY -= y + paddingY;
poseStack.pose().pushPose(); poseStack.pushPose();
poseStack.pose().translate(x + paddingX, y + paddingY, 0.0); poseStack.translate(x + paddingX, y + paddingY, 0.0);
if(disabled) { if(disabled) {
for(Control ctrl : childs) for(Control ctrl : childs)
@ -154,7 +152,7 @@ public abstract class Container extends BasicControl {
ctrl.draw(poseStack, mouseX, mouseY, ptt); ctrl.draw(poseStack, mouseX, mouseY, ptt);
} }
poseStack.pose().popPose(); poseStack.popPose();
} }
} }
@ -189,10 +187,4 @@ public abstract class Container extends BasicControl {
return null; return null;
} }
@Override
public void unfocus() {
for (Control control : childs) {
control.unfocus();
}
}
} }

View File

@ -8,26 +8,20 @@ import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*; import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Matrix4f;
import net.minecraft.client.KeyboardHandler;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font; 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.client.resources.language.I18n;
import net.minecraft.resources.ResourceLocation; 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.WDScreen;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
import net.montoyo.wd.utilities.data.Bounds; import net.montoyo.wd.utilities.Bounds;
import org.joml.Matrix4f; import org.lwjgl.glfw.GLFW;
import java.util.Arrays; import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.glEnable;
import static com.mojang.math.Axis.XP;
@OnlyIn(Dist.CLIENT)
public abstract class Control { public abstract class Control {
public static final int COLOR_BLACK = 0xFF000000; public static final int COLOR_BLACK = 0xFF000000;
@ -67,11 +61,11 @@ public abstract class Control {
return false; return false;
} }
public boolean keyUp(int key, int scanCode, int modifiers) { public boolean keyUp(int key) {
return false; return false;
} }
public boolean keyDown(int key, int scanCode, int modifiers) { public boolean keyDown(int key) {
return false; return false;
} }
@ -79,9 +73,6 @@ public abstract class Control {
return false; return false;
} }
public void unfocus() {
}
public boolean mouseReleased(double mouseX, double mouseY, int state) { public boolean mouseReleased(double mouseX, double mouseY, int state) {
return false; return false;
} }
@ -98,10 +89,10 @@ public abstract class Control {
return false; return false;
} }
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
} }
public void postDraw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void postDraw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
} }
public void destroy() { public void destroy() {
@ -117,7 +108,7 @@ public abstract class Control {
public abstract int getHeight(); public abstract int getHeight();
public abstract void setPos(int x, int y); public abstract void setPos(int x, int y);
public void fillRect(MultiBufferSource.BufferSource source, int x, double y, int w, int h, int color) { public void fillRect(int x, double y, int w, int h, int color) {
double x1 = (double) x; double x1 = (double) x;
double y1 = (double) y; double y1 = (double) y;
double x2 = (double) (x + w); double x2 = (double) (x + w);
@ -127,38 +118,34 @@ public abstract class Control {
int g = (color >> 8 ) & 0xFF; int g = (color >> 8 ) & 0xFF;
int b = color & 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.setShaderColor(1, 1, 1, 1f); RenderSystem.disableTexture();
// RenderSystem.disableTexture();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
VertexConsumer consumer = source.getBuffer(RenderType.gui()); vBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
consumer.vertex(x1, y2, 0.0).color(r, g, b, a).endVertex(); vBuffer.vertex(x1, y2, 0.0).endVertex();
consumer.vertex(x2, y2, 0.0).color(r, g, b, a).endVertex(); vBuffer.vertex(x2, y2, 0.0).endVertex();
consumer.vertex(x2, y1, 0.0).color(r, g, b, a).endVertex(); vBuffer.vertex(x2, y1, 0.0).endVertex();
consumer.vertex(x1, y1, 0.0).color(r, g, b, a).endVertex(); vBuffer.vertex(x1, y1, 0.0).endVertex();
tessellator.end();
RenderSystem.setShaderColor(sdrCol[0], sdrCol[1], sdrCol[2], sdrCol[3]);
RenderSystem.disableBlend(); RenderSystem.disableBlend();
// RenderSystem.enableTexture(); RenderSystem.enableTexture();glEnable(GL_TEXTURE_2D);
} }
public void fillTexturedRect(PoseStack poseStack, int x, int y, int w, int h, double u1, double v1, double u2, double v2) { public void fillTexturedRect(PoseStack poseStack, int x, int y, int w, int h, double u1, double v1, double u2, double v2) {
float x1 = x; double x1 = (double) x;
float y1 = y; double y1 = (double) y;
float x2 = (x + w); double x2 = (double) (x + w);
float y2 = (y + h); double y2 = (double) (y + h);
RenderSystem.setShader(GameRenderer::getPositionColorTexShader); vBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
Matrix4f p = poseStack.last().pose(); vBuffer.vertex(x1, y2, 0.0).uv((float) u1, (float) v2).color(255, 255, 255, 255).endVertex();
vBuffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX); vBuffer.vertex(x2, y2, 0.0).uv((float) u2, (float) v2).color(255, 255, 255, 255).endVertex();
vBuffer.vertex(p, x1, y2, 0.0f).color(255, 255, 255, 255).uv((float) u1, (float) v2).endVertex(); vBuffer.vertex(x2, y1, 0.0).uv((float) u2, (float) v1).color(255, 255, 255, 255).endVertex();
vBuffer.vertex(p, x2, y2, 0.0f).color(255, 255, 255, 255).uv((float) u2, (float) v2).endVertex(); vBuffer.vertex(x1, y1, 0.0).uv((float) u1, (float) v1).color(255, 255, 255, 255).endVertex();
vBuffer.vertex(p, x2, y1, 0.0f).color(255, 255, 255, 255).uv((float) u2, (float) v1).endVertex(); tessellator.end();
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) { public static void blend(boolean enable) {
@ -176,11 +163,11 @@ public abstract class Control {
RenderSystem.setShaderTexture(0, resLoc); RenderSystem.setShaderTexture(0, resLoc);
} }
public void drawBorder(GuiGraphics poseStack, int x, int y, int w, int h, int color) { public void drawBorder(PoseStack poseStack, int x, int y, int w, int h, int color) {
drawBorder(poseStack, x, y, w, h, color, 1.0); drawBorder(poseStack, x, y, w, h, color, 1.0);
} }
public void drawBorder(GuiGraphics poseStack, int x, int y, int w, int h, int color, double sz) { public void drawBorder(PoseStack poseStack, int x, int y, int w, int h, int color, double sz) {
double x1 = (double) x; double x1 = (double) x;
double y1 = (double) y; double y1 = (double) y;
double x2 = (double) (x + w); double x2 = (double) (x + w);
@ -190,9 +177,8 @@ public abstract class Control {
int g = (color >> 8 ) & 0xFF; int g = (color >> 8 ) & 0xFF;
int b = color & 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.setShaderColor(((float) r) / 255.f, ((float) g) / 255.f, ((float) b) / 255.f, ((float) a) / 255.f);
// RenderSystem.enableTexture(); RenderSystem.enableTexture();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
@ -222,46 +208,36 @@ public abstract class Control {
vBuffer.vertex(x2 - sz, y1, 0.0).endVertex(); vBuffer.vertex(x2 - sz, y1, 0.0).endVertex();
tessellator.end(); tessellator.end();
RenderSystem.setShaderColor(sdrCol[0], sdrCol[1], sdrCol[2], sdrCol[3]);
RenderSystem.disableBlend(); RenderSystem.disableBlend();
// RenderSystem.enableTexture(); RenderSystem.enableTexture();
} }
public GuiGraphics beginFramebuffer(RenderTarget fbo, float vpW, float vpH) { public PoseStack beginFramebuffer(RenderTarget fbo, float vpW, float vpH) {
GuiGraphics tmpGraphics = new GuiGraphics(Minecraft.getInstance(), Minecraft.getInstance().renderBuffers().bufferSource());
fbo.bindWrite(true); fbo.bindWrite(true);
RenderSystem.backupProjectionMatrix(); RenderSystem.backupProjectionMatrix();
RenderSystem.setProjectionMatrix(new Matrix4f().ortho(0.0f, vpW, vpH, 0.0f, -1.0f,1.0f), VertexSorting.ORTHOGRAPHIC_Z); RenderSystem.setProjectionMatrix(Matrix4f.orthographic(0.0f, vpW, vpH, 0.0f, -1.0f,1.0f));
tmpGraphics.pose().last().pose().set(RenderSystem.getModelViewStack().last().pose()); PoseStack poseStack = RenderSystem.getModelViewStack();
tmpGraphics.pose().last().normal().set(RenderSystem.getModelViewStack().last().normal());
PoseStack poseStack = tmpGraphics.pose();
poseStack.pushPose(); poseStack.pushPose();
poseStack.setIdentity(); poseStack.setIdentity();
poseStack.mulPose(XP.rotationDegrees(180.0f)); // poseStack.mulPose(Vector3f.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(); RenderSystem.applyModelViewMatrix();
if(!fbo.useDepth) if(!fbo.useDepth)
RenderSystem.disableDepthTest(); RenderSystem.disableDepthTest();
return tmpGraphics; return poseStack;
} }
public void endFramebuffer(GuiGraphics poseStack, RenderTarget fbo) { public void endFramebuffer(PoseStack poseStack, RenderTarget fbo) {
if(!fbo.useDepth) if(!fbo.useDepth)
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
RenderSystem.colorMask(true, true, true, true); RenderSystem.colorMask(true, true, true, true);
RenderSystem.restoreProjectionMatrix(); RenderSystem.restoreProjectionMatrix();
poseStack.pose().popPose(); poseStack.popPose();
RenderSystem.getModelViewStack().popPose();
RenderSystem.applyModelViewMatrix(); RenderSystem.applyModelViewMatrix();
fbo.unbindWrite(); fbo.unbindWrite();
mc.getMainRenderTarget().bindWrite(true); mc.getMainRenderTarget().bindWrite(true);

View File

@ -7,13 +7,12 @@ package net.montoyo.wd.client.gui.controls;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexFormat; 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.client.gui.loading.JsonOWrapper;
import net.montoyo.wd.utilities.data.Bounds; import net.montoyo.wd.utilities.Bounds;
import java.util.Arrays; import static org.lwjgl.opengl.GL11.*;
public class ControlGroup extends Container { public class ControlGroup extends Container {
@ -95,23 +94,22 @@ public class ControlGroup extends Container {
} }
@Override @Override
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
super.draw(poseStack, mouseX, mouseY, ptt); super.draw(poseStack, mouseX, mouseY, ptt);
if(visible) { if(visible) {
poseStack.pose().pushPose(); poseStack.pushPose();
float[] sdrCol = Arrays.copyOf(RenderSystem.getShaderColor(), 4);
RenderSystem.setShaderColor(0.5f, 0.5f, 0.5f, 1.f); RenderSystem.setShaderColor(0.5f, 0.5f, 0.5f, 1.f);
// RenderSystem.disableTexture(); RenderSystem.disableTexture();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
double x1 = x; double x1 = (double) x;
double y1 = y; double y1 = (double) y;
double x2 = (x + width); double x2 = (double) (x + width);
double y2 = (y + height); double y2 = (double) (y + height);
double bp = 4.0; double bp = 4.0;
double lw = labelW; double lw = (double) labelW;
x1 += bp; x1 += bp;
y1 += bp; y1 += bp;
@ -160,14 +158,12 @@ public class ControlGroup extends Container {
vBuffer.vertex(x2 - 1.0, y1, 0.0).endVertex(); vBuffer.vertex(x2 - 1.0, y1, 0.0).endVertex();
tessellator.end(); tessellator.end();
RenderSystem.setShaderColor(sdrCol[0], sdrCol[1], sdrCol[2], sdrCol[3]);
RenderSystem.disableBlend(); RenderSystem.disableBlend();
// RenderSystem.enableTexture(); RenderSystem.enableTexture();
poseStack.pose().popPose(); poseStack.popPose();
if(labelW != 0) if(labelW != 0)
poseStack.drawString(Minecraft.getInstance().font, label, x + 10 + ((int) bp), y, labelColor, labelShadowed); font.drawShadow(poseStack, label, x + 10 + ((int) bp), y, labelColor, labelShadowed);
} }
} }
@ -180,13 +176,6 @@ public class ControlGroup extends Container {
height = bounds.getHeight() + paddingY * 2; height = bounds.getHeight() + paddingY * 2;
} }
@Override
public void unfocus() {
for (Control control : childs) {
control.unfocus();
}
}
@Override @Override
public void load(JsonOWrapper json) { public void load(JsonOWrapper json) {
super.load(json); super.load(json);

View File

@ -6,10 +6,8 @@ package net.montoyo.wd.client.gui.controls;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
public class Icon extends BasicControl { public class Icon extends BasicControl {
@ -46,17 +44,17 @@ public class Icon extends BasicControl {
} }
@Override @Override
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(texture != null) { if(texture != null) {
poseStack.pose().pushPose(); poseStack.pushPose();
// RenderSystem.enableTexture(); RenderSystem.enableTexture();
RenderSystem.setShaderTexture(1, texture); RenderSystem.setShaderTexture(1, texture);
RenderSystem.bindTexture(1); RenderSystem.bindTexture(1);
RenderSystem.enableBlend(); RenderSystem.enableBlend();
fillTexturedRect(poseStack.pose(), x, y, width, height, u1, v1, u2, v2); fillTexturedRect(poseStack, x, y, width, height, u1, v1, u2, v2);
RenderSystem.disableBlend(); RenderSystem.disableBlend();
RenderSystem.bindTexture(-1); RenderSystem.bindTexture(-1);
poseStack.pose().popPose(); poseStack.popPose();
} }
} }

View File

@ -5,8 +5,6 @@
package net.montoyo.wd.client.gui.controls; package net.montoyo.wd.client.gui.controls;
import com.mojang.blaze3d.vertex.PoseStack; 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; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
public class Label extends BasicControl { public class Label extends BasicControl {
@ -74,12 +72,9 @@ public class Label extends BasicControl {
} }
@Override @Override
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(visible) if(visible)
poseStack.drawString( font.drawShadow(poseStack, label, x, y, color, shadowed);
Minecraft.getInstance().font,
label, x, y, color, shadowed
);
} }
@Override @Override

View File

@ -9,13 +9,8 @@ import com.mojang.blaze3d.pipeline.TextureTarget;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.TextComponent;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; 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; import java.util.ArrayList;
@ -101,21 +96,19 @@ public class List extends BasicControl {
if(fbo != null) if(fbo != null)
fbo.destroyBuffers(); fbo.destroyBuffers();
fbo = new TextureTarget(parent.screen2DisplayX(width), parent.screen2DisplayY(height), true, Minecraft.ON_OSX); fbo = new TextureTarget(parent.screen2DisplayX(width), parent.screen2DisplayY(height), false, Minecraft.ON_OSX);
fbo.setFilterMode(GL_NEAREST); fbo.setFilterMode(GL_NEAREST);
fbo.bindWrite(true); fbo.bindWrite(false);
RenderSystem.clearColor(0.0f, 0.0f, 0.0f, 1.f); //Set alpha to 1 RenderSystem.clearColor(0.0f, 0.0f, 0.0f, 1.f); //Set alpha to 1
RenderSystem.clearDepth(GL_COLOR_BUFFER_BIT); RenderSystem.clearDepth(GL_COLOR_BUFFER_BIT);
fbo.unbindWrite(); fbo.unbindWrite();
mc.getMainRenderTarget().bindWrite(true);
update = true; update = true;
} }
private void renderToFBO(MultiBufferSource.BufferSource source) { private void renderToFBO() {
GuiGraphics graphics = beginFramebuffer(fbo, width, height); PoseStack poseStack = beginFramebuffer(fbo, width, height);
GL11.glColorMask(true, true, true, true); poseStack.pushPose();
RenderSystem.applyModelViewMatrix(); fillRect(0, 0, width, height, COLOR_BLACK);
graphics.fill(0, 0, width, height, COLOR_BLACK);
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f); RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
int offset = 4 - getYOffset(); int offset = 4 - getYOffset();
@ -127,13 +120,13 @@ public class List extends BasicControl {
break; break;
int color = (i == selected) ? selColor : COLOR_WHITE; int color = (i == selected) ? selColor : COLOR_WHITE;
graphics.drawString(font, content.get(i).text, 4, i * 12 + offset, color); font.draw(poseStack, content.get(i).text, 4, i * 12 + offset, color);
} }
} }
graphics.renderOutline(0, 0, width, height, 0xFF808080); drawBorder(poseStack, 0, 0, width, height, 0xFF808080);
graphics.flush(); endFramebuffer(poseStack, fbo);
endFramebuffer(graphics, fbo); poseStack.popPose();
} }
@Override @Override
@ -248,16 +241,13 @@ public class List extends BasicControl {
if(isInScrollbar(mouseX, mouseY)) { if(isInScrollbar(mouseX, mouseY)) {
scrolling = true; scrolling = true;
scrollGrab = mouseY - (y + 1 + scrollPos); scrollGrab = mouseY - (y + 1 + scrollPos);
return true; } else if(selected >= 0)
} else if(selected >= 0) { parent.actionPerformed(new EntryClick(this));
System.out.println(parent.actionPerformed(new EntryClick(this)));
return true;
}
return false; return true;
} }
return false; return true;
} }
@Override @Override
@ -318,18 +308,19 @@ public class List extends BasicControl {
} }
@Override @Override
public void draw(GuiGraphics graphics, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(visible) { if(visible) {
if(update) { if(update) {
renderToFBO(graphics.bufferSource()); renderToFBO();
update = false; update = false;
} }
RenderSystem.setShaderTexture(0, fbo.getColorTextureId()); fbo.bindRead(); //TODO: Make sure is right
RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f); RenderSystem.setShaderColor(1.f, 1.f, 1.f, 1.f);
fillTexturedRect(graphics.pose(), x, y, width, height, 0.0, 1.0, 1.0, 0.0); fillTexturedRect(poseStack, x, y, width, height, 0.0, 1.0, 1.0, 0.0);
fbo.unbindRead();
fillRect(graphics.bufferSource(), x + width - 5, y + 1 + scrollPos, 4, scrollSize, (scrolling || isInScrollbar(mouseX, mouseY)) ? 0xFF202020 : 0xFF404040); fillRect(x + width - 5, y + 1 + scrollPos, 4, scrollSize, (scrolling || isInScrollbar(mouseX, mouseY)) ? 0xFF202020 : 0xFF404040);
} }
} }

View File

@ -5,18 +5,13 @@
package net.montoyo.wd.client.gui.controls; package net.montoyo.wd.client.gui.controls;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.components.EditBox;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
import org.cef.browser.CefBrowserOsr;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.ArrayList; import java.util.ArrayList;
import static java.awt.event.KeyEvent.VK_ENTER;
import static org.lwjgl.glfw.GLFW.*;
public class TextField extends Control { public class TextField extends Control {
public static class EnterPressedEvent extends Event<TextField> { public static class EnterPressedEvent extends Event<TextField> {
@ -99,48 +94,40 @@ public class TextField extends Control {
public TextField() { public TextField() {
field = new EditBox(font, 1, 1, 198, 20, Component.nullToEmpty("")); field = new EditBox(font, 1, 1, 198, 20, Component.nullToEmpty(""));
setFocused(false);
} }
public TextField(int x, int y, int width, int height) { public TextField(int x, int y, int width, int height) {
field = new EditBox(font, x + 1, y + 1, width - 2, height - 2, Component.nullToEmpty("")); 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) { 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 = new EditBox(font, x + 1, y + 1, width - 2, height - 2, Component.nullToEmpty(""));
field.setValue(text); 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 @Override
public boolean keyDown(int key, int scanCode, int modifiers) { public boolean keyDown(int key) {
return field.keyPressed(key, scanCode, modifiers); 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;
} }
@Override
public boolean keyUp(int key, int scanCode, int modifiers) {
return field.keyReleased(key, scanCode, modifiers);
}
@Override @Override
public boolean keyTyped(int keyCode, int modifier) { public boolean keyTyped(int keyCode, int modifier) {
if(keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) if(keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)
@ -154,56 +141,26 @@ public class TextField extends Control {
else else
old = null; old = null;
field.charTyped((char) keyCode, modifier);
if(enabled && field.isFocused() && !field.getValue().equals(old)) { if(enabled && field.isFocused() && !field.getValue().equals(old)) {
for(TextChangeListener tcl : listeners) for(TextChangeListener tcl : listeners)
tcl.onTextChange(this, old, field.getValue()); tcl.onTextChange(this, old, field.getValue());
parent.actionPerformed(new TextChangedEvent(this, old)); parent.actionPerformed(new TextChangedEvent(this, old));
} }
return field.charTyped((char) keyCode, modifier);
} }
return false; return false;
} }
@Override @Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
if (field.mouseClicked(mouseX, mouseY, mouseButton)) { return field.mouseClicked(mouseX, mouseY, mouseButton);
setFocused(true);
return true;
}
return false;
} }
@Override @Override
public void unfocus() { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
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); field.render(poseStack, mouseX, mouseY, ptt);
} }
@ -254,26 +211,23 @@ public class TextField extends Control {
@Override @Override
public void setPos(int x, int y) { public void setPos(int x, int y) {
field.setPosition( field.x = x + 1;
x + 1, field.y = y + 1;
y + 1
);
} }
@Override @Override
public int getX() { public int getX() {
return field.getX() - 1; return field.x - 1;
} }
@Override @Override
public int getY() { public int getY() {
return field.getY() - 1; return field.y - 1;
} }
public void setDisabled(boolean en) { public void setDisabled(boolean en) {
enabled = !en; enabled = !en;
if (!en) field.setFocus(enabled);
field.setFocused(false);
} }
public boolean isDisabled() { public boolean isDisabled() {
@ -281,11 +235,12 @@ public class TextField extends Control {
} }
public void enable() { public void enable() {
field.setFocus(true);
enabled = true; enabled = true;
} }
public void disable() { public void disable() {
field.setFocused(false); field.setFocus(false);
enabled = false; enabled = false;
} }
@ -306,7 +261,7 @@ public class TextField extends Control {
} }
public void setFocused(boolean val) { public void setFocused(boolean val) {
field.setFocused(val); field.setFocus(val);
} }
public boolean hasFocus() { public boolean hasFocus() {
@ -314,7 +269,15 @@ public class TextField extends Control {
} }
public void focus() { public void focus() {
field.setFocused(true); field.setFocus(true);
}
public void setMaxLength(int len) {
field.setMaxLength(len);
}
public int getMaxLength() {
return field.getMaxLength(); //TODO: access transformer
} }
public void setTextColor(int color) { public void setTextColor(int color) {
@ -351,10 +314,8 @@ public class TextField extends Control {
@Override @Override
public void load(JsonOWrapper json) { public void load(JsonOWrapper json) {
super.load(json); super.load(json);
field.setPosition( field.x = json.getInt("x", 0) + 1;
json.getInt("x", 0) + 1, field.y = json.getInt("y", 0) + 1;
json.getInt("y", 0) + 1
);
field.setWidth(json.getInt("width", 200) - 2); field.setWidth(json.getInt("width", 200) - 2);
field.setHeight(json.getInt("height", 22) - 2); field.setHeight(json.getInt("height", 22) - 2);
field.setValue(tr(json.getString("text", ""))); field.setValue(tr(json.getString("text", "")));
@ -367,7 +328,7 @@ public class TextField extends Control {
field.setTextColor(textColor); field.setTextColor(textColor);
field.setTextColorUneditable(disabledColor); field.setTextColorUneditable(disabledColor);
setFocused(false); field.setFocus(enabled);
} }
} }

View File

@ -6,10 +6,9 @@ package net.montoyo.wd.client.gui.controls;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft; 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.client.renderer.entity.ItemRenderer;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.eventbus.api.IEventBus;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
import java.util.ArrayList; import java.util.ArrayList;
@ -28,23 +27,23 @@ public class UpgradeGroup extends BasicControl {
} }
@Override @Override
public void draw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void draw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(upgrades != null) { if(upgrades != null) {
int x = this.x; int x = this.x;
for(ItemStack is: upgrades) { for(ItemStack is: upgrades) {
if(is == overStack && !disabled) if(is == overStack && !disabled)
fillRect(poseStack.bufferSource(), x, y, 16, 16, 0x80FF0000); fillRect(x, y, 16, 16, 0x80FF0000);
poseStack.renderItem(is, x, y); renderItem.renderAndDecorateItem(mc.player, is, x, y, 0);
poseStack.renderItemDecorations(font, is, x, y); renderItem.renderAndDecorateItem(is, font.lineHeight, x, y); //TODO is lineHeight right?
x += 18; x += 18;
} }
} }
} }
@Override @Override
public void postDraw(GuiGraphics poseStack, int mouseX, int mouseY, float ptt) { public void postDraw(PoseStack poseStack, int mouseX, int mouseY, float ptt) {
if(overStack != null) if(overStack != null)
parent.drawItemStackTooltip(poseStack, overStack, mouseX, mouseY); parent.drawItemStackTooltip(poseStack, overStack, mouseX, mouseY);
} }
@ -104,15 +103,9 @@ public class UpgradeGroup extends BasicControl {
@Override @Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) { public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
if(mouseButton == 0) { if(mouseButton == 0) {
// don't process the click if it's not inbounds, lol clickStack = overStack;
if (
mouseX >= x && mouseX <= x + width && return true;
mouseY >= y && mouseX <= y + height
) {
clickStack = overStack;
return true;
}
} }
return false; return false;

View File

@ -6,7 +6,7 @@ package net.montoyo.wd.client.gui.controls;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.montoyo.wd.client.gui.loading.JsonOWrapper; import net.montoyo.wd.client.gui.loading.JsonOWrapper;
import net.montoyo.wd.utilities.serialization.Util; import net.montoyo.wd.utilities.Util;
import net.montoyo.wd.utilities.VideoType; import net.montoyo.wd.utilities.VideoType;
import java.net.MalformedURLException; import java.net.MalformedURLException;

View File

@ -62,15 +62,24 @@ public class GuiLoader {
return ret; return ret;
} }
public static JsonObject getJson(ResourceLocation resLoc) throws IOException { public static JsonObject getJson(ResourceLocation resLoc) {
JsonObject ret = RESOURCES.get(resLoc); JsonObject ret = RESOURCES.get(resLoc);
if(ret == null) { if(ret == null) {
Resource resource; Resource resource;
resource = Minecraft.getInstance().getResourceManager().getResource(resLoc).get(); try {
resource = Minecraft.getInstance().getResourceManager().getResource(resLoc);
} catch(IOException e) {
Log.errorEx("Couldn't load JSON UI from file", e);
throw new RuntimeException(e);
}
JsonParser parser = new JsonParser(); JsonParser parser = new JsonParser();
ret = parser.parse(new InputStreamReader(resource.open())).getAsJsonObject(); ret = parser.parse(new InputStreamReader(resource.getInputStream())).getAsJsonObject();
try {
resource.close();
} catch(IOException e) {}
RESOURCES.put(resLoc, ret); RESOURCES.put(resLoc, ret);
} }

View File

@ -9,17 +9,7 @@ import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
public interface IItemRenderer { 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);
} }

View File

@ -0,0 +1,15 @@
/*
* 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);
}

View File

@ -4,127 +4,112 @@
package net.montoyo.wd.client.renderers; package net.montoyo.wd.client.renderers;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*; import com.mojang.blaze3d.vertex.*;
import net.minecraft.client.Minecraft; import com.mojang.math.Vector3f;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack; 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.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.montoyo.wd.client.ClientProxy; import org.lwjgl.BufferUtils;
import net.montoyo.wd.registry.ItemRegistry;
import net.montoyo.wd.item.ItemLaserPointer;
import org.joml.Matrix4f;
import static com.mojang.math.Axis.*; import java.nio.FloatBuffer;
import static org.lwjgl.opengl.GL11.*;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public final class LaserPointerRenderer implements IItemRenderer { public final class LaserPointerRenderer implements IItemRenderer {
private final Tesselator t = Tesselator.getInstance();
private final BufferBuilder bb = t.getBuilder(); private static final float PI = (float) Math.PI;
private final Tesselator t = Tesselator.getInstance();
public LaserPointerRenderer() { private final BufferBuilder bb = t.getBuilder();
} private final VertexBuffer vb = new VertexBuffer();
private final FloatBuffer matrix1 = BufferUtils.createFloatBuffer(16);
public static boolean isOn() { private final FloatBuffer renderBuffer = BufferUtils.createFloatBuffer(8);
if (Minecraft.getInstance().screen != null) return false;
public boolean isOn = false;
Minecraft mc = Minecraft.getInstance();
return mc.player != null && mc.level != null && public LaserPointerRenderer() {
( for(int i = 0; i < 8; i++)
ClientProxy.mouseOn || renderBuffer.put(0.0f);
ItemLaserPointer.isOn()
) && renderBuffer.position(0);
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 void render(PoseStack poseStack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
@Override //This whole method is a fucking hack
public boolean render(PoseStack poseStack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) { float sqrtSwingProg = (float) Math.sqrt(swingProgress);
RenderSystem.disableCull(); float sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
// RenderSystem.disableTexture();
RenderSystem.enableDepthTest(); RenderSystem.disableCull();
RenderSystem.enableBlend(); RenderSystem.disableTexture();
float PI = (float) Math.PI; poseStack.pushPose();
//Laser pointer
float sqrtSwingProg = (float) Math.sqrt(swingProgress); poseStack.pushPose();
float sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI); 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);
RenderSystem.setShader(GameRenderer::getPositionColorShader); 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));
var matrix0 = poseStack.last().pose(); poseStack.mulPose(Vector3f.XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
//Laser pointer poseStack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -30.0f));
poseStack.pushPose(); poseStack.translate(0.0f, 0.2f, 0.0f);
poseStack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, (float) (0.2f * Math.sin(sqrtSwingProg * PI * 2.0f)), (float) (-0.2f * Math.sin(swingProgress * PI))); poseStack.mulPose(Vector3f.XP.rotationDegrees(10.0f));
poseStack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f); poseStack.scale(1.0f / 16.0f, 1.0f / 16.0f, 1.0f / 16.0f);
poseStack.mulPose(YP.rotationDegrees((float) (handSideSign * (45.0f - Math.sin(swingProgress * swingProgress * PI) * 20.0f))));
poseStack.mulPose(ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f)); RenderSystem.setShaderColor(0.5f, 0.5f, 0.5f, 1.0f);
poseStack.mulPose(XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
poseStack.mulPose(YP.rotationDegrees(handSideSign * -30.0f)); bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
poseStack.translate(0.0f, 0.2f, 0.0f); bb.vertex(0.0, 0.0, 0.0).endVertex();
poseStack.mulPose(XP.rotationDegrees(10.0f)); bb.vertex(1.0, 0.0, 0.0).endVertex();
poseStack.scale(1.0f / 16.0f, 1.0f / 16.0f, 1.0f / 16.0f); bb.vertex(1.0, 0.0, 4.0).endVertex();
var matrix = poseStack.last().pose(); bb.vertex(0.0, 0.0, 4.0).endVertex();
bb.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); bb.vertex(0.0, 0.0, 0.0).endVertex();
bb.vertex(0.0, -1.0, 0.0).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); bb.vertex(0.0, -1.0, 4.0).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); bb.vertex(0.0, 0.0, 4.0).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(1.0, 0.0, 0.0).endVertex();
bb.vertex(1.0, -1.0, 0.0).endVertex();
bb.vertex(matrix, 0.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); bb.vertex(1.0, -1.0, 4.0).endVertex();
bb.vertex(matrix, 0.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); bb.vertex(1.0, 0.0, 4.0).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(0.0, -1.0, 4.0).endVertex();
bb.vertex(1.0, -1.0, 4.0).endVertex();
bb.vertex(matrix, 1.0f, 0.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); bb.vertex(1.0, 0.0, 4.0).endVertex();
bb.vertex(matrix, 1.0f, -1.0f, 0.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); bb.vertex(0.0, 0.0, 4.0).endVertex();
bb.vertex(matrix, 1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); t.end();
bb.vertex(matrix, 1.0f, 0.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); if(isOn) {
poseStack.translate(0.5f, -0.5f, 0.0f);
bb.vertex(matrix, 0.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); matrix1.position(0);
bb.vertex(matrix, 1.0f, -1.0f, 4.0f).color(0.5f, 0.5f, 0.5f, 1.0f).endVertex(); RenderSystem.getModelViewMatrix(); //Hax to get that damn position
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();
poseStack.popPose();
if (isOn()) drawLineBetween(bb, matrix0, matrix, new Vec3(0.5f, -0.5f, 0.5f), new Vec3(-40.0f, 4000.5f, -100.0f));
if(isOn) {
t.end(); //Actual laser
poseStack.pushPose();
RenderSystem.disableBlend(); RenderSystem.enableBlend();
RenderSystem.disableDepthTest(); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.DST_ALPHA);
// RenderSystem.enableTexture(); //Fix for shitty minecraft fire RenderSystem.setShaderColor(1.0f, 0.0f, 0.0f, 0.5f);
RenderSystem.enableCull(); RenderSystem.lineWidth(3.0f);
poseStack.popPose();
matrix1.position(12);
return true; 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...
private static void drawLineBetween(BufferBuilder bb, Matrix4f matrix0, Matrix4f matrix, Vec3 local, Vec3 target) { renderBuffer.put(matrix1.get());
//Calculate distance between points -> length of the line renderBuffer.position(0);
float distance = (float) local.distanceTo(target) / 2; RenderSystem.drawElements(GL_LINES, 0, GL_UNSIGNED_INT);
float quarterWidth = 0.25f; poseStack.popPose();
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(); RenderSystem.enableTexture(); //Fix for shitty minecraft fire
bb.vertex(matrix, quarterWidth + 0.25f, -0.25f, 0.5f).color((float) 0.5, (float) 0.0, (float) 0.0, (float) 1.0).endVertex(); RenderSystem.enableCull();
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();
}
} }

View File

@ -4,161 +4,132 @@
package net.montoyo.wd.client.renderers; package net.montoyo.wd.client.renderers;
import com.cinemamod.mcef.MCEFBrowser;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Vector3f;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.montoyo.wd.WebDisplays; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.config.ClientConfig;
import net.montoyo.wd.item.ItemMinePad2;
import static com.mojang.math.Axis.*; import static org.lwjgl.opengl.GL12.GL_RESCALE_NORMAL;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public final class MinePadRenderer implements IItemRenderer { public final class MinePadRenderer implements IItemRenderer {
private static final float PI = (float) Math.PI;
private final Minecraft mc = Minecraft.getInstance(); private static final float PI = (float) Math.PI;
private final ResourceLocation tex = new ResourceLocation("webdisplays", "textures/item/model/minepad.png"); private final Minecraft mc = Minecraft.getInstance();
private final ModelMinePad model = new ModelMinePad(); private final ResourceLocation tex = new ResourceLocation("webdisplays", "textures/models/minepad.png");
private final ClientProxy clientProxy = (ClientProxy) WebDisplays.PROXY; // private final ModelMinePad model = new ModelMinePad();
private final ClientProxy clientProxy = (ClientProxy) WebDisplays.PROXY;
private float sinSqrtSwingProg1;
private float sinSqrtSwingProg2; private float sinSqrtSwingProg1;
private float sinSwingProg1; private float sinSqrtSwingProg2;
private float sinSwingProg2; private float sinSwingProg1;
private float sinSwingProg2;
public static boolean renderAtSide(float handSideSign) {
float relSide = handSideSign; // public static void drawAxis() {
if (Minecraft.getInstance().player.getMainArm() == HumanoidArm.LEFT) relSide *= -1; // glDisable(GL_TEXTURE_2D);
// glBegin(GL_LINES);
// by default, the player holds the device off to the side // glColor4f(1.f, 0.f, 0.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
// if they are crouching, they hold it infront of them // glColor4f(1.f, 0.f, 0.f, 1.f); glVertex3d(5.0, 0.0, 0.0);
// however, if they are holding two at once, then it once again should just be held off to the side // glColor4f(0.f, 1.f, 0.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
boolean sideHold = Minecraft.getInstance().player.isShiftKeyDown() != ClientConfig.sidePad; // glColor4f(0.f, 1.f, 0.f, 1.f); glVertex3d(0.0, 5.0, 0.0);
if ( // glColor4f(0.f, 0.f, 1.f, 1.f); glVertex3d(0.0, 0.0, 0.0);
(relSide < 0 && Minecraft.getInstance().player.getItemInHand(InteractionHand.MAIN_HAND).getItem() instanceof ItemMinePad2) || // glColor4f(0.f, 0.f, 1.f, 1.f); glVertex3d(0.0, 0.0, 5.0);
(relSide > 0 && Minecraft.getInstance().player.getItemInHand(InteractionHand.OFF_HAND).getItem() instanceof ItemMinePad2) // glEnd();
) sideHold = true; // glEnable(GL_TEXTURE_2D);
// }
return sideHold;
} @Override
public final void render(PoseStack stack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) {
@Override //Pre-compute values
public final boolean render(PoseStack stack, ItemStack is, float handSideSign, float swingProgress, float equipProgress, MultiBufferSource multiBufferSource, int packedLight) { float sqrtSwingProg = (float) Math.sqrt(swingProgress);
//Pre-compute values sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI);
float sqrtSwingProg = (float) Math.sqrt(swingProgress); sinSqrtSwingProg2 = (float) Math.sin(sqrtSwingProg * PI * 2.0f);
sinSqrtSwingProg1 = (float) Math.sin(sqrtSwingProg * PI); sinSwingProg1 = (float) Math.sin(swingProgress * PI);
sinSqrtSwingProg2 = (float) Math.sin(sqrtSwingProg * PI * 2.0f); sinSwingProg2 = (float) Math.sin(swingProgress * swingProgress * PI);
sinSwingProg1 = (float) Math.sin(swingProgress * PI);
sinSwingProg2 = (float) Math.sin(swingProgress * swingProgress * PI); RenderSystem.disableCull();
// glEnable(GL_RESCALE_NORMAL);
boolean sideHold = renderAtSide(handSideSign);
//Render arm
//Render arm stack.pushPose();
stack.pushPose(); renderArmFirstPerson(stack, multiBufferSource, packedLight, equipProgress, handSideSign);
renderArmFirstPerson(stack, multiBufferSource, packedLight, equipProgress, handSideSign); stack.popPose();
stack.popPose();
// if (!sideHold && handSideSign == 1 && mc.player.getItemInHand(InteractionHand.OFF_HAND).isEmpty()) { //Prepare minePad transform
// stack.pushPose(); stack.pushPose();
// renderArmFirstPerson(stack, multiBufferSource, packedLight, 0, -handSideSign); stack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, 0.2f * sinSqrtSwingProg2, -0.2f * sinSwingProg1);
// stack.popPose(); 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));
//Prepare minePad transform stack.mulPose(Vector3f.XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f));
stack.pushPose(); stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -45.0f));
stack.translate(handSideSign * -0.4f * sinSqrtSwingProg1, 0.2f * sinSqrtSwingProg2, -0.2f * sinSwingProg1);
stack.translate(handSideSign * 0.56f, -0.52f - equipProgress * 0.6f, -0.72f); if(handSideSign >= 0.0f)
stack.mulPose(YP.rotationDegrees(handSideSign * (45.0f - sinSwingProg2 * 20.0f))); stack.translate(-1.065f, 0.0f, 0.0f);
stack.mulPose(ZP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * -20.0f)); else {
stack.mulPose(XP.rotationDegrees(sinSqrtSwingProg1 * -80.0f)); stack.translate(0.0f, 0.0f, -0.2f);
stack.mulPose(YP.rotationDegrees(handSideSign * -45.0f)); stack.mulPose(Vector3f.YP.rotationDegrees(20.0f));
stack.translate(-0.475f, -0.1f, 0.0f);
if (sideHold) { stack.mulPose(Vector3f.ZP.rotationDegrees(1.0f));
stack.translate(0.0f, 0.0f, -0.2f); }
stack.mulPose(YP.rotationDegrees(20.0f * -handSideSign));
float total = 0.475f; //Render model
float off = -0.025f; // gotta love magic numbers stack.pushPose();
stack.translate(-(total - off) + (off * handSideSign), -0.1f, 0.0f); stack.mulPose(Vector3f.XP.rotationDegrees(-90.0f));
stack.mulPose(ZP.rotationDegrees(1.0f)); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
} else if (handSideSign >= 0) // right hand RenderSystem.setShaderTexture(0, tex);
stack.translate(-1.065f, 0.0f, 0.0f); // model.render(1.f / 16.f);
else // left hand stack.popPose();
stack.translate(0.065f, 0.0f, 0.0f);
//Render web view
//Render model if(is.getTag() != null && is.getTag().contains("PadID")) {
stack.translate(0.063f, 0.28f, 0.001f); ClientProxy.PadData pd = clientProxy.getPadByID(is.getTag().getInt("PadID"));
model.render(multiBufferSource, stack);
stack.translate(-0.063f, -0.28f, -0.001f); if(pd != null) {
stack.translate(0.063f, 0.28f, 0.001f);
// force draw so the browser can be drawn ontop of the model RenderSystem.disableTexture();
multiBufferSource.getBuffer(RenderType.LINES); pd.view.draw(stack,0.0, 0.0, 27.65 / 32.0 + 0.01, 14.0 / 32.0 + 0.002);
}
if (is.getTag() != null && is.getTag().contains("PadID")) { }
ClientProxy.PadData pd = clientProxy.getPadByID(is.getTag().getUUID("PadID"));
stack.popPose();
//Render web view // glDisable(GL_RESCALE_NORMAL);
if (pd != null) { RenderSystem.enableCull();
double x1 = 0.0; }
double y1 = 0.0;
double x2 = 27.65 / 32.0 + 0.01; private void renderArmFirstPerson(PoseStack stack, MultiBufferSource buffer, int combinedLight, float equipProgress, float handSideSign) {
double y2 = 14.0 / 32.0 + 0.002; float tx = -0.3f * sinSqrtSwingProg1;
float ty = 0.4f * sinSqrtSwingProg2;
stack.translate(0.063f, 0.28f, 0.001f); float tz = -0.4f * sinSwingProg1;
// RenderSystem.setShaderTexture(0, tex);
stack.translate(handSideSign * (tx + 0.64000005f), ty - 0.6f - equipProgress * 0.6f, tz - 0.71999997f);
RenderSystem.disableDepthTest(); stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * 45.0f));
RenderSystem.setShader(GameRenderer::getPositionTexColorShader); stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * sinSqrtSwingProg1 * 70.0f));
RenderSystem.setShaderTexture(0, ((MCEFBrowser) pd.view).getRenderer().getTextureID()); stack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * sinSwingProg2 * -20.0f));
Tesselator t = Tesselator.getInstance(); stack.translate(-handSideSign, 3.6f, 3.5f);
BufferBuilder buffer = t.getBuilder(); stack.mulPose(Vector3f.ZP.rotationDegrees(handSideSign * 120.0f));
buffer.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); stack.mulPose(Vector3f.XP.rotationDegrees(200.0f));
buffer.vertex(stack.last().pose(), (float) x1, (float) y1, 0.0f).uv(0.0F, 1.0F).color(255, 255, 255, 255).endVertex(); stack.mulPose(Vector3f.YP.rotationDegrees(handSideSign * -135.0f));
buffer.vertex(stack.last().pose(), (float) x2, (float) y1, 0.0f).uv(1.0F, 1.0F).color(255, 255, 255, 255).endVertex(); stack.translate(handSideSign * 5.6f, 0.0f, 0.0f);
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(); PlayerRenderer playerRenderer = (PlayerRenderer) mc.getEntityRenderDispatcher().getRenderer(mc.player);
t.end(); RenderSystem.setShaderTexture(0, mc.player.getSkinTextureLocation());
RenderSystem.enableDepthTest();
} if(handSideSign >= 0.0f)
} playerRenderer.renderRightHand(stack, buffer, combinedLight, mc.player);
else
stack.popPose(); playerRenderer.renderLeftHand(stack, buffer, combinedLight, mc.player);
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);
}
} }

View File

@ -4,70 +4,60 @@
package net.montoyo.wd.client.renderers; package net.montoyo.wd.client.renderers;
import com.mojang.blaze3d.systems.RenderSystem; /*import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.*; import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.model.Model;
import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.model.geom.ModelPart;
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.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import org.joml.Matrix4f;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public final class ModelMinePad { public final class ModelMinePad extends Model {
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();
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(); // fields
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(); private final ModelPart base;
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(); private final ModelPart left;
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(); private final ModelPart right;
// 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(); public ModelMinePad() {
// 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(); super();
// 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(); textureWidth = 64;
// 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(); textureHeight = 32;
//
// 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(); base = new ModelPart(this, 0, 0);
// 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(); base.addBox(0F, 0F, 0F, 14, 1, 9);
// 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(); base.setRotationPoint(1F, 0F, 3.5F);
// 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(); 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) {
}
}*/

View File

@ -5,232 +5,164 @@
package net.montoyo.wd.client.renderers; package net.montoyo.wd.client.renderers;
import com.google.common.collect.ImmutableList; 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.BakedQuad;
import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.renderer.block.model.ItemOverrides;
import net.minecraft.client.renderer.block.model.ItemTransforms; 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.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.ModelState;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.ModelData; import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraftforge.client.model.data.ModelProperty; import net.minecraft.world.level.material.Material;
import net.montoyo.wd.utilities.data.BlockSide; import net.minecraftforge.client.model.data.IDynamicBakedModel;
import net.montoyo.wd.utilities.math.Vector3f; import net.minecraftforge.client.model.data.IModelData;
import net.montoyo.wd.utilities.math.Vector3i; import net.montoyo.wd.utilities.BlockSide;
import net.montoyo.wd.utilities.Vector3f;
import net.montoyo.wd.utilities.Vector3i;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Random;
import java.util.function.Function; import java.util.function.Function;
public class ScreenBaker implements BakedModel { public class ScreenBaker implements IModelBaker {
private static final List<BakedQuad> noQuads = ImmutableList.of(); private static final List<BakedQuad> noQuads = ImmutableList.of();
private final TextureAtlasSprite[] texs = new TextureAtlasSprite[16]; private final TextureAtlasSprite[] texs = new TextureAtlasSprite[16];
private final BlockSide[] blockSides = BlockSide.values(); private final BlockSide[] blockSides = BlockSide.values();
private final Direction[] blockFacings = Direction.values(); private final Direction[] blockFacings = Direction.values();
private final ModelState modelState; private final ModelState modelState;
private final Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter; private final Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter;
private final ItemOverrides overrides; private final ItemOverrides overrides;
private final ItemTransforms itemTransforms; 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;
public ScreenBaker(ModelState modelState, Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter, ItemOverrides overrides, ItemTransforms itemTransforms) { this.spriteGetter = spriteGetter;
this.modelState = modelState; this.overrides = overrides;
this.spriteGetter = spriteGetter; this.itemTransforms = itemTransforms;
this.overrides = overrides; }
this.itemTransforms = itemTransforms;
@Override
for (int i = 0; i < texs.length; i++) { public void loadTextures(TextureAtlas texMap) {
texs[i] = spriteGetter.apply(ScreenModelLoader.MATERIALS_SIDES[i]); for(int i = 0; i < texs.length; i++)
} texs[i] = texMap.getSprite(new ResourceLocation("webdisplays", "blocks/screen" + 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) {
} buf[pos * 7 + 0] = Float.floatToRawIntBits(vpos.x);
} buf[pos * 7 + 1] = Float.floatToRawIntBits(vpos.y);
buf[pos * 7 + 2] = Float.floatToRawIntBits(vpos.z);
private void putVertex(int[] buf, int pos, Vector3f vpos, TextureAtlasSprite tex, Vector3f uv, Vector3i normal) { buf[pos * 7 + 3] = 0xFFFFFFFF; //Color, let this white...
pos *= 8; buf[pos * 7 + 4] = Float.floatToRawIntBits(tex.getU(uv.x));
buf[pos * 7 + 5] = Float.floatToRawIntBits(tex.getV(uv.y));
buf[pos] = Float.floatToRawIntBits(vpos.x);
buf[pos + 1] = Float.floatToRawIntBits(vpos.y); int nx = (normal.x * 127) & 0xFF;
buf[pos + 2] = Float.floatToRawIntBits(vpos.z); int ny = (normal.y * 127) & 0xFF;
buf[pos + 3] = 0xFFFFFFFF; //Color, let this white... int nz = (normal.z * 127) & 0xFF;
buf[pos + 4] = Float.floatToRawIntBits(tex.getU(uv.x)); buf[pos * 7 + 6] = nx | (ny << 8) | (nz << 16);
buf[pos + 5] = Float.floatToRawIntBits(tex.getV(uv.y)); }
int nx = (normal.x * 127) & 0xFF; private Vector3f rotateVec(Vector3f vec, BlockSide side) {
int ny = (normal.y * 127) & 0xFF; switch(side) {
int nz = (normal.z * 127) & 0xFF; case BOTTOM: return new Vector3f(vec.x, 1.0f, 1.0f - vec.z);
buf[pos + 7] = nx | (ny << 8) | (nz << 16); 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);
private Vector3f rotateVec(Vector3f vec, BlockSide side) { case WEST: return new Vector3f(1.f , vec.x, vec.z);
return switch (side) { case EAST: return new Vector3f(0.0f, 1.0f - vec.x, vec.z);
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); throw new RuntimeException("Unknown block side " + side);
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); private Vector3f rotateTex(BlockSide side, float u, float v) {
//noinspection UnnecessaryDefault switch(side) {
default -> throw new RuntimeException("Unknown block side " + 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);
private Vector3f rotateTex(BlockSide side, float u, float v) { case WEST: return new Vector3f(v, 16.f - u, 0.0f);
return switch (side) { case EAST: return new Vector3f(16.f - v, u, 0.0f);
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); throw new RuntimeException("Unknown block side " + side);
case WEST -> new Vector3f(16.f - v, u, 0.0f); }
case EAST -> new Vector3f(v, 16.f - u, 0.0f);
//noinspection UnnecessaryDefault private BakedQuad bakeSide(BlockSide side, TextureAtlasSprite tex) {
default -> throw new RuntimeException("Unknown block side " + side); 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);
private BakedQuad bakeSide(BlockSide side, TextureAtlasSprite tex) { putVertex(data, 1, rotateVec(new Vector3f(1.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 16.0f, 16.0f), side.backward);
int[] data = new int[8 * 4]; putVertex(data, 0, rotateVec(new Vector3f(1.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 16.0f, 0.0f ), side.backward);
// I have no idea return new BakedQuad(data, 0xFFFFFFFF, blockFacings[side.ordinal()], tex, true);
int rotation = switch (side) { }
case NORTH, TOP, BOTTOM -> 2;
case SOUTH -> 0; @NotNull
case EAST -> 1; @Override
case WEST -> 3; public List<BakedQuad> getQuads(@org.jetbrains.annotations.Nullable BlockState state, @org.jetbrains.annotations.Nullable Direction side, @NotNull Random random, @NotNull IModelData iModelData) {
//noinspection UnnecessaryDefault if(side == null)
default -> throw new RuntimeException("Unknown block side " + side); return noQuads;
}; BlockState bs = state;
List<BakedQuad> ret = new ArrayList<>();
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); int sid = BlockSide.reverse(side.ordinal());
putVertex(data, (rotation + 1) % 4, rotateVec(new Vector3f(1.0f, 0.0f, 1.0f), side), tex, rotateTex(side, 0.0f, 16.0f), side.backward); BlockSide s = blockSides[sid];
putVertex(data, (rotation) % 4, rotateVec(new Vector3f(1.0f, 0.0f, 0.0f), side), tex, rotateTex(side, 0.0f, 0.0f), side.backward); TextureAtlasSprite tex = texs[15];
if(bs != null) {
return new BakedQuad(data, 0xFFFFFFFF, blockFacings[side.ordinal()].getOpposite(), tex, true); IntegerProperty[] sideFlags = new IntegerProperty[6];
} for(int i = 0; i < sideFlags.length; i++)
sideFlags[i] = IntegerProperty.create("neighbor" + i, 0, 15);
@Override tex = texs[bs.getValue(sideFlags[sid])];
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource random) { }
return getQuads(state, side, random, ModelData.EMPTY, null); ret.add(bakeSide(s, tex));
} return ret;
}
@Override
public @NotNull List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @NotNull RandomSource rand, @NotNull ModelData data, @Nullable RenderType renderType) { @Override
if (side == null) public boolean useAmbientOcclusion() {
return noQuads; return true;
}
List<BakedQuad> ret = new ArrayList<>();
@Override
int sid = BlockSide.reverse(side.ordinal()); public boolean isGui3d() {
BlockSide s = blockSides[sid]; return true;
TextureAtlasSprite tex = texs[15]; }
if (data.has(TEXTURES[side.ordinal()]))
tex = texs[data.get(TEXTURES[side.ordinal()])]; @Override
ret.add(bakeSide(s, tex)); public boolean usesBlockLight() {
return ret; return false;
} }
protected byte check(BlockState state, BlockAndTintGetter level, BlockPos pos, Vector3i dir) { @Override
BlockState u = level.getBlockState(pos.offset(dir.x, dir.y, dir.z)); public boolean isCustomRenderer() {
BlockState d = level.getBlockState(pos.offset(-dir.x, -dir.y, -dir.z)); return false;
if ( }
u.getBlock() == state.getBlock() &&
d.getBlock() != state.getBlock() @Override
) return (byte) 1; // away @Nonnull
else if ( public TextureAtlasSprite getParticleIcon() {
d.getBlock() == state.getBlock() && return texs[15];
u.getBlock() != state.getBlock() }
) return (byte) 2; // to
else if ( @Override
d.getBlock() != state.getBlock() && @Nonnull
u.getBlock() != state.getBlock() public ItemTransforms getTransforms() {
) return (byte) 3; // both return ItemTransforms.NO_TRANSFORMS;
return (byte) 0; // none }
}
@Override
@Override @Nonnull
public @NotNull ModelData getModelData(@NotNull BlockAndTintGetter level, @NotNull BlockPos pos, @NotNull BlockState state, @NotNull ModelData modelData) { public ItemOverrides getOverrides() {
ModelData.Builder builder = ModelData.builder(); return ItemOverrides.EMPTY;
}
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
} }

View File

@ -2,65 +2,56 @@ package net.montoyo.wd.client.renderers;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.renderer.block.model.ItemOverrides;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.*; import net.minecraft.client.resources.model.*;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.geometry.IGeometryBakingContext; import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IGeometryLoader; import net.minecraftforge.client.model.IModelLoader;
import net.minecraftforge.client.model.geometry.IUnbakedGeometry; import net.minecraftforge.client.model.geometry.IModelGeometry;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
public class ScreenModelLoader implements IGeometryLoader<ScreenModelLoader.ScreenModelGeometry> { public class ScreenModelLoader implements IModelLoader<ScreenModelLoader.ScreenModelGeometry> {
public static final ResourceLocation SCREEN_LOADER = new ResourceLocation("webdisplays", "screen_loader"); 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 ResourceLocation SCREEN_SIDE = new ResourceLocation("webdisplays", "block/screen");
private static final ResourceLocation[] SIDES = new ResourceLocation[16]; public static final Material MATERIAL_SIDE = ForgeHooksClient.getBlockMaterial(SCREEN_SIDE);
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 @Override
public ScreenModelGeometry read(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { public void onResourceManagerReload(ResourceManager resourceManager) {
}
@Override
public ScreenModelGeometry read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
return new ScreenModelGeometry(); return new ScreenModelGeometry();
} }
public static class ScreenModelGeometry implements IUnbakedGeometry<ScreenModelGeometry> {
@Override
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();
// }
// TODO: ? public static class ScreenModelGeometry implements IModelGeometry<ScreenModelGeometry> {
// @Override @Override
// public Collection<Material> getMaterials(IGeometryBakingContext iGeometryBakingContext, Function<ResourceLocation, UnbakedModel> function, Set<Pair<String, String>> set) { public BakedModel bake(IModelConfiguration owner, ModelBakery modelBakery, Function<net.minecraft.client.resources.model.Material, TextureAtlasSprite> spriteGetter, ModelState modelState, ItemOverrides itemOverrides, ResourceLocation resourceLocation) {
// return Arrays.asList(MATERIALS_SIDES); return new ScreenBaker(modelState, spriteGetter, itemOverrides, owner.getCameraTransforms());
// } }
@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);
}
} }
} }

View File

@ -4,186 +4,205 @@
package net.montoyo.wd.client.renderers; package net.montoyo.wd.client.renderers;
import com.cinemamod.mcef.MCEFBrowser; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*; import com.mojang.blaze3d.vertex.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.world.phys.AABB;
import net.montoyo.wd.WebDisplays; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.entity.ScreenBlockEntity; import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.entity.ScreenData; import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.utilities.math.Vector3f; import net.montoyo.wd.utilities.Vector3f;
import net.montoyo.wd.utilities.math.Vector3i; import net.montoyo.wd.utilities.Vector3i;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static com.mojang.math.Axis.*; import static com.mojang.math.Vector3f.*;
import static org.lwjgl.opengl.GL11.*;
public class ScreenRenderer implements BlockEntityRenderer<ScreenBlockEntity> { public class ScreenRenderer implements BlockEntityRenderer<TileEntityScreen> {
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;
//Disable lighting public static class ScreenRendererProvider implements BlockEntityRendererProvider<TileEntityScreen> {
// RenderSystem.enableTexture(); @Override
// RenderSystem.disableCull(); public @NotNull BlockEntityRenderer<TileEntityScreen> create(@NotNull Context arg) {
RenderSystem.disableBlend(); return new ScreenRenderer();
}
for (int i = 0; i < te.screenCount(); i++) { }
ScreenData scr = te.getScreen(i);
if (scr.browser == null) { private final Vector3f mid = new Vector3f();
double dist = WebDisplays.PROXY.distanceTo(te, Minecraft.getInstance().getEntityRenderDispatcher().camera.getPosition()); private final Vector3i tmpi = new Vector3i();
if (dist <= WebDisplays.INSTANCE.loadDistance2 * 16) private final Vector3f tmpf = new Vector3f();
scr.createBrowser(te, true);
else continue; @Override
} public void render(TileEntityScreen te, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
if(!te.isLoaded())
// TODO: manually backface cull the screens return;
tmpi.set(scr.side.right); //Disable lighting
tmpi.mul(scr.size.x); RenderSystem.enableTexture();
tmpi.addMul(scr.side.up, scr.size.y); RenderSystem.disableCull();
tmpf.set(tmpi); RenderSystem.disableBlend();
mid.set(0.5, 0.5, 0.5);
mid.addMul(tmpf, 0.5f); for(int i = 0; i < te.screenCount(); i++) {
tmpf.set(scr.side.left); TileEntityScreen.Screen scr = te.getScreen(i);
mid.addMul(tmpf, 0.5f); if(scr.browser == null) {
tmpf.set(scr.side.down); scr.browser = ((ClientProxy) WebDisplays.PROXY).getMCEF().createBrowser(WebDisplays.applyBlacklist(scr.url));
mid.addMul(tmpf, 0.5f);
if(scr.rotation.isVertical)
poseStack.pushPose(); scr.browser.resize(scr.resolution.y, scr.resolution.x);
poseStack.translate(mid.x, mid.y, mid.z); else
scr.browser.resize(scr.resolution.x, scr.resolution.y);
switch (scr.side) {
case BOTTOM: scr.doTurnOnAnim = true;
poseStack.mulPose(XP.rotation(90.f + 49.8f)); scr.turnOnTime = System.currentTimeMillis();
break; }
case TOP: tmpi.set(scr.side.right);
poseStack.mulPose(XN.rotation(90.f + 49.8f)); tmpi.mul(scr.size.x);
break; tmpi.addMul(scr.side.up, scr.size.y);
tmpf.set(tmpi);
case NORTH: mid.set(0.5, 0.5, 0.5);
poseStack.mulPose(YN.rotationDegrees(180.f)); mid.addMul(tmpf, 0.5f);
break; tmpf.set(scr.side.left);
mid.addMul(tmpf, 0.5f);
case SOUTH: tmpf.set(scr.side.down);
break; mid.addMul(tmpf, 0.5f);
case WEST: poseStack.pushPose();
poseStack.mulPose(YN.rotationDegrees(90.f)); poseStack.translate(mid.x, mid.y, mid.z);
break;
switch(scr.side) {
case EAST: case BOTTOM:
poseStack.mulPose(YP.rotationDegrees(90.f)); poseStack.mulPose(XP.rotation(90.f + 49.8f));
break; break;
}
case TOP:
if (scr.doTurnOnAnim) { poseStack.mulPose(XN.rotation(90.f + 49.8f));
long lt = System.currentTimeMillis() - scr.turnOnTime; break;
float ft = ((float) lt) / 100.0f;
case NORTH:
if (ft >= 1.0f) { poseStack.mulPose(YN.rotationDegrees(180.f));
ft = 1.0f; break;
scr.doTurnOnAnim = false;
} case SOUTH:
break;
poseStack.scale(ft, ft, 1.0f);
} case WEST:
poseStack.mulPose(YN.rotationDegrees(90.f));
if (!scr.rotation.isNull) break;
poseStack.mulPose(ZP.rotationDegrees(scr.rotation.angle));
case EAST:
float sw = ((float) scr.size.x) * 0.5f - 2.f / 16.f; poseStack.mulPose(YP.rotationDegrees(90.f));
float sh = ((float) scr.size.y) * 0.5f - 2.f / 16.f; break;
}
if (scr.rotation.isVertical) {
float tmp = sw; if(scr.doTurnOnAnim) {
sw = sh; long lt = System.currentTimeMillis() - scr.turnOnTime;
sh = tmp; float ft = ((float) lt) / 100.0f;
}
if(ft >= 1.0f) {
Tesselator tesselator = Tesselator.getInstance(); ft = 1.0f;
BufferBuilder builder = tesselator.getBuilder(); scr.doTurnOnAnim = false;
//TODO: don't use tesselator }
RenderSystem.enableDepthTest();
RenderSystem.setShader(GameRenderer::getPositionTexColorShader); poseStack.scale(ft, ft, 1.0f);
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); if(!scr.rotation.isNull)
builder.vertex(poseStack.last().pose(), -sw, -sh, 0.505f).uv(0.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); poseStack.mulPose(ZP.rotationDegrees(scr.rotation.angle));
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(); float sw = ((float) scr.size.x) * 0.5f - 2.f / 16.f;
builder.vertex(poseStack.last().pose(), -sw, sh, 0.505f).uv(0.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); float sh = ((float) scr.size.y) * 0.5f - 2.f / 16.f;
tesselator.end();//Minecraft does shit with mah texture otherwise...
RenderSystem.disableDepthTest(); if(scr.rotation.isVertical) {
float tmp = sw;
// TODO: it'd be neat to draw a mouse cursor on the screen sw = sh;
// // debug hit2pixels sh = tmp;
// HitResult result = Minecraft.getInstance().hitResult; }
// VertexConsumer consumer = bufferSource.getBuffer(RenderType.lines());
// poseStack.translate(-sw, -sh, 0); Tesselator tesselator = Tesselator.getInstance();
// if (result instanceof BlockHitResult hit) { BufferBuilder builder = tesselator.getBuilder();
// BlockPos bpos = hit.getBlockPos(); //TODO: Use tesselator
// RenderSystem.enableDepthTest();
// Vector3i pos = new Vector3i(hit.getBlockPos()); RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
// float hitX = ((float) result.getLocation().x) - (float) te.getBlockPos().getX(); RenderSystem._setShaderTexture(0, scr.browser.getTextureID());
// float hitY = ((float) result.getLocation().y) - (float) te.getBlockPos().getY(); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
// float hitZ = ((float) result.getLocation().z) - (float) te.getBlockPos().getZ(); builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
// Vector2i tmp = new Vector2i(); 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();
// if (BlockScreen.hit2pixels(scr.side, bpos, pos, scr, hitX, hitY, hitZ, tmp)) { builder.vertex(poseStack.last().pose(), sw, sh, 0.505f).uv(1.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
// float x = tmp.x / (float) scr.resolution.x * scr.size.x; builder.vertex(poseStack.last().pose(),-sw, sh, 0.505f).uv(0.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex();
// float y = tmp.y / (float) scr.resolution.y * scr.size.y; tesselator.end();//Minecraft does shit with mah texture otherwise...
// y = scr.size.y - y; RenderSystem.disableDepthTest();
// poseStack.popPose();
// 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 //Bounding box debugging
// poseStack.pushPose(); /*poseStack.pushPose();
// poseStack.translate(-te.getBlockPos().getX(), -te.getBlockPos().getY(), -te.getBlockPos().getZ()); poseStack.translate(-te.getBlockPos().getX(), -te.getBlockPos().getY(), -te.getBlockPos().getZ());
// LevelRenderer.renderLineBox( renderAABB(te.getRenderBoundingBox());
// poseStack, bufferSource.getBuffer(RenderType.LINES), poseStack.popPose();*/
// te.getRenderBoundingBox(), 1, 1, 1, 1f
// ); //Re-enable lighting
// poseStack.popPose(); RenderSystem.enableCull();
}
//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();
}
} }

View File

@ -1,133 +0,0 @@
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;
}
}

View File

@ -1,127 +0,0 @@
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.");
}

View File

@ -0,0 +1,121 @@
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);
}

View File

@ -1,219 +0,0 @@
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);
}
}

View File

@ -1,15 +0,0 @@
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;
}
}

View File

@ -1,9 +0,0 @@
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();
}

View File

@ -1,9 +0,0 @@
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();
}

View File

@ -1,12 +0,0 @@
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 "";
}

View File

@ -1,9 +0,0 @@
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();
}

View File

@ -1,8 +0,0 @@
package net.montoyo.wd.config.annoconfg.annotation.format;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Skip {
}

View File

@ -1,9 +0,0 @@
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();
}

View File

@ -1,16 +0,0 @@
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 "";
}

View File

@ -1,10 +0,0 @@
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();
}

View File

@ -1,10 +0,0 @@
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();
}

View File

@ -1,10 +0,0 @@
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();
}

View File

@ -1,86 +0,0 @@
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();
}
}

View File

@ -1,25 +0,0 @@
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;
}
}

View File

@ -1,38 +0,0 @@
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;
}
}

View File

@ -1,77 +0,0 @@
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 */
}
}

View File

@ -1,15 +0,0 @@
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;
}
}

View File

@ -1,49 +0,0 @@
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);
}
}

View File

@ -1,62 +0,0 @@
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);
}
}

View File

@ -1,62 +0,0 @@
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");
}
}

View File

@ -1,52 +0,0 @@
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);
}
}

View File

@ -1,79 +0,0 @@
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);
}
}
}

View File

@ -1,125 +0,0 @@
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);
}
}
}
}

View File

@ -1,56 +0,0 @@
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");
}
}

View File

@ -1,47 +0,0 @@
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;
}
}

View File

@ -1,74 +0,0 @@
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);
}
}
}

View File

@ -1,63 +0,0 @@
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();
}
}
}

View File

@ -1,48 +0,0 @@
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);
}
}
}
}

View File

@ -0,0 +1,24 @@
/*
* 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;
}
}

View File

@ -7,7 +7,6 @@ package net.montoyo.wd.core;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
// TODO: bring this back when SSR is implemented
public class CCArguments implements IComputerArgs { public class CCArguments implements IComputerArgs {
private final Object[] args; private final Object[] args;

View File

@ -5,18 +5,20 @@
package net.montoyo.wd.core; package net.montoyo.wd.core;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.montoyo.wd.registry.ItemRegistry; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.init.ItemInit;
public enum CraftComponent { public enum CraftComponent {
STONEKEY("stonekey", "StoneKey"),
UPGRADE("upgrade", "Upgrade"), STONE_KEY("stonekey", "Stone_Key"),
PERIPHERAL("peripheral", "Peripheral"), BLANK_UPGRADE("upgrade", "Blank_Upgrade"),
BATCELL("batcell", "BatCell"), PERIPHERAL_BASE("peripheral", "Peripheral_Base"),
BATPACK("batpack", "BatPack"), BATTERY_CELL("batcell", "Battery_Cell"),
LASERDIODE("laserdiode", "LaserDiode"), BATTERY_PACK("batpack", "Battery_Pack"),
LASER_DIODE("laserdiode", "Laser_Diode"),
BACKLIGHT("backlight", "Backlight"), BACKLIGHT("backlight", "Backlight"),
EXTCARD("extcard", "ExtCard"), EXTENSION_CARD("extcard", "Blank_Upgrade"),
BADEXTCARD("badextcard", "BadExtCard"); BAD_EXTENSION_CARD("badextcard", "Bad_Extension_Card");
private final String name; private final String name;
private final String wikiName; private final String wikiName;
@ -32,6 +34,7 @@ public enum CraftComponent {
} }
public ItemStack makeItemStack() { public ItemStack makeItemStack() {
return new ItemStack(ItemRegistry.getComputerCraftItem(ordinal()).get(), 1); return new ItemStack(ItemInit.itemCraftComp.get(), 1);
} }
} }

View File

@ -7,7 +7,6 @@ package net.montoyo.wd.core;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraft.advancements.CriterionTrigger; import net.minecraft.advancements.CriterionTrigger;
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance; import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance;
import net.minecraft.advancements.critereon.ContextAwarePredicate;
import net.minecraft.advancements.critereon.DeserializationContext; import net.minecraft.advancements.critereon.DeserializationContext;
import net.minecraft.advancements.critereon.EntityPredicate; import net.minecraft.advancements.critereon.EntityPredicate;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -20,8 +19,10 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
public class Criterion implements CriterionTrigger<Criterion.Instance> { public class Criterion implements CriterionTrigger<Criterion.Instance> {
public static class Instance extends AbstractCriterionTriggerInstance { public static class Instance extends AbstractCriterionTriggerInstance {
public Instance(ResourceLocation id, ContextAwarePredicate arg2) {
public Instance(ResourceLocation id, EntityPredicate.Composite arg2) {
super(id, arg2); super(id, arg2);
} }
} }
@ -59,15 +60,16 @@ public class Criterion implements CriterionTrigger<Criterion.Instance> {
@Override @Override
public @NotNull Instance createInstance(JsonObject json, DeserializationContext context) { public @NotNull Instance createInstance(JsonObject json, DeserializationContext context) {
return new Instance(id, EntityPredicate.fromJson(json, "instance", context)); return new Instance(id, EntityPredicate.Composite.fromJson(json, "instance", context));
} }
public void trigger(PlayerAdvancements ply) { public void trigger(PlayerAdvancements ply) {
ArrayList<Listener<Instance>> listeners = map.get(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 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)); Arrays.stream(copy).forEach(l -> l.run(ply));
} }
} }
} }

View File

@ -8,22 +8,22 @@ import net.minecraft.util.StringRepresentable;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.montoyo.wd.entity.KeyboardBlockEntity; import net.montoyo.wd.entity.TileEntityKeyboard;
import net.montoyo.wd.entity.RemoteControlBlockEntity; import net.montoyo.wd.entity.TileEntityRCtrl;
import net.montoyo.wd.entity.RedstoneControlBlockEntity; import net.montoyo.wd.entity.TileEntityRedCtrl;
import net.montoyo.wd.entity.ServerBlockEntity; import net.montoyo.wd.entity.TileEntityServer;
import net.montoyo.wd.registry.BlockRegistry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier; import java.util.function.Supplier;
public enum DefaultPeripheral implements StringRepresentable { public enum DefaultPeripheral implements StringRepresentable {
KEYBOARD("keyboard", "Keyboard", KeyboardBlockEntity::new, BlockRegistry.KEYBOARD_BLOCK), //WITH FACING (< 3)
KEYBOARD("keyboard", "Keyboard", TileEntityKeyboard::new, TileEntityKeyboard::getBlockFromTE), //WITH FACING (< 3)
// CC_INTERFACE("ccinterface", "ComputerCraft_Interface", TileEntityCCInterface.class), // CC_INTERFACE("ccinterface", "ComputerCraft_Interface", TileEntityCCInterface.class),
// OC_INTERFACE("cointerface", "OpenComputers_Interface", TileEntityOCInterface.class), // OC_INTERFACE("cointerface", "OpenComputers_Interface", TileEntityOCInterface.class),
REMOTE_CONTROLLER("remotectrl", "Remote_Controller", RemoteControlBlockEntity::new , BlockRegistry.REMOTE_CONTROLLER_BLOCK), //WITHOUT FACING (>= 3) REMOTE_CONTROLLER("remotectrl", "Remote_Controller", TileEntityRCtrl::new ,TileEntityRCtrl::getBlockFromTE), //WITHOUT FACING (>= 3)
REDSTONE_CONTROLLER("redstonectrl", "Redstone_Controller", RedstoneControlBlockEntity::new , BlockRegistry.REDSTONE_CONTROL_BLOCK), REDSTONE_CONTROLLER("redstonectrl", "Redstone_Controller", TileEntityRedCtrl::new ,TileEntityRedCtrl::getBlockFromTE),
SERVER("server", "Server", ServerBlockEntity::new, BlockRegistry.SERVER_BLOCK); SERVER("server", "Server", TileEntityServer::new, TileEntityServer::getBlockFromTE);
private final String name; private final String name;
private final String wikiName; private final String wikiName;

View File

@ -5,16 +5,19 @@
package net.montoyo.wd.core; package net.montoyo.wd.core;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.montoyo.wd.item.ItemUpgrade; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.config.ModConfig;
import net.montoyo.wd.init.ItemInit;
public enum DefaultUpgrade { public enum DefaultUpgrade {
LASERMOUSE("lasermouse", "LaserMouse"),
REDINPUT("redinput", "RedInput"), LASER_MOUSE("lasermouse", "Laser_Sensor"),
REDOUTPUT("redoutput", "RedOutput"), REDSTONE_INPUT("redinput", "Redstone_Input_Port"),
GPS("gps", "GPS"); REDSTONE_OUTPUT("redoutput", "Redstone_Output_Port"),
GPS("gps", "GPS_Module");
public final String name;
public final String wikiName; private final String name;
private final String wikiName;
DefaultUpgrade(String n, String wn) { DefaultUpgrade(String n, String wn) {
name = n; name = n;
@ -26,25 +29,7 @@ public enum DefaultUpgrade {
return name; return name;
} }
protected static boolean matches(ItemStack stack, DefaultUpgrade upgrade) { public boolean matches(ItemStack is) {
if (stack.getItem() instanceof ItemUpgrade upgrade1) return is.getItem() == ItemInit.itemUpgrade.get();
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);
} }
} }

View File

@ -5,7 +5,9 @@
package net.montoyo.wd.core; package net.montoyo.wd.core;
public enum HasAdvancement { public enum HasAdvancement {
DONT_KNOW, DONT_KNOW,
YES, YES,
NO NO
} }

View File

@ -7,8 +7,10 @@ package net.montoyo.wd.core;
import java.util.Map; import java.util.Map;
public interface IComputerArgs { public interface IComputerArgs {
String checkString(int i); String checkString(int i);
int checkInteger(int i); int checkInteger(int i);
Map checkTable(int i); Map checkTable(int i);
int count(); int count();
} }

View File

@ -7,9 +7,11 @@ package net.montoyo.wd.core;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.utilities.BlockSide;
import net.montoyo.wd.utilities.math.Vector3i; import net.montoyo.wd.utilities.Vector3i;
public interface IPeripheral { public interface IPeripheral {
boolean connect(Level world, BlockPos blockPos, BlockState blockState, Vector3i screenPos, BlockSide screenSide); 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