Bumped mod version to 0.1.4. Refactored crop harvesting and armor effects.

This commit is contained in:
IM23a-spirgif
2025-06-07 17:06:01 +02:00
parent 0e220c9371
commit 6c7f997fcb
5 changed files with 114 additions and 132 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ mod_name=Stalinium
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=MIT
# The mod version. See https://semver.org/
mod_version=0.1.3
mod_version=0.1.4
# 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.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
@@ -158,7 +158,6 @@ public class ComradeHandler {
})
)
)
// /comrade accept <leader>
.then(Commands.literal("accept")
.then(Commands.argument("leader", EntityArgument.player())
.executes(ctx -> {
@@ -196,7 +195,6 @@ public class ComradeHandler {
})
)
)
// /comrade remove <player>
.then(Commands.literal("remove")
.then(Commands.argument("player", EntityArgument.player())
.executes(ctx -> {
@@ -1,8 +1,10 @@
package net.krituximon.stalinium.item.custom;
import com.google.common.collect.ImmutableMap;
import net.krituximon.stalinium.event.ComradeHandler;
import net.krituximon.stalinium.item.ModArmorMaterials;
import net.minecraft.core.Holder;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
@@ -12,14 +14,15 @@ import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.ArmorMaterial;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
public class ModArmorItem extends ArmorItem {
private static final Map<Holder<ArmorMaterial>, List<MobEffectInstance>> MATERIAL_TO_EFFECT_MAP =
(new ImmutableMap.Builder<Holder<ArmorMaterial>, List<MobEffectInstance>>())
new ImmutableMap.Builder<Holder<ArmorMaterial>, List<MobEffectInstance>>()
.put(ModArmorMaterials.STALINIUM_ARMOR_MATERIAL,
List.of(new MobEffectInstance(MobEffects.HEALTH_BOOST, 100, 0, false, false)))
.build();
@@ -29,65 +32,71 @@ public class ModArmorItem extends ArmorItem {
}
@Override
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) {
if (entity instanceof Player player && !level.isClientSide() && hasFullSuitOfArmorOn(player)) {
evaluateArmorEffects(player);
}
public void inventoryTick(ItemStack stack,
Level level,
Entity entity,
int slotId,
boolean isSelected) {
if (!(entity instanceof Player player) || level.isClientSide()) return;
if (!hasFullSuitOfArmorOn(player)) return;
evaluateArmorEffects(player);
}
private void evaluateArmorEffects(Player player) {
for (Map.Entry<Holder<ArmorMaterial>, List<MobEffectInstance>> entry : MATERIAL_TO_EFFECT_MAP.entrySet()) {
Holder<ArmorMaterial> mapArmorMaterial = entry.getKey();
List<MobEffectInstance> mapEffect = entry.getValue();
if (hasPlayerCorrectArmorOn(mapArmorMaterial, player)) {
addEffectToPlayer(player, mapEffect);
}
for (var entry : MATERIAL_TO_EFFECT_MAP.entrySet()) {
Holder<ArmorMaterial> mat = entry.getKey();
List<MobEffectInstance> effects = entry.getValue();
if (!hasPlayerCorrectArmorOn(mat, player)) continue;
addEffectToPlayer(player, effects);
}
}
private void addEffectToPlayer(Player player, List<MobEffectInstance> mapEffect) {
AABB box = player.getBoundingBox().inflate(20.0);
int playersInBox = player.level().getEntitiesOfClass(
Player.class,
box,
p -> p instanceof ServerPlayer && player.isAlliedTo(p)
).size();
for (MobEffectInstance effect : mapEffect) {
int newAmplifier = Math.min(4, effect.getAmplifier() + playersInBox);
private void addEffectToPlayer(Player player, List<MobEffectInstance> baseEffects) {
int nearbyComrades = 0;
Optional<ComradeHandler.Party> partyOpt = ComradeHandler.findPartyOf(player.getUUID());
if (partyOpt.isPresent() && player.level() instanceof ServerLevel serverLevel) {
for (UUID memberUuid : partyOpt.get().members) {
if (memberUuid.equals(player.getUUID())) continue;
ServerPlayer online = serverLevel.getServer()
.getPlayerList()
.getPlayer(memberUuid);
if (online != null && online.distanceTo(player) <= 20.0) {
nearbyComrades++;
}
}
}
for (var base : baseEffects) {
int newAmp = Math.min(4, base.getAmplifier() + nearbyComrades);
player.addEffect(new MobEffectInstance(
effect.getEffect(),
effect.getDuration(),
newAmplifier,
effect.isAmbient(),
effect.isVisible()
base.getEffect(),
base.getDuration(),
newAmp,
base.isAmbient(),
base.isVisible()
));
}
}
private boolean hasPlayerCorrectArmorOn(Holder<ArmorMaterial> mapArmorMaterial, Player player) {
private boolean hasPlayerCorrectArmorOn(Holder<ArmorMaterial> mat, Player player) {
for (ItemStack armorStack : player.getArmorSlots()) {
if (!(armorStack.getItem() instanceof ArmorItem)) {
if (!(armorStack.getItem() instanceof ArmorItem ai)
|| ai.getMaterial() != mat) {
return false;
}
}
ArmorItem boots = ((ArmorItem) player.getInventory().getArmor(0).getItem());
ArmorItem leggings = ((ArmorItem) player.getInventory().getArmor(1).getItem());
ArmorItem chestplate = ((ArmorItem) player.getInventory().getArmor(2).getItem());
ArmorItem helmet = ((ArmorItem) player.getInventory().getArmor(3).getItem());
return boots.getMaterial() == mapArmorMaterial && leggings.getMaterial() == mapArmorMaterial
&& chestplate.getMaterial() == mapArmorMaterial && helmet.getMaterial() == mapArmorMaterial;
return true;
}
private boolean hasFullSuitOfArmorOn(Player player) {
ItemStack boots = player.getInventory().getArmor(0);
ItemStack leggings = player.getInventory().getArmor(1);
ItemStack chestplate = player.getInventory().getArmor(2);
ItemStack helmet = player.getInventory().getArmor(3);
return !boots.isEmpty() && !leggings.isEmpty() && !chestplate.isEmpty() && !helmet.isEmpty();
for (ItemStack armor : player.getArmorSlots()) {
if (armor.isEmpty()) return false;
}
return true;
}
@Override
public boolean isDamageable(ItemStack stack) { return false; }
@Override
public boolean isDamaged(ItemStack stack) { return false; }
}
@@ -26,6 +26,7 @@ import java.util.*;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BlockTags;
import org.jetbrains.annotations.NotNull;
public class StaliniumAxeItem extends AxeItem {
public StaliniumAxeItem(Tier tier, Properties properties) {
@@ -33,20 +34,20 @@ public class StaliniumAxeItem extends AxeItem {
}
@Override
public boolean mineBlock(ItemStack stack,
public boolean mineBlock(@NotNull ItemStack stack,
Level level,
BlockState state,
BlockPos pos,
LivingEntity miningEntity) {
@NotNull BlockState state,
@NotNull BlockPos pos,
@NotNull LivingEntity miningEntity) {
if (!level.isClientSide() && state.is(BlockTags.LOGS) && miningEntity instanceof Player) {
cutDownTree(level, pos, (Player) miningEntity, stack);
return true;
}
return true; // allow the chain to continue
return true;
}
@Override
public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
public boolean hurtEnemy(@NotNull ItemStack stack, LivingEntity target, LivingEntity attacker) {
return true;
}
@@ -1,118 +1,92 @@
package net.krituximon.stalinium.item.custom;
import net.krituximon.stalinium.event.ComradeHandler;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.item.HoeItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Tier;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.CropBlock;
import net.minecraft.world.level.block.state.BlockState;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class StaliniumHoeItem extends HoeItem {
public StaliniumHoeItem(Tier tier, Item.Properties properties) {
super(tier, properties);
public StaliniumHoeItem(Tier tier, Properties props) {
super(tier, props);
}
@Override
public InteractionResult useOn(UseOnContext ctx) {
Level level = ctx.getLevel();
BlockPos pos = ctx.getClickedPos();
BlockState state = level.getBlockState(pos);
Player player = ctx.getPlayer();
public boolean mineBlock(ItemStack stack,
Level level,
BlockState state,
BlockPos pos,
LivingEntity miner) {
if (level.isClientSide || !(miner instanceof Player player))
return super.mineBlock(stack, level, state, pos, miner);
// Only run on server side and if it's raining at this position and the block is a CropBlock
if (!level.isClientSide()
&& level.isRaining()
&& level.isRainingAt(pos)
&& state.getBlock() instanceof CropBlock) {
// Collect that blocks drops
// only for fully grown crops:
if (state.getBlock() instanceof CropBlock) {
List<ItemStack> drops = Block.getDrops(
state,
(ServerLevel) level,
pos,
null, // no block entity
null,
player,
ctx.getItemInHand()
stack
);
// Double each drops count and spawn them
for (ItemStack drop : drops) {
ItemStack doubled = drop.copy();
doubled.setCount(drop.getCount() * 2);
Block.popResource(level, pos, doubled);
}
// Destroy the block
// break the crop:
level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
return InteractionResult.SUCCESS;
}
if (!level.isClientSide() && player != null) {
Optional<ComradeHandler.Party> partyOpt = ComradeHandler.findPartyOf(player.getUUID());
if (partyOpt.isPresent()) {
ComradeHandler.Party party = partyOpt.get();
List<Player> comrades = new ArrayList<>();
ServerLevel serverLevel = (ServerLevel) level;
for (UUID memberUuid : party.members) {
if (memberUuid.equals(player.getUUID())) continue;
ServerPlayer online = serverLevel.getServer()
.getPlayerList()
.getPlayer(memberUuid);
if (online != null) {
// Check distance (8 blocks)
if (online.distanceTo(player) <= 8.0) {
comrades.add(online);
}
}
}
// 50% chance to send normal block drops to those comrades
if (level.getRandom().nextFloat() < 0.5f) {
for (ItemStack drop : Block.getDrops(state, (ServerLevel) level, pos, null)) {
for (Player buddy : comrades) {
buddy.addItem(drop.copy());
// 1) give base drops to the harvester:
for (ItemStack drop : drops) {
player.addItem(drop.copy());
}
// 2) if raining here, give them a second batch:
if (level.isRaining() && level.isRainingAt(pos)) {
for (ItemStack drop : drops) {
ItemStack extra = drop.copy();
extra.setCount(drop.getCount());
player.addItem(extra);
}
}
// 3) 50% chance to also duplicate to each ally in range:
if (!level.isClientSide() && level.getRandom().nextFloat() < 0.5f) {
Optional<ComradeHandler.Party> partyOpt = ComradeHandler.findPartyOf(player.getUUID());
if (partyOpt.isPresent()) {
ComradeHandler.Party party = partyOpt.get();
ServerLevel sl = (ServerLevel) level;
for (UUID member : party.members) {
if (member.equals(player.getUUID())) continue;
ServerPlayer ally = sl.getServer()
.getPlayerList()
.getPlayer(member);
if (ally != null && ally.distanceTo(player) <= 8.0) {
for (ItemStack drop : drops) {
ally.addItem(drop.copy());
}
}
}
}
}
return true;
}
return super.useOn(ctx);
return super.mineBlock(stack, level, state, pos, miner);
}
@Override
public boolean isDamageable(ItemStack stack) {
return false;
}
@Override
public boolean isDamaged(ItemStack stack) {
return false;
}
@Override
public void appendHoverText(ItemStack stack,
TooltipContext context,
List<Component> tooltipComponents,
TooltipFlag tooltipFlag) {
if (Screen.hasShiftDown()) {
tooltipComponents.add(Component.translatable("item.stalinium_hoe.tooltip_shift"));
} else {
tooltipComponents.add(Component.translatable("item.stalinium_hoe.tooltip"));
}
super.appendHoverText(stack, context, tooltipComponents, tooltipFlag);
}
@Override public boolean isDamageable(ItemStack stack) { return false; }
@Override public boolean isDamaged(ItemStack stack) { return false; }
}