Compare commits

..

6 Commits

Author SHA1 Message Date
Malte Reents e521690448 screen now openable
Der Screen für den Denkmalblock kann jetzt geöffnet werden. Er hat noch keinen Hintergrund o.ä.
2024-05-28 21:10:37 +02:00
Malte Reents a50d5f6cc7 block updates completely prohibitable
Man kann jetzt weder blöcke platzieren noch abbauen, sofern der denkmalblock ein redstone signal erhält. Block hat noch kein Interface und kann nciht verschoben werden
2024-04-07 17:29:37 +02:00
Malte Reents 7319724efa working on DataIO
DataIO ist fertig; viele kleinigkeiten wurden sonst auch ncoh hinzugefügt
2024-04-06 22:05:59 +02:00
Malte Reents e6acd9460d basic functions for replacing work
Es wird ein Block platziert wenn man auf einen Guardian rechtsklicked. Grafiken laden auch
2024-03-14 15:17:01 +01:00
Malte 0c99c0b24e Merge pull request 'syncing with main' (#16) from main into denkmalschutzblock
Reviewed-on: #16
2024-03-13 23:10:59 +01:00
Malte Reents 328e15d4d5 Block gets placed, when clicked on Guardian
es gibt ein Item, wenn man mit dem auf einen Elder Guardian rechtsklickt, stirbt der Guardian und ein Block spawnt
2024-03-13 22:57:45 +01:00
100 changed files with 2674 additions and 434 deletions

0
.gitignore vendored Executable file → Normal file
View File

0
LICENSE Executable file → Normal file
View File

1
README.md Executable file → Normal file
View File

@ -7,5 +7,4 @@ für den ReentsEntertainment Minecraft Server
TODO: TODO:
- Gird-Blöcke - Gird-Blöcke
- Client-seitig alle Ordner mit "client[...] benennen, für einfache Importe (fixt z.B. das Problem für networking, alle keys doppelt importieren zu müssen)

0
Workspace/Icons/schiffsblock.xcf Executable file → Normal file
View File

6
build.gradle Executable file → Normal file
View File

@ -1,5 +1,5 @@
plugins { plugins {
id 'fabric-loom' version '1.6-SNAPSHOT' id 'fabric-loom' version '1.4-SNAPSHOT'
id 'maven-publish' id 'maven-publish'
} }
@ -33,7 +33,7 @@ loom {
inherit server inherit server
name "Data Generation" name "Data Generation"
vmArg "-Dfabric-api.datagen" vmArg "-Dfabric-api.datagen"
vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/java")}" vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}"
vmArg "-Dfabric-api.datagen.modid=reservermod" vmArg "-Dfabric-api.datagen.modid=reservermod"
runDir "build/datagen" runDir "build/datagen"
@ -46,7 +46,7 @@ sourceSets {
main { main {
resources { resources {
srcDirs += [ srcDirs += [
'src/main/java' 'src/main/generated'
] ]
} }
} }

10
gradle.properties Executable file → Normal file
View File

@ -4,14 +4,14 @@ org.gradle.parallel=true
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/develop # check these on https://fabricmc.net/develop
minecraft_version=1.21 minecraft_version=1.19.2
yarn_mappings=1.21+build.9 yarn_mappings=1.19.2+build.28
loader_version=0.15.11 loader_version=0.14.23
# Mod Properties # Mod Properties
mod_version=1.0.4 mod_version=1.0.3
maven_group=modchest maven_group=modchest
archives_base_name=reservermod archives_base_name=reservermod
# Dependencies # Dependencies
fabric_version=0.100.7+1.21 fabric_version=0.76.1+1.19.2

2
gradle/wrapper/gradle-wrapper.properties vendored Executable file → Normal file
View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

0
gradlew.bat vendored Executable file → Normal file
View File

0
settings.gradle Executable file → Normal file
View File

View File

@ -1,17 +1,18 @@
package modchestClient; package modchest;
import modchestClient.networking.modNetworkingClient; import modchest.util.clientInitializer;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public class REServerModClient implements ClientModInitializer { public class REServerModClient implements ClientModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger("modchest"); // Erster Error Logger public static final Logger LOGGER = LoggerFactory.getLogger("modchest"); // Erster Error Logger
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
// This entrypoint is suitable for setting up client-specific logic, such as rendering. // This entrypoint is suitable for setting up client-specific logic, such as rendering.
clientInitializer.renderer();
modNetworkingClient.registerC2SPackets(); //Identifier unter denen der Client zuhoert werden registriert clientInitializer.networking();
LOGGER.info("Modchest-Client successfully loaded!"); LOGGER.info("Modchest-Client successfully loaded!");
} }

View File

@ -0,0 +1,41 @@
package modchest.clientScreen;
import com.mojang.blaze3d.systems.RenderSystem;
import modchest.screen.denkMalBlockScreenHandler;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
public class denkMalBlockScreen extends HandledScreen<denkMalBlockScreenHandler> {
//private static final Identifier TEXTURE = new Identifier(REServerMod.MOD_ID, );
public denkMalBlockScreen(denkMalBlockScreenHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
}
@Override
protected void init() {
super.init();;
titleX = (backgroundWidth - textRenderer.getWidth(title)) / 2;
}
@Override
protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
//RenderSystem.setShaderTexture(0, TEXTURE);
int x = (width - backgroundWidth) / 2;
int y = (height - backgroundHeight) / 2;
drawTexture(matrices, x, y, 0, 0, backgroundWidth, backgroundHeight);
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
renderBackground(matrices);
super.render(matrices, mouseX, mouseY, delta);
drawMouseoverTooltip(matrices, mouseX, mouseY);
}
}

View File

@ -0,0 +1,77 @@
package modchest.mixin.client;
import modchest.REServerModClient;
import modchest.networking.modNetworkingClient;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(net.minecraft.client.gui.screen.DeathScreen.class)
public class DeathScreen extends Screen {
protected DeathScreen(Text title) {
super(Text.of("useless"));
} //Da wir einen bereits bestehenden Screen erweitern, wird dieser Text nie angezeigt
@Inject(method = "init", at = @At("TAIL")) //Dieser Code wird in den eigentlich bereits bestehenden Code der Klasse DeathScreen hinzugefügt
private void addMultiSleepButtons(CallbackInfo info) {;
int widthButton = 40; //Die generelle Breite der knoepfe wird definiert
int heightButton = 20; // " hoehe "
int yOffset = 5; //Wie gross der Abstand zwischen der oberen Kante un dem knop sein soll (der Nullpunkt (0|0) ist soswohl im Fenster als auch beim Knopf oben links die Ecke)
int xOffset = this.width / 2 - widthButton / 2; //Die Mitte wird ausgerechnet (Mitte vom fenster minus halbe Breite des knopfes um tatsächlich die Mitte zu haben, weil koordinaten und so
this.addDrawableChild(
new ButtonWidget(xOffset - 2 * (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#1"), button -> { //Knopf wird erzeugt
REServerModClient.LOGGER.info("First Button for using spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create(); //Neuer Buffer wird erstellt
buffer.writeInt(1); //Beschrieben, damit der Server weiss, welcher knopf gedrueckt wurde
sendPacket(buffer); //Und an den Server gesendet zum Speichern; Die gesamte logik passiert auf dem server, damit man keien fake koordinaten oder so eingeben kann
})
);
this.addDrawableChild(
new ButtonWidget(xOffset - (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#2"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Second Button for using spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(2);
sendPacket(buffer);
})
);
this.addDrawableChild(
new ButtonWidget(xOffset, yOffset, widthButton, heightButton, Text.translatable("#3"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Third Button for using spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(3);
sendPacket(buffer);
})
);
this.addDrawableChild(
new ButtonWidget(xOffset + (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#4"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Fourth Button for using spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(4);
sendPacket(buffer);
})
);
this.addDrawableChild(
new ButtonWidget(xOffset + 2 * (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#5"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Fifth Button for using spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(5);
sendPacket(buffer);
})
);
}
@Unique
private synchronized void sendPacket(PacketByteBuf buffer) {
try {
ClientPlayNetworking.send(modNetworkingClient.death_multi_respawn_buttons, buffer);
} catch (Exception e) {}
}
}

View File

@ -0,0 +1,77 @@
package modchest.mixin.client;
import modchest.REServerModClient;
import modchest.networking.modNetworkingClient;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(net.minecraft.client.gui.screen.SleepingChatScreen.class)
public class SleepingChatScreen extends Screen { //Sehr identisch zu Death Screen, siehe dort fuer Kommentare!!
protected SleepingChatScreen(Text title) {
super(Text.of("useless"));
}
@Inject(method = "init", at = @At("TAIL"))
private void addMultiSleepButtons(CallbackInfo info) {
int widthButton = 40;
int heightButton = 20;
int yOffset = 5;
int xOffset = this.width / 2 - widthButton / 2;
this.addDrawableChild(
new ButtonWidget(xOffset - 2 * (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#1"), button -> {
REServerModClient.LOGGER.info("First Button for saving spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(1);
sendPacket(buffer);
})
);
this.addDrawableChild(
new ButtonWidget(xOffset - (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#2"), button -> {
REServerModClient.LOGGER.info("Second Button for saving spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(2);
sendPacket(buffer);
})
);
this.addDrawableChild(
new ButtonWidget(xOffset, yOffset, widthButton, heightButton, Text.translatable("#3"), button -> {
REServerModClient.LOGGER.info("Third Button for saving spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(3);
sendPacket(buffer);
})
);
this.addDrawableChild(
new ButtonWidget(xOffset + (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#4"), button -> {
REServerModClient.LOGGER.info("Fourth Button for saving spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(4);
sendPacket(buffer);
})
);
this.addDrawableChild(
new ButtonWidget(xOffset + 2 * (widthButton + 5), yOffset, widthButton, heightButton, Text.translatable("#5"), button -> {
REServerModClient.LOGGER.info("Fifth Button for saving spawn pressed!");
PacketByteBuf buffer = PacketByteBufs.create();
buffer.writeInt(5);
sendPacket(buffer);
})
);
}
@Unique
private synchronized void sendPacket(PacketByteBuf buffer) {
try {
ClientPlayNetworking.send(modNetworkingClient.start_sleeping_call_buttons, buffer);
} catch (Exception e) {}
}
}

View File

@ -0,0 +1,16 @@
package modchest.networking;
import modchest.REServerMod;
import modchest.networking.packet.respawnRequestS2CPacket;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.util.Identifier;
public class modNetworkingClient { //Identifier werden eingeführt
public static final Identifier request_respawn = new Identifier(REServerMod.MOD_ID, "request_respawn"); //alle Identifier muessen leider IMMER auf Client und Server (doppelt) eingefuehrt werden
public static final Identifier start_sleeping_call_buttons = new Identifier(REServerMod.MOD_ID, "start_sleeping_call_buttons");
public static final Identifier death_multi_respawn_buttons = new Identifier(REServerMod.MOD_ID, "death_call_respawn_buttons");
public static void registerS2CPackets() { //Identifier fuer packets werden registriert (Identifier die der Server aufruft um beim Client was auszufuehren)
ClientPlayNetworking.registerGlobalReceiver(request_respawn, respawnRequestS2CPacket::receive); //was der Client dann machen soll steht in der receive Methode
}
}

View File

@ -1,18 +1,15 @@
package modchestClient.networking.packet; package modchest.networking.packet;
import modchest.REServerModClient;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.network.packet.CustomPayload; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.PacketByteBuf;
public class respawnRequestS2CPacket { public class respawnRequestS2CPacket {
/*
public static void receive(MinecraftClient minecraftClient, ClientPlayNetworkHandler clientPlayNetworkHandler, PacketByteBuf packetByteBuf, PacketSender packetSender) { public static void receive(MinecraftClient minecraftClient, ClientPlayNetworkHandler clientPlayNetworkHandler, PacketByteBuf packetByteBuf, PacketSender packetSender) {
//REServerModClient.LOGGER.info("Server asked for respawn after pressing a saved respawn button!"); //REServerModClient.LOGGER.info("Server asked for respawn after pressing a saved respawn button!");
minecraftClient.player.requestRespawn(); minecraftClient.player.requestRespawn();
} }
*/
public static void receive(MinecraftClient minecraftClient, CustomPayload payload) {
//REServerModClient.LOGGER.info("Server asked for respawn after pressing a saved respawn button!");
assert minecraftClient.player != null;
minecraftClient.player.requestRespawn();
}
} }

View File

@ -0,0 +1,35 @@
package modchest.util;
import modchest.block.modBlocks;
import modchest.clientScreen.denkMalBlockScreen;
import modchest.networking.modNetworkingClient;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.client.render.RenderLayer;
import modchest.screen.modScreenHandler;
public class clientInitializer {
public static void itemGroups() {
//modItemGroup.modchest(); // Item Gruppe fürs Creative-Inventar wird erstellt; In dieser Gruppe sollen
// dann alle Items und Blöcke dieser Mod angezeigt werden
}
public static void itemsAndBlocks() {
//modItems.setItems(); // die Items werden erstellt
//modBlocks.setBlocks(); // Hier werden die Blöcke erstellt
//modBlockEntities.registerBlockEntities(); // Die Interaktionsmenüs für die Blöcke werden erstellt
}
public static void events() { //Events, bei denen custom Code ausgefuehrt wird, werden eingefuehrt
}
public static void networking() { //Identifier unter denen der Server zuhoert werden registriert
modNetworkingClient.registerS2CPackets(); //Identifier unter denen der Client zuhoert werden registriert
}
public static void renderer() { //Grafikrenderer werden aufgerufen
BlockRenderLayerMap.INSTANCE.putBlock(modBlocks.denk_mal_block, RenderLayer.getTranslucent()); //denk_mal_block bekommt die Faehigkeit, transparente Grafiken zu haben
HandledScreens.register(modScreenHandler.denk_mal_block_screen_handler, denkMalBlockScreen::new);
}
}

View File

@ -1,67 +0,0 @@
package modchestClient.mixin;
import modchestClient.REServerModClient;
import modchestClient.networking.payload.startSleepingCallButtons;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(net.minecraft.client.gui.screen.DeathScreen.class)
public class DeathScreen extends Screen {
protected DeathScreen(Text title) {
super(Text.of("useless"));
} //Da wir einen bereits bestehenden Screen erweitern, wird dieser Text nie angezeigt
@Inject(method = "init", at = @At("TAIL")) //Dieser Code wird in den eigentlich bereits bestehenden Code der Klasse DeathScreen hinzugefügt
private void addMultiSleepButtons(CallbackInfo info) {
int widthButton = 40; //Die generelle Breite der knoepfe wird definiert
int heightButton = 20; // " hoehe "
int yOffset = 5; //Wie gross der Abstand zwischen der oberen Kante un dem knopf sein soll (der Nullpunkt (0|0) ist sowohl im Fenster als auch beim Knopf oben links die Ecke)
int xOffset = this.width / 2 - widthButton / 2; //Die Mitte wird ausgerechnet (Mitte vom fenster minus halbe Breite des knopfes um tatsächlich die Mitte zu haben, weil koordinaten und so
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#1"), button -> { //Knopf wird erzeugt
REServerModClient.LOGGER.info("First Button for using spawn pressed!");
sendPacket(1); //Und an den Server gesendet zum Speichern; die gesamte logik passiert auf dem server, damit man keine fake koordinaten oder so eingeben kann
}).dimensions(xOffset - 2 * (widthButton + 5), yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#2"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Second Button for using spawn pressed!");
sendPacket(2);
}).dimensions(xOffset - (widthButton + 5), yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#3"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Third Button for using spawn pressed!");
sendPacket(3);
}).dimensions(xOffset, yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#4"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Fourth Button for using spawn pressed!");
sendPacket(4);
}).dimensions(xOffset + (widthButton + 5), yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#5"), button -> { //Kommentare siehe knopf #1
REServerModClient.LOGGER.info("Fifth Button for using spawn pressed!");
sendPacket(5);
}).dimensions(xOffset + 2 * (widthButton + 5), yOffset, widthButton, heightButton).build()
);
}
@Unique
private synchronized void sendPacket(int number) {
try {
ClientPlayNetworking.send(new startSleepingCallButtons(number));
} catch (Exception e) {
REServerModClient.LOGGER.info("Error when trying to network to server in DeathScreen class: " + e);
}
}
}

View File

@ -1,68 +0,0 @@
package modchestClient.mixin;
import modchestClient.REServerModClient;
import modchestClient.networking.payload.deathMultiRespawnButtons;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(net.minecraft.client.gui.screen.SleepingChatScreen.class)
public class SleepingChatScreen extends Screen { //Sehr identisch zu Death Screen, siehe dort fuer Kommentare!
protected SleepingChatScreen(Text title) {
super(Text.of("useless"));
}
@Inject(method = "init", at = @At("TAIL"))
private void addMultiSleepButtons(CallbackInfo info) {
int widthButton = 40;
int heightButton = 20;
int yOffset = 5;
int xOffset = this.width / 2 - widthButton / 2;
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#1"), button -> {
REServerModClient.LOGGER.info("First Button for saving spawn pressed!");
sendPacket(1);
}).dimensions(xOffset - 2 * (widthButton + 5), yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#2"), button -> {
REServerModClient.LOGGER.info("Second Button for saving spawn pressed!");
sendPacket(2);
}).dimensions(xOffset - (widthButton + 5), yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#3"), button -> {
REServerModClient.LOGGER.info("Third Button for saving spawn pressed!");
sendPacket(3);
}).dimensions(xOffset, yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#4"), button -> {
REServerModClient.LOGGER.info("Fourth Button for saving spawn pressed!");
sendPacket(4);
}).dimensions(xOffset + (widthButton + 5), yOffset, widthButton, heightButton).build()
);
this.addDrawableChild(
ButtonWidget.builder(Text.translatable("#5"), button -> {
REServerModClient.LOGGER.info("Fifth Button for saving spawn pressed!");
sendPacket(5);
}).dimensions(xOffset + 2 * (widthButton + 5), yOffset, widthButton, heightButton).build()
);
}
@Unique
private synchronized void sendPacket(int number) {
try {
ClientPlayNetworking.send(new deathMultiRespawnButtons(number));
} catch (Exception e) {
REServerModClient.LOGGER.info("Error when trying to network to server in sleepingChatScreen class: " + e);
}
}
}

View File

@ -1,30 +0,0 @@
package modchestClient.networking;
import modchest.REServerMod;
import modchestClient.networking.packet.respawnRequestS2CPacket;
import modchestClient.networking.payload.requestRespawn;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.minecraft.util.Identifier;
public class modNetworkingClient { //Identifier werden eingeführt //alle Identifier muessen leider IMMER auf Client und Server (doppelt) eingefuehrt werden
public static final Identifier request_respawn = Identifier.of(REServerMod.MOD_ID, "request_respawn");
public static final Identifier start_sleeping_call_buttons = Identifier.of(REServerMod.MOD_ID, "start_sleeping_call_buttons");
public static final Identifier death_call_respawn_buttons = Identifier.of(REServerMod.MOD_ID, "death_call_respawn_buttons");
public static void registerC2SPackets() { //Identifier fuer packets werden registriert (Identifier die der Server aufruft um beim CLient was auszufuehren)
//PayloadTypeRegistry.playC2S().register(startSleepingCallButtons.ID, startSleepingCallButtons.CODEC);
//PayloadTypeRegistry.playC2S().register(deathMultiRespawnButtons.ID, deathMultiRespawnButtons.CODEC);
PayloadTypeRegistry.playS2C().register(requestRespawn.ID, requestRespawn.CODEC);
ClientPlayNetworking.registerGlobalReceiver(requestRespawn.ID, (payload, context) -> {
context.client().execute(() -> {
respawnRequestS2CPacket.receive(context.client(), payload);
}
);});
//ClientPlayNetworking.registerGlobalReceiver(request_respawn, respawnRequestS2CPacket::receive); //was der Client dann machen soll steht in der receive Methode
}
}

View File

@ -1,18 +0,0 @@
package modchestClient.networking.payload;
import modchest.networking.modNetworkingServer;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.packet.CustomPayload;
public record deathMultiRespawnButtons(int number) implements CustomPayload {
public static final CustomPayload.Id<deathMultiRespawnButtons> ID = new CustomPayload.Id<>(modNetworkingServer.death_call_respawn_buttons);
public static final PacketCodec<RegistryByteBuf, deathMultiRespawnButtons> CODEC = PacketCodec.tuple(PacketCodecs.INTEGER, deathMultiRespawnButtons::number, deathMultiRespawnButtons::new);
//PacketCodec.tuple(PacketCodecs.INTEGER, requestRespawn::new);
@Override
public Id<? extends CustomPayload> getId() {
return null;
}
}

View File

@ -1,17 +0,0 @@
package modchestClient.networking.payload;
import modchestClient.networking.modNetworkingClient;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.packet.CustomPayload;
public record requestRespawn(int number) implements CustomPayload {
public static final CustomPayload.Id<requestRespawn> ID = new CustomPayload.Id<>(modNetworkingClient.request_respawn);
public static final PacketCodec<RegistryByteBuf, requestRespawn> CODEC = PacketCodec.tuple(PacketCodecs.INTEGER, requestRespawn::number, requestRespawn::new);
@Override
public Id<? extends CustomPayload> getId() {
return null;
}
}

View File

@ -1,17 +0,0 @@
package modchestClient.networking.payload;
import modchest.networking.modNetworkingServer;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.packet.CustomPayload;
public record startSleepingCallButtons(int number) implements CustomPayload {
public static final CustomPayload.Id<startSleepingCallButtons> ID = new CustomPayload.Id<>(modNetworkingServer.start_sleeping_call_buttons);
public static final PacketCodec<RegistryByteBuf, startSleepingCallButtons> CODEC = PacketCodec.tuple(PacketCodecs.INTEGER, startSleepingCallButtons::number, startSleepingCallButtons::new);
@Override
public Id<? extends CustomPayload> getId() {
return null;
}
}

2
src/client/resources/reservermod.client.mixins.json Executable file → Normal file
View File

@ -1,6 +1,6 @@
{ {
"required": true, "required": true,
"package": "modchestClient.mixin", "package": "modchest.mixin.client",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"client": [ "client": [
"DeathScreen", "DeathScreen",

0
src/documentation/Development Executable file → Normal file
View File

0
src/documentation/Documentation Executable file → Normal file
View File

0
src/documentation/Features Executable file → Normal file
View File

View File

@ -17,6 +17,7 @@ public class REServerMod implements ModInitializer {
initializer.itemsAndBlocks(); initializer.itemsAndBlocks();
initializer.events(); initializer.events();
initializer.networking(); initializer.networking();
initializer.renderer();
LOGGER.info("Modchest successfully loaded!"); LOGGER.info("Modchest successfully loaded!");
} }

View File

@ -0,0 +1,178 @@
package modchest.block.custom;
import modchest.REServerMod;
import modchest.block.entity.denkMalBlockEntity;
import modchest.util.denkMalBlockUtil;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.DispenserBlockEntity;
import net.minecraft.block.entity.DropperBlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.stat.Stats;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.explosion.Explosion;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mutable;
import static modchest.block.modBlocks.denk_mal_block_placeholder;
public class denkMalBlock extends BlockWithEntity implements BlockEntityProvider { //Item soll nicht craftable sein
public static BooleanProperty POWERED = BooleanProperty.of("powered"); //speichert ob der Block ein Redstonesignal erhaelt
public denkMalBlock(FabricBlockSettings fabricBlockSettings) {
super(fabricBlockSettings);
setDefaultState(getDefaultState().with(POWERED, false)); //Block ist beim platzieren immer aus
}
@Override
public BlockRenderType getRenderType(BlockState state) { //ruft auf, die Grafik zu rendern
return BlockRenderType.MODEL;
}
private static VoxelShape SHAPE = BlockWithEntity.createCuboidShape(0, 0, 0, 16, 32, 16); //Erstellt eine approximation des Koerpers; braucht weniger Leistung als ein Volles Rendern
@Override
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { //Beschreibt die tatsaechlichen Konturen
return SHAPE;
}
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { //dropt alle Items im Inventar, wenn der Block zerstoert wird
if (state.getBlock() != newState.getBlock()) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof denkMalBlockEntity) {
//ItemScatterer.spawn(world, pos, (denkMalBlockEntity) blockEntity);
world.updateComparators(pos, this);
}
super.onStateReplaced(state, world, pos, newState, moved);
}
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new denkMalBlockEntity(pos, state);
}
@Override
public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { //damit man durch den Glasteil des blockes sehen kann
return true;
}
@Override //Block soll nicht gedroped werden
public boolean shouldDropItemsOnExplosion(Explosion explosion) {
return false;
}
@Override
public void onPlaced(World world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) { //platziert den placeholder block oben drauf, weil es in miencraft keine 2 hohen Bloecke gibt
super.onPlaced(world, pos, state, placer, itemStack);
if (!world.isClient) {
world.setBlockState(pos.up(1), denk_mal_block_placeholder.getDefaultState(), Block.NOTIFY_ALL); //platziert den placeholder Block ueber sich selbst
world.updateNeighbors(pos, Blocks.AIR);
state.updateNeighbors(world, pos, Block.NOTIFY_ALL);
}
}
@Override
public void onBroken(WorldAccess world, BlockPos pos, BlockState state) { //entfernt sich aus der Liste der zu ueberpruefenden bloecke
denkMalBlockUtil data = new denkMalBlockUtil();
world.setBlockState(pos.up(1), Blocks.AIR.getDefaultState(), Block.NOTIFY_ALL); //entfernt den Placeholder block ueber sich
int[] temp = new int[3];
temp[0] = pos.getX();
temp[1] = pos.getY();
temp[2] = pos.getZ();
data.removeBlock(temp); //entfernt sich aus der liste der Abbauverhindernden Bloecke
}
//CODE ZUM UEBERPREUFEN OB MIT REDSTONE GEPOWERED
@Override
@Nullable
public BlockState getPlacementState(ItemPlacementContext ctx) {
return (BlockState) this.getDefaultState().with(POWERED, ctx.getWorld().isReceivingRedstonePower(ctx.getBlockPos()));
}
@Override
public void neighborUpdate(BlockState state, World world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
if (world.isClient) {
return;
}
boolean bl = state.get(POWERED);
if (bl != world.isReceivingRedstonePower(pos)) {
if (bl) {
world.createAndScheduleBlockTick(pos, this, 4);
} else {
world.setBlockState(pos, (BlockState) state.cycle(POWERED), Block.NOTIFY_LISTENERS);
changePositionList(state, world, pos);
}
}
}
@Override
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (state.get(POWERED).booleanValue() && !world.isReceivingRedstonePower(pos)) {
world.setBlockState(pos, (BlockState) state.cycle(POWERED), Block.NOTIFY_LISTENERS);
changePositionList(state, world, pos);
}
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(POWERED);
}
//CODE ZUM UEBERÜREUFEN OB MIT REDSTONE GEPOWERED ZUENDE
private void changePositionList(BlockState state, World world, BlockPos pos) { //aendert ob der Block in der Liste der Bloecke steht, die das abbauen verhindern
denkMalBlockUtil data = new denkMalBlockUtil();
if (!world.isClient) {
int[] temp = new int[3];
temp[0] = pos.getX();
temp[1] = pos.getY();
temp[2] = pos.getZ();
int[] range = new int[6]; //noch ist die range auf 20 Bloecke, soll aber spaeter via ein Entity vom Spieler veraendert werden koennen
range[0] = 20;
range[1] = 20;
range[2] = 20;
range[3] = 20;
range[4] = 20;
range[5] = 20;
if (!state.get(POWERED)) {
data.addBlock(temp, range);
} else {
data.removeBlock(temp);
}
}
}
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (world.isClient) {
return ActionResult.SUCCESS;
}
BlockEntity blockEntity = world.getBlockEntity(pos);
player.openHandledScreen((denkMalBlockEntity) blockEntity);
return ActionResult.CONSUME;
}
}

View File

@ -0,0 +1,45 @@
package modchest.block.custom;
import modchest.REServerMod;
import modchest.util.denkMalBlockUtil;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.WorldAccess;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import static modchest.block.modBlocks.denk_mal_block_placeholder;
public class denkMalBlockPlaceholder extends BlockWithEntity { //Block der simuliert, dass der DenkMalBLock 2 Bloecke hoch waere
public denkMalBlockPlaceholder(Settings settings) {
super(settings);
}
@Override
public BlockRenderType getRenderType(BlockState state) { //Grafik kommt vom DenkMalBLock, dieser Block muss also unsichtbar sein
return BlockRenderType.INVISIBLE;
}
@Override
public void onBroken(WorldAccess world, BlockPos pos, BlockState state) { //Loescht den eigentlichen DenkMalBlock
denkMalBlockUtil data = new denkMalBlockUtil(); //denkMalBLockUtil holt sich alle infos von der static dataSaverIO Klasse
world.setBlockState(pos.down(1), Blocks.AIR.getDefaultState(), Block.NOTIFY_ALL); //unter diesem Block wird Luft platziert
int[] temp = new int[3];
temp[0] = pos.getX();
temp[1] = (pos.getY()-1);
temp[2] = pos.getZ();
data.removeBlock(temp); //Loescht den denkMalBLock aus der Liste der abbauverhindernden Bloecke
}
@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return null;
}
}

View File

@ -1,39 +1,37 @@
package modchest.block.custom; package modchest.block.custom;
import com.mojang.serialization.MapCodec;
import modchest.block.entity.modBlockEntities; import modchest.block.entity.modBlockEntities;
import modchest.block.entity.steeringWheelEntity; import modchest.block.entity.steeringWheelEntity;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.BlockWithEntity; import net.minecraft.block.BlockWithEntity;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker; import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemScatterer; import net.minecraft.util.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
//gibt dem Block steering_wheel eigenschaften, wie z.B. das Interaktionsmenü, oder Grafiken //gibt dem Block steering_wheel eigenschaften, wie z.B. das Interaktionsmenü, oder Grafiken
public class steeringWheelBlock extends BlockWithEntity { public class steeringWheelBlock extends BlockWithEntity implements BlockEntityProvider {
public steeringWheelBlock(Settings settings) { public steeringWheelBlock(Settings settings) {
super(settings); super(settings);
} }
@Override @Override
protected MapCodec<? extends BlockWithEntity> getCodec() { public BlockRenderType getRenderType(BlockState state) {//ruft auf, die Grafik zu rendern
return null;
}
/* stuff benötigt um das Interaktionsmenü zu laden!*/
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL; return BlockRenderType.MODEL;
} }
@Override @Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { //Aufgerufen bei blockstate veraenderung, z.B. restonestaerke
if (state.getBlock() != newState.getBlock()) { if (state.getBlock() != newState.getBlock()) {
BlockEntity blockEntity = world.getBlockEntity(pos); BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof steeringWheelEntity) { if (blockEntity instanceof steeringWheelEntity) {
@ -43,7 +41,8 @@ public class steeringWheelBlock extends BlockWithEntity {
super.onStateReplaced(state, world, pos, newState, moved); super.onStateReplaced(state, world, pos, newState, moved);
} }
} }
/*
/* stuff benötigt um das Interaktionsmenü zu laden!*/
@Override //wird bei einem rechtsklick aufgerufen (ersellt das Blockentity) @Override //wird bei einem rechtsklick aufgerufen (ersellt das Blockentity)
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!world.isClient) { if (!world.isClient) {
@ -55,7 +54,7 @@ public class steeringWheelBlock extends BlockWithEntity {
} }
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
*/
@Nullable @Nullable
@Override @Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
@ -64,6 +63,6 @@ public class steeringWheelBlock extends BlockWithEntity {
@Nullable @Nullable
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) { public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return validateTicker( type, modBlockEntities.steering_wheel_interface, steeringWheelEntity::tick); return checkType( type, modBlockEntities.steering_wheel_interface, steeringWheelEntity::tick);
} }
} }

View File

@ -0,0 +1,72 @@
package modchest.block.entity;
import modchest.REServerMod;
import modchest.screen.denkMalBlockScreenHandler;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.screen.Generic3x3ContainerScreenHandler;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.Text;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable;
public class denkMalBlockEntity extends BlockEntity implements NamedScreenHandlerFactory//, ImplementedInventory
{
//private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(3, ItemStack.EMPTY);
private SimpleInventory inventory = new SimpleInventory(3);
private int[] protectedAreaSize = new int[6]; //range ist 6 stellen lang mit immer der erlaubten range in negative richtung, dann positiv fuer alle 3 Koordinaten, also: -x, +x, -y, +y, -z, +z Richtung
private int[] posBlock = new int[3];
protected denkMalBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
public denkMalBlockEntity(BlockPos pos, BlockState state) {
super(modBlockEntities.denk_mal_block_interface, pos, state);
posBlock[0] = pos.getX();
posBlock[1] = pos.getY();
posBlock[2] = pos.getZ();
}
//@Override
public int size() {
return 3;
}
//@Override
public DefaultedList<ItemStack> getItems() {
return null;
}
@Override
public Text getDisplayName() {
return Text.literal("Denkmal Block");
}
@Nullable
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
//return new Generic3x3ContainerScreenHandler(syncId, inv, this);
REServerMod.LOGGER.info("creating Menu!");
return new denkMalBlockScreenHandler(syncId, inv, inventory);
}
@Override
protected void writeNbt(NbtCompound nbt) {
}
@Override
public void readNbt(NbtCompound nbt) {
}
}

View File

@ -4,17 +4,21 @@ import modchest.REServerMod;
import modchest.block.modBlocks; import modchest.block.modBlocks;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
//rendert letztendlich die Interaktionsmenüs der Blöcke //rendert letztendlich die Interaktionsmenüs der Blöcke
public class modBlockEntities { public class modBlockEntities {
public static BlockEntityType<steeringWheelEntity> steering_wheel_interface; // Interaktionsmenü wird erstellt public static BlockEntityType<steeringWheelEntity> steering_wheel_interface; // Interaktionsmenü wird erstellt
public static BlockEntityType<denkMalBlockEntity> denk_mal_block_interface;
public static void registerBlockEntities() { public static void registerBlockEntities() {
steering_wheel_interface = Registry.register(Registries.BLOCK_ENTITY_TYPE, steering_wheel_interface = Registry.register(Registry.BLOCK_ENTITY_TYPE,
Identifier.of(REServerMod.MOD_ID, "steering_wheel_interface"), // Interkationsmenü wird gerendert new Identifier(REServerMod.MOD_ID, "steering_wheel_interface"), // Interkationsmenü wird gerendert
FabricBlockEntityTypeBuilder.create(steeringWheelEntity::new, modBlocks.steering_wheel).build(null)); FabricBlockEntityTypeBuilder.create(steeringWheelEntity::new, modBlocks.steering_wheel).build(null));
denk_mal_block_interface = Registry.register(Registry.BLOCK_ENTITY_TYPE,
new Identifier(REServerMod.MOD_ID, "denk_mal_block_interface"),
FabricBlockEntityTypeBuilder.create(denkMalBlockEntity::new, modBlocks.denk_mal_block).build(null));
} }
} }

View File

@ -1,34 +1,47 @@
package modchest.block; package modchest.block;
import modchest.block.custom.denkMalBlock;
import modchest.block.custom.denkMalBlockPlaceholder;
import modchest.block.custom.steeringWheelBlock; import modchest.block.custom.steeringWheelBlock;
import modchest.item.modItemGroup; import modchest.item.modItemGroup;
import modchest.REServerMod; import modchest.REServerMod;
import net.minecraft.item.Item; import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
//setzt die blöcke auf //setzt die blöcke auf
public class modBlocks { public class modBlocks {
public static Block steering_wheel; // Block wird erstellt; das entsprechende Item zum Block muss in "modItemGroup" getrennt zur mod Block Gruppe hinzugefügt werden" public static Block steering_wheel; // Block wird erstellt
public static Block denk_mal_block;
public static Block denk_mal_block_placeholder;
public static void setBlocks() {// Block wird definiert public static void setBlocks() {// Block wird definiert
steering_wheel = registerBlock("steering_wheel", steering_wheel = registerBlock("steering_wheel",
new steeringWheelBlock(FabricBlockSettings.create().strength(1.0f).requiresTool()), new steeringWheelBlock(FabricBlockSettings.of(Material.WOOD).strength(1.0f).requiresTool().nonOpaque()),
modItemGroup.item_group1); modItemGroup.modchest);
denk_mal_block = registerBlock("denk_mal_block",
new denkMalBlock(FabricBlockSettings.of(Material.METAL).strength(4.0f).requiresTool().luminance((state) -> state.get(denkMalBlock.POWERED) ? 5 : 0).nonOpaque()),
modItemGroup.modchest);
denk_mal_block_placeholder = registerBlockWithoutItem("denk_mal_block_placeholder",
new denkMalBlockPlaceholder(FabricBlockSettings.of(Material.METAL).strength(4.0f).requiresTool().nonOpaque()));
} }
private static Block registerBlock(String name, Block block, ItemGroup group) { // Nicht verändern! Fügt die oben private static Block registerBlock(String name, Block block, ItemGroup group) { // Nicht verändern! Fügt die oben definierten Blöcke dem Register hinzu
// definierten Blöcke dem Register Registry.register(Registry.ITEM, new Identifier(REServerMod.MOD_ID, name),
// hinzu new BlockItem(block, new FabricItemSettings().group(group)));
Registry.register(Registries.ITEM, Identifier.of(REServerMod.MOD_ID, name), return Registry.register(Registry.BLOCK, new Identifier(REServerMod.MOD_ID, name), block);
new BlockItem(block, new Item.Settings())); }
return Registry.register(Registries.BLOCK, Identifier.of(REServerMod.MOD_ID, name), block);
private static Block registerBlockWithoutItem(String name, Block block) { // Nicht verändern! Fügt die oben definierten Blöcke dem Register hinzu
return Registry.register(Registry.BLOCK, new Identifier(REServerMod.MOD_ID, name), block);
} }
public static void registerModBlocks() { // Error Logger halt... public static void registerModBlocks() { // Error Logger halt...

View File

@ -1,4 +1,3 @@
/*
package modchest.data; package modchest.data;
import modchest.item.modItems; import modchest.item.modItems;
@ -17,4 +16,3 @@ public class ModLootTableGenerator extends FabricBlockLootTableProvider {
//oreDrops(modBlocks.steering_wheel, modItems.shipblock); mit silktouch würde steering_wheel gedroped werden, ohne würde shipblock gedroped werden //oreDrops(modBlocks.steering_wheel, modItems.shipblock); mit silktouch würde steering_wheel gedroped werden, ohne würde shipblock gedroped werden
} }
} }
*/

View File

@ -1,4 +1,3 @@
/*
package modchest.data; package modchest.data;
import modchest.block.modBlocks; import modchest.block.modBlocks;
@ -25,4 +24,3 @@ public class ModModelProvider extends FabricModelProvider {
//itemModelGenerator.register(modItems.shipblock, Models.GENERATED); //ergänzt die Texturen für die Items //itemModelGenerator.register(modItems.shipblock, Models.GENERATED); //ergänzt die Texturen für die Items
} }
} }
*/

View File

@ -1,4 +1,3 @@
/*
package modchest.data; package modchest.data;
import modchest.item.modItems; import modchest.item.modItems;
@ -20,4 +19,3 @@ public class ModRecipeGenerator extends FabricRecipeProvider {
//offerSmelting(exporter, List.of(modItems.shipblock), , ); //generiert das rezept zum herstellen (hier mir braten) //offerSmelting(exporter, List.of(modItems.shipblock), , ); //generiert das rezept zum herstellen (hier mir braten)
} }
} }
*/

View File

@ -4,11 +4,11 @@ import modchest.REServerMod;
import modchest.util.setAndGetMultiButtonsSpawn; import modchest.util.setAndGetMultiButtonsSpawn;
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World; import net.minecraft.world.World;
public class playerAfterRespawnEvent implements ServerPlayerEvents.AfterRespawn { //Wenn die Multi-Spawn mod verwendet wurde, muss der Vanillaspawn wieder gesetzt werden public class playerAfterRespawnEvent implements ServerPlayerEvents.AfterRespawn { //Wenn die Multi-Spawn mod verwendet wurde, muss der Vanillaspawn wieder gesetzt werden
@ -23,7 +23,7 @@ public class playerAfterRespawnEvent implements ServerPlayerEvents.AfterRespawn
String[] parts = nbt.getString("dimension").split(":"); //holt sich die gespeicherte Dimension; trennt den String entspreichend; damit sollte es auch funktionieren, sollte eine Mod weitere Dimensionen hinzufuegen String[] parts = nbt.getString("dimension").split(":"); //holt sich die gespeicherte Dimension; trennt den String entspreichend; damit sollte es auch funktionieren, sollte eine Mod weitere Dimensionen hinzufuegen
parts = parts[2].split("]"); parts = parts[2].split("]");
RegistryKey<World> dim = RegistryKey.of(RegistryKeys.WORLD, Identifier.of(parts[0])); RegistryKey<World> dim = RegistryKey.of(Registry.WORLD_KEY, new Identifier(parts[0]));
float angle = nbt.getFloat("angle"); //Und den blickwinkel float angle = nbt.getFloat("angle"); //Und den blickwinkel

View File

@ -0,0 +1,18 @@
package modchest.event;
import modchest.util.denkMalBlockUtil;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
public class playerBreakBlockEvents implements PlayerBlockBreakEvents.Before {
@Override
public boolean beforeBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity) {
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
}
}

View File

@ -0,0 +1,56 @@
package modchest.item.custom;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
import oshi.annotation.concurrent.ThreadSafe;
import static modchest.block.modBlocks.denk_mal_block;
public class denkMalItem extends Item {
World thisWorld;
boolean used = false;
public denkMalItem(FabricItemSettings fabricItemSettings) {
super(fabricItemSettings);
}
public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) {
if (thisWorld != null) {
if (entity.getType().toString().equals("entity.minecraft.elder_guardian")) {
user.sendMessage(Text.of(String.valueOf(Registry.BLOCK.getId(denk_mal_block))));
entity.kill();
if (!entity.isAlive()) {
BlockPos pos = new BlockPos((int) entity.getPos().getX(), ((int) entity.getPos().getY()), (int) entity.getPos().getZ());
try {
BlockState state = denk_mal_block.getDefaultState();
thisWorld.setBlockState(pos, state, Block.NOTIFY_ALL);
} catch (Exception e) {
user.sendMessage((Text) e);
}
}
return ActionResult.SUCCESS;
}
}
return ActionResult.PASS;
}
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) { //wird vor useOnEntity aufgerufen
thisWorld = world;
return TypedActionResult.pass(user.getStackInHand(hand));
}
}

View File

@ -1,39 +1,19 @@
package modchest.item; package modchest.item;
import modchest.REServerMod; import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import modchest.block.modBlocks;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
//definiert eine neue Itemgruppe mit dem identifier itemlist1, wird in einer de .json files dann in "Malte's Mod" umbenannt fürs spiel; in der Liste sollen alle Items dieser Mod im Creative Inventar angezeigt werden //definiert eine neue Itemgruppe mit dem identifier itemlist1, wird in einer de .json files dann in "Malte's Mod" umbenannt fürs spiel; in der Liste sollen alle Items dieser Mod im Creative Inventar angezeigt werden
public class modItemGroup { public class modItemGroup {
public static final RegistryKey<ItemGroup> item_group_key1 = RegistryKey.of(Registries.ITEM_GROUP.getKey(), Identifier.of(REServerMod.MOD_ID, "item_group_key1")); public static ItemGroup modchest;
public static final ItemGroup item_group1 = FabricItemGroup.builder()
.icon(() -> new ItemStack(Blocks.COBBLESTONE)) //Icon ist halt bisher noch ein Cobblestone, weil ich keine sprits erstellt habe... :(
.displayName(Text.translatable("itemGroup.modchest.itemlist1"))
.build();
public static void modchest() { public static void modchest() {
//Registriert die Gruppe modchest = FabricItemGroupBuilder.build(
Registry.register(Registries.ITEM_GROUP, item_group_key1, item_group1); new Identifier("modchest", "itemlist1"),
() -> new ItemStack(Blocks.COBBLESTONE)); //Icon ist halt bisher noch ein Cobblestone, weil ich keine sprits erstellt habe... :(
//Registers the items to the group
ItemGroupEvents.modifyEntriesEvent(item_group_key1).register(item_group1 -> {
item_group1.add(modItems.pirates_coin);
item_group1.add(modBlocks.steering_wheel);
}
);
} }
} }

View File

@ -1,28 +1,32 @@
package modchest.item; package modchest.item;
import modchest.REServerMod; import modchest.REServerMod;
import modchest.item.custom.denkMalItem;
import modchest.item.custom.piratesCoinItem; import modchest.item.custom.piratesCoinItem;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.registry.Registry;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
//Liste der Items die hinzugefügt werden, ausgenommen Blöcke //Liste der Items die hinzugefügt werden, ausgenommen Blöcke
public class modItems { public class modItems {
public static Item shipblock; // shipblock wird erstellt, sollte man mal umbenenne. Ist eine Zutat die man für private static Item shipblock; // shipblock wird erstellt, sollte man mal umbenenne. Ist eine Zutat die man für
// das steering_wheel braucht zum craften, mehr macht es bisher nicht // das steering_wheel braucht zum craften, mehr macht es bisher nicht
public static Item pirates_coin; // pirates Coin wird erstellt; definition siehe ./custom/piratesCoinItem da ist private static Item pirates_coin; // pirates Coin wird erstellt; definition siehe ./custom/piratesCoinItem da ist
// im detail erklärt was das Item machen soll // im detail erklärt was das Item machen soll
private static Item denk_mal_item;
public static void setItems() { // Items werden beschrieben, bzw. dem Register hinzugefügt; das entsprechende Item zum Block muss in "modItemGroup" getrennt zur mod Block Gruppe hinzugefügt werden" public static void setItems() { // Items werden beschrieben, bzw. dem Register hinzugefügt
shipblock = registerItem("shipblock", new Item(new Item.Settings())); shipblock = registerItem("shipblock", new Item(new FabricItemSettings().group(modItemGroup.modchest)));
pirates_coin = registerItem("pirates_coin", pirates_coin = registerItem("pirates_coin",
new piratesCoinItem(new Item.Settings().maxCount(16))); new piratesCoinItem(new FabricItemSettings().group(modItemGroup.modchest).maxCount(16)));
denk_mal_item = registerItem("denk_mal_item",
new denkMalItem(new FabricItemSettings().group(modItemGroup.modchest).maxCount(1)));
} }
private static Item registerItem(String name, Item item) { // Methode, die die Items dann letztendlich hinzufügt; private static Item registerItem(String name, Item item) { // Methode, die die Items dann letztendlich hinzufügt;
// nicht bearbeiten ist eine generische MEthode // nicht bearbeiten ist eine generische MEthode
return Registry.register(Registries.ITEM, Identifier.of(REServerMod.MOD_ID, name), item); return Registry.register(Registry.ITEM, new Identifier(REServerMod.MOD_ID, name), item);
} }
public static void registerModItems() { public static void registerModItems() {

View File

@ -0,0 +1,29 @@
package modchest.mixin;
import modchest.REServerMod;
import modchest.util.interfaces.LevelStorageInterface;
import net.minecraft.world.level.storage.LevelStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.world.level.storage.LevelStorage.Session;
import java.io.File;
@Mixin(Session.class)
public abstract class LevelStorageMixin implements LevelStorageInterface {
@Final
@Shadow
LevelStorage.LevelSave directory;
public File getFile() { //gibt den Dateipfad zurueck
File dateiPfad = null;
try {
dateiPfad = directory.path().toFile(); //Versucht den Dateipfad einzulesen; weil es sehr frueh kommt besonders abgesichert
} catch (Exception e) {
REServerMod.LOGGER.info("Error when trying to read File path: {}", e.toString());
}
return dateiPfad;
}
}

View File

@ -0,0 +1,49 @@
package modchest.mixin;
import modchest.REServerMod;
import modchest.util.interfaces.LevelStorageInterface;
import modchest.util.dataSaverIO;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.storage.LevelStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.io.File;
@Mixin(MinecraftServer.class)
public class MinecraftServerMixin {
@Shadow
@Final
protected LevelStorage.Session session;
@Unique
dataSaverIO dataSaver = new dataSaverIO();
@Inject(method = "prepareStartRegion", at = @At("TAIL"))
private void prepareStartRegion(CallbackInfo ci) { //wird beim Start des Servers aufgerufen
dataSaver.resetData(); //stellt sicher, dass keine Daten von einer Welt in eine andere "leaken" in dem es alle Daten loescht
LevelStorageInterface levelStorage = (LevelStorageInterface) session; //castet session mit dem Interface, damit custom Methoden verwendet werden koennen
try {
File file;
file = levelStorage.getFile(); //holt sich den Dateipfad
if (file != null) {
dataSaver.writeFilePath(file); //schreibt den Dateipfad der Welt fuer das dataSaverIO
dataSaver.readFile(); //holt die Daten von der Festplatte in den RAM
} else {
REServerMod.LOGGER.info("file is zero");
}
} catch (Exception e) {
REServerMod.LOGGER.info("file could not be read with Exception: {}", e.toString());
}
}
@Inject(method = "shutdown", at = @At("HEAD"))
private void shutdown(CallbackInfo ci) { //is called when server shuts down
dataSaver.saveFile(); //Saves the Serverdata
}
}

View File

@ -1,7 +1,7 @@
package modchest.mixin; package modchest.mixin;
import modchest.REServerMod; import modchest.REServerMod;
import modchest.util.ServerPlayerEntityInterface; import modchest.util.interfaces.ServerPlayerEntityInterface;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -37,8 +37,9 @@ public abstract class ServerPlayerEntityMixin implements ServerPlayerEntityInter
REServerMod.LOGGER.info("Error while saving custom NBt-Data: " + e); REServerMod.LOGGER.info("Error while saving custom NBt-Data: " + e);
} }
} else { } else {
REServerMod.LOGGER.info("write failed! This probably means, that the player hasn't set a custom spanpoint yet"); REServerMod.LOGGER.info("write failed! This probably means, that the player hasn't set a custom spawnpoint yet");
} }
//REServerMod.LOGGER.info("writeCustomDataToNbt called");
} }
@Inject(method = "readCustomDataFromNbt", at = @At("TAIL")) @Inject(method = "readCustomDataFromNbt", at = @At("TAIL"))

View File

@ -11,16 +11,16 @@ import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.block.BedBlock; import net.minecraft.block.BedBlock;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@Mixin(BedBlock.class) @Mixin(BedBlock.class)
public class bedBlock { public class bedBlockMixin {
@Inject(method = "onBreak", at = @At("HEAD")) @Inject(method = "onBreak", at = @At("HEAD"))
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player, CallbackInfoReturnable<BlockState> cir) { //Ueberprueft, wenn ein Bett zerstoert wird, ob jemand dieses Bett als Spawnpunkt hat public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player, CallbackInfo ci) { //Ueberprueft, wenn ein Bett zerstoert wird, ob jemand dieses Bett als Spawnpunkt hat
if (!world.isClient) { //Stellt sicher, dass das ganze nicht auf dem Client gerechnet wird, weil der Code sonst abstuertzt if (!world.isClient) { //Stellt sicher, dass das ganze nicht auf dem Client gerechnet wird, weil der Code sonst abstuertzt
int posBedX = pos.getX(); int posBedX = pos.getX();

View File

@ -0,0 +1,41 @@
package modchest.mixin;
import modchest.REServerMod;
import modchest.util.denkMalBlockUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FlintAndSteelItem;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(FlintAndSteelItem.class)
public class flintAndSteelItemMixin {
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
public void useOnBlock(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
if(!callPlaceable(context)) {
cir.setReturnValue(ActionResult.FAIL);
}
}
@Unique
private boolean callPlaceable(ItemUsageContext context) {
try {
PlayerEntity player = context.getPlayer();
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
} catch (Exception e) {
REServerMod.LOGGER.info("Exception in variables: " + e.toString());
}
return false;
}
}

View File

@ -0,0 +1,41 @@
package modchest.mixin;
import modchest.REServerMod;
import modchest.util.denkMalBlockUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Item.class)
public class itemMixin {
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
public void useOnBlock(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
if(!callPlaceable(context)) {
cir.setReturnValue(ActionResult.FAIL);
}
}
@Unique
private boolean callPlaceable(ItemUsageContext context) {
try {
PlayerEntity player = context.getPlayer();
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
} catch (Exception e) {
REServerMod.LOGGER.info("Exception in variables: " + e.toString());
}
return false;
}
}

View File

@ -0,0 +1,34 @@
package modchest.mixin;
import modchest.util.denkMalBlockUtil;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockItem.class)
public class playerPlaceBlockMixin {
@Inject(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At("HEAD"), cancellable = true)
public void canPlace(ItemPlacementContext context, CallbackInfoReturnable<ActionResult> cir) {
if(!callPlaceable(context)) {
cir.setReturnValue(ActionResult.FAIL);
}
}
@Unique
private boolean callPlaceable(ItemPlacementContext context) {
PlayerEntity player = context.getPlayer();
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
denkMalBlockUtil util = new denkMalBlockUtil();
return util.allowBlocks(world, player, pos);
}
}

View File

@ -3,40 +3,17 @@ package modchest.networking;
import modchest.REServerMod; import modchest.REServerMod;
import modchest.networking.packet.deathScreenMultiButtonsC2SPacket; import modchest.networking.packet.deathScreenMultiButtonsC2SPacket;
import modchest.networking.packet.setNewRespawnsC2SPacket; import modchest.networking.packet.setNewRespawnsC2SPacket;
import modchest.networking.payload.deathMultiRespawnButtons;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import modchest.networking.payload.startSleepingCallButtons;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class modNetworkingServer { //Identifier werden eingeführt public class modNetworkingServer { //Identifier werden eingeführt
public static final Identifier request_respawn = Identifier.of(REServerMod.MOD_ID, "request_respawn"); //alle Identifier muessen leider IMMER auf Client und Server (doppelt) eingefuehrt werden public static final Identifier request_respawn = new Identifier(REServerMod.MOD_ID, "request_respawn"); //alle Identifier muessen leider IMMER auf Client und Server (doppelt) eingefuehrt werden
public static final Identifier start_sleeping_call_buttons = Identifier.of(REServerMod.MOD_ID, "start_sleeping_call_buttons"); public static final Identifier start_sleeping_call_buttons = new Identifier(REServerMod.MOD_ID, "start_sleeping_call_buttons");
public static final Identifier death_call_respawn_buttons = Identifier.of(REServerMod.MOD_ID, "death_call_respawn_buttons"); public static final Identifier death_multi_respawn_buttons = new Identifier(REServerMod.MOD_ID, "death_call_respawn_buttons");
public static void registerS2CPackets() { //Identifier fuer packets werden registriert (Identifier die der Client aufruft um beim Server was auszufuehren) public static void registerC2SPackets() { //Identifier fuer packets werden registriert (Identifier die der Client aufruft um beim Server was auszufuehren)
PayloadTypeRegistry.playC2S().register(startSleepingCallButtons.ID, startSleepingCallButtons.CODEC); ServerPlayNetworking.registerGlobalReceiver(start_sleeping_call_buttons, setNewRespawnsC2SPacket::receive); //was der Server dann machen soll steht in der receive Methode
PayloadTypeRegistry.playC2S().register(deathMultiRespawnButtons.ID, deathMultiRespawnButtons.CODEC);
//PayloadTypeRegistry.playC2S().register(requestRespawn.ID, requestRespawn.CODEC);
ServerPlayNetworking.registerGlobalReceiver(startSleepingCallButtons.ID, (payload, context) -> { ServerPlayNetworking.registerGlobalReceiver(death_multi_respawn_buttons, deathScreenMultiButtonsC2SPacket::receive);
context.server().execute(() -> {
setNewRespawnsC2SPacket.receive(context.server(), context.player(), payload.number());
}
);});
ServerPlayNetworking.registerGlobalReceiver(deathMultiRespawnButtons.ID, (payload, context) -> {
context.server().execute(() -> {
deathScreenMultiButtonsC2SPacket.receive(context.server(), context.player(), payload.number());
}
);});
//ServerPlayNetworking.registerGlobalReceiver(start_sleeping_call_buttons, setNewRespawnsC2SPacket::receive); //was der Server dann machen soll steht in der receive Methode
//ServerPlayNetworking.registerGlobalReceiver(death_multi_respawn_buttons, deathScreenMultiButtonsC2SPacket::receive);
} }
} }

View File

