forradalom es szabadsagharc: island structure, update ak47, rework revolver

This commit is contained in:
2026-03-15 17:25:45 +01:00
parent 87e4c03db6
commit 351c41c028
47 changed files with 837 additions and 246 deletions

View File

@@ -1,11 +1,8 @@
package dev.tggamesyt.szar;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
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;
@@ -17,25 +14,7 @@ public class AK47Item extends Item {
super(settings);
}
@Override
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
if (!(entity instanceof PlayerEntity player)) return;
if (!selected) return;
if (!player.isUsingItem()) return;
if (world.isClient) return;
if (player.getItemCooldownManager().isCoolingDown(this)) return;
if (!consumeAmmo(player)) return;
player.getWorld().playSound(null, player.getBlockPos(),
SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.PLAYERS, 0.5f, 1.8f);
BulletEntity bullet = new BulletEntity(world, player);
bullet.setVelocity(player, player.getPitch(), player.getYaw(), 0f, 4.5f, 1.0f);
world.spawnEntity(bullet);
player.getItemCooldownManager().set(this, 2); // fire rate
}
private boolean consumeAmmo(PlayerEntity player) {
public boolean consumeAmmo(PlayerEntity player) {
if (player.getAbilities().creativeMode) return true;
for (int i = 0; i < player.getInventory().size(); i++) {
@@ -50,7 +29,7 @@ public class AK47Item extends Item {
@Override
public UseAction getUseAction(ItemStack stack) {
return UseAction.NONE;
return UseAction.BOW; // raises arm
}
@Override

View File

@@ -3,6 +3,7 @@ package dev.tggamesyt.szar;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
@@ -13,14 +14,20 @@ import net.minecraft.network.PacketByteBuf;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class BulletEntity extends ThrownItemEntity {
private static final float BASE_DAMAGE = 13.0F;
private static final float PIERCE_BREAK_THRESHOLD = 0.4F;
private float pierceValue = 1.0F;
private int stillTicks = 0;
private double lastX, lastY, lastZ;
@@ -47,7 +54,7 @@ public class BulletEntity extends ThrownItemEntity {
if (movedSq < 0.0001) {
stillTicks++;
if (stillTicks >= 3) { // discard after 3 ticks of no movement
if (stillTicks >= 3) {
discard();
return;
}
@@ -79,20 +86,60 @@ public class BulletEntity extends ThrownItemEntity {
this,
livingOwner
);
target.damage(source, 13.0F);
// Damage scaled by remaining pierce value
target.damage(source, BASE_DAMAGE * pierceValue);
}
discard();
// Don't discard — bullet continues through entities
// But reduce pierce value a bit for entity hits
pierceValue -= 0.3F;
if (pierceValue <= 0) {
discard();
}
}
@Override
protected void onBlockHit(net.minecraft.util.hit.BlockHitResult hit) {
super.onBlockHit(hit);
// Use exact hit position + nudge along face normal to sit on surface
protected void onBlockHit(BlockHitResult hit) {
if (getWorld().isClient) return;
BlockPos blockPos = hit.getBlockPos();
BlockState state = getWorld().getBlockState(blockPos);
Vec3d pos = hit.getPos();
Direction face = hit.getSide();
spawnImpact(pos, face);
discard();
float resistance = state.getBlock().getBlastResistance();
if (!state.isAir()) {
pierceValue -= resistance;
}
if (pierceValue <= 0) {
// Bullet stopped — spawn impact and discard
spawnImpact(pos, face);
discard();
return;
}
if (resistance < PIERCE_BREAK_THRESHOLD && !state.isAir()) {
// Break the block
if (getWorld() instanceof ServerWorld serverWorld) {
// Play break sound
getWorld().playSound(
null,
blockPos,
state.getSoundGroup().getBreakSound(),
SoundCategory.BLOCKS,
1.0F,
1.0F
);
serverWorld.breakBlock(blockPos, true, getOwner());
}
// Bullet continues — don't call super, don't discard
} else {
// Block too strong to break — bullet stops here
spawnImpact(pos, face);
discard();
}
}
private void spawnImpact(Vec3d pos, Direction face) {

View File

@@ -3,6 +3,7 @@ package dev.tggamesyt.szar;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.SpawnReason;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.ai.goal.LookAroundGoal;
import net.minecraft.entity.ai.goal.MeleeAttackGoal;
@@ -13,10 +14,21 @@ import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.mob.PathAwareEntity;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.structure.StructureStart;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.Structure;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
public class EpsteinEntity extends PathAwareEntity implements Arrestable {
@@ -24,6 +36,7 @@ public class EpsteinEntity extends PathAwareEntity implements Arrestable {
public EpsteinEntity(EntityType<? extends PathAwareEntity> type, World world) {
super(type, world);
this.setPersistent();
}
@Override

View File

@@ -13,7 +13,10 @@ 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.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
@@ -241,6 +244,15 @@ public class IslamTerrorist extends PathAwareEntity implements Arrestable{
}
}
@Override
protected void dropLoot(DamageSource source, boolean causedByPlayer) {
Random r = new Random();
int number = r.nextInt(3) + 1;
ItemStack powder = new ItemStack(Items.GUNPOWDER, number);
this.dropStack(powder);
}
// ================= DAMAGE =================

View File

@@ -0,0 +1,57 @@
package dev.tggamesyt.szar;
import com.mojang.serialization.Codec;
import net.minecraft.structure.StructurePlacementData;
import net.minecraft.util.BlockRotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.Heightmap;
import net.minecraft.world.gen.structure.Structure;
import net.minecraft.world.gen.structure.StructureType;
import java.util.Optional;
public class IslandStructure extends Structure {
public static final Codec<IslandStructure> CODEC =
Structure.createCodec(IslandStructure::new);
public IslandStructure(Config config) {
super(config);
}
@Override
protected Optional<StructurePosition> getStructurePosition(Context context) {
ChunkPos chunkPos = context.chunkPos();
int x = chunkPos.getCenterX();
int z = chunkPos.getCenterZ();
// Find water surface — scan down from world height to sea level
int seaLevel = context.chunkGenerator().getSeaLevel();
int surfaceY = context.chunkGenerator().getHeightInGround(
x, z,
Heightmap.Type.OCEAN_FLOOR_WG,
context.world(),
context.noiseConfig()
);
// Must be underwater (ocean floor below sea level)
if (surfaceY >= seaLevel - 2) return Optional.empty();
// Place structure at sea level + 1 so it sits on the water surface
BlockPos pos = new BlockPos(x, seaLevel + 1, z);
StructurePlacementData placement = new StructurePlacementData()
.setRotation(BlockRotation.random(context.random()));
return Structure.getStructurePosition(context, Heightmap.Type.WORLD_SURFACE_WG, collector ->
collector.addPiece(new IslandStructurePiece(context, pos, BlockPos.ORIGIN, placement))
);
}
@Override
public StructureType<?> getType() {
return Szar.ISLAND_TYPE;
}
}

View File

@@ -0,0 +1,87 @@
package dev.tggamesyt.szar;
import net.minecraft.block.entity.ChestBlockEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.structure.SimpleStructurePiece;
import net.minecraft.structure.StructureContext;
import net.minecraft.structure.StructurePlacementData;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.structure.Structure;
public class IslandStructurePiece extends SimpleStructurePiece {
private static final Identifier TEMPLATE_ID =
new Identifier(Szar.MOD_ID, "island");
/* ===== NORMAL CONSTRUCTOR (Worldgen) ===== */
public IslandStructurePiece(
Structure.Context context,
BlockPos pos,
BlockPos origin,
StructurePlacementData placement
) {
super(
Szar.ISLAND_PIECE,
0,
context.structureTemplateManager(),
TEMPLATE_ID,
TEMPLATE_ID.toString(),
placement,
pos
);
}
/* ===== NBT CONSTRUCTOR (Chunk Save/Load) ===== */
public IslandStructurePiece(StructureContext context, NbtCompound nbt) {
super(
Szar.ISLAND_PIECE,
nbt,
context.structureTemplateManager(),
identifier -> new StructurePlacementData()
);
}
/* ===== Metadata Handler (DATA structure blocks) ===== */
@Override
protected void handleMetadata(
String metadata,
BlockPos pos,
ServerWorldAccess world,
Random random,
BlockBox boundingBox
) {
}
@Override
public void generate(StructureWorldAccess world, StructureAccessor structureAccessor,
ChunkGenerator chunkGenerator, Random random,
BlockBox chunkBox, ChunkPos chunkPos, BlockPos pivot) {
// This actually places the structure blocks
super.generate(world, structureAccessor, chunkGenerator, random, chunkBox, chunkPos, pivot);
BlockBox box = this.getBoundingBox();
for (int bx = box.getMinX(); bx <= box.getMaxX(); bx++) {
for (int by = box.getMinY(); by <= box.getMaxY(); by++) {
for (int bz = box.getMinZ(); bz <= box.getMaxZ(); bz++) {
BlockPos pos = new BlockPos(bx, by, bz);
if (world.getBlockEntity(pos) instanceof ChestBlockEntity chest) {
chest.setLootTable(
new Identifier(Szar.MOD_ID, "chests/island"),
random.nextLong()
);
}
}
}
}
}
}

View File

@@ -1,11 +1,13 @@
package dev.tggamesyt.szar;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
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.network.PacketByteBuf;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
@@ -15,6 +17,8 @@ import net.minecraft.util.UseAction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import static dev.tggamesyt.szar.Szar.REVOLVER_STATE_SYNC;
public class RevolverItem extends Item {
public static final int CHAMBERS = 6;
@@ -75,4 +79,16 @@ public class RevolverItem extends Item {
return 72000; // held indefinitely
}
public static void syncRevolverToClient(ServerPlayerEntity player, ItemStack stack) {
boolean[] chambers = RevolverItem.getChambers(stack);
int current = RevolverItem.getCurrentChamber(stack);
PacketByteBuf buf = PacketByteBufs.create();
for (int i = 0; i < RevolverItem.CHAMBERS; i++) {
buf.writeBoolean(chambers[i]);
}
buf.writeInt(current);
ServerPlayNetworking.send(player, REVOLVER_STATE_SYNC, buf);
}
}

View File

@@ -9,8 +9,10 @@ import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
@@ -26,6 +28,7 @@ import net.minecraft.advancement.Advancement;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.ChestBlockEntity;
import net.minecraft.entity.*;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.damage.DamageType;
@@ -38,6 +41,11 @@ import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*;
import net.minecraft.loot.LootPool;
import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.function.SetCountLootFunction;
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.registry.*;
import net.minecraft.registry.entry.RegistryEntry;
@@ -79,6 +87,7 @@ import net.minecraft.world.gen.structure.StructureType;
import net.minecraft.world.poi.PointOfInterestType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.jmx.Server;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@@ -93,9 +102,16 @@ public class Szar implements ModInitializer {
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_STATE_SYNC = new Identifier(MOD_ID, "revolver_state_sync");
public static final Identifier BULLET_IMPACT = new Identifier(MOD_ID, "bullet_impact");
public static final Identifier REVOLVER_SCROLL = new Identifier(MOD_ID, "revolver_scroll");
public static final Identifier REVOLVER_SPIN_RESULT = new Identifier(MOD_ID, "revolver_spin_result"); // S2C
public static final Identifier AK47_SHOOT = new Identifier(MOD_ID, "ak47_shoot");
public static final Identifier REVOLVER_CHAMBER_CHANGE = new Identifier(MOD_ID, "revolver_chamber_change");
public static final SoundEvent REVOLVER_CLICK1_SOUND = SoundEvent.of(new Identifier(MOD_ID, "revolver_click1"));
public static final SoundEvent REVOLVER_CLICK2_SOUND = SoundEvent.of(new Identifier(MOD_ID, "revolver_click2"));
public static final SoundEvent REVOLVER_CLICK3_SOUND = SoundEvent.of(new Identifier(MOD_ID, "revolver_click3"));
public static final SoundEvent REVOLVER_ROLL_SOUND = SoundEvent.of(new Identifier(MOD_ID, "revolver_roll"));
public static final SoundEvent BESZIV = Registry.register(
Registries.SOUND_EVENT,
new Identifier(MOD_ID, "besziv"),
@@ -239,6 +255,7 @@ public class Szar implements ModInitializer {
.dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized
.build()
);
public static final EntityType<HitterEntity> HitterEntityType =
Registry.register(
Registries.ENTITY_TYPE,
@@ -373,12 +390,62 @@ public class Szar implements ModInitializer {
private final Map<UUID, BlockPos> sleepingPlayers = new HashMap<>();
@Override
public void onInitialize() {
ServerPlayNetworking.registerGlobalReceiver(AK47_SHOOT, (server, player, handler, buf, responseSender) -> {
server.execute(() -> {
ItemStack stack = player.getMainHandStack();
if (!stack.isOf(Szar.AK47)) return;
if (player.getItemCooldownManager().isCoolingDown(Szar.AK47)) return;
AK47Item ak = (AK47Item) Szar.AK47;
if (!ak.consumeAmmo(player)) return;
player.getWorld().playSound(null, player.getBlockPos(),
SoundEvents.ENTITY_GENERIC_EXPLODE, SoundCategory.PLAYERS, 0.5f, 1.8f);
BulletEntity bullet = new BulletEntity(player.getWorld(), player);
bullet.setVelocity(player, player.getPitch(), player.getYaw(), 0f, 4.5f, 1.0f);
player.getWorld().spawnEntity(bullet);
// Recoil when shooting downward while falling
recoil(player, 0.1);
player.getItemCooldownManager().set(Szar.AK47, 2);
});
});
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
PoliceSpawnTimerStore.remove(handler.player);
});
ServerPlayNetworking.registerGlobalReceiver(REVOLVER_SCROLL, (server, player, handler, buf, responseSender) -> {
int direction = buf.readInt();
server.execute(() -> {
ItemStack stack = player.getMainHandStack();
if (!stack.isOf(Szar.REVOLVER)) return;
int current = RevolverItem.getCurrentChamber(stack);
int next = (current + direction + RevolverItem.CHAMBERS) % RevolverItem.CHAMBERS;
RevolverItem.setCurrentChamber(stack, next);
playRevolverClick(player);
RevolverItem.syncRevolverToClient(player, stack); // <- here
});
});
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);
player.getWorld().playSound(null, player.getBlockPos(),
Szar.REVOLVER_ROLL_SOUND, SoundCategory.PLAYERS, 1f, 1f);
// Tell client how many steps for animation
PacketByteBuf replyBuf = PacketByteBufs.create();
replyBuf.writeInt(steps);
ServerPlayNetworking.send(player, REVOLVER_SPIN_RESULT, replyBuf);
RevolverItem.syncRevolverToClient(player, stack);
});
});
ServerPlayNetworking.registerGlobalReceiver(REVOLVER_CHAMBER_CHANGE, (server, player, handler, buf, responseSender) -> {
int index = buf.readInt();
boolean wasLoaded = buf.readBoolean(); // true = unloading, false = loading
boolean wasLoaded = buf.readBoolean();
server.execute(() -> {
ItemStack stack = player.getMainHandStack();
@@ -387,12 +454,10 @@ public class Szar implements ModInitializer {
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)) {
@@ -403,33 +468,11 @@ public class Szar implements ModInitializer {
}
}
}
});
});
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);
// Advance to next chamber after loading/unloading
RevolverItem.setCurrentChamber(stack, (index + 1) % RevolverItem.CHAMBERS);
playRevolverClick(player);
RevolverItem.syncRevolverToClient(player, stack);
});
});
ServerPlayNetworking.registerGlobalReceiver(REVOLVER_SHOOT, (server, player, handler, buf, responseSender) -> {
@@ -462,11 +505,15 @@ public class Szar implements ModInitializer {
BulletEntity bullet = new BulletEntity(player.getWorld(), player);
bullet.setVelocity(player, player.getPitch(), player.getYaw(), 0f, 4.5f, 0.0f);
player.getWorld().spawnEntity(bullet);
// Recoil when shooting downward while falling
recoil(player, 0.2);
}
}
// Always advance chamber after trigger pull
RevolverItem.setCurrentChamber(stack, (current + 1) % RevolverItem.CHAMBERS);
playRevolverClick(player);
RevolverItem.syncRevolverToClient(player, stack);
});
});
ServerPlayNetworking.registerGlobalReceiver(CONFIG_SYNC,
@@ -759,12 +806,6 @@ public class Szar implements ModInitializer {
NyanEntityType,
1, 1, 1
);
BiomeModifications.addSpawn(
BiomeSelectors.includeByKey(BiomeKeys.FOREST, BiomeKeys.FLOWER_FOREST),
SpawnGroup.MONSTER,
EpsteinEntityType,
1, 1, 1
);
BiomeModifications.addFeature(
BiomeSelectors.tag(BiomeTags.IS_JUNGLE),
GenerationStep.Feature.VEGETAL_DECORATION,
@@ -912,6 +953,26 @@ public class Szar implements ModInitializer {
new Identifier(MOD_ID, "nyansniffer"),
new PaintingVariant(32, 32)
);
// In Szar.java onInitialize:
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
if (world.isClient) return ActionResult.PASS;
BlockPos pos = hitResult.getBlockPos();
if (!(world.getBlockEntity(pos) instanceof ChestBlockEntity chest)) return ActionResult.PASS;
// Check if this is an island chest by checking if it has our loot table pending
// Once loot generates we can't check anymore, so tag it via NBT during structure gen
NbtCompound nbt = chest.createNbt();
if (!nbt.getString("szar_chest_type").equals("island")) return ActionResult.PASS;
// Set center item if not already set
ItemStack center = chest.getStack(13);
if (center.isEmpty()) {
chest.setStack(13, new ItemStack(Szar.EPSTEIN_FILES));
}
nbt.remove("szar_chest_type");
return ActionResult.PASS;
});
}
// In your ModItems or wherever you register items
@@ -1066,6 +1127,19 @@ public class Szar implements ModInitializer {
new Identifier(MOD_ID, "casino"),
() -> CasinoStructure.CODEC
);
public static final StructurePieceType ISLAND_PIECE =
Registry.register(
Registries.STRUCTURE_PIECE,
new Identifier(MOD_ID, "island_piece"),
IslandStructurePiece::new
);
public static final StructureType<IslandStructure> ISLAND_TYPE =
Registry.register(
Registries.STRUCTURE_TYPE,
new Identifier(MOD_ID, "island"),
() -> IslandStructure.CODEC
);
static VoxelShape shape0 = VoxelShapes.cuboid(0.1875f, 0f, 0.625f, 0.6875f, 0.5f, 1.125f);
static VoxelShape shape1 = VoxelShapes.cuboid(0.1875f, 1.5f, 0.625f, 0.6875f, 2f, 1.125f);
static VoxelShape shape2 = VoxelShapes.cuboid(0.5625f, 0f, 0.25f, 1.0625f, 2f, 0.75f);
@@ -1732,32 +1806,29 @@ public class Szar implements ModInitializer {
}
}
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
);
public static void recoil(ServerPlayerEntity player, double recoil) {
if (player.isCreative()) {
return;
}
double recoilfinal = player.isOnGround() ? recoil / 2 : recoil;
// Opposite of the direction the player is looking
float pitch = (float) Math.toRadians(player.getPitch());
float yaw = (float) Math.toRadians(player.getYaw());
double dx = -(-Math.cos(pitch) * Math.sin(yaw)) * recoilfinal;
double dy = -(- Math.sin(pitch)) * recoilfinal;
double dz = -( Math.cos(pitch) * Math.cos(yaw)) * recoilfinal;
player.addVelocity(dx, dy, dz);
player.velocityModified = true;
player.fallDistance = Math.max(0, player.fallDistance - (float)(dy * 8));
}
private static void playRevolverClick(ServerPlayerEntity player) {
float pitch = 0.9F + player.getWorld().getRandom().nextFloat() * 0.2F; // 0.9 to 1.1
player.getWorld().playSound(null, player.getBlockPos(),
Szar.REVOLVER_CLICK2_SOUND, SoundCategory.PLAYERS, 1f, pitch);
}
}

