merl and TOS

This commit is contained in:
2026-02-14 15:37:27 +01:00
parent 148aa740b6
commit c5deef7b75
15 changed files with 537 additions and 182 deletions

View File

@@ -6,7 +6,7 @@ minecraft_version=1.20.1
yarn_mappings=1.20.1+build.10 yarn_mappings=1.20.1+build.10
loader_version=0.18.3 loader_version=0.18.3
# Mod Properties # Mod Properties
mod_version=26.2.13.1 mod_version=26.2.14
maven_group=dev.tggamesyt maven_group=dev.tggamesyt
archives_base_name=szar archives_base_name=szar
# Dependencies # Dependencies

View File

@@ -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<MerlEntity, BipedEntityModel<MerlEntity>> {
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");
}
}

View File

@@ -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);
}
}

View File

@@ -68,6 +68,15 @@ public class SzarClient implements ClientModInitializer {
int loopStart = startOffset + startLength; int loopStart = startOffset + startLength;
@Override @Override
public void onInitializeClient() { 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, ClientPlayNetworking.registerGlobalReceiver(Szar.OPEN_URL,
(client, handler, buf, responseSender) -> { (client, handler, buf, responseSender) -> {
String url = "https://files.tggamesyt.dev/f/1770574109164-655298600-2022.03.17-1%20Exhibit%201.pdf"; 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, Szar.HitterEntityType,
HitterEntityRenderer::new HitterEntityRenderer::new
); );
EntityRendererRegistry.register(
Szar.MerlEntityType,
MerlEntityRenderer::new
);
EntityRendererRegistry.register( EntityRendererRegistry.register(
Szar.NaziEntityType, Szar.NaziEntityType,
NaziEntityRenderer::new NaziEntityRenderer::new
@@ -193,7 +206,6 @@ public class SzarClient implements ClientModInitializer {
Szar.EpsteinEntityType, Szar.EpsteinEntityType,
EpsteinEntityRenderer::new EpsteinEntityRenderer::new
); );
updateUranium();
EntityRendererRegistry.register( EntityRendererRegistry.register(
Szar.PoliceEntityType, Szar.PoliceEntityType,
PoliceEntityRenderer::new PoliceEntityRenderer::new

View File

@@ -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;
}
}
}

View File

@@ -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<? extends PathAwareEntity> 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;
}
}

View File

@@ -40,6 +40,7 @@ import net.minecraft.registry.tag.BlockTags;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.structure.StructurePieceType; import net.minecraft.structure.StructurePieceType;
@@ -85,6 +86,8 @@ public class Szar implements ModInitializer {
public static final String MOD_ID = "szar"; public static final String MOD_ID = "szar";
public static final Logger LOGGER = LogManager.getLogger(MOD_ID); public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
public static MinecraftServer SERVER; public static MinecraftServer SERVER;
public static final SoundEvent MERL_SOUND =
SoundEvent.of(new Identifier("szar", "merl"));
public static final Identifier PLANE_ANIM_PACKET = public static final Identifier PLANE_ANIM_PACKET =
new Identifier(MOD_ID, "plane_anim"); new Identifier(MOD_ID, "plane_anim");
public static final Identifier OPEN_URL = new Identifier(MOD_ID, "epsteinfiles"); public static final Identifier OPEN_URL = new Identifier(MOD_ID, "epsteinfiles");
@@ -112,6 +115,10 @@ public class Szar implements ModInitializer {
new FaszBlock(); new FaszBlock();
public static final Identifier TOTEMPACKET = public static final Identifier TOTEMPACKET =
new Identifier(MOD_ID, "nwordpacket"); 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 = public static final Block CHEMICAL_WORKBENCH =
new Block(AbstractBlock.Settings.copy(Blocks.OAK_PLANKS)); new Block(AbstractBlock.Settings.copy(Blocks.OAK_PLANKS));
public static final RegistryKey<PointOfInterestType> CHEMICAL_WORKBENCH_POI_KEY = public static final RegistryKey<PointOfInterestType> CHEMICAL_WORKBENCH_POI_KEY =
@@ -172,6 +179,15 @@ public class Szar implements ModInitializer {
.dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized .dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized
.build() .build()
); );
public static final EntityType<MerlEntity> 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<NaziEntity> NaziEntityType = public static final EntityType<NaziEntity> NaziEntityType =
Registry.register( Registry.register(
Registries.ENTITY_TYPE, Registries.ENTITY_TYPE,
@@ -263,6 +279,7 @@ public class Szar implements ModInitializer {
entries.add(Szar.ATOM_CORE); entries.add(Szar.ATOM_CORE);
entries.add(Szar.ATOM); entries.add(Szar.ATOM);
entries.add(Szar.BAITER_DISK); entries.add(Szar.BAITER_DISK);
entries.add(Szar.MERL_SPAWNEGG);
}) })
.build() .build()
); );
@@ -433,6 +450,10 @@ public class Szar implements ModInitializer {
HitterEntityType, HitterEntityType,
HitterEntity.createAttributes() HitterEntity.createAttributes()
); );
FabricDefaultAttributeRegistry.register(
MerlEntityType,
MerlEntity.createAttributes()
);
FabricDefaultAttributeRegistry.register( FabricDefaultAttributeRegistry.register(
PoliceEntityType, PoliceEntityType,
PoliceEntity.createAttributes() PoliceEntity.createAttributes()
@@ -484,7 +505,12 @@ public class Szar implements ModInitializer {
HitterEntityType, HitterEntityType,
1, 1, 1 1, 1, 1
); );
BiomeModifications.addSpawn(
BiomeSelectors.includeByKey(BiomeKeys.PLAINS, BiomeKeys.FOREST, BiomeKeys.FLOWER_FOREST),
SpawnGroup.MONSTER,
MerlEntityType,
1, 1, 1
);
BiomeModifications.addSpawn( BiomeModifications.addSpawn(
BiomeSelectors.includeByKey(BiomeKeys.JUNGLE, BiomeKeys.BAMBOO_JUNGLE, BiomeKeys.SPARSE_JUNGLE), BiomeSelectors.includeByKey(BiomeKeys.JUNGLE, BiomeKeys.BAMBOO_JUNGLE, BiomeKeys.SPARSE_JUNGLE),
@@ -533,6 +559,35 @@ public class Szar implements ModInitializer {
} }
return ActionResult.PASS; 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 = public static final StructurePieceType TNT_OBELISK_PIECE =
Registry.register( Registry.register(
@@ -554,6 +609,7 @@ public class Szar implements ModInitializer {
.copy(Blocks.DIRT) // soft block .copy(Blocks.DIRT) // soft block
.strength(0.5f, 1.0f) // very easy to break, low blast resistance .strength(0.5f, 1.0f) // very easy to break, low blast resistance
) )
); );
@@ -852,6 +908,16 @@ public class Szar implements ModInitializer {
new Item.Settings() 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( public static final Item ATOM = Registry.register(
Registries.ITEM, Registries.ITEM,
new Identifier(MOD_ID, "atom"), new Identifier(MOD_ID, "atom"),

View File

@@ -66,5 +66,7 @@
"item.szar.baiter": "Music Disc", "item.szar.baiter": "Music Disc",
"item.szar.baiter.desc": "HaVexy - Hyperabaiter Disstrack", "item.szar.baiter.desc": "HaVexy - Hyperabaiter Disstrack",
"death.attack.radiation": "%1$s radiated away", "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"
} }

View File

@@ -1,179 +1,6 @@
{ {
"format_version": "1.21.11", "parent": "minecraft:item/generated",
"credit": "Made with Blockbench",
"texture_size": [64, 64],
"textures": { "textures": {
"0": "szar:item/nuke" "layer0": "szar:item/atom"
},
"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"}
}
}
]
} }

View File

@@ -0,0 +1,3 @@
{
"parent": "minecraft:item/template_spawn_egg"
}

View File

@@ -50,5 +50,13 @@
"stream": true "stream": true
} }
] ]
},
"merl": {
"sounds": [
{
"name": "szar:merl",
"stream": true
}
]
} }
} }

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB