Bumped mod version to 0.1.4. Refactored crop harvesting and armor effects.
This commit is contained in:
+1
-1
@@ -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.
|
# 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.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.
|
# 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
|
||||||
|
|||||||
@@ -158,7 +158,6 @@ public class ComradeHandler {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
// /comrade accept <leader>
|
|
||||||
.then(Commands.literal("accept")
|
.then(Commands.literal("accept")
|
||||||
.then(Commands.argument("leader", EntityArgument.player())
|
.then(Commands.argument("leader", EntityArgument.player())
|
||||||
.executes(ctx -> {
|
.executes(ctx -> {
|
||||||
@@ -196,7 +195,6 @@ public class ComradeHandler {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
// /comrade remove <player>
|
|
||||||
.then(Commands.literal("remove")
|
.then(Commands.literal("remove")
|
||||||
.then(Commands.argument("player", EntityArgument.player())
|
.then(Commands.argument("player", EntityArgument.player())
|
||||||
.executes(ctx -> {
|
.executes(ctx -> {
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package net.krituximon.stalinium.item.custom;
|
package net.krituximon.stalinium.item.custom;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import net.krituximon.stalinium.event.ComradeHandler;
|
||||||
import net.krituximon.stalinium.item.ModArmorMaterials;
|
import net.krituximon.stalinium.item.ModArmorMaterials;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.effect.MobEffectInstance;
|
import net.minecraft.world.effect.MobEffectInstance;
|
||||||
import net.minecraft.world.effect.MobEffects;
|
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.ArmorMaterial;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ModArmorItem extends ArmorItem {
|
public class ModArmorItem extends ArmorItem {
|
||||||
private static final Map<Holder<ArmorMaterial>, List<MobEffectInstance>> MATERIAL_TO_EFFECT_MAP =
|
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,
|
.put(ModArmorMaterials.STALINIUM_ARMOR_MATERIAL,
|
||||||
List.of(new MobEffectInstance(MobEffects.HEALTH_BOOST, 100, 0, false, false)))
|
List.of(new MobEffectInstance(MobEffects.HEALTH_BOOST, 100, 0, false, false)))
|
||||||
.build();
|
.build();
|
||||||
@@ -29,65 +32,71 @@ public class ModArmorItem extends ArmorItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) {
|
public void inventoryTick(ItemStack stack,
|
||||||
if (entity instanceof Player player && !level.isClientSide() && hasFullSuitOfArmorOn(player)) {
|
Level level,
|
||||||
|
Entity entity,
|
||||||
|
int slotId,
|
||||||
|
boolean isSelected) {
|
||||||
|
if (!(entity instanceof Player player) || level.isClientSide()) return;
|
||||||
|
if (!hasFullSuitOfArmorOn(player)) return;
|
||||||
evaluateArmorEffects(player);
|
evaluateArmorEffects(player);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void evaluateArmorEffects(Player player) {
|
private void evaluateArmorEffects(Player player) {
|
||||||
for (Map.Entry<Holder<ArmorMaterial>, List<MobEffectInstance>> entry : MATERIAL_TO_EFFECT_MAP.entrySet()) {
|
for (var entry : MATERIAL_TO_EFFECT_MAP.entrySet()) {
|
||||||
Holder<ArmorMaterial> mapArmorMaterial = entry.getKey();
|
Holder<ArmorMaterial> mat = entry.getKey();
|
||||||
List<MobEffectInstance> mapEffect = entry.getValue();
|
List<MobEffectInstance> effects = entry.getValue();
|
||||||
|
if (!hasPlayerCorrectArmorOn(mat, player)) continue;
|
||||||
if (hasPlayerCorrectArmorOn(mapArmorMaterial, player)) {
|
addEffectToPlayer(player, effects);
|
||||||
addEffectToPlayer(player, mapEffect);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEffectToPlayer(Player player, List<MobEffectInstance> mapEffect) {
|
private void addEffectToPlayer(Player player, List<MobEffectInstance> baseEffects) {
|
||||||
AABB box = player.getBoundingBox().inflate(20.0);
|
int nearbyComrades = 0;
|
||||||
int playersInBox = player.level().getEntitiesOfClass(
|
Optional<ComradeHandler.Party> partyOpt = ComradeHandler.findPartyOf(player.getUUID());
|
||||||
Player.class,
|
if (partyOpt.isPresent() && player.level() instanceof ServerLevel serverLevel) {
|
||||||
box,
|
for (UUID memberUuid : partyOpt.get().members) {
|
||||||
p -> p instanceof ServerPlayer && player.isAlliedTo(p)
|
if (memberUuid.equals(player.getUUID())) continue;
|
||||||
).size();
|
ServerPlayer online = serverLevel.getServer()
|
||||||
|
.getPlayerList()
|
||||||
for (MobEffectInstance effect : mapEffect) {
|
.getPlayer(memberUuid);
|
||||||
int newAmplifier = Math.min(4, effect.getAmplifier() + playersInBox);
|
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(
|
player.addEffect(new MobEffectInstance(
|
||||||
effect.getEffect(),
|
base.getEffect(),
|
||||||
effect.getDuration(),
|
base.getDuration(),
|
||||||
newAmplifier,
|
newAmp,
|
||||||
effect.isAmbient(),
|
base.isAmbient(),
|
||||||
effect.isVisible()
|
base.isVisible()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasPlayerCorrectArmorOn(Holder<ArmorMaterial> mapArmorMaterial, Player player) {
|
private boolean hasPlayerCorrectArmorOn(Holder<ArmorMaterial> mat, Player player) {
|
||||||
for (ItemStack armorStack : player.getArmorSlots()) {
|
for (ItemStack armorStack : player.getArmorSlots()) {
|
||||||
if (!(armorStack.getItem() instanceof ArmorItem)) {
|
if (!(armorStack.getItem() instanceof ArmorItem ai)
|
||||||
|
|| ai.getMaterial() != mat) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasFullSuitOfArmorOn(Player player) {
|
private boolean hasFullSuitOfArmorOn(Player player) {
|
||||||
ItemStack boots = player.getInventory().getArmor(0);
|
for (ItemStack armor : player.getArmorSlots()) {
|
||||||
ItemStack leggings = player.getInventory().getArmor(1);
|
if (armor.isEmpty()) return false;
|
||||||
ItemStack chestplate = player.getInventory().getArmor(2);
|
}
|
||||||
ItemStack helmet = player.getInventory().getArmor(3);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return !boots.isEmpty() && !leggings.isEmpty() && !chestplate.isEmpty() && !helmet.isEmpty();
|
@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.server.level.ServerPlayer;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class StaliniumAxeItem extends AxeItem {
|
public class StaliniumAxeItem extends AxeItem {
|
||||||
public StaliniumAxeItem(Tier tier, Properties properties) {
|
public StaliniumAxeItem(Tier tier, Properties properties) {
|
||||||
@@ -33,20 +34,20 @@ public class StaliniumAxeItem extends AxeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mineBlock(ItemStack stack,
|
public boolean mineBlock(@NotNull ItemStack stack,
|
||||||
Level level,
|
Level level,
|
||||||
BlockState state,
|
@NotNull BlockState state,
|
||||||
BlockPos pos,
|
@NotNull BlockPos pos,
|
||||||
LivingEntity miningEntity) {
|
@NotNull LivingEntity miningEntity) {
|
||||||
if (!level.isClientSide() && state.is(BlockTags.LOGS) && miningEntity instanceof Player) {
|
if (!level.isClientSide() && state.is(BlockTags.LOGS) && miningEntity instanceof Player) {
|
||||||
cutDownTree(level, pos, (Player) miningEntity, stack);
|
cutDownTree(level, pos, (Player) miningEntity, stack);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return true; // allow the chain to continue
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
public boolean hurtEnemy(@NotNull ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,118 +1,92 @@
|
|||||||
package net.krituximon.stalinium.item.custom;
|
package net.krituximon.stalinium.item.custom;
|
||||||
|
|
||||||
import net.krituximon.stalinium.event.ComradeHandler;
|
import net.krituximon.stalinium.event.ComradeHandler;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
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.entity.player.Player;
|
||||||
import net.minecraft.world.item.*;
|
import net.minecraft.world.item.HoeItem;
|
||||||
import net.minecraft.world.item.context.UseOnContext;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Tier;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.CropBlock;
|
import net.minecraft.world.level.block.CropBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class StaliniumHoeItem extends HoeItem {
|
public class StaliniumHoeItem extends HoeItem {
|
||||||
public StaliniumHoeItem(Tier tier, Item.Properties properties) {
|
public StaliniumHoeItem(Tier tier, Properties props) {
|
||||||
super(tier, properties);
|
super(tier, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InteractionResult useOn(UseOnContext ctx) {
|
public boolean mineBlock(ItemStack stack,
|
||||||
Level level = ctx.getLevel();
|
Level level,
|
||||||
BlockPos pos = ctx.getClickedPos();
|
BlockState state,
|
||||||
BlockState state = level.getBlockState(pos);
|
BlockPos pos,
|
||||||
Player player = ctx.getPlayer();
|
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
|
// only for fully grown crops:
|
||||||
if (!level.isClientSide()
|
if (state.getBlock() instanceof CropBlock) {
|
||||||
&& level.isRaining()
|
|
||||||
&& level.isRainingAt(pos)
|
|
||||||
&& state.getBlock() instanceof CropBlock) {
|
|
||||||
|
|
||||||
// Collect that block’s drops
|
|
||||||
List<ItemStack> drops = Block.getDrops(
|
List<ItemStack> drops = Block.getDrops(
|
||||||
state,
|
state,
|
||||||
(ServerLevel) level,
|
(ServerLevel) level,
|
||||||
pos,
|
pos,
|
||||||
null, // no block entity
|
null,
|
||||||
player,
|
player,
|
||||||
ctx.getItemInHand()
|
stack
|
||||||
);
|
);
|
||||||
|
|
||||||
// Double each drop’s count and spawn them
|
// break the crop:
|
||||||
|
level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
||||||
|
|
||||||
|
// 1) give base drops to the harvester:
|
||||||
for (ItemStack drop : drops) {
|
for (ItemStack drop : drops) {
|
||||||
ItemStack doubled = drop.copy();
|
player.addItem(drop.copy());
|
||||||
doubled.setCount(drop.getCount() * 2);
|
|
||||||
Block.popResource(level, pos, doubled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the block
|
// 2) if raining here, give them a second batch:
|
||||||
level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3);
|
if (level.isRaining() && level.isRainingAt(pos)) {
|
||||||
return InteractionResult.SUCCESS;
|
for (ItemStack drop : drops) {
|
||||||
|
ItemStack extra = drop.copy();
|
||||||
|
extra.setCount(drop.getCount());
|
||||||
|
player.addItem(extra);
|
||||||
}
|
}
|
||||||
if (!level.isClientSide() && player != null) {
|
}
|
||||||
|
|
||||||
|
// 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());
|
Optional<ComradeHandler.Party> partyOpt = ComradeHandler.findPartyOf(player.getUUID());
|
||||||
if (partyOpt.isPresent()) {
|
if (partyOpt.isPresent()) {
|
||||||
ComradeHandler.Party party = partyOpt.get();
|
ComradeHandler.Party party = partyOpt.get();
|
||||||
List<Player> comrades = new ArrayList<>();
|
ServerLevel sl = (ServerLevel) level;
|
||||||
ServerLevel serverLevel = (ServerLevel) level;
|
for (UUID member : party.members) {
|
||||||
for (UUID memberUuid : party.members) {
|
if (member.equals(player.getUUID())) continue;
|
||||||
if (memberUuid.equals(player.getUUID())) continue;
|
ServerPlayer ally = sl.getServer()
|
||||||
ServerPlayer online = serverLevel.getServer()
|
|
||||||
.getPlayerList()
|
.getPlayerList()
|
||||||
.getPlayer(memberUuid);
|
.getPlayer(member);
|
||||||
if (online != null) {
|
if (ally != null && ally.distanceTo(player) <= 8.0) {
|
||||||
// Check distance (8 blocks)
|
for (ItemStack drop : drops) {
|
||||||
if (online.distanceTo(player) <= 8.0) {
|
ally.addItem(drop.copy());
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.useOn(ctx);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
return super.mineBlock(stack, level, state, pos, miner);
|
||||||
public boolean isDamageable(ItemStack stack) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public boolean isDamageable(ItemStack stack) { return false; }
|
||||||
public boolean isDamaged(ItemStack stack) {
|
@Override public boolean isDamaged(ItemStack stack) { return false; }
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user