View File

@@ -162,5 +162,37 @@
"stream": true
}
]
},
"revolver_click1": {
"sounds": [
{
"name": "szar:revolver_click1",
"stream": true
}
]
},
"revolver_click2": {
"sounds": [
{
"name": "szar:revolver_click2",
"stream": true
}
]
},
"revolver_click3": {
"sounds": [
{
"name": "szar:revolver_click3",
"stream": true
}
]
},
"revolver_roll": {
"sounds": [
{
"name": "szar:revolver_roll",
"stream": true
}
]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,7 +1,8 @@
{
"replace": false,
"values": [
"szar:niggerite_block"
"szar:niggerite_block",
"szar:cigany"
]
}

View File

@@ -0,0 +1,61 @@
{
"type": "minecraft:chest",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "szar:epstein_files"
}
]
},
{
"rolls": 26,
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 40,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:binomial",
"n": 1,
"p": 0.2
},
"add": true
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:diamond",
"weight": 30,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:binomial",
"n": 1,
"p": 0.2
},
"add": true
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_block",
"weight": 20
},
{
"type": "minecraft:item",
"name": "minecraft:diamond_block",
"weight": 10
}
]
}
]
}

View File

@@ -0,0 +1,17 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"DDD",
"DDD",
"DDD"
],
"key": {
"D": {
"item": "minecraft:debug_stick"
}
},
"result": {
"item": "szar:cigany",
"count": 1
}
}

Binary file not shown.

View File

@@ -0,0 +1,11 @@
{
"values": [
"minecraft:ocean",
"minecraft:deep_ocean",
"minecraft:cold_ocean",
"minecraft:deep_cold_ocean",
"minecraft:lukewarm_ocean",
"minecraft:deep_lukewarm_ocean",
"minecraft:warm_ocean"
]
}

View File

@@ -0,0 +1,8 @@
{
"type": "szar:island",
"biomes": "#szar:island",
"step": "surface_structures",
"terrain_adaptation": "beard_thin",
"spawn_overrides": {},
"config": {}
}

View File

@@ -0,0 +1,14 @@
{
"structures": [
{
"structure": "szar:island",
"weight": 1
}
],
"placement": {
"type": "minecraft:random_spread",
"spacing": 40,
"separation": 20,
"salt": 533693546
}
}