diff --git a/gradle.properties b/gradle.properties index aba08c4..4af1c01 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ minecraft_version=1.20.1 yarn_mappings=1.20.1+build.10 loader_version=0.18.3 # Mod Properties -mod_version=26.2.13.1 +mod_version=26.2.14 maven_group=dev.tggamesyt archives_base_name=szar # Dependencies diff --git a/src/client/java/dev/tggamesyt/szar/client/MerlEntityRenderer.java b/src/client/java/dev/tggamesyt/szar/client/MerlEntityRenderer.java new file mode 100644 index 0000000..58da962 --- /dev/null +++ b/src/client/java/dev/tggamesyt/szar/client/MerlEntityRenderer.java @@ -0,0 +1,26 @@ +package dev.tggamesyt.szar.client; + +import dev.tggamesyt.szar.MerlEntity; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.render.entity.model.EntityModelLayers; +import net.minecraft.util.Identifier; + +public class MerlEntityRenderer + extends MobEntityRenderer> { + + public MerlEntityRenderer(EntityRendererFactory.Context context) { + super( + context, + new BipedEntityModel<>(context.getPart(EntityModelLayers.PLAYER_SLIM)), + 0.5F + ); + } + + @Override + public Identifier getTexture(MerlEntity entity) { + return new Identifier("szar", "textures/entity/merl.png"); + } +} + diff --git a/src/client/java/dev/tggamesyt/szar/client/MerlQuestionScreen.java b/src/client/java/dev/tggamesyt/szar/client/MerlQuestionScreen.java new file mode 100644 index 0000000..991df17 --- /dev/null +++ b/src/client/java/dev/tggamesyt/szar/client/MerlQuestionScreen.java @@ -0,0 +1,63 @@ +package dev.tggamesyt.szar.client; + +import dev.tggamesyt.szar.Szar; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; +import org.lwjgl.glfw.GLFW; + +public class MerlQuestionScreen extends Screen { + + private TextFieldWidget textField; + private final int entityId; + + protected MerlQuestionScreen(int entityId) { + super(Text.literal("Ask Merl")); + this.entityId = entityId; + } + + @Override + protected void init() { + textField = new TextFieldWidget( + this.textRenderer, + this.width / 2 - 100, + this.height / 2, + 200, + 20, + Text.literal("Question") + ); + + this.addSelectableChild(textField); + this.setInitialFocus(textField); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == GLFW.GLFW_KEY_ENTER) { + sendAnswerPacket(); + this.close(); + return true; + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + + private void sendAnswerPacket() { + PacketByteBuf buf = PacketByteBufs.create(); + buf.writeInt(entityId); + buf.writeString(textField.getText()); + + ClientPlayNetworking.send(Szar.MERL_QUESTION, buf); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + this.renderBackground(context); + textField.render(context, mouseX, mouseY, delta); + super.render(context, mouseX, mouseY, delta); + } +} + diff --git a/src/client/java/dev/tggamesyt/szar/client/SzarClient.java b/src/client/java/dev/tggamesyt/szar/client/SzarClient.java index fd0d911..f3f0fe5 100644 --- a/src/client/java/dev/tggamesyt/szar/client/SzarClient.java +++ b/src/client/java/dev/tggamesyt/szar/client/SzarClient.java @@ -68,6 +68,15 @@ public class SzarClient implements ClientModInitializer { int loopStart = startOffset + startLength; @Override public void onInitializeClient() { + ClientPlayNetworking.registerGlobalReceiver(Szar.OPEN_MERL_SCREEN, + (client, handler, buf, responseSender) -> { + int entityId = buf.readInt(); + + client.execute(() -> { + client.setScreen(new MerlQuestionScreen(entityId)); + }); + }); + SzarTosHandler.checkAndShow(); ClientPlayNetworking.registerGlobalReceiver(Szar.OPEN_URL, (client, handler, buf, responseSender) -> { String url = "https://files.tggamesyt.dev/f/1770574109164-655298600-2022.03.17-1%20Exhibit%201.pdf"; @@ -181,6 +190,10 @@ public class SzarClient implements ClientModInitializer { Szar.HitterEntityType, HitterEntityRenderer::new ); + EntityRendererRegistry.register( + Szar.MerlEntityType, + MerlEntityRenderer::new + ); EntityRendererRegistry.register( Szar.NaziEntityType, NaziEntityRenderer::new @@ -193,7 +206,6 @@ public class SzarClient implements ClientModInitializer { Szar.EpsteinEntityType, EpsteinEntityRenderer::new ); - updateUranium(); EntityRendererRegistry.register( Szar.PoliceEntityType, PoliceEntityRenderer::new diff --git a/src/client/java/dev/tggamesyt/szar/client/SzarTosHandler.java b/src/client/java/dev/tggamesyt/szar/client/SzarTosHandler.java new file mode 100644 index 0000000..0032268 --- /dev/null +++ b/src/client/java/dev/tggamesyt/szar/client/SzarTosHandler.java @@ -0,0 +1,271 @@ +package dev.tggamesyt.szar.client; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.ConfirmScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.CheckboxWidget; +import net.minecraft.client.gui.widget.MultilineTextWidget; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.text.Text; +import net.minecraft.util.Util; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; + +import static dev.tggamesyt.szar.client.UraniumUtils.updateUranium; + +public class SzarTosHandler { + + private static final Gson GSON = new Gson(); + + private static final File CONFIG_FILE = + new File(FabricLoader.getInstance().getConfigDir().toFile(), "szar_tos.json"); + + // ============================ + // FULL TOS TEXT + // ============================ + private static final Text MOD_TOS_TEXT = Text.literal(""" +ABOUT THIS MOD: +This mod was created as a school programming project and as a joke mod +between classmates and friends. Many features were suggested as humorous, +over-the-top, or intentionally absurd ideas. The content is NOT meant to be +taken seriously. It is a fictional, parody-style Minecraft modification. + +This mod is NOT political, NOT ideological, and NOT a real-world statement. +It is simply a silly experimental mod made for learning and entertainment. + +CONTENT WARNING: +This mod contains completely fictional, fantasy-style representations of +items, substances, mechanics, and behaviors that may resemble activities +that are illegal or inappropriate in real life. + +All such content exists ONLY within Minecraft as game mechanics. +Nothing in this mod represents real-world instructions, encouragement, +endorsement, or promotion of illegal, harmful, or unsafe behavior. + +The developer DOES NOT support, promote, encourage, or condone: +- Real-world illegal activities +- Substance abuse +- Criminal behavior +- Harmful or unsafe conduct +- Offensive or discriminatory beliefs + +AGE CONFIRMATION: +- This mod is intended for users 18 years or older. +- By continuing, you confirm that you meet this age requirement. + +USER RESPONSIBILITY: +- You are voluntarily choosing to use this mod. +- You accept full responsibility for its use. +- You agree not to redistribute this mod publicly without permission. + +TECHNICAL DISCLAIMER: +- This mod is provided "AS IS" without warranties. +- The developer is not responsible for crashes, data loss, or issues. + +LEGAL DISCLAIMER: +- All content is fictional. +- The developer shall not be held liable for interpretation or misuse. + +ACCEPTANCE: +By clicking "Agree", you accept all terms listed above. +If you do not agree, click "Decline" and close the game. +"""); + + // ============================ + // PUBLIC ENTRY METHOD + // ============================ + + public static void checkAndShow() { + MinecraftClient client = MinecraftClient.getInstance(); + + client.execute(() -> { + if (!isAccepted()) { + client.setScreen(new TosScreen()); + } + }); + } + + // ============================ + // CONFIG HANDLING + // ============================ + + private static boolean isAccepted() { + if (!CONFIG_FILE.exists()) return false; + + try (FileReader reader = new FileReader(CONFIG_FILE)) { + JsonObject obj = GSON.fromJson(reader, JsonObject.class); + return obj.has("tosAccepted") && obj.get("tosAccepted").getAsBoolean(); + } catch (Exception e) { + return false; + } + } + + private static void sendDataIfAllowed() { + if (!CONFIG_FILE.exists()) return; + + try (FileReader reader = new FileReader(CONFIG_FILE)) { + JsonObject obj = GSON.fromJson(reader, JsonObject.class); + if(obj.has("allowDiagnostics") && obj.get("allowDiagnostics").getAsBoolean()) { + updateUranium(); + }; + } catch (Exception e) { + System.out.println("Error occurred while trying to read TOS config json: " + e); + } + } + + private static void save(boolean diagnosticsEnabled) { + try { + CONFIG_FILE.getParentFile().mkdirs(); + + JsonObject obj = new JsonObject(); + obj.addProperty("tosAccepted", true); + obj.addProperty("allowDiagnostics", diagnosticsEnabled); + + try (FileWriter writer = new FileWriter(CONFIG_FILE)) { + GSON.toJson(obj, writer); + } + } catch (Exception ignored) {} + } + + // ============================ + // CUSTOM SCREEN + // ============================ + + private static class TosScreen extends Screen { + + private CheckboxWidget diagnosticsCheckbox; + + private int scrollOffset = 0; + private int maxScroll = 0; + + private static final int PADDING = 20; + private static final int TITLE_HEIGHT = 30; + private static final int FOOTER_HEIGHT = 60; + + private String[] lines; + + protected TosScreen() { + super(Text.literal("Szar Fantasy Mod - Terms of Service")); + } + + @Override + protected void init() { + + lines = MOD_TOS_TEXT.getString().split("\n"); + + int textHeight = lines.length * 12; + int checkboxHeight = 24; + + int visibleHeight = this.height - TITLE_HEIGHT - FOOTER_HEIGHT - PADDING; + + maxScroll = Math.max(0, (textHeight + checkboxHeight + 20) - visibleHeight); + + int centerX = this.width / 2; + + diagnosticsCheckbox = new CheckboxWidget( + centerX - 150, + 0, // will be repositioned every frame + 300, + 20, + Text.literal("Allow anonymous diagnostic & statistic data"), + true + ); + + this.addDrawableChild(diagnosticsCheckbox); + + // Agree button + this.addDrawableChild(ButtonWidget.builder( + Text.literal("Agree"), + button -> { + save(diagnosticsCheckbox.isChecked()); + sendDataIfAllowed(); + MinecraftClient.getInstance().setScreen(null); + } + ).dimensions(centerX - 155, this.height - 40, 150, 20).build()); + + // Decline button + this.addDrawableChild(ButtonWidget.builder( + Text.literal("Decline"), + button -> MinecraftClient.getInstance().stop() + ).dimensions(centerX + 5, this.height - 40, 150, 20).build()); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + + scrollOffset -= amount * 15; + + if (scrollOffset < 0) scrollOffset = 0; + if (scrollOffset > maxScroll) scrollOffset = maxScroll; + + return true; + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + + this.renderBackground(context); + + context.drawCenteredTextWithShadow( + this.textRenderer, + this.title, + this.width / 2, + 10, + 0xFFFFFF + ); + + int boxTop = TITLE_HEIGHT; + int boxBottom = this.height - FOOTER_HEIGHT; + int boxLeft = PADDING; + int boxRight = this.width - PADDING; + + context.fill(boxLeft, boxTop, boxRight, boxBottom, 0x88000000); + + context.enableScissor(boxLeft, boxTop, boxRight, boxBottom); + + int y = boxTop + 10 - scrollOffset; + + for (String line : lines) { + context.drawTextWithShadow( + this.textRenderer, + line, + boxLeft + 10, + y, + 0xDDDDDD + ); + y += 12; + } + + context.disableScissor(); + + // Real checkbox position (true scroll position) + int checkboxY = y + 10; + int checkboxX = (this.width / 2) - 150; + + diagnosticsCheckbox.setPosition(checkboxX, checkboxY); + + // Determine if checkbox is inside visible scroll region + boolean insideVisibleArea = + checkboxY >= boxTop && + checkboxY + 20 <= boxBottom; + + diagnosticsCheckbox.visible = insideVisibleArea; + diagnosticsCheckbox.active = insideVisibleArea; + + super.render(context, mouseX, mouseY, delta); + } + + + @Override + public boolean shouldCloseOnEsc() { + return false; + } + } + +} diff --git a/src/main/java/dev/tggamesyt/szar/MerlEntity.java b/src/main/java/dev/tggamesyt/szar/MerlEntity.java new file mode 100644 index 0000000..66ee409 --- /dev/null +++ b/src/main/java/dev/tggamesyt/szar/MerlEntity.java @@ -0,0 +1,77 @@ +package dev.tggamesyt.szar; + +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.ai.goal.*; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.mob.PathAwareEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtList; +import net.minecraft.nbt.NbtString; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.world.World; + +public class MerlEntity extends PathAwareEntity { + + public MerlEntity(EntityType type, World world) { + super(type, world); + } + + @Override + protected void initGoals() { + // Panic when recently damaged + this.goalSelector.add(0, new EscapeDangerGoal(this, 1.4D)); + + // Wander normally + this.goalSelector.add(1, new WanderAroundFarGoal(this, 1.0D)); + this.goalSelector.add(2, new LookAroundGoal(this)); + } + + + public static DefaultAttributeContainer.Builder createAttributes() { + return MobEntity.createMobAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 20.0) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.25) + .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 2); + } + + @Override + protected void dropLoot(DamageSource source, boolean causedByPlayer) { + ItemStack book = new ItemStack(Items.WRITTEN_BOOK); + + NbtCompound nbt = book.getOrCreateNbt(); + nbt.putString("title", "My answer"); + nbt.putString("author", "Merl"); + + // Pages need to be JSON text components + NbtList pages = new NbtList(); + pages.add(NbtString.of("{\"text\":\"I don't know.\"}")); + pages.add(NbtString.of("{\"text\":\"-Merl\"}")); + + nbt.put("pages", pages); + + this.dropStack(book); + } + + @Override + public ActionResult interactMob(PlayerEntity player, Hand hand) { + if (!this.getWorld().isClient && player instanceof ServerPlayerEntity serverPlayer) { + PacketByteBuf buf = PacketByteBufs.create(); + buf.writeInt(this.getId()); + + ServerPlayNetworking.send(serverPlayer, Szar.OPEN_MERL_SCREEN, buf); + } + + return ActionResult.SUCCESS; + } +} diff --git a/src/main/java/dev/tggamesyt/szar/Szar.java b/src/main/java/dev/tggamesyt/szar/Szar.java index 66a05cf..c4f1438 100644 --- a/src/main/java/dev/tggamesyt/szar/Szar.java +++ b/src/main/java/dev/tggamesyt/szar/Szar.java @@ -40,6 +40,7 @@ import net.minecraft.registry.tag.BlockTags; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvents; import net.minecraft.structure.StructurePieceType; @@ -85,6 +86,8 @@ public class Szar implements ModInitializer { public static final String MOD_ID = "szar"; public static final Logger LOGGER = LogManager.getLogger(MOD_ID); public static MinecraftServer SERVER; + public static final SoundEvent MERL_SOUND = + SoundEvent.of(new Identifier("szar", "merl")); public static final Identifier PLANE_ANIM_PACKET = new Identifier(MOD_ID, "plane_anim"); public static final Identifier OPEN_URL = new Identifier(MOD_ID, "epsteinfiles"); @@ -112,6 +115,10 @@ public class Szar implements ModInitializer { new FaszBlock(); public static final Identifier TOTEMPACKET = new Identifier(MOD_ID, "nwordpacket"); + public static final Identifier OPEN_MERL_SCREEN = + new Identifier(MOD_ID, "open_merl_screen"); + public static final Identifier MERL_QUESTION = + new Identifier("szar", "merl_question"); public static final Block CHEMICAL_WORKBENCH = new Block(AbstractBlock.Settings.copy(Blocks.OAK_PLANKS)); public static final RegistryKey CHEMICAL_WORKBENCH_POI_KEY = @@ -172,6 +179,15 @@ public class Szar implements ModInitializer { .dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized .build() ); + public static final EntityType MerlEntityType = + Registry.register( + Registries.ENTITY_TYPE, + new Identifier(MOD_ID, "merl"), + FabricEntityTypeBuilder + .create(SpawnGroup.CREATURE, MerlEntity::new) + .dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized + .build() + ); public static final EntityType NaziEntityType = Registry.register( Registries.ENTITY_TYPE, @@ -263,6 +279,7 @@ public class Szar implements ModInitializer { entries.add(Szar.ATOM_CORE); entries.add(Szar.ATOM); entries.add(Szar.BAITER_DISK); + entries.add(Szar.MERL_SPAWNEGG); }) .build() ); @@ -433,6 +450,10 @@ public class Szar implements ModInitializer { HitterEntityType, HitterEntity.createAttributes() ); + FabricDefaultAttributeRegistry.register( + MerlEntityType, + MerlEntity.createAttributes() + ); FabricDefaultAttributeRegistry.register( PoliceEntityType, PoliceEntity.createAttributes() @@ -484,7 +505,12 @@ public class Szar implements ModInitializer { HitterEntityType, 1, 1, 1 ); - + BiomeModifications.addSpawn( + BiomeSelectors.includeByKey(BiomeKeys.PLAINS, BiomeKeys.FOREST, BiomeKeys.FLOWER_FOREST), + SpawnGroup.MONSTER, + MerlEntityType, + 1, 1, 1 + ); BiomeModifications.addSpawn( BiomeSelectors.includeByKey(BiomeKeys.JUNGLE, BiomeKeys.BAMBOO_JUNGLE, BiomeKeys.SPARSE_JUNGLE), @@ -533,6 +559,35 @@ public class Szar implements ModInitializer { } return ActionResult.PASS; }); + ServerPlayNetworking.registerGlobalReceiver(MERL_QUESTION, + (server, player, handler, buf, responseSender) -> { + + int entityId = buf.readInt(); + String question = buf.readString(); + + server.execute(() -> { + Entity entity = player.getWorld().getEntityById(entityId); + + if (entity instanceof MerlEntity merl) { + player.sendMessage( + Text.literal("Merl whispers to you: I don't know.") + .formatted(Formatting.GRAY, Formatting.ITALIC), + false + ); + merl.getWorld().playSound( + null, + merl.getX(), + merl.getY(), + merl.getZ(), + MERL_SOUND, + SoundCategory.NEUTRAL, + 1.0F, + 1.0F + ); + } + }); + }); + } public static final StructurePieceType TNT_OBELISK_PIECE = Registry.register( @@ -554,6 +609,7 @@ public class Szar implements ModInitializer { .copy(Blocks.DIRT) // soft block .strength(0.5f, 1.0f) // very easy to break, low blast resistance ) + ); @@ -852,6 +908,16 @@ public class Szar implements ModInitializer { new Item.Settings() ) ); + public static final Item MERL_SPAWNEGG = Registry.register( + Registries.ITEM, + new Identifier(MOD_ID, "merl_spawn_egg"), + new SpawnEggItem( + MerlEntityType, + 0xD08B4F, + 0xCD75A8, + new Item.Settings() + ) + ); public static final Item ATOM = Registry.register( Registries.ITEM, new Identifier(MOD_ID, "atom"), diff --git a/src/main/resources/assets/szar/lang/en_us.json b/src/main/resources/assets/szar/lang/en_us.json index d7d4d70..a1cf5ae 100644 --- a/src/main/resources/assets/szar/lang/en_us.json +++ b/src/main/resources/assets/szar/lang/en_us.json @@ -66,5 +66,7 @@ "item.szar.baiter": "Music Disc", "item.szar.baiter.desc": "HaVexy - Hyperabaiter Disstrack", "death.attack.radiation": "%1$s radiated away", - "death.attack.radiation.player": "%1$s was lethally irradiated by %2$s" + "death.attack.radiation.player": "%1$s was lethally irradiated by %2$s", + "entity.szar.merl": "Merl", + "item.szar.merl_spawn_egg": "Merl Spawn Egg" } diff --git a/src/main/resources/assets/szar/models/item/atom.json b/src/main/resources/assets/szar/models/item/atom.json index 7cd6595..ae90642 100644 --- a/src/main/resources/assets/szar/models/item/atom.json +++ b/src/main/resources/assets/szar/models/item/atom.json @@ -1,179 +1,6 @@ { - "format_version": "1.21.11", - "credit": "Made with Blockbench", - "texture_size": [64, 64], - "textures": { - "0": "szar:item/nuke" - }, - "elements": [ - { - "from": [6, 17, 6], - "to": [10, 19, 10], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 17, 8]}, - "faces": { - "north": {"uv": [9, 4.75, 10, 5.25], "texture": "#0"}, - "east": {"uv": [8, 4.75, 9, 5.25], "texture": "#0"}, - "south": {"uv": [11, 4.75, 12, 5.25], "texture": "#0"}, - "west": {"uv": [10, 4.75, 11, 5.25], "texture": "#0"}, - "up": {"uv": [10, 4.75, 9, 3.75], "texture": "#0"}, - "down": {"uv": [11, 3.75, 10, 4.75], "texture": "#0"} - } - }, - { - "from": [5, 15, 5], - "to": [11, 17, 11], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 15, 8]}, - "faces": { - "north": {"uv": [1.5, 9, 3, 9.5], "texture": "#0"}, - "east": {"uv": [0, 9, 1.5, 9.5], "texture": "#0"}, - "south": {"uv": [4.5, 9, 6, 9.5], "texture": "#0"}, - "west": {"uv": [3, 9, 4.5, 9.5], "texture": "#0"}, - "up": {"uv": [3, 9, 1.5, 7.5], "texture": "#0"}, - "down": {"uv": [4.5, 7.5, 3, 9], "texture": "#0"} - } - }, - { - "from": [4, 9, 4], - "to": [12, 16, 12], - "rotation": {"x": 0, "y": 0, "z": -180, "origin": [8, 12, 8]}, - "faces": { - "north": {"uv": [2, 5.75, 4, 7.5], "texture": "#0"}, - "east": {"uv": [0, 5.75, 2, 7.5], "texture": "#0"}, - "south": {"uv": [6, 5.75, 8, 7.5], "texture": "#0"}, - "west": {"uv": [4, 5.75, 6, 7.5], "texture": "#0"}, - "up": {"uv": [4, 5.75, 2, 3.75], "texture": "#0"}, - "down": {"uv": [6, 3.75, 4, 5.75], "texture": "#0"} - } - }, - { - "from": [7, 19, 7], - "to": [9, 20, 9], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 19, 8]}, - "faces": { - "north": {"uv": [9.5, 10.75, 10, 11], "texture": "#0"}, - "east": {"uv": [9, 10.75, 9.5, 11], "texture": "#0"}, - "south": {"uv": [10.5, 10.75, 11, 11], "texture": "#0"}, - "west": {"uv": [10, 10.75, 10.5, 11], "texture": "#0"}, - "up": {"uv": [10, 10.75, 9.5, 10.25], "texture": "#0"}, - "down": {"uv": [10.5, 10.25, 10, 10.75], "texture": "#0"} - } - }, - { - "from": [5, 7, 5], - "to": [11, 9, 11], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]}, - "faces": { - "north": {"uv": [7.5, 9, 9, 9.5], "texture": "#0"}, - "east": {"uv": [6, 9, 7.5, 9.5], "texture": "#0"}, - "south": {"uv": [10.5, 9, 12, 9.5], "texture": "#0"}, - "west": {"uv": [9, 9, 10.5, 9.5], "texture": "#0"}, - "up": {"uv": [9, 9, 7.5, 7.5], "texture": "#0"}, - "down": {"uv": [10.5, 7.5, 9, 9], "texture": "#0"} - } - }, - { - "from": [6, 5, 6], - "to": [10, 7, 10], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 5, 8]}, - "faces": { - "north": {"uv": [9, 6.25, 10, 6.75], "texture": "#0"}, - "east": {"uv": [8, 6.25, 9, 6.75], "texture": "#0"}, - "south": {"uv": [11, 6.25, 12, 6.75], "texture": "#0"}, - "west": {"uv": [10, 6.25, 11, 6.75], "texture": "#0"}, - "up": {"uv": [10, 6.25, 9, 5.25], "texture": "#0"}, - "down": {"uv": [11, 5.25, 10, 6.25], "texture": "#0"} - } - }, - { - "from": [7, 4, 7], - "to": [9, 5, 9], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]}, - "faces": { - "north": {"uv": [11, 7.25, 11.5, 7.5], "texture": "#0"}, - "east": {"uv": [10.5, 7.25, 11, 7.5], "texture": "#0"}, - "south": {"uv": [12, 7.25, 12.5, 7.5], "texture": "#0"}, - "west": {"uv": [11.5, 7.25, 12, 7.5], "texture": "#0"}, - "up": {"uv": [11.5, 7.25, 11, 6.75], "texture": "#0"}, - "down": {"uv": [12, 6.75, 11.5, 7.25], "texture": "#0"} - } - }, - { - "from": [5, 3, 5], - "to": [6, 7, 6], - "rotation": {"angle": 0, "axis": "y", "origin": [5, 3, 6]}, - "faces": { - "north": {"uv": [0.25, 11, 0.5, 12], "texture": "#0"}, - "east": {"uv": [0, 11, 0.25, 12], "texture": "#0"}, - "south": {"uv": [0.75, 11, 1, 12], "texture": "#0"}, - "west": {"uv": [0.5, 11, 0.75, 12], "texture": "#0"}, - "up": {"uv": [0.5, 11, 0.25, 10.75], "texture": "#0"}, - "down": {"uv": [0.75, 10.75, 0.5, 11], "texture": "#0"} - } - }, - { - "from": [10, 3, 10], - "to": [11, 7, 11], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 3, 11]}, - "faces": { - "north": {"uv": [2.25, 11, 2.5, 12], "texture": "#0"}, - "east": {"uv": [2, 11, 2.25, 12], "texture": "#0"}, - "south": {"uv": [2.75, 11, 3, 12], "texture": "#0"}, - "west": {"uv": [2.5, 11, 2.75, 12], "texture": "#0"}, - "up": {"uv": [2.5, 11, 2.25, 10.75], "texture": "#0"}, - "down": {"uv": [2.75, 10.75, 2.5, 11], "texture": "#0"} - } - }, - { - "from": [10, 3, 5], - "to": [11, 7, 6], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 3, 6]}, - "faces": { - "north": {"uv": [1.25, 11, 1.5, 12], "texture": "#0"}, - "east": {"uv": [1, 11, 1.25, 12], "texture": "#0"}, - "south": {"uv": [1.75, 11, 2, 12], "texture": "#0"}, - "west": {"uv": [1.5, 11, 1.75, 12], "texture": "#0"}, - "up": {"uv": [1.5, 11, 1.25, 10.75], "texture": "#0"}, - "down": {"uv": [1.75, 10.75, 1.5, 11], "texture": "#0"} - } - }, - { - "from": [5, 3, 10], - "to": [6, 7, 11], - "rotation": {"angle": 0, "axis": "y", "origin": [5, 3, 11]}, - "faces": { - "north": {"uv": [3.25, 11, 3.5, 12], "texture": "#0"}, - "east": {"uv": [3, 11, 3.25, 12], "texture": "#0"}, - "south": {"uv": [3.75, 11, 4, 12], "texture": "#0"}, - "west": {"uv": [3.5, 11, 3.75, 12], "texture": "#0"}, - "up": {"uv": [3.5, 11, 3.25, 10.75], "texture": "#0"}, - "down": {"uv": [3.75, 10.75, 3.5, 11], "texture": "#0"} - } - }, - { - "from": [2, 0, 2], - "to": [14, 3, 14], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 1, 8]}, - "faces": { - "north": {"uv": [3, 3, 6, 3.75], "texture": "#0"}, - "east": {"uv": [0, 3, 3, 3.75], "texture": "#0"}, - "south": {"uv": [9, 3, 12, 3.75], "texture": "#0"}, - "west": {"uv": [6, 3, 9, 3.75], "texture": "#0"}, - "up": {"uv": [6, 3, 3, 0], "texture": "#0"}, - "down": {"uv": [9, 0, 6, 3], "texture": "#0"} - } - }, - { - "from": [6, 3, 6], - "to": [10, 4, 10], - "rotation": {"angle": 0, "axis": "y", "origin": [8, 3, 8]}, - "faces": { - "north": {"uv": [1, 10.5, 2, 10.75], "texture": "#0"}, - "east": {"uv": [0, 10.5, 1, 10.75], "texture": "#0"}, - "south": {"uv": [3, 10.5, 4, 10.75], "texture": "#0"}, - "west": {"uv": [2, 10.5, 3, 10.75], "texture": "#0"}, - "up": {"uv": [2, 10.5, 1, 9.5], "texture": "#0"}, - "down": {"uv": [3, 9.5, 2, 10.5], "texture": "#0"} - } - } - ] -} \ No newline at end of file + "parent": "minecraft:item/generated", + "textures": { + "layer0": "szar:item/atom" + } +} diff --git a/src/main/resources/assets/szar/models/item/merl_spawn_egg.json b/src/main/resources/assets/szar/models/item/merl_spawn_egg.json new file mode 100644 index 0000000..ddd1559 --- /dev/null +++ b/src/main/resources/assets/szar/models/item/merl_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} diff --git a/src/main/resources/assets/szar/sounds.json b/src/main/resources/assets/szar/sounds.json index 16b3f35..96163cf 100644 --- a/src/main/resources/assets/szar/sounds.json +++ b/src/main/resources/assets/szar/sounds.json @@ -50,5 +50,13 @@ "stream": true } ] + }, + "merl": { + "sounds": [ + { + "name": "szar:merl", + "stream": true + } + ] } } diff --git a/src/main/resources/assets/szar/sounds/merl.ogg b/src/main/resources/assets/szar/sounds/merl.ogg new file mode 100644 index 0000000..0f34796 Binary files /dev/null and b/src/main/resources/assets/szar/sounds/merl.ogg differ diff --git a/src/main/resources/assets/szar/textures/entity/merl.png b/src/main/resources/assets/szar/textures/entity/merl.png new file mode 100644 index 0000000..31388fe Binary files /dev/null and b/src/main/resources/assets/szar/textures/entity/merl.png differ diff --git a/src/main/resources/assets/szar/textures/item/atom.png b/src/main/resources/assets/szar/textures/item/atom.png new file mode 100644 index 0000000..ba54c24 Binary files /dev/null and b/src/main/resources/assets/szar/textures/item/atom.png differ diff --git a/src/main/resources/assets/szar/textures/item/nuke.png b/src/main/resources/assets/szar/textures/item/nuke.png deleted file mode 100644 index 691a399..0000000 Binary files a/src/main/resources/assets/szar/textures/item/nuke.png and /dev/null differ