@ -1,39 +1,44 @@
package modchest.networking.packet; package modchest.networking.packet;
import modchest.REServerMod; import modchest.REServerMod;
import modchest.networking.payload.requestRespawn; import modchest.networking.modNetworkingServer;
import modchest.util.setAndGetMultiButtonsSpawn; import modchest.util.setAndGetMultiButtonsSpawn;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.awt.*;
import java.util.Arrays; import java.util.Arrays;
public class deathScreenMultiButtonsC2SPacket { public class deathScreenMultiButtonsC2SPacket {
public static void receive(MinecraftServer server, ServerPlayerEntity player, int number) { //Passiert auf dem Server!!! public static void receive(MinecraftServer server, ServerPlayerEntity player, //Passiert auf dem Server!!!
ServerPlayNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender) {
setAndGetMultiButtonsSpawn setAndGet = new setAndGetMultiButtonsSpawn(); //um die nicht-statischen Methoden aufzurufen, erzeugen wir ein Objekt. Wir speichern aber keine Daten in der Klasse, daher ist das OK setAndGetMultiButtonsSpawn setAndGet = new setAndGetMultiButtonsSpawn(); //um die nicht-statischen Methoden aufzurufen, erzeugen wir ein Objekt. Wir speichern aber keine Daten in der Klasse, daher ist das OK
int num; //num steht fuer Number, und sagt, welcher der 5 Knoepfe gedrueckt wurde, da das Spiel abstuertzt wenn man buf.readInt() mehr als einmal ausfuehrt int num; //num steht fuer Number, und sagt, welcher der 5 Knoepfe gedrueckt wurde, da das Spiel abstuertzt wenn man buf.readInt() mehr als einmal ausfuehrt
try { try {
num = number; //Um Spielabstuertze definitiv zu verhindern in einem try block, hat aber nie Probleme gemacht, also eine reine absicherung num = buf.readInt(); //Um Spielabstuertze definitiv zu verhindern in einem try block, hat aber nie Probleme gemacht, also eine reine absicherung
} catch (Exception e) { } catch (Exception e) {
REServerMod.LOGGER.info("Following Error when trying to get the number of pressed Button: " + e + "continuing with Button 1"); REServerMod.LOGGER.info("Following Error when trying to get the number of pressed Button: " + e + "continuing bwith Button 1");
num = 1; num = 1;
} }
setAndGet.setMultiSpawnVanilla(player); setAndGet.setMultiSpawnVanilla(player);
int[] posXYZ = setAndGet.getMultiSpawn(player, number); //neue Koordinaten werden vom Server geholt int[] posXYZ = setAndGet.getMultiSpawn(player, num); //neue Koordinaten werden vom Server geholt
if (posXYZ.length == 3 && posXYZ[0] < 77889900) { //Stellt sicher, dass die 3 spawnkoordinaten nicht null sind; Koordinaten 77889900 sind ausserhalb der Welt und werden daher von mir in setAndGetMultiSpawnButtonsSpawn als Errorcodes verwendet if (posXYZ.length == 3 && posXYZ[0] < 77889900) { //Stellt sicher, dass die 3 spawnkoordinaten nicht null sind; Koordinaten 77889900 sind ausserhalb der Welt und werden daher von mir in setAndGetMultiSpawnButtonsSpawn als Errorcodes verwendet
try { try {
//REServerMod.LOGGER.info("try Respawning from Multi-Sapwn"); //REServerMod.LOGGER.info("try Respawning from Multi-Sapwn");
player.setSpawnPoint(World.OVERWORLD, new BlockPos(posXYZ[0], posXYZ[1], posXYZ[2]), 0, true, true); //neuer Spawn wird gesetzt player.setSpawnPoint(World.OVERWORLD, new BlockPos(posXYZ[0], posXYZ[1], posXYZ[2]), 0, true, true); //neuer Spawn wird gesetzt
ServerPlayNetworking.send(player, new requestRespawn(1)); //Anfrage an den Client zum respawnen wird gesendet ServerPlayNetworking.send(player, modNetworkingServer.request_respawn, PacketByteBufs.create()); //Anfrage an den Client zum respawnen wird gesendet
player.sendMessage((Text.translatable("chat.modchest.multispawn.respawned", num))); player.sendMessage((Text.translatable("chat.modchest.multispawn.respawned", num)));
REServerMod.LOGGER.info("Respawned Player " + player.getNameForScoreboard() + " at " + Arrays.toString(setAndGet.getMultiSpawn(player, num))); REServerMod.LOGGER.info("Respawned Player " + player.getEntityName() + " at " + Arrays.toString(setAndGet.getMultiSpawn(player, num)));
setAndGet.setMultiSpawn(player, 6); setAndGet.setMultiSpawn(player, 6);
} catch (Exception e) { } catch (Exception e) {
REServerMod.LOGGER.info("Sorry! Following error, trying to respawn player " + player.getDisplayName() + ": " + e); REServerMod.LOGGER.info("Sorry! Following error, trying to respawn player " + player.getDisplayName() + ": " + e);

View File

@ -2,15 +2,21 @@ package modchest.networking.packet;
import modchest.REServerMod; import modchest.REServerMod;
import modchest.util.setAndGetMultiButtonsSpawn; import modchest.util.setAndGetMultiButtonsSpawn;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import java.util.Arrays;
public class setNewRespawnsC2SPacket { public class setNewRespawnsC2SPacket {
public static void receive(MinecraftServer server, ServerPlayerEntity player, int number) { public static void receive(MinecraftServer server, ServerPlayerEntity player, //Passiert auf dem Server!!!
ServerPlayNetworkHandler handler, PacketByteBuf buf, PacketSender responseSender) {
setAndGetMultiButtonsSpawn setAndGet = new setAndGetMultiButtonsSpawn(); setAndGetMultiButtonsSpawn setAndGet = new setAndGetMultiButtonsSpawn();
try { try {
switch (number) { //Wird nur einmal angefragt, daher muss buf.readInt() nicht als variable gesetzt werden switch (buf.readInt()) { //Wird nur einmal angefragt, daher muss buf.readInt() nicht als variable gesetzt werden
case 1: case 1:
setAndGet.setMultiSpawn(player, 1); //Spawnpunkt wird gespeichert setAndGet.setMultiSpawn(player, 1); //Spawnpunkt wird gespeichert
player.sendMessage(Text.translatable("chat.modchest.multispawn.setspawn", "1")); player.sendMessage(Text.translatable("chat.modchest.multispawn.setspawn", "1"));

View File

@ -1,17 +0,0 @@
package modchest.networking.payload;
import modchest.networking.modNetworkingServer;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.packet.CustomPayload;
public record deathMultiRespawnButtons(int number) implements CustomPayload {
public static final CustomPayload.Id<deathMultiRespawnButtons> ID = new CustomPayload.Id<>(modNetworkingServer.death_call_respawn_buttons);
public static final PacketCodec<RegistryByteBuf, deathMultiRespawnButtons> CODEC = PacketCodec.tuple(PacketCodecs.INTEGER, deathMultiRespawnButtons::number, deathMultiRespawnButtons::new);
@Override
public Id<? extends CustomPayload> getId() {
return null;
}
}

View File

@ -1,17 +0,0 @@
package modchest.networking.payload;
import modchest.networking.modNetworkingServer;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.packet.CustomPayload;
public record requestRespawn(int number) implements CustomPayload {
public static final CustomPayload.Id<requestRespawn> ID = new CustomPayload.Id<>(modNetworkingServer.request_respawn);
public static final PacketCodec<RegistryByteBuf, requestRespawn> CODEC = PacketCodec.tuple(PacketCodecs.INTEGER, requestRespawn::number, requestRespawn::new);
@Override
public Id<? extends CustomPayload> getId() {
return null;
}
}

View File

@ -1,17 +0,0 @@
package modchest.networking.payload;
import modchest.networking.modNetworkingServer;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.packet.CustomPayload;
public record startSleepingCallButtons(int number) implements CustomPayload {
public static final CustomPayload.Id<startSleepingCallButtons> ID = new CustomPayload.Id<>(modNetworkingServer.start_sleeping_call_buttons);
public static final PacketCodec<RegistryByteBuf, startSleepingCallButtons> CODEC = PacketCodec.tuple(PacketCodecs.INTEGER, startSleepingCallButtons::number, startSleepingCallButtons::new);
@Override
public Id<? extends CustomPayload> getId() {
return null;
}
}

View File

@ -0,0 +1,173 @@
package modchest.screen;
import modchest.REServerMod;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.Generic3x3ContainerScreenHandler;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.screen.slot.Slot;
public class denkMalBlockScreenHandler extends ScreenHandler {
private final Inventory inventory;
private static final int field_30788 = 9;
private static final int field_30789 = 9;
private static final int field_30790 = 36;
private static final int field_30791 = 36;
private static final int field_30792 = 45;
public denkMalBlockScreenHandler(int syncId, PlayerInventory playerInventory) {
this(syncId, playerInventory, new SimpleInventory(9));
}
public denkMalBlockScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
//super(ScreenHandlerType.GENERIC_3X3, syncId);
super(modScreenHandler.denk_mal_block_screen_handler, syncId);
checkSize(inventory, 3);
this.inventory = inventory;
inventory.onOpen(playerInventory.player);
this.addSlot(new Slot(inventory, 0, 12 ,15));
this.addSlot(new Slot(inventory, 1, 86 ,15));
this.addSlot(new Slot(inventory, 2, 186 ,60));
int j;
int i;
for (i = 0; i < 3; ++i) {
for (j = 0; j < 3; ++j) {
this.addSlot(new Slot(inventory, j + i * 3, 62 + j * 18, 17 + i * 18));
}
}
for (i = 0; i < 3; ++i) {
for (j = 0; j < 9; ++j) {
this.addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
}
/*
super(ScreenHandlerType.GENERIC_3X3, syncId);
int j;
int i;
Generic3x3ContainerScreenHandler.checkSize(inventory, 9);
this.inventory = inventory;
inventory.onOpen(playerInventory.player);
for (i = 0; i < 3; ++i) {
for (j = 0; j < 3; ++j) {
this.addSlot(new Slot(inventory, j + i * 3, 62 + j * 18, 17 + i * 18));
}
}
for (i = 0; i < 3; ++i) {
for (j = 0; j < 9; ++j) {
this.addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
}*/
}
@Override
public boolean canUse(PlayerEntity player) {
return this.inventory.canPlayerUse(player);
}
@Override
public ItemStack transferSlot(PlayerEntity player, int index) {
ItemStack itemStack = ItemStack.EMPTY;
Slot slot = (Slot)this.slots.get(index);
if (slot != null && slot.hasStack()) {
ItemStack itemStack2 = slot.getStack();
itemStack = itemStack2.copy();
if (index < 9 ? !this.insertItem(itemStack2, 9, 45, true) : !this.insertItem(itemStack2, 0, 9, false)) {
return ItemStack.EMPTY;
}
if (itemStack2.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
} else {
slot.markDirty();
}
if (itemStack2.getCount() == itemStack.getCount()) {
return ItemStack.EMPTY;
}
slot.onTakeItem(player, itemStack2);
}
return itemStack;
}
@Override
public void close(PlayerEntity player) {
super.close(player);
this.inventory.onClose(player);
}
/*
public denkMalBlockScreenHandler(int syncId, PlayerInventory inventory) {
this(syncId, inventory, new SimpleInventory(3));
}
public denkMalBlockScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
super(modScreenHandler.denk_mal_block_screen_handler, syncId);
checkSize(inventory, 3);
this.inventory = inventory;
inventory.onOpen(playerInventory.player);
this.addSlot(new Slot(inventory, 0, 12 ,15));
this.addSlot(new Slot(inventory, 1, 86 ,15));
this.addSlot(new Slot(inventory, 2, 186 ,60));
addPlayerInventory(playerInventory);
addPlayerHotbar(playerInventory);
}
@Override
public ItemStack transferSlot(PlayerEntity player, int invSlot) { //kuemmert sich um Unfig wie shift-click
ItemStack newStack = ItemStack.EMPTY;
Slot slot = this.slots.get(invSlot);
if (slot != null && slot.hasStack()) {
ItemStack originalStack = slot.getStack();
if (invSlot < this.inventory.size()) {
if (!this.insertItem(originalStack, this.inventory.size(), this.slots.size(), true)) {
return ItemStack.EMPTY;
}
} else if (!this.insertItem(originalStack, 0, this.inventory.size(), false)) {
return ItemStack.EMPTY;
}
if (originalStack.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
} else {
slot.markDirty();;
}
}
return newStack;
}
@Override
public boolean canUse(PlayerEntity player) {
return this.inventory.canPlayerUse(player);
}
private void addPlayerInventory(PlayerInventory playerInventory) {
for (int i = 0; i < 3; i++) {
for (int l = 0; l < 9; ++l) {
this.addSlot(new Slot(playerInventory, l + i*9 +9, 8 + l * 18, 86 + i * 18));
}
}
}
private void addPlayerHotbar(PlayerInventory playerInventory) {
for (int i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 144));
}
}
*/
}

View File

@ -0,0 +1,12 @@
package modchest.screen;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.screen.StonecutterScreenHandler;
public class modScreenHandler {
public static ScreenHandlerType<denkMalBlockScreenHandler> denk_mal_block_screen_handler;
public static void registerAllScreenHandlers() {
denk_mal_block_screen_handler = new ScreenHandlerType<>(denkMalBlockScreenHandler::new);
}
}

View File

@ -0,0 +1,68 @@
package modchest.util;
import modchest.REServerMod;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtIo;
import java.io.*;
public class dataSaverIO { //Speichert alles mod-relevanten Serverdaten ab
private static File reServerFile = null;
private static NbtCompound reServerNbt = null;
public dataSaverIO() {}
void readFromFile() { //laedt die Daten der Datei; macht der Server bereits automatisch, danke mixin!
try {
reServerNbt = NbtIo.read(reServerFile); //liest die Datei
if (reServerNbt == null) { //sollte der Nbt-Tag noch nciht existieren, wird er erstellt
reServerNbt = new NbtCompound();
}
} catch (IOException e) { //sollte das IO einen Fehler haben, sollte aber nie vorkommen, wird die mod versuchen es zu fixen, indem sie einen neuen NbtTag erstellt und mit dem weiter arbeitet
REServerMod.LOGGER.error("Error when trying to read from file: " + String.valueOf(e) + " trying to fix it by making a new Nbt");
reServerNbt = new NbtCompound();
} catch (Exception e) { //alle anderen exception, versucht er genau so zu fixen. Loescht alle alten Daten, aber besser, als das die Mod garnicht mehr geht
reServerNbt = new NbtCompound();
}
}
void writeToFile() { //speichert den Nbt-Tag als Datei ab; macht der Server auch automatisch
reServerNbt.putInt("NullSafety", 1); //gibt manchmal Probleme wenn nichts im Nbt-Tag steht, deswegen wird hin und wieder mal eine NullSafety abgespeichert
try {
if (reServerNbt != null) { //stellt sicher, das auch wirklich wirklich was im NbtTag steht vor dem abspeichern
NbtIo.write(reServerNbt, reServerFile);
}
} catch (Exception e) {
REServerMod.LOGGER.error("Error when trying to write to file: " + String.valueOf(e));
}
}
public void writeToNbt(NbtCompound nbt) { //ueberschreibt den ServerNbt-Tag, pass auf, dass du nicht sachen von anderen Teilen der mods vergisst mit zu kopieren!
reServerNbt = nbt;
}
public NbtCompound getFromNbt() { //uebergibt den servernbt
if (reServerNbt == null) { //sollte der server-nbt-tag noch nciht existieren, wird er neu erstellt
REServerMod.LOGGER.error("ServerNbt ist null in getFromNbt!"); //eigentlich sollte es nicht auftreten...
reServerNbt = new NbtCompound();
}
return reServerNbt;
}
public void readFile() { //public version, den servernbt von der Datei einzulesen
readFromFile();
}
public void saveFile() { //moeglichkeit, die datei force-abzuspeichern
writeToFile();
}
public void writeFilePath(File file) { //setzt den Pfad fuer den Server-Nbt-Tag wird vom server dank mixin automatisch gesetzt
reServerFile = new File(file, "REServerMod" + ".dat");
}
public void resetData() { //resets the data of this class
reServerFile = null;
reServerNbt = new NbtCompound();
}
}

View File

@ -0,0 +1,84 @@
package modchest.util;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Arrays;
import java.util.Set;
import static java.lang.Math.abs;
public class denkMalBlockUtil extends dataSaverIO{
public denkMalBlockUtil() {}
public void addBlock(int[] pos, int[] range) { //fuegt bloecke der Liste an abbauverhindernden Bloecke hinzu
NbtCompound tempNbt = new NbtCompound(); //Nbt in dem die Blockdaten gespeichert werden
NbtCompound nbt = returnLoadedNbt(); //holt sich den denkmalblock nbt
tempNbt.putIntArray("position", pos);
tempNbt.putIntArray("range", range); //range ist 6 stellen lang mit immer der erlaubten range in negative richtung, dann positiv fuer alle 3 Koordinaten, also: -x, +x, -y, +y, -z, +z Richtung
nbt.put(Arrays.toString(pos), tempNbt); //speichert die daten des neuen Blocks ab
saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab
}
public void removeBlock(int[] posString) { //loescht bloecke aus Liste an abbauverhindernden Bloecken
NbtCompound nbt = returnLoadedNbt(); //holt sich den denkmalblock nbt
nbt.remove(Arrays.toString(posString)); //entfernt diesen block
saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab
}
private NbtCompound returnLoadedNbt() { //gibt den denkmalblock nbt zurueck
NbtCompound nbt = getFromNbt(); //laedt den gesamten reServerNbt
nbt = (NbtCompound) nbt.get("denkmalblock");//nimmt den denkmalblocknbt und laedt diesen
if (nbt == null) { //sollte der nbt noch nicht existieren wird er erstellt
nbt = new NbtCompound();
}
return nbt;
}
private void saveInNbt(NbtCompound nbt) { //speichert den denkmalblock nbt im reServerNbt ab
NbtCompound reServerNbt = getFromNbt(); //holt den reServerNbt
reServerNbt.put("denkmalblock", nbt); //schreibt den denkmalblock nbt ab
writeToNbt(reServerNbt); //schreibt den editierten reServerNbt
}
public boolean allowBlocks(World world, PlayerEntity player, BlockPos pos) {
if (world.getRegistryKey() == World.OVERWORLD) {
if (!player.isCreative()) {
NbtCompound nbt = returnLoadedNbt();
Set<String> set = nbt.getKeys();
String[] keys = set.toArray(new String[0]);//erzeugt einen String-Array mit allen keys
for (String key : keys) {
if (inRange((NbtCompound) nbt.get(key), pos)) {
if (!world.isClient) {
player.sendMessage(Text.of("Can't change Blocks here! This area is protected!"));
}
return false;
}
}
}
}
return true;
}
private boolean inRange(NbtCompound nbt, BlockPos pos) {
int[] denkPos = nbt.getIntArray("position");
int[] denkRange = nbt.getIntArray("range");
int[] blockPos = new int[3];
blockPos[0] = pos.getX();
blockPos[1] = pos.getY();
blockPos[2] = pos.getZ();
for(int i = 0; i < 3; i++) {
int dif = (denkPos[i] - blockPos[i]);
if(dif > abs(denkRange[i]) && dif < abs(denkRange[i++])) {
return false;
}
}
return true;
}
}

View File

@ -3,10 +3,13 @@ package modchest.util;
import modchest.block.entity.modBlockEntities; import modchest.block.entity.modBlockEntities;
import modchest.block.modBlocks; import modchest.block.modBlocks;
import modchest.event.playerAfterRespawnEvent; import modchest.event.playerAfterRespawnEvent;
import modchest.event.playerBreakBlockEvents;
import modchest.item.modItemGroup; import modchest.item.modItemGroup;
import modchest.item.modItems; import modchest.item.modItems;
import modchest.networking.modNetworkingServer; import modchest.networking.modNetworkingServer;
import modchest.screen.modScreenHandler;
import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
public class initializer { public class initializer {
public static void itemGroups() { public static void itemGroups() {
@ -22,9 +25,14 @@ public class initializer {
public static void events() { //Events, bei denen custom Code ausgefuehrt wird, werden eingefuehrt public static void events() { //Events, bei denen custom Code ausgefuehrt wird, werden eingefuehrt
ServerPlayerEvents.AFTER_RESPAWN.register(new playerAfterRespawnEvent()); ServerPlayerEvents.AFTER_RESPAWN.register(new playerAfterRespawnEvent());
PlayerBlockBreakEvents.BEFORE.register(new playerBreakBlockEvents());
} }
public static void networking() { //Identifier unter denen der Server zuhoert werden registriert public static void networking() { //Identifier unter denen der Server zuhoert werden registriert
modNetworkingServer.registerS2CPackets(); modNetworkingServer.registerC2SPackets();
}
public static void renderer() {
modScreenHandler.registerAllScreenHandlers();
} }
} }

View File

@ -0,0 +1,7 @@
package modchest.util.interfaces;
import java.io.File;
public interface LevelStorageInterface { //Interface, damit der Server den Pfad holen kann
File getFile();
}

View File

@ -1,4 +1,4 @@
package modchest.util; package modchest.util.interfaces;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;

View File

@ -1,11 +1,12 @@
package modchest.util; package modchest.util;
import modchest.REServerMod; import modchest.REServerMod;
import modchest.util.interfaces.ServerPlayerEntityInterface;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryKey;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.World; import net.minecraft.world.World;
public class setAndGetMultiButtonsSpawn { public class setAndGetMultiButtonsSpawn {

View File

@ -0,0 +1,10 @@
{
"variants": {
"powered=false": {
"model": "modchest:block/denk_mal_block_aus"
},
"powered=true": {
"model": "modchest:block/denk_mal_block_an"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "modchest:block/denk_mal_block_placeholder"
}
}
}

View File

0
src/main/resources/assets/modchest/icon.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

0
src/main/resources/assets/modchest/icon.png.old Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 453 B

13
src/main/resources/assets/modchest/lang/de_de.json Executable file → Normal file
View File

@ -1,14 +1,15 @@
{ {
"item.modchest.shipblock": "Schiffsblock", "block.modchest.denk_mal_block": "Denkmal Block",
"item.modchest.pirates_coin": "OP Piraten ding zum Testen",
"block.modchest.steering_wheel": "Lenkrad", "block.modchest.steering_wheel": "Lenkrad",
"itemGroup.modchest.itemlist1": "Malte's Mod",
"chat.modchest.multispawn.beddestroyed": "Scheint so, als wäre das Bett zerstört worden!", "chat.modchest.multispawn.beddestroyed": "Scheint so, als wäre das Bett zerstört worden!",
"chat.modchest.multispawn.getable": "Diese spawn location konnte nicht geladen werden!",
"chat.modchest.multispawn.respawned": "Respawne bei #%s", "chat.modchest.multispawn.respawned": "Respawne bei #%s",
"chat.modchest.multispawn.setspawn": "Nutze spawn #%s", "chat.modchest.multispawn.setspawn": "Nutze spawn #%s",
"chat.modchest.multispawn.setspawnerror": "Fehler beim speichern!", "chat.modchest.multispawn.setspawnerror": "Fehler beim speichern!",
"chat.modchest.multispawn.spawnnotset": "Es scheint so, als wäre dieser Spawn nicht gesetzt!",
"chat.modchest.multispawn.spawnnotsaved": "Fehler beim Versuch, diesen Spawn zu speichern!", "chat.modchest.multispawn.spawnnotsaved": "Fehler beim Versuch, diesen Spawn zu speichern!",
"chat.modchest.multispawn.getable": "Diese spawn location konnte nicht geladen werden!" "chat.modchest.multispawn.spawnnotset": "Es scheint so, als wäre dieser Spawn nicht gesetzt!",
"item.modchest.denk_mal_item": "Denkmal Item",
"item.modchest.pirates_coin": "OP Piraten ding zum Testen",
"item.modchest.shipblock": "Schiffsblock",
"itemGroup.modchest.itemlist1": "Malte's Mod"
} }

8
src/main/resources/assets/modchest/lang/en_pt.json Executable file → Normal file
View File

@ -1,8 +1,10 @@
{ {
"item.modchest.shipblock": "Hanno, änder die Sprache!", "item.modchest.shipblock": "Ste'r thaat ship!" ,
"item.modchest.pirates_coin": "Ya coin for tha pirrrrrates!", "item.modchest.pirates_coin": "Ya coin for tha pirrrrrates!",
"block.modchest.steering_wheel": "Ne, du kriegst keine hilfreichen Angaben mit der Sprache!", "block.modchest.steering_wheel": "Arr! All' h'nd on bord!",
"itemGroup.modchest.itemlist1": "Änder doch endlich die Sprache...", "item.modchest.denk_mal_item": "Don't le' anyon' destr'y your stuff, mate",
"block.modchest.denk_mal_block": "Tortuga no breaky",
"itemGroup.modchest.itemlist1": "Pantry",
"chat.modchest.multispawn.beddestroyed": "Sorry, mate! Looks like that cap'n doesn't like you", "chat.modchest.multispawn.beddestroyed": "Sorry, mate! Looks like that cap'n doesn't like you",
"chat.modchest.multispawn.respawned": "Prepare to board some ship, lads!", "chat.modchest.multispawn.respawned": "Prepare to board some ship, lads!",

2
src/main/resources/assets/modchest/lang/en_us.json Executable file → Normal file
View File

@ -2,6 +2,8 @@
"item.modchest.shipblock": "Shipblock", "item.modchest.shipblock": "Shipblock",
"item.modchest.pirates_coin": "Pirate's Coin", "item.modchest.pirates_coin": "Pirate's Coin",
"block.modchest.steering_wheel": "Steering Wheel", "block.modchest.steering_wheel": "Steering Wheel",
"item.modchest.denk_mal_item": "preservation item",
"block.modchest.denk_mal_block": "preservation block",
"itemGroup.modchest.itemlist1": "new blocks", "itemGroup.modchest.itemlist1": "new blocks",
"chat.modchest.multispawn.beddestroyed": "Oh shit! Looks like that bed got destroyed!", "chat.modchest.multispawn.beddestroyed": "Oh shit! Looks like that bed got destroyed!",

View File

@ -0,0 +1,89 @@
{
"parent": "block/cube_all",
"credit": "Made with Blockbench",
"texture_size": [64, 64],
"textures": {
"1": "modchest:block/denk_mal_block",
"2": "modchest:block/denk_mal_block_kern_an",
"3": "modchest:block/denk_mal_block_basis",
"particle": "modchest:block/denk_mal_block_kern_aus"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 4, 4], "texture": "#3"},
"east": {"uv": [0, 4, 4, 8], "texture": "#3"},
"south": {"uv": [4, 0, 8, 4], "texture": "#3"},
"west": {"uv": [4, 4, 8, 8], "texture": "#3"},
"up": {"uv": [4, 12, 0, 8], "texture": "#3"},
"down": {"uv": [12, 0, 8, 4], "texture": "#3"}
}
},
{
"from": [0, 16, 0],
"to": [16, 32, 16],
"faces": {
"north": {"uv": [0, 0, 4, 4], "texture": "#1"},
"east": {"uv": [0, 4, 4, 8], "texture": "#1"},
"south": {"uv": [4, 0, 8, 4], "texture": "#1"},
"west": {"uv": [4, 4, 8, 8], "texture": "#1"},
"up": {"uv": [4, 12, 0, 8], "texture": "#1"},
"down": {"uv": [12, 0, 8, 4], "texture": "#1"}
}
},
{
"from": [3, 18, 3],
"to": [13, 29, 13],
"faces": {
"north": {"uv": [0, 0, 5, 5.5], "texture": "#2"},
"east": {"uv": [5, 0, 10, 5.5], "texture": "#2"},
"south": {"uv": [0, 5.5, 5, 11], "texture": "#2"},
"west": {"uv": [5, 5.5, 10, 11], "texture": "#2"},
"up": {"uv": [15, 5, 10, 0], "texture": "#2"},
"down": {"uv": [15, 5, 10, 10], "texture": "#2"}
}
}
],
"display": {
"thirdperson_righthand": {
"scale": [0.5, 0.5, 0.5]
},
"thirdperson_lefthand": {
"scale": [0.5, 0.5, 0.5]
},
"firstperson_righthand": {
"rotation": [1, 0, 0],
"translation": [2.5, -1.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"firstperson_lefthand": {
"translation": [2.5, -1.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"ground": {
"scale": [0.5, 0.5, 0.5]
},
"gui": {
"translation": [0, -3.25, 0],
"scale": [0.5, 0.5, 0.5]
},
"head": {
"translation": [0, 11.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"fixed": {
"translation": [0, -1.75, 0],
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "VoxelShapes",
"origin": [8, 8, 8],
"color": 0,
"children": [0, 1, 2]
}
]
}

View File

@ -0,0 +1,89 @@
{
"parent": "block/cube_all",
"credit": "Made with Blockbench",
"texture_size": [64, 64],
"textures": {
"1": "modchest:block/denk_mal_block",
"2": "modchest:block/denk_mal_block_kern_aus",
"3": "modchest:block/denk_mal_block_basis",
"particle": "modchest:block/denk_mal_block_kern_aus"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 4, 4], "texture": "#3"},
"east": {"uv": [0, 4, 4, 8], "texture": "#3"},
"south": {"uv": [4, 0, 8, 4], "texture": "#3"},
"west": {"uv": [4, 4, 8, 8], "texture": "#3"},
"up": {"uv": [4, 12, 0, 8], "texture": "#3"},
"down": {"uv": [12, 0, 8, 4], "texture": "#3"}
}
},
{
"from": [0, 16, 0],
"to": [16, 32, 16],
"faces": {
"north": {"uv": [0, 0, 4, 4], "texture": "#1"},
"east": {"uv": [0, 4, 4, 8], "texture": "#1"},
"south": {"uv": [4, 0, 8, 4], "texture": "#1"},
"west": {"uv": [4, 4, 8, 8], "texture": "#1"},
"up": {"uv": [4, 12, 0, 8], "texture": "#1"},
"down": {"uv": [12, 0, 8, 4], "texture": "#1"}
}
},
{
"from": [3, 18, 3],
"to": [13, 29, 13],
"faces": {
"north": {"uv": [0, 0, 5, 5.5], "texture": "#2"},
"east": {"uv": [5, 0, 10, 5.5], "texture": "#2"},
"south": {"uv": [0, 5.5, 5, 11], "texture": "#2"},
"west": {"uv": [5, 5.5, 10, 11], "texture": "#2"},
"up": {"uv": [15, 5, 10, 0], "texture": "#2"},
"down": {"uv": [15, 5, 10, 10], "texture": "#2"}
}
}
],
"display": {
"thirdperson_righthand": {
"scale": [0.5, 0.5, 0.5]
},
"thirdperson_lefthand": {
"scale": [0.5, 0.5, 0.5]
},
"firstperson_righthand": {
"rotation": [1, 0, 0],
"translation": [2.5, -1.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"firstperson_lefthand": {
"translation": [2.5, -1.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"ground": {
"scale": [0.5, 0.5, 0.5]
},
"gui": {
"translation": [0, -3.25, 0],
"scale": [0.5, 0.5, 0.5]
},
"head": {
"translation": [0, 11.5, 0],
"scale": [0.5, 0.5, 0.5]
},
"fixed": {
"translation": [0, -1.75, 0],
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "VoxelShapes",
"origin": [8, 8, 8],
"color": 0,
"children": [0, 1, 2]
}
]
}

View File

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"particle": "modchest:block/denk_mal_block"
}
}

View File

@ -1,6 +1,914 @@
{ {
"parent": "block/cube_all", "credit": "Made with Blockbench",
"textures": { "textures": {
"all": "modchest:block/steering_wheel" "0": "block/acacia_planks",
"1": "block/diamond_block",
"4": "block/polished_blackstone",
"5": "block/raw_iron_block",
"particle": "block/acacia_planks"
},
"elements": [
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 0],
"to": [8.5, 11.5913, 1],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 0],
"to": [8.5, 11.5913, 1],
"rotation": {"angle": 45, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 17, 6.4087],
"to": [8.5, 18, 9.5913],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 17, 6.4087],
"to": [8.5, 18, 9.5913],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 17, 6.4087],
"to": [8.5, 18, 9.5913],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 15],
"to": [8.5, 11.5913, 16],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 15],
"to": [8.5, 11.5913, 16],
"rotation": {"angle": 45, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 2, 6.4087],
"to": [8.5, 3, 9.5913],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 2, 6.4087],
"to": [8.5, 3, 9.5913],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 2, 6.4087],
"to": [8.5, 3, 9.5913],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 2, 6.4087],
"to": [8.5, 3, 9.5913],
"rotation": {"angle": 45, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 0],
"to": [8.5, 11.5913, 1],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 0],
"to": [8.5, 11.5913, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 17, 6.4087],
"to": [8.5, 18, 9.5913],
"rotation": {"angle": 45, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 15],
"to": [8.5, 11.5913, 16],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.4087, 15],
"to": [8.5, 11.5913, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#0"},
"south": {"uv": [0, 0, 1, 1], "texture": "#0"},
"west": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#0"},
"up": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 0, 1, 1], "texture": "#0"}
}
},
{
"from": [7.5, 9.7, -1.5],
"to": [8.5, 10.45, 6.5],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 0.75], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [2, 0, 3, 8], "texture": "#0"}
}
},
{
"from": [7.5, 9.6, 9.5],
"to": [8.5, 10.35, 17.5],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 0.75], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [2, 0, 3, 8], "texture": "#0"}
}
},
{
"from": [7.5, 0.5, 7.55],
"to": [8.5, 8.5, 8.3],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"south": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"up": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"down": {"uv": [2, 0, 3, 0.75], "texture": "#0"}
}
},
{
"from": [7.5, 11.5, 7.55],
"to": [8.5, 19.5, 8.3],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"south": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"up": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"down": {"uv": [2, 0, 3, 0.75], "texture": "#0"}
}
},
{
"from": [7.5, 0.5, 7.55],
"to": [8.5, 8.5, 8.3],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"south": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"up": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"down": {"uv": [2, 0, 3, 0.75], "texture": "#0"}
}
},
{
"from": [7.5, 9.65, 9.5],
"to": [8.5, 10.4, 17.5],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 0.75], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [2, 0, 3, 8], "texture": "#0"}
}
},
{
"from": [7.5, 9.65, -1.5],
"to": [8.5, 10.4, 6.5],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 0.75], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 270, "texture": "#0"},
"south": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 90, "texture": "#0"},
"up": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"down": {"uv": [2, 0, 3, 8], "texture": "#0"}
}
},
{
"from": [7.5, 11.5, 7.55],
"to": [8.5, 19.5, 8.3],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"east": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"south": {"uv": [2, 0, 3, 8], "rotation": 180, "texture": "#0"},
"west": {"uv": [2, 0, 2.75, 8], "rotation": 180, "texture": "#0"},
"up": {"uv": [2, 0, 3, 0.75], "texture": "#0"},
"down": {"uv": [2, 0, 3, 0.75], "texture": "#0"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 9.70163, 6.5],
"to": [8.5, 10.29837, 9.5],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [5, 3, 3, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 180, "texture": "#5"},
"south": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 180, "texture": "#5"},
"up": {"uv": [1, 1, 3, 3], "texture": "#5"},
"down": {"uv": [4, 3, 6, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 9.70163, 6.5],
"to": [8.5, 10.29837, 9.5],
"rotation": {"angle": 45, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [5, 3, 3, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 180, "texture": "#5"},
"south": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 180, "texture": "#5"},
"up": {"uv": [1, 1, 3, 3], "texture": "#5"},
"down": {"uv": [4, 3, 6, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.5, 7.70163],
"to": [8.5, 11.5, 8.29837],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [4, 3, 6, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 90, "texture": "#5"},
"south": {"uv": [1, 1, 3, 3], "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 270, "texture": "#5"},
"up": {"uv": [5, 3, 3, 5], "texture": "#5"},
"down": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.5, 7.70163],
"to": [8.5, 11.5, 8.29837],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [4, 3, 6, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 90, "texture": "#5"},
"south": {"uv": [1, 1, 3, 3], "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 270, "texture": "#5"},
"up": {"uv": [5, 3, 3, 5], "texture": "#5"},
"down": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.5, 7.70163],
"to": [8.5, 11.5, 8.29837],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [4, 3, 6, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 90, "texture": "#5"},
"south": {"uv": [1, 1, 3, 3], "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 270, "texture": "#5"},
"up": {"uv": [5, 3, 3, 5], "texture": "#5"},
"down": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 8.5, 7.70163],
"to": [8.5, 11.5, 8.29837],
"rotation": {"angle": 45, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [5, 3, 3, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 180, "texture": "#5"},
"south": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 180, "texture": "#5"},
"up": {"uv": [1, 1, 3, 3], "texture": "#5"},
"down": {"uv": [4, 3, 6, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 9.70163, 6.5],
"to": [8.5, 10.29837, 9.5],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [4, 3, 6, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 90, "texture": "#5"},
"south": {"uv": [1, 1, 3, 3], "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 270, "texture": "#5"},
"up": {"uv": [5, 3, 3, 5], "texture": "#5"},
"down": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [7.5, 9.70163, 6.5],
"to": [8.5, 10.29837, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [4, 3, 6, 5], "rotation": 180, "texture": "#5"},
"east": {"uv": [7, 5, 10, 8], "rotation": 90, "texture": "#5"},
"south": {"uv": [1, 1, 3, 3], "texture": "#5"},
"west": {"uv": [7, 5, 10, 8], "rotation": 270, "texture": "#5"},
"up": {"uv": [5, 3, 3, 5], "texture": "#5"},
"down": {"uv": [5, 4, 3, 2], "rotation": 180, "texture": "#5"}
}
},
{
"name": "diamon",
"from": [7.5, 9.5, 7.5],
"to": [8.7, 10.5, 8.5],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1.2, 1], "rotation": 180, "texture": "#1"},
"east": {"uv": [8, 8, 15, 15], "rotation": 180, "texture": "#1"},
"south": {"uv": [0, 0, 1.2, 1], "rotation": 180, "texture": "#1"},
"west": {"uv": [0, 0, 1, 1], "rotation": 180, "texture": "#missing"},
"up": {"uv": [0, 0, 1.2, 1], "texture": "#1"},
"down": {"uv": [0, 0, 1.2, 1], "texture": "#1"}
}
},
{
"name": "diamond",
"from": [7.5, 9.5, 7.5],
"to": [8.7, 10.5, 8.5],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 1.2, 1], "rotation": 180, "texture": "#1"},
"east": {"uv": [6, 6, 15, 15], "rotation": 90, "texture": "#1"},
"south": {"uv": [6, 4, 7.2, 5], "texture": "#1"},
"west": {"uv": [0, 0, 1, 1], "rotation": 270, "texture": "#missing"},
"up": {"uv": [0, 0, 1.2, 1], "texture": "#1"},
"down": {"uv": [0, 0, 1.2, 1], "rotation": 180, "texture": "#1"}
}
},
{
"name": "AufhängungDrehteil",
"from": [5.5, 9, 7.5],
"to": [7.5, 11, 8.5],
"rotation": {"angle": -22.5, "axis": "x", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 2, 2], "rotation": 180, "texture": "#0"},
"east": {"uv": [0, 0, 2, 1], "rotation": 90, "texture": "#0"},
"south": {"uv": [0, 0, 2, 2], "texture": "#0"},
"west": {"uv": [0, 0, 2, 1], "rotation": 270, "texture": "#0"},
"up": {"uv": [0, 0, 2, 1], "texture": "#0"},
"down": {"uv": [0, 0, 2, 1], "rotation": 180, "texture": "#0"}
}
},
{
"from": [0.5, 0, 0.75],
"to": [5.5, 1, 15],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 14.25, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 14.25, 1], "texture": "#0"},
"up": {"uv": [0, 0, 14.25, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 14.25], "texture": "#0"}
}
},
{
"from": [0.5, 2, 1.75],
"to": [5.5, 3, 13.75],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 12, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 12, 1], "texture": "#0"},
"up": {"uv": [0, 0, 12, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 12], "texture": "#0"}
}
},
{
"from": [0.5, 0.5, 0.25],
"to": [5.5, 12.5, 1.25],
"rotation": {"angle": 22.5, "axis": "x", "origin": [0, 0, 0]},
"faces": {
"north": {"uv": [9, 0, 14, 12], "texture": "#0"},
"east": {"uv": [0, 0, 1, 12], "texture": "#0"},
"south": {"uv": [5, 0, 10, 12], "texture": "#0"},
"west": {"uv": [0, 0, 1, 12], "texture": "#0"},
"up": {"uv": [0, 0, 1, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 1], "texture": "#0"}
}
},
{
"from": [0.5, 1, 1.25],
"to": [5.5, 2, 14.25],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 13, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 13, 1], "texture": "#0"},
"up": {"uv": [0, 0, 13, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 13], "texture": "#0"}
}
},
{
"from": [0.5, 10.5, 5],
"to": [5.5, 11.5, 10.75],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 5.75, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 5.75, 1], "texture": "#0"},
"up": {"uv": [0, 0, 5.75, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 5.75], "texture": "#0"}
}
},
{
"from": [0.5, 3, 2],
"to": [5.5, 4, 13.75],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 11.75, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 11.75, 1], "texture": "#0"},
"up": {"uv": [0, 0, 11.75, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 11.75], "texture": "#0"}
}
},
{
"from": [0.5, 5, 2.75],
"to": [5.5, 6, 12.75],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 10, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 10, 1], "texture": "#0"},
"up": {"uv": [0, 0, 10, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 10], "texture": "#0"}
}
},
{
"from": [0.5, 6, 3.25],
"to": [5.5, 7, 12.5],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 9.25, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 9.25, 1], "texture": "#0"},
"up": {"uv": [0, 0, 9.25, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 9.25], "texture": "#0"}
}
},
{
"from": [0.5, 7, 3.75],
"to": [5.5, 8, 12],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 8.25, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 8.25, 1], "texture": "#0"},
"up": {"uv": [0, 0, 8.25, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 8.25], "texture": "#0"}
}
},
{
"from": [0.5, 9, 4.5],
"to": [5.5, 10, 11.25],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 6.75, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 6.75, 1], "texture": "#0"},
"up": {"uv": [0, 0, 6.75, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 6.75], "texture": "#0"}
}
},
{
"from": [0.5, 10, 5],
"to": [5.5, 11, 10.75],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 5.75, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 5.75, 1], "texture": "#0"},
"up": {"uv": [0, 0, 5.75, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 5.75], "texture": "#0"}
}
},
{
"from": [0.5, 8, 4],
"to": [5.5, 9, 11.5],
"faces": {
"north": {"uv": [9, 0, 14, 1], "texture": "#0"},
"east": {"uv": [0, 0, 7.5, 1], "texture": "#0"},
"south": {"uv": [5, 0, 10, 1], "texture": "#0"},
"west": {"uv": [0, 0, 7.5, 1], "texture": "#0"},
"up": {"uv": [0, 0, 7.5, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 7.5], "texture": "#0"}
}
},
{
"from": [0.5, 4, 2.5],
"to": [5.5, 5, 13.25],
"faces": {
"north": {"uv": [9, 0, 12, 1], "texture": "#0"},
"east": {"uv": [0, 0, 10.75, 1], "texture": "#0"},
"south": {"uv": [5, 0, 7, 1], "texture": "#0"},
"west": {"uv": [0, 0, 13.75, 1], "texture": "#0"},
"up": {"uv": [0, 0, 10.75, 2], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 2, 10.75], "texture": "#0"}
}
},
{
"from": [0.5, -5.5, 13.25],
"to": [5.5, 6.5, 14.25],
"rotation": {"angle": -22.5, "axis": "x", "origin": [0, 0, 0]},
"faces": {
"north": {"uv": [9, 0, 14, 12], "texture": "#0"},
"east": {"uv": [0, 0, 1, 12], "texture": "#0"},
"south": {"uv": [5, 0, 10, 12], "texture": "#0"},
"west": {"uv": [0, 0, 1, 12], "texture": "#0"},
"up": {"uv": [0, 0, 1, 5], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 0, 5, 1], "texture": "#0"}
}
},
{
"from": [1, 4, 5],
"to": [5.5, 13, 11],
"faces": {
"north": {"uv": [0, 0, 4.5, 9], "texture": "#0"},
"east": {"uv": [0, 0, 6, 9], "texture": "#0"},
"south": {"uv": [0, 0, 4.5, 9], "texture": "#0"},
"west": {"uv": [0, 0, 6, 9], "texture": "#0"},
"up": {"uv": [0, 0, 4.5, 6], "texture": "#0"},
"down": {"uv": [0, 0, 4.5, 6], "texture": "#missing"}
}
},
{
"from": [1, 0, 2],
"to": [5.5, 4, 14],
"faces": {
"north": {"uv": [0, 0, 4.5, 4], "texture": "#0"},
"east": {"uv": [0, 0, 12, 4], "texture": "#0"},
"south": {"uv": [0, 0, 4.5, 4], "texture": "#0"},
"west": {"uv": [0, 0, 12, 4], "texture": "#0"},
"up": {"uv": [0, 0, 4.5, 12], "texture": "#0"},
"down": {"uv": [0, 0, 4.5, 12], "texture": "#0"}
}
},
{
"from": [1, 4, 11],
"to": [5.5, 6, 13],
"faces": {
"north": {"uv": [0, 0, 4.5, 2], "texture": "#0"},
"east": {"uv": [0, 0, 2, 2], "texture": "#0"},
"south": {"uv": [0, 0, 4.5, 2], "texture": "#0"},
"west": {"uv": [0, 0, 2, 2], "texture": "#0"},
"up": {"uv": [0, 0, 4.5, 2], "texture": "#0"},
"down": {"uv": [0, 0, 4.5, 2], "texture": "#missing"}
}
},
{
"from": [1, 4, 3],
"to": [5.5, 6, 5],
"faces": {
"north": {"uv": [0, 0, 4.5, 2], "texture": "#0"},
"east": {"uv": [0, 0, 2, 2], "texture": "#0"},
"south": {"uv": [0, 0, 4.5, 2], "texture": "#0"},
"west": {"uv": [0, 0, 2, 2], "texture": "#0"},
"up": {"uv": [0, 0, 4.5, 2], "texture": "#0"},
"down": {"uv": [0, 0, 4.5, 2], "texture": "#missing"}
}
},
{
"from": [2, 9, 0],
"to": [4, 11, 0.25],
"rotation": {"angle": 22.5, "axis": "x", "origin": [0, 0, 0]},
"faces": {
"north": {"uv": [3, 1, 5, 3], "texture": "#4"},
"east": {"uv": [0, 0, 0.25, 2], "texture": "#4"},
"south": {"uv": [0, 0, 2, 2], "texture": "#missing"},
"west": {"uv": [0, 0, 0.25, 2], "texture": "#4"},
"up": {"uv": [0, 0, 2, 0.25], "texture": "#4"},
"down": {"uv": [0, 0, 2, 0.25], "texture": "#4"}
}
},
{
"from": [2, 11.45, 6.65],
"to": [2.6, 13.7, 9.15],
"faces": {
"north": {"uv": [0, 0, 0.6, 2.25], "texture": "#4"},
"east": {"uv": [0, 0, 2.5, 2.25], "texture": "#4"},
"south": {"uv": [0, 0, 0.6, 2.25], "texture": "#4"},
"west": {"uv": [0, 0, 2.5, 2.25], "texture": "#4"},
"up": {"uv": [0, 0, 0.6, 2.5], "texture": "#4"},
"down": {"uv": [0, 0, 0.6, 2.5], "texture": "#missing"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 12.35109, 6.85],
"to": [3.375, 12.74891, 8.85],
"rotation": {"angle": -45, "axis": "x", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 12.35109, 6.85],
"to": [3.375, 12.74891, 8.85],
"rotation": {"angle": -22.5, "axis": "x", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 12.35109, 6.85],
"to": [3.375, 12.74891, 8.85],
"rotation": {"angle": 0, "axis": "y", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 12.35109, 6.85],
"to": [3.375, 12.74891, 8.85],
"rotation": {"angle": 22.5, "axis": "x", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 12.35109, 6.85],
"to": [3.375, 12.74891, 8.85],
"rotation": {"angle": 45, "axis": "x", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 11.55, 7.65109],
"to": [3.375, 13.55, 8.04891],
"rotation": {"angle": -22.5, "axis": "x", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 11.55, 7.65109],
"to": [3.375, 13.55, 8.04891],
"rotation": {"angle": 0, "axis": "y", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
}
},
{
"name": "hexadecagon",
"from": [2.625, 11.55, 7.65109],
"to": [3.375, 13.55, 8.04891],
"rotation": {"angle": 22.5, "axis": "x", "origin": [3, 12.55, 7.85]},
"faces": {
"north": {"uv": [5, 7, 6, 8], "texture": "#5"},
"east": {"uv": [2, 13, 0, 11], "texture": "#5"},
"south": {"uv": [2, 13, 3, 14], "texture": "#5"},
"west": {"uv": [0, 0, 1, 1], "texture": "#missing"},
"up": {"uv": [8, 2, 9, 3], "texture": "#5"},
"down": {"uv": [3, 4, 4, 5], "texture": "#5"}
} }
} }
],
"display": {
"fixed": {
"rotation": [0, 90, 0]
}
},
"groups": [
{
"name": "Rad",
"origin": [8, 8, 8],
"color": 0,
"children": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
{
"name": "Speichen",
"origin": [8, 10, 8],
"color": 0,
"children": [16, 17, 18, 19, 20, 21, 22, 23]
},
{
"name": "Mittelteil",
"origin": [8, 8, 8],
"color": 0,
"children": [24, 25, 26, 27, 28, 29, 30, 31]
},
32,
33,
34
]
},
{
"name": "Aufhängung1",
"origin": [0, 0, 0],
"color": 0,
"children": [35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48]
},
{
"name": "Aufhängung2",
"origin": [0, 0, 0],
"color": 0,
"children": [49, 50, 51, 52]
},
53,
54,
{
"name": "hexadecagon",
"origin": [8, 8, 8],
"color": 0,
"children": [55, 56, 57, 58, 59, 60, 61, 62]
}
]
}

View File

@ -0,0 +1,3 @@
{
"parent": "modchest:block/denk_mal_block_aus"
}

View File

@ -0,0 +1,218 @@
{
"credit": "Made with Blockbench",
"textures": {
"1": "modchest:item/denk_mal_item"
},
"elements": [
{
"from": [7, 0, 8],
"to": [8, 9, 9],
"faces": {
"north": {"uv": [0, 0, 1, 9], "texture": "#1"},
"east": {"uv": [1, 0, 2, 9], "texture": "#1"},
"south": {"uv": [2, 0, 3, 9], "texture": "#1"},
"west": {"uv": [3, 0, 4, 9], "texture": "#1"},
"up": {"uv": [14, 6, 13, 5], "texture": "#1"},
"down": {"uv": [14, 6, 13, 7], "texture": "#1"}
}
},
{
"from": [7, 12, 8],
"to": [8, 13, 9],
"faces": {
"north": {"uv": [13, 7, 14, 8], "texture": "#1"},
"east": {"uv": [13, 8, 14, 9], "texture": "#1"},
"south": {"uv": [13, 9, 14, 10], "texture": "#1"},
"west": {"uv": [13, 10, 14, 11], "texture": "#1"},
"up": {"uv": [14, 12, 13, 11], "texture": "#1"},
"down": {"uv": [13, 13, 12, 14], "texture": "#1"}
}
},
{
"from": [7, 7, 9],
"to": [8, 10, 10],
"faces": {
"north": {"uv": [9, 0, 10, 3], "texture": "#1"},
"east": {"uv": [1, 9, 2, 12], "texture": "#1"},
"south": {"uv": [2, 9, 3, 12], "texture": "#1"},
"west": {"uv": [3, 9, 4, 12], "texture": "#1"},
"up": {"uv": [14, 13, 13, 12], "texture": "#1"},
"down": {"uv": [14, 13, 13, 14], "texture": "#1"}
}
},
{
"from": [7, 7, 7],
"to": [8, 10, 8],
"faces": {
"north": {"uv": [9, 3, 10, 6], "texture": "#1"},
"east": {"uv": [9, 6, 10, 9], "texture": "#1"},
"south": {"uv": [9, 9, 10, 12], "texture": "#1"},
"west": {"uv": [10, 0, 11, 3], "texture": "#1"},
"up": {"uv": [1, 15, 0, 14], "texture": "#1"},
"down": {"uv": [15, 0, 14, 1], "texture": "#1"}
}
},
{
"from": [8, 7, 8],
"to": [9, 10, 9],
"faces": {
"north": {"uv": [10, 3, 11, 6], "texture": "#1"},
"east": {"uv": [10, 6, 11, 9], "texture": "#1"},
"south": {"uv": [10, 9, 11, 12], "texture": "#1"},
"west": {"uv": [11, 0, 12, 3], "texture": "#1"},
"up": {"uv": [6, 15, 5, 14], "texture": "#1"},
"down": {"uv": [15, 5, 14, 6], "texture": "#1"}
}
},
{
"from": [8, 0, 8],
"to": [9, 2, 9],
"faces": {
"north": {"uv": [1, 12, 2, 14], "texture": "#1"},
"east": {"uv": [2, 12, 3, 14], "texture": "#1"},
"south": {"uv": [3, 12, 4, 14], "texture": "#1"},
"west": {"uv": [12, 3, 13, 5], "texture": "#1"},
"up": {"uv": [8, 15, 7, 14], "texture": "#1"},
"down": {"uv": [15, 7, 14, 8], "texture": "#1"}
}
},
{
"from": [6, 0, 8],
"to": [7, 2, 9],
"faces": {
"north": {"uv": [4, 12, 5, 14], "texture": "#1"},
"east": {"uv": [5, 12, 6, 14], "texture": "#1"},
"south": {"uv": [12, 5, 13, 7], "texture": "#1"},
"west": {"uv": [6, 12, 7, 14], "texture": "#1"},
"up": {"uv": [9, 15, 8, 14], "texture": "#1"},
"down": {"uv": [15, 8, 14, 9], "texture": "#1"}
}
},
{
"from": [7, 0, 9],
"to": [8, 2, 10],
"faces": {
"north": {"uv": [7, 12, 8, 14], "texture": "#1"},
"east": {"uv": [12, 7, 13, 9], "texture": "#1"},
"south": {"uv": [8, 12, 9, 14], "texture": "#1"},
"west": {"uv": [9, 12, 10, 14], "texture": "#1"},
"up": {"uv": [10, 15, 9, 14], "texture": "#1"},
"down": {"uv": [15, 9, 14, 10], "texture": "#1"}
}
},
{
"from": [7, 0, 7],
"to": [8, 2, 8],
"faces": {
"north": {"uv": [12, 9, 13, 11], "texture": "#1"},
"east": {"uv": [10, 12, 11, 14], "texture": "#1"},
"south": {"uv": [11, 12, 12, 14], "texture": "#1"},
"west": {"uv": [12, 11, 13, 13], "texture": "#1"},
"up": {"uv": [11, 15, 10, 14], "texture": "#1"},
"down": {"uv": [15, 10, 14, 11], "texture": "#1"}
}
},
{
"from": [6, 7, 8],
"to": [7, 10, 9],
"faces": {
"north": {"uv": [11, 3, 12, 6], "texture": "#1"},
"east": {"uv": [11, 6, 12, 9], "texture": "#1"},
"south": {"uv": [11, 9, 12, 12], "texture": "#1"},
"west": {"uv": [12, 0, 13, 3], "texture": "#1"},
"up": {"uv": [7, 15, 6, 14], "texture": "#1"},
"down": {"uv": [15, 6, 14, 7], "texture": "#1"}
}
},
{
"from": [7, 8, 6],
"to": [8, 12, 7],
"faces": {
"north": {"uv": [4, 0, 5, 4], "texture": "#1"},
"east": {"uv": [4, 4, 5, 8], "texture": "#1"},
"south": {"uv": [5, 0, 6, 4], "texture": "#1"},
"west": {"uv": [5, 4, 6, 8], "texture": "#1"},
"up": {"uv": [2, 15, 1, 14], "texture": "#1"},
"down": {"uv": [15, 1, 14, 2], "texture": "#1"}
}
},
{
"from": [7, 8, 10],
"to": [8, 12, 11],
"faces": {
"north": {"uv": [6, 0, 7, 4], "texture": "#1"},
"east": {"uv": [6, 4, 7, 8], "texture": "#1"},
"south": {"uv": [7, 0, 8, 4], "texture": "#1"},
"west": {"uv": [7, 4, 8, 8], "texture": "#1"},
"up": {"uv": [3, 15, 2, 14], "texture": "#1"},
"down": {"uv": [15, 2, 14, 3], "texture": "#1"}
}
},
{
"from": [9, 8, 8],
"to": [10, 12, 9],
"faces": {
"north": {"uv": [8, 0, 9, 4], "texture": "#1"},
"east": {"uv": [4, 8, 5, 12], "texture": "#1"},
"south": {"uv": [8, 4, 9, 8], "texture": "#1"},
"west": {"uv": [5, 8, 6, 12], "texture": "#1"},
"up": {"uv": [4, 15, 3, 14], "texture": "#1"},
"down": {"uv": [15, 3, 14, 4], "texture": "#1"}
}
},
{
"from": [5, 8, 8],
"to": [6, 12, 9],
"faces": {
"north": {"uv": [6, 8, 7, 12], "texture": "#1"},
"east": {"uv": [7, 8, 8, 12], "texture": "#1"},
"south": {"uv": [8, 8, 9, 12], "texture": "#1"},
"west": {"uv": [0, 9, 1, 13], "texture": "#1"},
"up": {"uv": [5, 15, 4, 14], "texture": "#1"},
"down": {"uv": [15, 4, 14, 5], "texture": "#1"}
}
},
{
"from": [7.25, 9, 8.25],
"to": [7.75, 9.5, 8.75],
"faces": {
"north": {"uv": [0, 13, 1, 14], "texture": "#1"},
"east": {"uv": [13, 0, 14, 1], "texture": "#1"},
"south": {"uv": [13, 1, 14, 2], "texture": "#1"},
"west": {"uv": [13, 2, 14, 3], "texture": "#1"},
"up": {"uv": [14, 4, 13, 3], "texture": "#1"},
"down": {"uv": [14, 4, 13, 5], "texture": "#1"}
}
}
],
"display": {
"thirdperson_righthand": {
"translation": [0.5, 5, 0.5]
},
"thirdperson_lefthand": {
"translation": [-0.5, 5, 0.5]
},
"firstperson_righthand": {
"rotation": [-13, 26, 0],
"translation": [1.25, 6, 0]
},
"firstperson_lefthand": {
"rotation": [-13, 20, 0],
"translation": [1.25, 6, 0]
},
"ground": {
"rotation": [26, 0, 0],
"translation": [0, 3.25, 0]
},
"gui": {
"rotation": [0, 0, -34],
"translation": [1.25, 1, 0]
},
"head": {
"translation": [0, 13.75, 0]
},
"fixed": {
"translation": [0, 0.75, -0.5]
}
}
}

View File

View File

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

0
src/main/resources/data/icon.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

View File

View File

View File

View File

View File

View File

View File

@ -0,0 +1,26 @@
{
"type": "minecraft:crafting_shaped",
"category": "buliding",
"key": {
"X": {
"item": "minecraft:emerald"
},
"H": {
"item": "minecraft:amethyst_cluster"
},
"M": {
"item": "minecraft:stone"
},
"I": {
"item": "minecraft:stick"
}
},
"pattern": [
"HXH",
" I ",
"MIM"
],
"result": {
"item": "modchest:denk_mal_item"
}
}

View File

View File

View File

7
src/main/resources/fabric.mod.json Executable file → Normal file
View File

@ -9,8 +9,7 @@
"Theo Dupuis", "Theo Dupuis",
"Paula Dupuis", "Paula Dupuis",
"Jakob Kircher", "Jakob Kircher",
"Clemens von Molo", "Clemens von Molo"
"Hanno Reents"
], ],
"contact": { "contact": {
"homepage": "reents.tv", "homepage": "reents.tv",
@ -24,7 +23,7 @@
"modchest.REServerMod" "modchest.REServerMod"
], ],
"client": [ "client": [
"modchestClient.REServerModClient" "modchest.REServerModClient"
], ],
"fabric-datagen": [ "fabric-datagen": [
"modchest.REServerModDataGenerator" "modchest.REServerModDataGenerator"
@ -39,7 +38,7 @@
], ],
"depends": { "depends": {
"fabricloader": ">=0.14.23", "fabricloader": ">=0.14.23",
"minecraft": "~1.21", "minecraft": "~1.19.2",
"java": ">=17", "java": ">=17",
"fabric-api": "*" "fabric-api": "*"
}, },

9
src/main/resources/reservermod.mixins.json Executable file → Normal file
View File

@ -3,8 +3,13 @@
"package": "modchest.mixin", "package": "modchest.mixin",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"mixins": [ "mixins": [
"ServerPlayerEntityMixin", "bedBlockMixin",
"bedBlock" "flintAndSteelItemMixin",
"itemMixin",
"LevelStorageMixin",
"MinecraftServerMixin",
"playerPlaceBlockMixin",
"ServerPlayerEntityMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1