diff --git a/gradle.properties b/gradle.properties index 3602886..3b22db3 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.3.12 +mod_version=26.3.12.1 maven_group=dev.tggamesyt archives_base_name=szar # Dependencies diff --git a/src/client/java/dev/tggamesyt/szar/client/RevolverScreen.java b/src/client/java/dev/tggamesyt/szar/client/RevolverScreen.java new file mode 100644 index 0000000..90ca936 --- /dev/null +++ b/src/client/java/dev/tggamesyt/szar/client/RevolverScreen.java @@ -0,0 +1,132 @@ +package dev.tggamesyt.szar.client; + +import dev.tggamesyt.szar.RevolverItem; +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.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; + +public class RevolverScreen extends Screen { + + private final ItemStack revolverStack; + + private static final int[][] SLOT_OFFSETS = { + { 0, -50}, {43, -25}, {43, 25}, + { 0, 50}, {-43, 25}, {-43,-25} + }; + + public RevolverScreen(ItemStack stack) { + super(Text.literal("Revolver")); + this.revolverStack = stack; + } + + @Override + protected void init() { + int cx = this.width / 2; + int cy = this.height / 2; + + boolean[] chambers = RevolverItem.getChambers(revolverStack); + + for (int i = 0; i < RevolverItem.CHAMBERS; i++) { + final int index = i; + int bx = cx + SLOT_OFFSETS[i][0] - 15; + int by = cy + SLOT_OFFSETS[i][1] - 10; + + this.addDrawableChild(ButtonWidget.builder( + getChamberText(index, chambers), + btn -> { + PlayerEntity player = MinecraftClient.getInstance().player; + if (player == null) return; + + boolean[] current = RevolverItem.getChambers(revolverStack); + + if (current[index]) { + // Optimistically update client visual + current[index] = false; + RevolverItem.setChambers(revolverStack, current); + } else { + // Check if player has bullet before sending — purely for visual feedback + boolean hasBullet = false; + for (int o = 0; o < player.getInventory().size(); o++) { + ItemStack s = player.getInventory().getStack(o); + if (!s.isEmpty() && s.isOf(Szar.BULLET_ITEM)) { + hasBullet = true; + break; + } + } + if (!hasBullet) return; // don't even send packet + + current[index] = true; + RevolverItem.setChambers(revolverStack, current); + } + + // Send to server — server does the actual inventory changes + PacketByteBuf buf = PacketByteBufs.create(); + buf.writeInt(index); + buf.writeBoolean(!current[index]); // wasLoaded = what it WAS before the flip + ClientPlayNetworking.send(Szar.REVOLVER_CHAMBER_CHANGE, buf); + + clearChildren(); + init(); + } + ).dimensions(bx, by, 30, 20).build()); + } + + this.addDrawableChild(ButtonWidget.builder( + Text.literal("Done"), + btn -> this.close() + ).dimensions(cx - 40, cy + 75, 80, 20).build()); + } + + private boolean takeBullet(PlayerEntity player) { + for (int i = 0; i < player.getInventory().size(); i++) { + ItemStack s = player.getInventory().getStack(i); + if (!s.isEmpty() && s.isOf(Szar.BULLET_ITEM)) { + s.decrement(1); + return true; + } + } + return false; + } + + private Text getChamberText(int i, boolean[] chambers) { + int current = RevolverItem.getCurrentChamber(revolverStack); + String prefix = (i == current) ? "►" : " "; + return Text.literal(prefix + (chambers[i] ? "●" : "○")); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + this.renderBackground(context); + context.drawCenteredTextWithShadow(this.textRenderer, + Text.literal("Load Revolver"), this.width / 2, this.height / 2 - 70, 0xFFFFFF); + context.drawCenteredTextWithShadow(this.textRenderer, + Text.literal("► = current chamber"), this.width / 2, this.height / 2 - 58, 0xAAAAAA); + super.render(context, mouseX, mouseY, delta); + } + + @Override + public boolean shouldPause() { + return false; + } + + private void syncToServer() { + boolean[] chambers = RevolverItem.getChambers(revolverStack); + int current = RevolverItem.getCurrentChamber(revolverStack); + + PacketByteBuf buf = PacketByteBufs.create(); + for (int i = 0; i < RevolverItem.CHAMBERS; i++) { + buf.writeBoolean(chambers[i]); + } + buf.writeInt(current); + + ClientPlayNetworking.send(Szar.REVOLVER_SYNC, buf); + } +} \ No newline at end of file diff --git a/src/client/java/dev/tggamesyt/szar/client/SzarClient.java b/src/client/java/dev/tggamesyt/szar/client/SzarClient.java index 0707e27..aa35ebc 100644 --- a/src/client/java/dev/tggamesyt/szar/client/SzarClient.java +++ b/src/client/java/dev/tggamesyt/szar/client/SzarClient.java @@ -7,6 +7,7 @@ import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; @@ -54,6 +55,7 @@ import net.minecraft.util.math.Box; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; +import org.lwjgl.glfw.GLFW; import org.spongepowered.asm.mixin.Unique; import java.io.File; @@ -97,8 +99,25 @@ public class SzarClient implements ClientModInitializer { int startLength = 596; int loopLength = 541; int loopStart = startOffset + startLength; + + public static final KeyBinding SPIN_KEY = KeyBindingHelper.registerKeyBinding( + new KeyBinding("key.szar.spin", InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_R, "key.categories.szar") + ); @Override public void onInitializeClient() { + +// Then in a ClientTickEvents.END_CLIENT_TICK: + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (SPIN_KEY.wasPressed() && client.player != null) { + ItemStack stack = client.player.getMainHandStack(); + if (stack.isOf(Szar.REVOLVER)) { + // Send spin packet to server + ClientPlayNetworking.send(Szar.REVOLVER_SPIN, + PacketByteBufs.create()); + } + } + }); ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> { PacketByteBuf buf = PacketByteBufs.create(); @@ -190,6 +209,8 @@ public class SzarClient implements ClientModInitializer { SzarTosHandler.checkAndShow(); ClientPlayNetworking.registerGlobalReceiver(Szar.OPEN_URL, (client, handler, buf, responseSender) -> { + assert client.player != null; + if (PlayerConfigStore.get(client.player.getUuid(), "nsfw")) {return;} String url = "https://files.tggamesyt.dev/f/1770574109164-655298600-2022.03.17-1%20Exhibit%201.pdf"; // maybe https://www.justice.gov/epstein/doj-disclosures diff --git a/src/client/java/dev/tggamesyt/szar/client/SzarTosHandler.java b/src/client/java/dev/tggamesyt/szar/client/SzarTosHandler.java index 211bbc0..3ea5752 100644 --- a/src/client/java/dev/tggamesyt/szar/client/SzarTosHandler.java +++ b/src/client/java/dev/tggamesyt/szar/client/SzarTosHandler.java @@ -29,18 +29,11 @@ public class SzarTosHandler { 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 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. -okay, AI slop aside, this mod includes various "unacceptable" -or age restricted topics, so please tell your age below. -please note this is only saved locally, and can be edited any time from Mod Menu's settings, -but for your own safety please only disable filters approppriate for your age. +okay, AI slop aside, this mod includes various "unacceptable" or age restricted topics, so please tell your age below. please note this is only saved locally, and can be edited any time from Mod Menu's settings, but for your own safety please only disable filters approppriate for your age. -also do NOT attempt to do any illegal activities that you see in this mod, -this is purely a fictional representation of thoose things. +also do NOT attempt to do any illegal activities that you see in this mod, this is purely a fictional representation of thoose things. thank you and enjoy my silly mod <3 """); @@ -149,10 +142,32 @@ thank you and enjoy my silly mod <3 protected TosScreen() { super(Text.literal("Szar Mod - Information")); } - + private List buildWrappedLines(String raw, int maxWidth) { + List result = new ArrayList<>(); + for (String paragraph : raw.split("\n", -1)) { + if (paragraph.isEmpty()) { + result.add(""); + continue; + } + // Word-wrap this paragraph + String[] words = paragraph.split(" "); + StringBuilder current = new StringBuilder(); + for (String word : words) { + String test = current.isEmpty() ? word : current + " " + word; + if (this.textRenderer.getWidth(test) <= maxWidth) { + current = new StringBuilder(test); + } else { + if (!current.isEmpty()) result.add(current.toString()); + current = new StringBuilder(word); + } + } + if (!current.isEmpty()) result.add(current.toString()); + } + return result; + } @Override protected void init() { - lines = MOD_TOS_TEXT.getString().split("\n"); + lines = buildWrappedLines(MOD_TOS_TEXT.getString(), this.width - PADDING * 2 - 20).toArray(new String[0]); int textHeight = lines.length * 12; int visibleHeight = this.height - TITLE_HEIGHT - FOOTER_HEIGHT - PADDING; diff --git a/src/client/java/dev/tggamesyt/szar/client/mixin/RevolverAttackMixin.java b/src/client/java/dev/tggamesyt/szar/client/mixin/RevolverAttackMixin.java new file mode 100644 index 0000000..10b27df --- /dev/null +++ b/src/client/java/dev/tggamesyt/szar/client/mixin/RevolverAttackMixin.java @@ -0,0 +1,38 @@ +package dev.tggamesyt.szar.client.mixin; + +import dev.tggamesyt.szar.Szar; +import dev.tggamesyt.szar.client.RevolverScreen; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.Mouse; +import net.minecraft.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Mouse.class) +public class RevolverAttackMixin { + + @Inject(method = "onMouseButton", at = @At("HEAD"), cancellable = true) + private void onMouseButton(long window, int button, int action, int mods, CallbackInfo ci) { + MinecraftClient client = MinecraftClient.getInstance(); + if (client.player == null) return; + if (client.currentScreen != null) return; // let screens handle their own clicks + if (button != 0 || action != 1) return; // only left click press + + ItemStack stack = client.player.getMainHandStack(); + if (!stack.isOf(Szar.REVOLVER)) return; + + ci.cancel(); // cancel vanilla handling entirely + + if (!client.player.isUsingItem()) { + // Not aiming — open loading screen + client.execute(() -> client.setScreen(new RevolverScreen(stack))); + } else { + // Aiming — shoot + ClientPlayNetworking.send(Szar.REVOLVER_SHOOT, PacketByteBufs.create()); + } + } +} \ No newline at end of file diff --git a/src/client/resources/szar.client.mixins.json b/src/client/resources/szar.client.mixins.json index 6d360c4..baf434d 100644 --- a/src/client/resources/szar.client.mixins.json +++ b/src/client/resources/szar.client.mixins.json @@ -19,6 +19,7 @@ "PlayerModelMixin", "RadiatedItemRendererMixin", "RadiationHeartMixin", + "RevolverAttackMixin", "ScreenFlipMixin", "SplashOverlayMixin", "TGcapeMixin", diff --git a/src/main/generated/.cache/0dcec3edc46b99b91b10474633480b6842e700fc b/src/main/generated/.cache/0dcec3edc46b99b91b10474633480b6842e700fc index 4899d6a..59fbbc5 100644 --- a/src/main/generated/.cache/0dcec3edc46b99b91b10474633480b6842e700fc +++ b/src/main/generated/.cache/0dcec3edc46b99b91b10474633480b6842e700fc @@ -1,3 +1,3 @@ -// 1.20.1 2026-03-07T14:06:37.8445606 szar/World Gen +// 1.20.1 2026-03-12T15:35:10.4101688 szar/World Gen 1d26b5da3b0a2ea6b23d456d1f0b82455a788ca1 data\szar\worldgen\configured_feature\uranium_ore.json 32864170bdb41310f9ee5d06f5720dfdb3badb6d data\szar\worldgen\placed_feature\uranium_ore_placed.json diff --git a/src/main/generated/.cache/79d6404f7b0803346bb38c848032926817f10037 b/src/main/generated/.cache/79d6404f7b0803346bb38c848032926817f10037 index 520e7c2..1e5219f 100644 --- a/src/main/generated/.cache/79d6404f7b0803346bb38c848032926817f10037 +++ b/src/main/generated/.cache/79d6404f7b0803346bb38c848032926817f10037 @@ -1,2 +1,2 @@ -// 1.20.1 2026-03-07T14:06:37.8455587 szar/Tags for minecraft:point_of_interest_type +// 1.20.1 2026-03-12T15:35:10.4111575 szar/Tags for minecraft:point_of_interest_type eba137b51c50a7143a3668876f41adaa1447b1d1 data\minecraft\tags\point_of_interest_type\acquirable_job_site.json diff --git a/src/main/generated/.cache/e8da7d0da6535b734ad1b062d141fd76f701db77 b/src/main/generated/.cache/e8da7d0da6535b734ad1b062d141fd76f701db77 index 7b86b67..3bc64ec 100644 --- a/src/main/generated/.cache/e8da7d0da6535b734ad1b062d141fd76f701db77 +++ b/src/main/generated/.cache/e8da7d0da6535b734ad1b062d141fd76f701db77 @@ -1,2 +1,2 @@ -// 1.20.1 2026-03-07T14:06:37.8432546 szar/Tags for minecraft:item -935692b1c49ef3164e01f8a993f3ce8002919afe data\minecraft\tags\items\music_discs.json +// 1.20.1 2026-03-12T15:35:10.4091576 szar/Tags for minecraft:item +7121c061f919b2837a56cb20f3ca5ccd0b11976d data\minecraft\tags\items\music_discs.json diff --git a/src/main/generated/data/minecraft/tags/items/music_discs.json b/src/main/generated/data/minecraft/tags/items/music_discs.json index 1aa7631..d1b9b1b 100644 --- a/src/main/generated/data/minecraft/tags/items/music_discs.json +++ b/src/main/generated/data/minecraft/tags/items/music_discs.json @@ -4,6 +4,7 @@ "szar:pop_tart", "szar:baiter", "szar:efn", - "szar:hello" + "szar:hello", + "szar:erika" ] } \ No newline at end of file diff --git a/src/main/java/dev/tggamesyt/szar/AK47Item.java b/src/main/java/dev/tggamesyt/szar/AK47Item.java index 7d7105a..ae85184 100644 --- a/src/main/java/dev/tggamesyt/szar/AK47Item.java +++ b/src/main/java/dev/tggamesyt/szar/AK47Item.java @@ -37,7 +37,7 @@ public class AK47Item extends Item { for (int i = 0; i < player.getInventory().size(); i++) { ItemStack stack = player.getInventory().getStack(i); - if (stack.isOf(Szar.AK_AMMO)) { + if (stack.isOf(Szar.BULLET_ITEM)) { stack.decrement(1); return true; } diff --git a/src/main/java/dev/tggamesyt/szar/BulletEntity.java b/src/main/java/dev/tggamesyt/szar/BulletEntity.java index 4f0fc6f..3e5d77c 100644 --- a/src/main/java/dev/tggamesyt/szar/BulletEntity.java +++ b/src/main/java/dev/tggamesyt/szar/BulletEntity.java @@ -6,10 +6,8 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.projectile.thrown.ThrownItemEntity; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryKeys; import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; import net.minecraft.world.World; public class BulletEntity extends ThrownItemEntity { @@ -56,7 +54,7 @@ public class BulletEntity extends ThrownItemEntity { @Override protected Item getDefaultItem() { - return Szar.AK_AMMO; + return Szar.BULLET_ITEM; } @Override diff --git a/src/main/java/dev/tggamesyt/szar/ModItemTagProvider.java b/src/main/java/dev/tggamesyt/szar/ModItemTagProvider.java index 4ec182a..d0df137 100644 --- a/src/main/java/dev/tggamesyt/szar/ModItemTagProvider.java +++ b/src/main/java/dev/tggamesyt/szar/ModItemTagProvider.java @@ -19,5 +19,6 @@ public class ModItemTagProvider extends FabricTagProvider.ItemTagProvider { getOrCreateTagBuilder(ItemTags.MUSIC_DISCS).add(Szar.BAITER_DISC); getOrCreateTagBuilder(ItemTags.MUSIC_DISCS).add(Szar.EFN_DISK); getOrCreateTagBuilder(ItemTags.MUSIC_DISCS).add(Szar.HELLO_DISC); + getOrCreateTagBuilder(ItemTags.MUSIC_DISCS).add(Szar.ERIKA_DISC); } } \ No newline at end of file diff --git a/src/main/java/dev/tggamesyt/szar/NaziEntity.java b/src/main/java/dev/tggamesyt/szar/NaziEntity.java index d4de862..71071b6 100644 --- a/src/main/java/dev/tggamesyt/szar/NaziEntity.java +++ b/src/main/java/dev/tggamesyt/szar/NaziEntity.java @@ -100,6 +100,9 @@ public class NaziEntity extends PathAwareEntity implements Arrestable{ if (rand.nextFloat() < 0.01F) { this.dropItem(Szar.AK47); } + if (rand.nextFloat() < 0.01F) { + this.dropItem(Szar.ERIKA_DISC); + } if (rand.nextFloat() < 0.01F) { ItemStack book = new ItemStack(Items.WRITTEN_BOOK); @@ -118,7 +121,7 @@ public class NaziEntity extends PathAwareEntity implements Arrestable{ int count = rand.nextInt(17); if (count > 0) { - this.dropStack(new ItemStack(Szar.AK_AMMO, count)); + this.dropStack(new ItemStack(Szar.BULLET_ITEM, count)); } } diff --git a/src/main/java/dev/tggamesyt/szar/PoliceEntity.java b/src/main/java/dev/tggamesyt/szar/PoliceEntity.java index 5a3ae95..aae2d81 100644 --- a/src/main/java/dev/tggamesyt/szar/PoliceEntity.java +++ b/src/main/java/dev/tggamesyt/szar/PoliceEntity.java @@ -11,11 +11,17 @@ 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.Items; +import net.minecraft.util.TypeFilter; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; import net.minecraft.util.math.random.Random; import net.minecraft.world.ServerWorldAccess; import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; + +import java.util.List; public class PoliceEntity extends PathAwareEntity { @@ -41,9 +47,24 @@ public class PoliceEntity extends PathAwareEntity { .add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 1.0); // half heart } public static boolean canSpawnHere(EntityType type, ServerWorldAccess world, SpawnReason reason, BlockPos pos, Random random) { - // Only spawn near players - return world.getClosestPlayer(pos.getX(), pos.getY(), pos.getZ(), 48, false) != null - && world.getLightLevel(pos) > 8; // optional, spawn in light + if (world.getClosestPlayer(pos.getX(), pos.getY(), pos.getZ(), 48, false) == null) return false; + + Box searchBox = new Box(pos).expand(60); + + int playerCount = world.getEntitiesByType( + TypeFilter.instanceOf(PlayerEntity.class), + searchBox, + e -> true + ).size(); + + int policeCount = world.getEntitiesByType( + TypeFilter.instanceOf(PoliceEntity.class), + searchBox, + e -> true + ).size(); + + int limit = Math.min(playerCount, 10); + return policeCount < limit; } diff --git a/src/main/java/dev/tggamesyt/szar/RevolverItem.java b/src/main/java/dev/tggamesyt/szar/RevolverItem.java new file mode 100644 index 0000000..7bae012 --- /dev/null +++ b/src/main/java/dev/tggamesyt/szar/RevolverItem.java @@ -0,0 +1,78 @@ +package dev.tggamesyt.szar; + +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.UseAction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class RevolverItem extends Item { + + public static final int CHAMBERS = 6; + + public RevolverItem(Settings settings) { + super(settings); + } + + // ── NBT helpers ────────────────────────────────────────────── + + public static boolean[] getChambers(ItemStack stack) { + NbtCompound nbt = stack.getOrCreateNbt(); + boolean[] chambers = new boolean[CHAMBERS]; + for (int i = 0; i < CHAMBERS; i++) { + chambers[i] = nbt.getBoolean("chamber_" + i); + } + return chambers; + } + + public static void setChambers(ItemStack stack, boolean[] chambers) { + NbtCompound nbt = stack.getOrCreateNbt(); + for (int i = 0; i < CHAMBERS; i++) { + nbt.putBoolean("chamber_" + i, chambers[i]); + } + } + + public static int getCurrentChamber(ItemStack stack) { + return stack.getOrCreateNbt().getInt("current_chamber"); + } + + public static void setCurrentChamber(ItemStack stack, int index) { + stack.getOrCreateNbt().putInt("current_chamber", index); + } + + /** Rotate by a random 1-6 steps (called by keybind) */ + public static void spin(ItemStack stack, World world) { + int steps = 1 + world.getRandom().nextInt(CHAMBERS); + int current = getCurrentChamber(stack); + setCurrentChamber(stack, (current + steps) % CHAMBERS); + //play sound + } + + // ── Use (right-click hold = aim) ───────────────────────────── + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + player.setCurrentHand(hand); + return TypedActionResult.consume(player.getStackInHand(hand)); + } + + @Override + public UseAction getUseAction(ItemStack stack) { + return UseAction.BOW; // raises arm + } + + @Override + public int getMaxUseTime(ItemStack stack) { + return 72000; // held indefinitely + } + +} \ No newline at end of file diff --git a/src/main/java/dev/tggamesyt/szar/RouletteBlock.java b/src/main/java/dev/tggamesyt/szar/RouletteBlock.java index f0871e9..68e7003 100644 --- a/src/main/java/dev/tggamesyt/szar/RouletteBlock.java +++ b/src/main/java/dev/tggamesyt/szar/RouletteBlock.java @@ -19,10 +19,7 @@ import net.minecraft.state.StateManager; import net.minecraft.state.property.DirectionProperty; import net.minecraft.state.property.Properties; import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; -import net.minecraft.util.BlockMirror; -import net.minecraft.util.BlockRotation; -import net.minecraft.util.Hand; +import net.minecraft.util.*; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -103,11 +100,14 @@ public class RouletteBlock extends Block implements BlockEntityProvider { @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - if (PlayerConfigStore.get(player, "gambling")) {return ActionResult.FAIL;} + if (PlayerConfigStore.get(player, "gambling")) { + player.sendMessage(Text.literal("You cannot use this because you are underage.").formatted(Formatting.RED), true); + return ActionResult.PASS; + } if (hand != Hand.MAIN_HAND) return ActionResult.PASS; BlockEntity blockEntity = world.getBlockEntity(pos); - if (!(blockEntity instanceof RouletteBlockEntity be)) { + if (!(blockEntity instanceof RouletteBlockEntity)) { return ActionResult.PASS; } diff --git a/src/main/java/dev/tggamesyt/szar/SlotMachineBlock.java b/src/main/java/dev/tggamesyt/szar/SlotMachineBlock.java index 4622162..c1d9a57 100644 --- a/src/main/java/dev/tggamesyt/szar/SlotMachineBlock.java +++ b/src/main/java/dev/tggamesyt/szar/SlotMachineBlock.java @@ -92,11 +92,14 @@ public class SlotMachineBlock extends Block implements BlockEntityProvider { @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - if (PlayerConfigStore.get(player, "gambling")) {return ActionResult.FAIL;} + if (PlayerConfigStore.get(player, "gambling")) { + player.sendMessage(Text.literal("You cannot use this because you are underage.").formatted(Formatting.RED), true); + return ActionResult.PASS; + } if (hand != Hand.MAIN_HAND) return ActionResult.PASS; BlockEntity blockEntity = world.getBlockEntity(pos); - if (!(blockEntity instanceof SlotMachineBlockEntity be)) { + if (!(blockEntity instanceof SlotMachineBlockEntity)) { return ActionResult.PASS; } diff --git a/src/main/java/dev/tggamesyt/szar/Szar.java b/src/main/java/dev/tggamesyt/szar/Szar.java index fc31183..b1a555d 100644 --- a/src/main/java/dev/tggamesyt/szar/Szar.java +++ b/src/main/java/dev/tggamesyt/szar/Szar.java @@ -58,11 +58,14 @@ import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.Rarity; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.village.TradeOffer; import net.minecraft.village.VillagerProfession; import net.minecraft.world.Heightmap; +import net.minecraft.world.World; import net.minecraft.world.biome.BiomeKeys; import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.YOffset; @@ -87,6 +90,10 @@ 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 Identifier REVOLVER_SHOOT = new Identifier(MOD_ID, "revolver_shoot"); + public static final Identifier REVOLVER_SPIN = new Identifier(MOD_ID, "revolver_spin"); + public static final Identifier REVOLVER_SYNC = new Identifier(MOD_ID, "revolver_sync"); + public static final Identifier REVOLVER_CHAMBER_CHANGE = new Identifier(MOD_ID, "revolver_chamber_change"); public static final SoundEvent BESZIV = Registry.register( Registries.SOUND_EVENT, new Identifier(MOD_ID, "besziv"), @@ -169,7 +176,7 @@ public class Szar implements ModInitializer { 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"); + new Identifier(MOD_ID, "merl_question"); public static final Block CHEMICAL_WORKBENCH = new Block(AbstractBlock.Settings.copy(Blocks.OAK_PLANKS)); public static final RegistryKey CHEMICAL_WORKBENCH_POI_KEY = @@ -317,8 +324,9 @@ public class Szar implements ModInitializer { entries.add(Szar.KEY_ITEM); entries.add(Szar.HANDCUFF_ITEM); // crazy weponary - entries.add(Szar.AK_AMMO); + entries.add(Szar.BULLET_ITEM); entries.add(Szar.AK47); + entries.add(Szar.REVOLVER); entries.add(Szar.ATOM_DETONATOR); entries.add(Szar.URANIUM_ORE); entries.add(Szar.URANIUM); @@ -339,6 +347,7 @@ public class Szar implements ModInitializer { entries.add(Szar.ROULETTE); entries.add(Szar.FIRTANA); entries.add(Szar.HELLO_DISC); + entries.add(Szar.ERIKA_DISC); // nsfw entries.add(Szar.FASZITEM); entries.add(Szar.CNDM); @@ -362,6 +371,95 @@ public class Szar implements ModInitializer { private final Map sleepingPlayers = new HashMap<>(); @Override public void onInitialize() { + ServerPlayNetworking.registerGlobalReceiver(REVOLVER_CHAMBER_CHANGE, (server, player, handler, buf, responseSender) -> { + int index = buf.readInt(); + boolean wasLoaded = buf.readBoolean(); // true = unloading, false = loading + + server.execute(() -> { + ItemStack stack = player.getMainHandStack(); + if (!stack.isOf(Szar.REVOLVER)) return; + + boolean[] chambers = RevolverItem.getChambers(stack); + + if (wasLoaded) { + // Unload — give shell + chambers[index] = false; + RevolverItem.setChambers(stack, chambers); + player.getInventory().insertStack(new ItemStack(Szar.BULLET_ITEM)); + } else { + // Load — take bullet from inventory + for (int i = 0; i < player.getInventory().size(); i++) { + ItemStack s = player.getInventory().getStack(i); + if (!s.isEmpty() && s.isOf(Szar.BULLET_ITEM)) { + s.decrement(1); + chambers[index] = true; + RevolverItem.setChambers(stack, chambers); + break; + } + } + } + }); + }); + ServerPlayNetworking.registerGlobalReceiver(REVOLVER_SYNC, (server, player, handler, buf, responseSender) -> { + // Read 6 booleans from packet + boolean[] chambers = new boolean[RevolverItem.CHAMBERS]; + for (int i = 0; i < RevolverItem.CHAMBERS; i++) { + chambers[i] = buf.readBoolean(); + } + int currentChamber = buf.readInt(); + + server.execute(() -> { + ItemStack stack = player.getMainHandStack(); + if (!stack.isOf(Szar.REVOLVER)) return; + RevolverItem.setChambers(stack, chambers); + RevolverItem.setCurrentChamber(stack, currentChamber); + }); + }); + ServerPlayNetworking.registerGlobalReceiver(REVOLVER_SPIN, (server, player, handler, buf, responseSender) -> { + server.execute(() -> { + ItemStack stack = player.getMainHandStack(); + if (!stack.isOf(Szar.REVOLVER)) return; + int steps = 1 + player.getWorld().getRandom().nextInt(RevolverItem.CHAMBERS); + int current = RevolverItem.getCurrentChamber(stack); + RevolverItem.setCurrentChamber(stack, (current + steps) % RevolverItem.CHAMBERS); + // Notify player + player.sendMessage(Text.literal("*click* chamber " + + (RevolverItem.getCurrentChamber(stack) + 1)).formatted(Formatting.GRAY), true); + }); + }); + ServerPlayNetworking.registerGlobalReceiver(REVOLVER_SHOOT, (server, player, handler, buf, responseSender) -> { + server.execute(() -> { + ItemStack stack = player.getMainHandStack(); + if (!stack.isOf(Szar.REVOLVER)) return; + + boolean[] chambers = RevolverItem.getChambers(stack); + int current = RevolverItem.getCurrentChamber(stack); + boolean isHeadshot = player.isSneaking(); + + if (!chambers[current]) { + // Empty — dry fire click + player.getWorld().playSound(null, player.getBlockPos(), + SoundEvents.BLOCK_DISPENSER_FAIL, SoundCategory.PLAYERS, 1f, 1.5f); + } else { + chambers[current] = false; + RevolverItem.setChambers(stack, chambers);; + + player.getWorld().playSound(null, player.getBlockPos(), + SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.PLAYERS, 0.5f, 1.8f); + + if (isHeadshot) { + player.damage(player.getWorld().getDamageSources().genericKill(), Float.MAX_VALUE); + } else { + BulletEntity bullet = new BulletEntity(player.getWorld(), player); + bullet.setVelocity(player, player.getPitch(), player.getYaw(), 0f, 4.5f, 0.0f); + player.getWorld().spawnEntity(bullet); + } + } + + // Always advance chamber after trigger pull + RevolverItem.setCurrentChamber(stack, (current + 1) % RevolverItem.CHAMBERS); + }); + }); ServerPlayNetworking.registerGlobalReceiver(CONFIG_SYNC, (server, player, handler, buf, responseSender) -> { // Read on netty thread, process on server thread @@ -591,6 +689,14 @@ public class Szar implements ModInitializer { Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, // avoids leaves PoliceEntity::canSpawnHere // your custom condition ); + BiomeModifications.addSpawn( + BiomeSelectors.all(), // or a more specific selector + SpawnGroup.AMBIENT, + Szar.PoliceEntityType, + 15, // weight (vanilla zombie is 100, so 15 is fairly rare) + 1, // min group size + 3 // max group size + ); ServerTickEvents.END_SERVER_TICK.register(PlayerValueTimer::onServerTick); BiomeModifications.addSpawn( BiomeSelectors.includeByKey( @@ -799,7 +905,11 @@ public class Szar implements ModInitializer { ); } - + // In your ModItems or wherever you register items + public static final Item REVOLVER = Registry.register( + Registries.ITEM, new Identifier(MOD_ID, "revolver"), + new RevolverItem(new Item.Settings().maxCount(1)) + ); public static ObeliskCoreBlockEntity findNearestObelisk(ServerWorld world, BlockPos center, int radius) { ObeliskCoreBlockEntity closest = null; @@ -1090,7 +1200,7 @@ public class Szar implements ModInitializer { RegistryKey.of(RegistryKeys.DAMAGE_TYPE, new Identifier(MOD_ID, "radiation")); public static final RegistryKey FCK_DAMAGE = RegistryKey.of(RegistryKeys.DAMAGE_TYPE, new Identifier(MOD_ID, "fck")); - public static final Item AK_AMMO = Registry.register( + public static final Item BULLET_ITEM = Registry.register( Registries.ITEM, new Identifier(MOD_ID, "bullet"), new Item(new Item.Settings()) @@ -1309,7 +1419,7 @@ public class Szar implements ModInitializer { public static final Item POPTART = Registry.register( Registries.ITEM, new Identifier(MOD_ID, "pop_tart"), - new MusicDiscItem(13, NYAN_MUSIC, new Item.Settings() + new MusicDiscItem(13, NYAN_MUSIC, new Item.Settings().maxCount(1) .food(new FoodComponent.Builder() .saturationModifier(0.6f). hunger((Math.random() < 0.5) ? 6 : 7) // SIX OR SEVEN @@ -1322,7 +1432,13 @@ public class Szar implements ModInitializer { new Identifier(MOD_ID, "baiter"), new MusicDiscItem(12, BAITER, new Item.Settings().maxCount(1).rarity(Rarity.RARE), 172) ); - + public static final SoundEvent ERIKA = + SoundEvent.of(new Identifier(MOD_ID, "erika")); + public static final Item ERIKA_DISC = Registry.register( + Registries.ITEM, + new Identifier(MOD_ID, "erika"), + new MusicDiscItem(9, ERIKA, new Item.Settings().maxCount(1).rarity(Rarity.RARE), 180) + ); public static final SoundEvent HELLO = SoundEvent.of(new Identifier(MOD_ID, "firtana")); public static final Item HELLO_DISC = Registry.register( @@ -1606,5 +1722,33 @@ public class Szar implements ModInitializer { pregnantPartners.put(player.getUuid(), partner.getUuid()); } } + + private static void shootBullet(ServerPlayerEntity player) { + World world = player.getWorld(); + Vec3d start = player.getEyePos(); + Vec3d dir = player.getRotationVec(1.0f); + Vec3d end = start.add(dir.multiply(100)); // 100 block range + + net.minecraft.util.hit.HitResult hit = world.raycast(new net.minecraft.world.RaycastContext( + start, end, + net.minecraft.world.RaycastContext.ShapeType.COLLIDER, + net.minecraft.world.RaycastContext.FluidHandling.NONE, + player + )); + + // Entity hit check + Box box = new Box(start, end).expand(1); + net.minecraft.util.hit.EntityHitResult entityHit = + net.minecraft.entity.projectile.ProjectileUtil.raycast( + player, start, end, box, + e -> !e.isSpectator() && e != player && e.canHit(), 100 * 100 + ); + + if (entityHit != null) { + entityHit.getEntity().damage( + world.getDamageSources().playerAttack(player), 8.0f + ); + } + } } diff --git a/src/main/resources/assets/szar/lang/en_us.json b/src/main/resources/assets/szar/lang/en_us.json index 603e385..549bbeb 100644 --- a/src/main/resources/assets/szar/lang/en_us.json +++ b/src/main/resources/assets/szar/lang/en_us.json @@ -112,5 +112,18 @@ "painting.szar.axolotl.author": "Unknown (Szar Mod)", "painting.szar.chicken_jokey.title": "Chicken Jokey", - "painting.szar.chicken_jokey.author": "Unknown (Szar Mod)" + "painting.szar.chicken_jokey.author": "Unknown (Szar Mod)", + + "item.szar.erika": "Music Disc", + "item.szar.erika.desc": "Herms Niel - Erika", + + "advancement.szar.nwordpass.title": "Nig-", + "advancement.szar.nwordpass.description": "Get an N-word pass", + + "advancement.szar.two_towers.title": "Hmm, familiar...", + "advancement.szar.two_towers.description": "You were there when the towers fell", + + "item.szar.revolver": "Revolver", + "item.szar.revolver_bullet": "Revolver Bullet", + "item.szar.bullet_shell": "Revolver Bullet Shell" } diff --git a/src/main/resources/assets/szar/models/item/bullet_shell.json b/src/main/resources/assets/szar/models/item/bullet_shell.json new file mode 100644 index 0000000..f8ca665 --- /dev/null +++ b/src/main/resources/assets/szar/models/item/bullet_shell.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "szar:item/bullet" + } +} diff --git a/src/main/resources/assets/szar/models/item/erika.json b/src/main/resources/assets/szar/models/item/erika.json new file mode 100644 index 0000000..fdcdad5 --- /dev/null +++ b/src/main/resources/assets/szar/models/item/erika.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "szar:item/erika" + } +} diff --git a/src/main/resources/assets/szar/models/item/revolver.json b/src/main/resources/assets/szar/models/item/revolver.json new file mode 100644 index 0000000..39a0181 --- /dev/null +++ b/src/main/resources/assets/szar/models/item/revolver.json @@ -0,0 +1,312 @@ +{ + "format_version": "1.21.11", + "credit": "Converted from TechGuns ModelRevolver", + "texture_size": [64, 32], + "textures": { + "0": "szar:item/revolver", + "particle": "szar:item/revolver" + }, + "elements": [ + { + "name": "Shape1", + "from": [17, 22.5, 8.5], + "to": [25, 23.5, 9.5], + "rotation": {"angle": 45, "axis": "x", "origin": [17, 23, 9]}, + "faces": { + "north": {"uv": [0.25, 2.5, 2.25, 3], "texture": "#0"}, + "east": {"uv": [2.25, 2.5, 2.5, 3], "texture": "#0"}, + "south": {"uv": [2.5, 2.5, 4.5, 3], "texture": "#0"}, + "west": {"uv": [0, 2.5, 0.25, 3], "texture": "#0"}, + "up": {"uv": [0.25, 2, 2.25, 2.5], "texture": "#0"}, + "down": {"uv": [2.25, 2, 4.25, 2.5], "texture": "#0"} + } + }, + { + "name": "Shape2", + "from": [28.5, 25.8, 8.5], + "to": [30.5, 26.8, 9.5], + "faces": { + "north": {"uv": [8.25, 0.5, 8.75, 1], "texture": "#0"}, + "east": {"uv": [8.75, 0.5, 9, 1], "texture": "#0"}, + "south": {"uv": [9, 0.5, 9.5, 1], "texture": "#0"}, + "west": {"uv": [8, 0.5, 8.25, 1], "texture": "#0"}, + "up": {"uv": [8.25, 0, 8.75, 0.5], "texture": "#0"}, + "down": {"uv": [8.75, 0, 9.25, 0.5], "texture": "#0"} + } + }, + { + "name": "Shape3", + "from": [4.5, 24, 8.5], + "to": [5.5, 25, 9.5], + "faces": { + "north": {"uv": [8.25, 3, 8.5, 3.5], "texture": "#0"}, + "east": {"uv": [8.5, 3, 8.75, 3.5], "texture": "#0"}, + "south": {"uv": [8.75, 3, 9, 3.5], "texture": "#0"}, + "west": {"uv": [8, 3, 8.25, 3.5], "texture": "#0"}, + "up": {"uv": [8.25, 2.5, 8.5, 3], "texture": "#0"}, + "down": {"uv": [8.5, 2.5, 8.75, 3], "texture": "#0"} + } + }, + { + "name": "Shape4", + "from": [17, 24, 8], + "to": [31, 26, 10], + "rotation": {"angle": 45, "axis": "x", "origin": [17, 25, 9]}, + "faces": { + "north": {"uv": [0.5, 1, 4, 2], "texture": "#0"}, + "east": {"uv": [4, 1, 4.5, 2], "texture": "#0"}, + "south": {"uv": [4.5, 1, 8, 2], "texture": "#0"}, + "west": {"uv": [0, 1, 0.5, 2], "texture": "#0"}, + "up": {"uv": [0.5, 0, 4, 1], "texture": "#0"}, + "down": {"uv": [4, 0, 7.5, 1], "texture": "#0"} + } + }, + { + "name": "Shape5", + "from": [5.5, 23, 8.5], + "to": [7.5, 25, 9.5], + "faces": { + "north": {"uv": [8.25, 1.5, 8.75, 2.5], "texture": "#0"}, + "east": {"uv": [8.75, 1.5, 9, 2.5], "texture": "#0"}, + "south": {"uv": [9, 1.5, 9.5, 2.5], "texture": "#0"}, + "west": {"uv": [8, 1.5, 8.25, 2.5], "texture": "#0"}, + "up": {"uv": [8.25, 1, 8.75, 1.5], "texture": "#0"}, + "down": {"uv": [8.75, 1, 9.25, 1.5], "texture": "#0"} + } + }, + { + "name": "Shape6", + "from": [9.5, 22, 7], + "to": [14.5, 23, 11], + "faces": { + "north": {"uv": [1, 11, 2.25, 11.5], "texture": "#0"}, + "east": {"uv": [2.25, 11, 3.25, 11.5], "texture": "#0"}, + "south": {"uv": [3.25, 11, 4.5, 11.5], "texture": "#0"}, + "west": {"uv": [0, 11, 1, 11.5], "texture": "#0"}, + "up": {"uv": [1, 9, 2.25, 11], "texture": "#0"}, + "down": {"uv": [2.25, 9, 3.5, 11], "texture": "#0"} + } + }, + { + "name": "Shape7", + "from": [11, 18.5, 8], + "to": [14, 18.5, 10], + "faces": { + "north": {"uv": [13, 8.5, 13.75, 8.5], "texture": "#0"}, + "east": {"uv": [13.75, 8.5, 14.25, 8.5], "texture": "#0"}, + "south": {"uv": [14.25, 8.5, 15, 8.5], "texture": "#0"}, + "west": {"uv": [12.5, 8.5, 13, 8.5], "texture": "#0"}, + "up": {"uv": [13, 7.5, 13.75, 8.5], "texture": "#0"}, + "down": {"uv": [13.75, 7.5, 14.5, 8.5], "texture": "#0"} + } + }, + { + "name": "Shape8", + "from": [8, 25.5, 8], + "to": [17, 26.5, 10], + "faces": { + "north": {"uv": [11, 1, 13.25, 1.5], "texture": "#0"}, + "east": {"uv": [13.25, 1, 13.75, 1.5], "texture": "#0"}, + "south": {"uv": [13.75, 1, 16, 1.5], "texture": "#0"}, + "west": {"uv": [10.5, 1, 11, 1.5], "texture": "#0"}, + "up": {"uv": [11, 0, 13.25, 1], "texture": "#0"}, + "down": {"uv": [13.25, 0, 15.5, 1], "texture": "#0"} + } + }, + { + "name": "Shape9", + "from": [10, 20.5, 8], + "to": [16, 21.5, 10], + "faces": { + "north": {"uv": [11, 7, 12.5, 7.5], "texture": "#0"}, + "east": {"uv": [12.5, 7, 13, 7.5], "texture": "#0"}, + "south": {"uv": [13, 7, 14.5, 7.5], "texture": "#0"}, + "west": {"uv": [10.5, 7, 11, 7.5], "texture": "#0"}, + "up": {"uv": [11, 6, 12.5, 7], "texture": "#0"}, + "down": {"uv": [12.5, 6, 14, 7], "texture": "#0"} + } + }, + { + "name": "Shape10", + "from": [8, 21.5, 8], + "to": [17, 23.5, 10], + "faces": { + "north": {"uv": [11, 5, 13.25, 6], "texture": "#0"}, + "east": {"uv": [13.25, 5, 13.75, 6], "texture": "#0"}, + "south": {"uv": [13.75, 5, 16, 6], "texture": "#0"}, + "west": {"uv": [10.5, 5, 11, 6], "texture": "#0"}, + "up": {"uv": [11, 4, 13.25, 5], "texture": "#0"}, + "down": {"uv": [13.25, 4, 15.5, 5], "texture": "#0"} + } + }, + { + "name": "Shape12", + "from": [14, 18.5, 8], + "to": [15, 20.5, 10], + "faces": { + "north": {"uv": [15, 7, 15.25, 8], "texture": "#0"}, + "east": {"uv": [15.25, 7, 15.75, 8], "texture": "#0"}, + "south": {"uv": [15.75, 7, 16, 8], "texture": "#0"}, + "west": {"uv": [14.5, 7, 15, 8], "texture": "#0"}, + "up": {"uv": [15, 6, 15.25, 7], "texture": "#0"}, + "down": {"uv": [15.25, 6, 15.5, 7], "texture": "#0"} + } + }, + { + "name": "Shape14", + "from": [5, 21.5, 8], + "to": [7, 23.5, 10], + "faces": { + "north": {"uv": [6.5, 3, 7, 4], "texture": "#0"}, + "east": {"uv": [7, 3, 7.5, 4], "texture": "#0"}, + "south": {"uv": [7.5, 3, 8, 4], "texture": "#0"}, + "west": {"uv": [6, 3, 6.5, 4], "texture": "#0"}, + "up": {"uv": [6.5, 2, 7, 3], "texture": "#0"}, + "down": {"uv": [7, 2, 7.5, 3], "texture": "#0"} + } + }, + { + "name": "Shape15", + "from": [10, 18.5, 8], + "to": [11, 20.5, 10], + "faces": { + "north": {"uv": [15, 7, 15.25, 8], "texture": "#0"}, + "east": {"uv": [15.25, 7, 15.75, 8], "texture": "#0"}, + "south": {"uv": [15.75, 7, 16, 8], "texture": "#0"}, + "west": {"uv": [14.5, 7, 15, 8], "texture": "#0"}, + "up": {"uv": [15, 6, 15.25, 7], "texture": "#0"}, + "down": {"uv": [15.25, 6, 15.5, 7], "texture": "#0"} + } + }, + { + "name": "Shape16", + "from": [4, 19.5, 8], + "to": [10, 21.5, 10], + "faces": { + "north": {"uv": [7, 5, 8.5, 6], "texture": "#0"}, + "east": {"uv": [8.5, 5, 9, 6], "texture": "#0"}, + "south": {"uv": [9, 5, 10.5, 6], "texture": "#0"}, + "west": {"uv": [6.5, 5, 7, 6], "texture": "#0"}, + "up": {"uv": [7, 4, 8.5, 5], "texture": "#0"}, + "down": {"uv": [8.5, 4, 10, 5], "texture": "#0"} + } + }, + { + "name": "Shape17", + "from": [4, 17.5, 8], + "to": [8, 19.5, 10], + "faces": { + "north": {"uv": [6.75, 7, 7.75, 8], "texture": "#0"}, + "east": {"uv": [7.75, 7, 8.25, 8], "texture": "#0"}, + "south": {"uv": [8.25, 7, 9.25, 8], "texture": "#0"}, + "west": {"uv": [6.25, 7, 6.75, 8], "texture": "#0"}, + "up": {"uv": [6.75, 6, 7.75, 7], "texture": "#0"}, + "down": {"uv": [7.75, 6, 8.75, 7], "texture": "#0"} + } + }, + { + "name": "Shape18", + "from": [3, 12.5, 8], + "to": [7, 17.5, 10], + "faces": { + "north": {"uv": [6.75, 9, 7.75, 11.5], "texture": "#0"}, + "east": {"uv": [7.75, 9, 8.25, 11.5], "texture": "#0"}, + "south": {"uv": [8.25, 9, 9.25, 11.5], "texture": "#0"}, + "west": {"uv": [6.25, 9, 6.75, 11.5], "texture": "#0"}, + "up": {"uv": [6.75, 8, 7.75, 9], "texture": "#0"}, + "down": {"uv": [7.75, 8, 8.75, 9], "texture": "#0"} + } + }, + { + "name": "Shape19", + "from": [7, 21.5, 8], + "to": [8, 25.5, 10], + "faces": { + "north": {"uv": [9.75, 8.5, 10, 10.5], "texture": "#0"}, + "east": {"uv": [10, 8.5, 10.5, 10.5], "texture": "#0"}, + "south": {"uv": [10.5, 8.5, 10.75, 10.5], "texture": "#0"}, + "west": {"uv": [9.25, 8.5, 9.75, 10.5], "texture": "#0"}, + "up": {"uv": [9.75, 7.5, 10, 8.5], "texture": "#0"}, + "down": {"uv": [10, 7.5, 10.25, 8.5], "texture": "#0"} + } + }, + { + "name": "Shape20", + "from": [8, 23.5, 7.5], + "to": [17, 25.5, 10.5], + "faces": { + "north": {"uv": [10.75, 3, 13, 4], "texture": "#0"}, + "east": {"uv": [13, 3, 13.75, 4], "texture": "#0"}, + "south": {"uv": [13.75, 3, 16, 4], "texture": "#0"}, + "west": {"uv": [10, 3, 10.75, 4], "texture": "#0"}, + "up": {"uv": [10.75, 1.5, 13, 3], "texture": "#0"}, + "down": {"uv": [13, 1.5, 15.25, 3], "texture": "#0"} + } + }, + { + "name": "Shape21", + "from": [9.5, 23, 6.5], + "to": [14.5, 25, 11.5], + "faces": { + "north": {"uv": [1.25, 8, 2.5, 9], "texture": "#0"}, + "east": {"uv": [2.5, 8, 3.75, 9], "texture": "#0"}, + "south": {"uv": [3.75, 8, 5, 9], "texture": "#0"}, + "west": {"uv": [0, 8, 1.25, 9], "texture": "#0"}, + "up": {"uv": [1.25, 5.5, 2.5, 8], "texture": "#0"}, + "down": {"uv": [2.5, 5.5, 3.75, 8], "texture": "#0"} + } + }, + { + "name": "Shape22", + "from": [9.5, 25, 7], + "to": [14.5, 26, 11], + "faces": { + "north": {"uv": [1, 5, 2.25, 5.5], "texture": "#0"}, + "east": {"uv": [2.25, 5, 3.25, 5.5], "texture": "#0"}, + "south": {"uv": [3.25, 5, 4.5, 5.5], "texture": "#0"}, + "west": {"uv": [0, 5, 1, 5.5], "texture": "#0"}, + "up": {"uv": [1, 3, 2.25, 5], "texture": "#0"}, + "down": {"uv": [2.25, 3, 3.5, 5], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [0, 90, 0], + "translation": [0, -4.75, -0.75], + "scale": [0.4, 0.4, 0.4] + }, + "thirdperson_lefthand": { + "rotation": [0, -90, 0], + "translation": [0, -4.75, -0.75], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_righthand": { + "rotation": [0, 90, 0], + "translation": [2.5, -1, 0.25], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, -90, 0], + "translation": [2.5, -1, 0.25], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [-2.75, -1, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [30, -135, 0], + "translation": [4.25, -5.5, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "rotation": [0, 90, 0], + "translation": [-0.75, -4, 5.5] + }, + "fixed": { + "translation": [-3.5, -5.5, 0], + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/szar/models/item/revolver_bullet.json b/src/main/resources/assets/szar/models/item/revolver_bullet.json new file mode 100644 index 0000000..f8ca665 --- /dev/null +++ b/src/main/resources/assets/szar/models/item/revolver_bullet.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "szar:item/bullet" + } +} diff --git a/src/main/resources/assets/szar/sounds.json b/src/main/resources/assets/szar/sounds.json index fa3101a..e6d076c 100644 --- a/src/main/resources/assets/szar/sounds.json +++ b/src/main/resources/assets/szar/sounds.json @@ -146,5 +146,13 @@ "stream": true } ] + }, + "erika": { + "sounds": [ + { + "name": "szar:erika", + "stream": true + } + ] } } diff --git a/src/main/resources/assets/szar/sounds/erika.ogg b/src/main/resources/assets/szar/sounds/erika.ogg new file mode 100644 index 0000000..50134d8 Binary files /dev/null and b/src/main/resources/assets/szar/sounds/erika.ogg differ diff --git a/src/main/resources/assets/szar/sounds/revolver_reload.ogg b/src/main/resources/assets/szar/sounds/revolver_reload.ogg new file mode 100644 index 0000000..5735415 Binary files /dev/null and b/src/main/resources/assets/szar/sounds/revolver_reload.ogg differ diff --git a/src/main/resources/assets/szar/textures/item/erika.png b/src/main/resources/assets/szar/textures/item/erika.png new file mode 100644 index 0000000..3794648 Binary files /dev/null and b/src/main/resources/assets/szar/textures/item/erika.png differ diff --git a/src/main/resources/assets/szar/textures/item/revolver.png b/src/main/resources/assets/szar/textures/item/revolver.png new file mode 100644 index 0000000..f4a230e Binary files /dev/null and b/src/main/resources/assets/szar/textures/item/revolver.png differ diff --git a/src/main/resources/data/szar/advancements/nwordpass.json b/src/main/resources/data/szar/advancements/nwordpass.json index 85de080..1a89398 100644 --- a/src/main/resources/data/szar/advancements/nwordpass.json +++ b/src/main/resources/data/szar/advancements/nwordpass.json @@ -3,8 +3,8 @@ "icon": { "item": "szar:nwordpass" }, - "title": "Nig-", - "description": "Get an N-word pass", + "title": {"translate": "advancement.szar.nwordpass.title"}, + "description": {"translate": "advancement.szar.nwordpass.description"}, "show_toast": true }, "criteria": { diff --git a/src/main/resources/data/szar/advancements/two_towers_explosion.json b/src/main/resources/data/szar/advancements/two_towers_explosion.json index b82c471..eebf86a 100644 --- a/src/main/resources/data/szar/advancements/two_towers_explosion.json +++ b/src/main/resources/data/szar/advancements/two_towers_explosion.json @@ -6,8 +6,8 @@ }, "display": { "icon": { "item": "szar:towers" }, - "title": "Hmm, familiar...", - "description": "You were there when the towers fell", + "title": {"translate": "advancement.szar.two_towers.title"}, + "description": {"translate": "advancement.szar.two_towers.description"}, "frame": "challenge", "show_toast": true, "announce_to_chat": true diff --git a/src/main/resources/data/szar/loot_tables/blocks/obelisk_core.json b/src/main/resources/data/szar/loot_tables/blocks/obelisk_core.json new file mode 100644 index 0000000..8e36ba1 --- /dev/null +++ b/src/main/resources/data/szar/loot_tables/blocks/obelisk_core.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "conditions": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "enchantments": [ + { + "enchantment": "minecraft:silk_touch", + "levels": {"min": 1} + } + ] + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "szar:towers" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/resourcepacks/racist/assets/szar/lang/en_us.json b/src/main/resources/resourcepacks/racist/assets/szar/lang/en_us.json index 4400582..7929115 100644 --- a/src/main/resources/resourcepacks/racist/assets/szar/lang/en_us.json +++ b/src/main/resources/resourcepacks/racist/assets/szar/lang/en_us.json @@ -21,5 +21,7 @@ "entity.szar.gypsy": "Burglar", "item.szar.epstein_files": "?", "entity.szar.epstein": "Old Man", - "item.szar.epstein_spawn_egg": "Old Man Spawn Egg" + "item.szar.epstein_spawn_egg": "Old Man Spawn Egg", + "advancement.szar.nwordpass.title": "Monke", + "advancement.szar.nwordpass.description": "Get a ? (idk which one since they all look the same)" }