community update

This commit is contained in:
2026-03-16 11:23:06 +01:00
parent 2a14de0b5e
commit 3f43125038
21 changed files with 548 additions and 158 deletions

View File

@@ -1,19 +1,21 @@
package dev.tggamesyt.szar;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.mob.PathAwareEntity;
import net.minecraft.util.math.MathHelper;
import java.util.EnumSet;
public class AK47AttackGoal extends Goal {
private final NaziEntity mob;
private final PathAwareEntity mob;
private final float range;
private final int cooldownTicks;
private int cooldown;
public AK47AttackGoal(NaziEntity mob, float range, int cooldownTicks) {
public AK47AttackGoal(PathAwareEntity mob, float range, int cooldownTicks) {
this.mob = mob;
this.range = range;
this.cooldownTicks = cooldownTicks;

View File

@@ -11,7 +11,7 @@ import net.minecraft.world.World;
public class AK47Item extends Item {
public AK47Item(Settings settings) {
super(settings);
super(settings.maxDamage(512));
}
public boolean consumeAmmo(PlayerEntity player) {
@@ -21,6 +21,10 @@ public class AK47Item extends Item {
ItemStack stack = player.getInventory().getStack(i);
if (stack.isOf(Szar.BULLET_ITEM)) {
stack.decrement(1);
ItemStack gun = player.getMainHandStack();
if (gun.isOf(Szar.AK47)) {
gun.damage(1, player, p -> p.sendToolBreakStatus(p.getActiveHand()));
}
return true;
}
}

View File

@@ -1,9 +1,12 @@
package dev.tggamesyt.szar;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
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.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
@@ -32,6 +35,23 @@ public class AtomSummonerItem extends Item {
ServerWorld serverWorld = (ServerWorld) world;
ItemStack stack = player.getStackInHand(hand);
// Shift + right-click → open coordinate screen
if (player.isSneaking()) {
if (world.isClient()) {
return TypedActionResult.success(stack);
}
// Tell the client to open the screen
ServerPlayNetworking.send(
(ServerPlayerEntity) player,
Szar.OPEN_DETONATOR_SCREEN,
PacketByteBufs.empty()
);
return TypedActionResult.success(stack);
}
// Normal right-click → existing raycast behaviour
if (world.isClient()) return TypedActionResult.success(stack);
// Raycast from eyes
Vec3d start = player.getCameraPosVec(1.0F);
Vec3d direction = player.getRotationVec(1.0F);

View File

@@ -0,0 +1,89 @@
package dev.tggamesyt.szar;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.ai.goal.WanderAroundFarGoal;
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.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.world.World;
import org.jetbrains.annotations.Nullable;
public class CommunistEntity extends PathAwareEntity implements Arrestable{
public static boolean arrestable = false;
@Nullable
private StalinEntity leader;
public CommunistEntity(EntityType<? extends PathAwareEntity> type, World world) {
super(type, world);
this.equipStack(EquipmentSlot.MAINHAND, new ItemStack(Szar.AK47));
}
@Override
protected void initGoals() {
this.goalSelector.add(2, new FollowLeaderWanderGoal(this, 1.0D, 6.0F));
this.goalSelector.add(3, new WanderAroundFarGoal(this, 0.8D));
this.goalSelector.add(1, new AK47AttackGoal(this, 16.0F, 2));
}
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) {
var rand = this.getRandom();
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);
NbtCompound nbt = book.getOrCreateNbt();
nbt.putString("title", "Communist's message");
nbt.putString("author", "Communist");
// Pages need to be JSON text components
NbtList pages = new NbtList();
pages.add(NbtString.of("{\"text\":\"Communism good\"}"));
nbt.put("pages", pages);
this.dropStack(book);
}
int count = rand.nextInt(17);
if (count > 0) {
this.dropStack(new ItemStack(Szar.BULLET_ITEM, count));
}
}
@Override
public boolean isArrestable() {
return arrestable;
}
public void setLeader(StalinEntity leader) {
this.leader = leader;
}
@Nullable
public StalinEntity getLeader() {
return this.leader;
}
}

View File

@@ -24,7 +24,7 @@ public class RevolverItem extends Item {
public static final int CHAMBERS = 6;
public RevolverItem(Settings settings) {
super(settings);
super(settings.maxDamage(384));
}
// ── NBT helpers ──────────────────────────────────────────────

View File

@@ -0,0 +1,151 @@
package dev.tggamesyt.szar;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.goal.LookAroundGoal;
import net.minecraft.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.entity.ai.goal.WanderAroundFarGoal;
import net.minecraft.entity.attribute.DefaultAttributeContainer;
import net.minecraft.entity.attribute.EntityAttributeModifier;
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.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.random.Random;
import net.minecraft.world.LocalDifficulty;
import net.minecraft.world.ServerWorldAccess;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import static dev.tggamesyt.szar.Szar.CommunistEntityType;
public class StalinEntity extends PathAwareEntity implements Arrestable{
public static boolean arrestable = true;
public StalinEntity(EntityType<? extends PathAwareEntity> type, World world) {
super(type, world);
}
@Override
protected void initGoals() {
this.goalSelector.add(0, new MeleeAttackGoal(this, 1.2D, true));
this.goalSelector.add(2, new WanderAroundFarGoal(this, 1.0D));
this.goalSelector.add(3, new LookAroundGoal(this));
this.targetSelector.add(1, new AggroOnHitRevengeGoal(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", "The Communist Manifesto");
nbt.putString("author", "Karl Marx");
// Pages need to be JSON text components
NbtList pages = new NbtList();
pages.add(NbtString.of("{\"text\":\"The Communist Manifesto\\n - Communism good\\n - Share all shit\"}"));
pages.add(NbtString.of("{\"text\":\"no money?\"}"));
nbt.put("pages", pages);
this.dropStack(book);
}
@Override
public boolean isArrestable() {
return arrestable;
}
@Override
@Nullable
public EntityData initialize(
ServerWorldAccess world,
LocalDifficulty difficulty,
SpawnReason spawnReason,
@Nullable EntityData entityData,
@Nullable NbtCompound entityNbt
) {
// Always call super
EntityData data = super.initialize(world, difficulty, spawnReason, entityData, entityNbt);
Random random = world.getRandom();
this.getAttributeInstance(EntityAttributes.GENERIC_FOLLOW_RANGE)
.addPersistentModifier(
new EntityAttributeModifier(
"Random spawn bonus",
random.nextTriangular(0.0D, 0.11485D),
EntityAttributeModifier.Operation.MULTIPLY_BASE
)
);
this.setLeftHanded(random.nextFloat() < 0.05F);
// 🔥 SPAWN GROUP HERE
if (spawnReason == SpawnReason.NATURAL && world instanceof ServerWorld serverWorld) {
int groupSize = 4 + serverWorld.random.nextInt(7); // 410 Bs
for (int i = 0; i < groupSize; i++) {
Entity entityB = CommunistEntityType.create(serverWorld);
if (entityB != null) {
double offsetX = (serverWorld.random.nextDouble() - 0.5) * 6;
double offsetZ = (serverWorld.random.nextDouble() - 0.5) * 6;
entityB.refreshPositionAndAngles(
this.getX() + offsetX,
this.getY(),
this.getZ() + offsetZ,
serverWorld.random.nextFloat() * 360F,
0F
);
serverWorld.spawnEntity(entityB);
if (entityB instanceof CommunistEntity Communist) {
Communist.setLeader(this);
}
}
}
}
return data;
}
@Override
public void setAttacker(@Nullable LivingEntity attacker) {
super.setAttacker(attacker);
if (attacker == null || this.getWorld().isClient) return;
List<CommunistEntity> allies = this.getWorld().getEntitiesByClass(
CommunistEntity.class,
this.getBoundingBox().expand(16),
Communist -> Communist.getLeader() == this && Communist.isAlive()
);
for (CommunistEntity Communist : allies) {
Communist.setTarget(attacker);
}
}
}

View File

@@ -26,6 +26,7 @@ import net.fabricmc.fabric.api.object.builder.v1.world.poi.PointOfInterestHelper
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
import net.minecraft.advancement.Advancement;
import net.minecraft.block.*;
import net.minecraft.block.dispenser.FallibleItemDispenserBehavior;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.ChestBlockEntity;
@@ -40,6 +41,7 @@ import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.*;
import net.minecraft.loot.LootPool;
import net.minecraft.loot.entry.ItemEntry;
@@ -66,14 +68,15 @@ import net.minecraft.util.ActionResult;
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.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.*;
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.RaycastContext;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeKeys;
import net.minecraft.world.gen.GenerationStep;
@@ -100,6 +103,8 @@ public class Szar implements ModInitializer {
public static final String MOD_ID = "szar";
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
public static MinecraftServer SERVER;
public static final Identifier OPEN_DETONATOR_SCREEN = new Identifier(MOD_ID, "open_coord_screen");
public static final Identifier DETONATOR_INPUT = new Identifier(MOD_ID, "coord_input");
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_STATE_SYNC = new Identifier(MOD_ID, "revolver_state_sync");
@@ -265,6 +270,15 @@ public class Szar implements ModInitializer {
.dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized
.build()
);
public static final EntityType<StalinEntity> StalinEntityType =
Registry.register(
Registries.ENTITY_TYPE,
new Identifier(MOD_ID, "stalin"),
FabricEntityTypeBuilder
.create(SpawnGroup.CREATURE, StalinEntity::new)
.dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized
.build()
);
public static final EntityType<MerlEntity> MerlEntityType =
Registry.register(
Registries.ENTITY_TYPE,
@@ -283,6 +297,15 @@ public class Szar implements ModInitializer {
.dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized
.build()
);
public static final EntityType<CommunistEntity> CommunistEntityType =
Registry.register(
Registries.ENTITY_TYPE,
new Identifier(MOD_ID, "communist"),
FabricEntityTypeBuilder
.create(SpawnGroup.CREATURE, CommunistEntity::new)
.dimensions(EntityDimensions.fixed(0.6F, 1.8F)) // player-sized
.build()
);
public static final EntityType<PoliceEntity> PoliceEntityType =
Registry.register(
Registries.ENTITY_TYPE,
@@ -336,6 +359,8 @@ public class Szar implements ModInitializer {
entries.add(Szar.NWORD_PASS);
entries.add(Szar.HITTER_SPAWNEGG);
entries.add(Szar.NAZI_SPAWNEGG);
entries.add(Szar.STALIN_SPAWNEGG);
entries.add(Szar.COMMUNIST_SPAWNEGG);
entries.add(Szar.NIGGER_SPAWNEGG);
entries.add(Szar.GYPSY_SPAWNEGG);
entries.add(Szar.TERRORIST_SPAWNEGG);
@@ -506,6 +531,7 @@ public class Szar implements ModInitializer {
bullet.setVelocity(player, player.getPitch(), player.getYaw(), 0f, 4.5f, 0.0f);
player.getWorld().spawnEntity(bullet);
// Recoil when shooting downward while falling
stack.damage(1, player, p -> p.sendToolBreakStatus(p.getActiveHand()));
recoil(player, 0.2);
}
}
@@ -723,6 +749,14 @@ public class Szar implements ModInitializer {
HitterEntityType,
HitterEntity.createAttributes()
);
FabricDefaultAttributeRegistry.register(
CommunistEntityType,
CommunistEntity.createAttributes()
);
FabricDefaultAttributeRegistry.register(
StalinEntityType,
StalinEntity.createAttributes()
);
FabricDefaultAttributeRegistry.register(
MerlEntityType,
MerlEntity.createAttributes()
@@ -786,6 +820,12 @@ public class Szar implements ModInitializer {
HitterEntityType,
1, 1, 1
);
BiomeModifications.addSpawn(
BiomeSelectors.includeByKey(BiomeKeys.WINDSWEPT_HILLS, BiomeKeys.WINDSWEPT_GRAVELLY_HILLS, BiomeKeys.STONY_PEAKS),
SpawnGroup.MONSTER,
StalinEntityType,
1, 1, 1
);
BiomeModifications.addSpawn(
BiomeSelectors.includeByKey(BiomeKeys.PLAINS, BiomeKeys.FOREST, BiomeKeys.FLOWER_FOREST),
SpawnGroup.MONSTER,
@@ -973,6 +1013,56 @@ public class Szar implements ModInitializer {
return ActionResult.PASS;
});
DispenserBlock.registerBehavior(Szar.ATOM, new FallibleItemDispenserBehavior() {
@Override
protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) {
ServerWorld serverWorld = pointer.getWorld();
BlockPos dispenserPos = pointer.getPos();
Direction facing = pointer.getBlockState().get(DispenserBlock.FACING);
// Spawn 1 block in front of the dispenser (mimics useOnBlock)
BlockPos spawnBlock = dispenserPos.offset(facing);
Vec3d spawnPos = Vec3d.ofCenter(spawnBlock).add(0, 1, 0);
AtomEntity atom = new AtomEntity(Szar.AtomEntityType, serverWorld);
atom.setPosition(spawnPos.x, spawnPos.y, spawnPos.z);
serverWorld.spawnEntity(atom);
// Damage item, remove if broken
stack.damage(1, serverWorld.getRandom(), null);
if (stack.getDamage() >= stack.getMaxDamage()) {
stack.decrement(1);
}
return stack;
}
});
ServerPlayNetworking.registerGlobalReceiver(DETONATOR_INPUT, (server, player, handler, buf, responseSender) -> {
int x = buf.readInt();
int z = buf.readInt();
if (!player.getMainHandStack().isOf(Szar.ATOM_DETONATOR)) {return;}
server.execute(() -> {
ServerWorld world = player.getServerWorld();
int topY = world.getTopY(
Heightmap.Type.WORLD_SURFACE, x, z
);
Vec3d spawnPos = new Vec3d(x + 0.5, topY + 100, z + 0.5);
AtomEntity atom = new AtomEntity(Szar.AtomEntityType, world);
atom.setPosition(spawnPos.x, spawnPos.y, spawnPos.z);
atom.readCustomDataFromNbt(new NbtCompound() {{
putBoolean("Armed", true);
}});
world.spawnEntity(atom);
player.getItemCooldownManager().set(Szar.ATOM_DETONATOR, 20 * 60);
player.getMainHandStack().damage(1, player,
p -> p.sendToolBreakStatus(player.getActiveHand()));
});
});
}
// In your ModItems or wherever you register items
@@ -1576,6 +1666,26 @@ public class Szar implements ModInitializer {
new Item.Settings()
)
);
public static final Item STALIN_SPAWNEGG = Registry.register(
Registries.ITEM,
new Identifier(MOD_ID, "stalin_spawn_egg"),
new SpawnEggItem(
StalinEntityType,
0xA82100,
0x404040,
new Item.Settings()
)
);
public static final Item COMMUNIST_SPAWNEGG = Registry.register(
Registries.ITEM,
new Identifier(MOD_ID, "communist_spawn_egg"),
new SpawnEggItem(
CommunistEntityType,
0xA82100,
0xF8C912,
new Item.Settings()
)
);
public static final Item MERL_SPAWNEGG = Registry.register(
Registries.ITEM,
new Identifier(MOD_ID, "merl_spawn_egg"),

View File

@@ -128,5 +128,10 @@
"item.szar.bullet_shell": "Revolver Bullet Shell",
"key.categories.szar": "Szar",
"key.szar.spin": "Interact with Revolver"
"key.szar.spin": "Interact with Revolver",
"entity.szar.stalin": "Stalin",
"item.szar.stalin_spawn_egg":"Stalin Spawn Egg",
"entity.szar.communist": "Communist",
"item.szar.communist_spawn_egg":"Communist Spawn Egg"
}

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB