Fixed the Tools breaking on stripping and pathing and made the axe not capitate player placed logs

Signed-off-by: IM23a-cernik <cernik@bzz.ch>
This commit is contained in:
IM23a-cernik
2025-05-21 10:46:46 +02:00
parent 5679e323e4
commit 8620edae24
9 changed files with 176 additions and 15 deletions
-1
View File
@@ -126,7 +126,6 @@ dependencies {
// Example mod dependency using a file as dependency // Example mod dependency using a file as dependency
// implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar") // implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar")
// Example project dependency using a sister or child project: // Example project dependency using a sister or child project:
// implementation project(":myproject") // implementation project(":myproject")
+1 -1
View File
@@ -34,7 +34,7 @@ mod_name=Stalinium
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT mod_license=MIT
# The mod version. See https://semver.org/ # The mod version. See https://semver.org/
mod_version=0.0.8 mod_version=0.0.10
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources. # This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html # See https://maven.apache.org/guides/mini/guide-naming-conventions.html
@@ -10,6 +10,8 @@ import net.krituximon.stalinium.screen.ModMenuTypes;
import net.krituximon.stalinium.screen.custom.StaliniumPressMenu; import net.krituximon.stalinium.screen.custom.StaliniumPressMenu;
import net.krituximon.stalinium.screen.custom.StaliniumPressScreen; import net.krituximon.stalinium.screen.custom.StaliniumPressScreen;
import net.krituximon.stalinium.sound.ModSounds; import net.krituximon.stalinium.sound.ModSounds;
import net.krituximon.stalinium.util.PlacedLogStorage;
import net.krituximon.stalinium.util.PlayerLogEvents;
import net.krituximon.stalinium.worldgen.ModFeatures; import net.krituximon.stalinium.worldgen.ModFeatures;
import net.krituximon.stalinium.worldgen.StaliniumVeinFeature; import net.krituximon.stalinium.worldgen.StaliniumVeinFeature;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
@@ -62,6 +64,7 @@ public class Stalinium
ModSounds.register(modEventBus); ModSounds.register(modEventBus);
ModParticles.register(modEventBus); ModParticles.register(modEventBus);
ModCreativeModeTabs.register(modEventBus); ModCreativeModeTabs.register(modEventBus);
PlayerLogEvents.register();
// Register ourselves for server and other game events we are interested in. // Register ourselves for server and other game events we are interested in.
// Note that this is necessary if and only if we want *this* class (Stalinium) to respond directly to events. // Note that this is necessary if and only if we want *this* class (Stalinium) to respond directly to events.
@@ -25,11 +25,11 @@ public class ModItems {
public static final DeferredItem<SwordItem> STALINIUM_SWORD = ITEMS.register("stalinium_sword", public static final DeferredItem<SwordItem> STALINIUM_SWORD = ITEMS.register("stalinium_sword",
() -> new StaliniumSwordItem(ModTiers.STALINIUM, new Item.Properties() () -> new StaliniumSwordItem(ModTiers.STALINIUM, new Item.Properties()
.attributes(SwordItem.createAttributes(ModTiers.STALINIUM, 3, -2.4f)))); .attributes(SwordItem.createAttributes(ModTiers.STALINIUM, 3f, -2.4f))));
public static final DeferredItem<AxeItem> STALINIUM_AXE = ITEMS.register("stalinium_axe", public static final DeferredItem<AxeItem> STALINIUM_AXE = ITEMS.register("stalinium_axe",
() -> new StaliniumAxeItem(ModTiers.STALINIUM, new Item.Properties() () -> new StaliniumAxeItem(ModTiers.STALINIUM, new Item.Properties()
.attributes(AxeItem.createAttributes(ModTiers.STALINIUM, 5, -3.0f)))); .attributes(AxeItem.createAttributes(ModTiers.STALINIUM, 5f, -3.0f))));
public static final DeferredItem<ShovelItem> STALINIUM_SHOVEL = ITEMS.register("stalinium_shovel", public static final DeferredItem<ShovelItem> STALINIUM_SHOVEL = ITEMS.register("stalinium_shovel",
() -> new StaliniumShovelItem(ModTiers.STALINIUM, new Item.Properties() () -> new StaliniumShovelItem(ModTiers.STALINIUM, new Item.Properties()
@@ -1,13 +1,17 @@
package net.krituximon.stalinium.item; package net.krituximon.stalinium.item;
import net.krituximon.stalinium.util.PlacedLogStorage;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.AxeItem; import net.minecraft.world.item.AxeItem;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Tier; import net.minecraft.world.item.Tier;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@@ -24,17 +28,21 @@ public class StaliniumAxeItem extends AxeItem {
cutDownTree(level, pos, (Player)miningEntity, stack); cutDownTree(level, pos, (Player)miningEntity, stack);
return true; return true;
} }
return super.mineBlock(stack, level, state, pos, miningEntity); return true;
} }
private void cutDownTree(Level level, BlockPos start, Player player, ItemStack stack) { private void cutDownTree(Level level, BlockPos start, Player player, ItemStack stack) {
Set<BlockPos> toBreak = new HashSet<>(); Set<BlockPos> toBreak = new HashSet<>();
Deque<BlockPos> queue = new ArrayDeque<>(); Deque<BlockPos> queue = new ArrayDeque<>();
queue.add(start); queue.add(start);
PlacedLogStorage storage = PlacedLogStorage.get((ServerLevel) level);
while (!queue.isEmpty() && toBreak.size() < 256) { while (!queue.isEmpty() && toBreak.size() < 256) {
BlockPos current = queue.removeFirst(); BlockPos current = queue.removeFirst();
if (toBreak.contains(current)) continue; if (toBreak.contains(current)) continue;
BlockState bs = level.getBlockState(current); BlockState bs = level.getBlockState(current);
if (storage.contains(current)) continue;
if (bs.is(BlockTags.LOGS)) { if (bs.is(BlockTags.LOGS)) {
toBreak.add(current); toBreak.add(current);
for (int dx = -1; dx <= 1; dx++) { for (int dx = -1; dx <= 1; dx++) {
@@ -57,7 +65,7 @@ public class StaliniumAxeItem extends AxeItem {
@Override @Override
public int getMaxDamage(ItemStack stack) { public int getMaxDamage(ItemStack stack) {
return 0; return 2;
} }
@Override @Override
@@ -69,4 +77,13 @@ public class StaliniumAxeItem extends AxeItem {
public boolean isDamaged(ItemStack stack) { public boolean isDamaged(ItemStack stack) {
return false; return false;
} }
@Override
public InteractionResult useOn(UseOnContext ctx) {
ItemStack stack = ctx.getItemInHand();
int oldDamage = stack.getDamageValue();
InteractionResult res = super.useOn(ctx);
stack.setDamageValue(oldDamage);
return res;
}
} }
@@ -6,7 +6,6 @@ import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.AxeItem;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ShovelItem; import net.minecraft.world.item.ShovelItem;
import net.minecraft.world.item.Tier; import net.minecraft.world.item.Tier;
@@ -15,6 +14,9 @@ import net.minecraft.world.level.block.state.BlockState;
import java.util.List; import java.util.List;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
public class StaliniumShovelItem extends ShovelItem { public class StaliniumShovelItem extends ShovelItem {
public StaliniumShovelItem(Tier tier, Properties properties) { public StaliniumShovelItem(Tier tier, Properties properties) {
super(tier, properties); super(tier, properties);
@@ -27,9 +29,10 @@ public class StaliniumShovelItem extends ShovelItem {
miningEntity.addEffect(haste); miningEntity.addEffect(haste);
Level world = miningEntity.getCommandSenderWorld(); Level world = miningEntity.getCommandSenderWorld();
var box = miningEntity.getBoundingBox().inflate(10.0); var box = miningEntity.getBoundingBox().inflate(10.0);
world.getEntitiesOfClass(LivingEntity.class, box, p -> p instanceof LivingEntity).forEach( List<Player> nearby = world.getEntitiesOfClass(Player.class, box, p -> p instanceof ServerPlayer && miningEntity.isAlliedTo(p));
p -> p.addEffect(haste) for (Player p : nearby) {
); p.addEffect(haste);
}
} }
return true; return true;
} }
@@ -46,6 +49,15 @@ public class StaliniumShovelItem extends ShovelItem {
@Override @Override
public int getMaxDamage(ItemStack stack) { public int getMaxDamage(ItemStack stack) {
return 0; return 2;
} }
}
@Override
public InteractionResult useOn(UseOnContext ctx) {
ItemStack stack = ctx.getItemInHand();
int oldDamage = stack.getDamageValue();
InteractionResult res = super.useOn(ctx);
stack.setDamageValue(oldDamage);
return res;
}
}
@@ -24,7 +24,7 @@ public class StaliniumSwordItem extends SwordItem {
attacker.addEffect(strength); attacker.addEffect(strength);
Level world = attacker.getCommandSenderWorld(); Level world = attacker.getCommandSenderWorld();
var box = attacker.getBoundingBox().inflate(5.0); var box = attacker.getBoundingBox().inflate(5.0);
List<Player> nearby = world.getEntitiesOfClass(Player.class, box, p -> p instanceof ServerPlayer); List<Player> nearby = world.getEntitiesOfClass(Player.class, box, p -> p instanceof ServerPlayer && attacker.isAlliedTo(p));
for (Player p : nearby) { for (Player p : nearby) {
p.addEffect(strength); p.addEffect(strength);
} }
@@ -43,6 +43,11 @@ public class StaliniumSwordItem extends SwordItem {
@Override @Override
public int getMaxDamage(ItemStack stack) { public int getMaxDamage(ItemStack stack) {
return 0; return 2;
} }
}
@Override
public void postHurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
}
}
@@ -0,0 +1,85 @@
package net.krituximon.stalinium.util;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.saveddata.SavedData;
import java.util.Set;
public class PlacedLogStorage extends SavedData {
/* ------------------------------------------------------------------ */
/* Data */
/* ------------------------------------------------------------------ */
private final Set<BlockPos> placedLogs = new ObjectOpenHashSet<>();
/* ------------------------------------------------------------------ */
/* Constructors required by DataStorage.computeIfAbsent */
/* ------------------------------------------------------------------ */
/**
* Creates a brand-new, empty storage object (used when no save-file exists yet).
*/
public PlacedLogStorage() {
}
public PlacedLogStorage(CompoundTag compoundTag, HolderLookup.Provider provider) {
}
@Override
public CompoundTag save(CompoundTag compoundTag, HolderLookup.Provider provider) {
long[] packed = placedLogs.stream().mapToLong(BlockPos::asLong).toArray();
compoundTag.putLongArray("logs", packed);
return compoundTag;
}
/**
* Re-hydrates the storage from NBT (used when the save-file already exists).
*/
public PlacedLogStorage(CompoundTag tag) {
for (long packed : tag.getLongArray("logs")) {
placedLogs.add(BlockPos.of(packed));
}
}
/* ------------------------------------------------------------------ */
/* SavedData implementation */
/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* Public helpers (used by PlayerLogEvents, etc.) */
/* ------------------------------------------------------------------ */
public void add(BlockPos pos) {
if (placedLogs.add(pos)) setDirty();
}
public void remove(BlockPos pos) {
if (placedLogs.remove(pos)) setDirty();
}
public boolean contains(BlockPos pos) {
return placedLogs.contains(pos);
}
/* ------------------------------------------------------------------ */
/* Accessor */
/* ------------------------------------------------------------------ */
private static final String DATA_NAME = "stalinium_placed_logs";
public static PlacedLogStorage get(ServerLevel level) {
SavedData.Factory<PlacedLogStorage> factory =
new SavedData.Factory<>( // <T extends SavedData>
PlacedLogStorage::new, // Function<CompoundTag, PlacedLogStorage>
PlacedLogStorage::new); // Supplier<PlacedLogStorage>
return level.getDataStorage().computeIfAbsent(factory, DATA_NAME);
}
}
@@ -0,0 +1,40 @@
package net.krituximon.stalinium.util;
import net.minecraft.core.BlockPos;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.player.Player;
import net.minecraft.server.level.ServerLevel;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.level.BlockEvent;
import net.neoforged.bus.api.SubscribeEvent;
/**
* Listens for block place & break events to mark / un-mark player placed logs.
* Register this class during mod-initialisation: MinecraftForge.EVENT_BUS.register(new PlayerLogEvents());
*/
public class PlayerLogEvents {
/* Player (or entity) places a block */
@SubscribeEvent
public void onBlockPlaced(BlockEvent.EntityPlaceEvent e) {
if (!(e.getLevel() instanceof ServerLevel level)) return;
if (!e.getPlacedBlock().is(BlockTags.LOGS)) return;
PlacedLogStorage.get(level).add(e.getPos());
}
/* Any time the block is removed (player break, piston, explosion …) */
@SubscribeEvent
public void onBlockBroken(BlockEvent.BreakEvent e) {
if (!(e.getLevel() instanceof ServerLevel level)) return;
BlockPos pos = e.getPos();
PlacedLogStorage.get(level).remove(pos);
}
public static void register() {
NeoForge.EVENT_BUS.register(new PlayerLogEvents());
}
}