Added StaliniumCharge effect and integrated it with sword.

- Created `StaliniumChargeEffect` with speed/knockback buffs.
- Registered `ModEffects` and `StaliniumChargeEffect`.
- Updated `StaliniumSwordItem` to apply the custom effect and added cooldown handling.
- Simplified effect logic, replacing vanilla effects with the custom one.
- Ensured sword remains unbreakable.
This commit is contained in:
IM23a-spirgif
2025-05-26 17:09:26 +02:00
parent 35364bd4d5
commit 7007a9684b
4 changed files with 86 additions and 53 deletions
@@ -2,6 +2,7 @@ package net.krituximon.stalinium;
import net.krituximon.stalinium.block.ModBlocks;
import net.krituximon.stalinium.block.entity.ModBlockEntities;
import net.krituximon.stalinium.datagen.ModEffects;
import net.krituximon.stalinium.item.ModCreativeModeTabs;
import net.krituximon.stalinium.item.ModItems;
import net.krituximon.stalinium.particle.BloodParticle;
@@ -79,6 +80,7 @@ public class Stalinium
ModFeatures.register(modEventBus);
ModBlockEntities.register(modEventBus);
ModMenuTypes.register(modEventBus);
ModEffects.register(modEventBus);
}
private void commonSetup(final FMLCommonSetupEvent event)
@@ -0,0 +1,21 @@
package net.krituximon.stalinium.datagen;
import net.krituximon.stalinium.Stalinium;
import net.krituximon.stalinium.effect.StaliniumChargeEffect;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.core.registries.Registries;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.DeferredHolder;
public class ModEffects {
public static final DeferredRegister<MobEffect> EFFECTS =
DeferredRegister.create(Registries.MOB_EFFECT, Stalinium.MODID);
public static final DeferredHolder<MobEffect, StaliniumChargeEffect> STALINIUM_CHARGE =
EFFECTS.register("stalinium_charge", StaliniumChargeEffect::new);
public static void register(IEventBus bus) {
EFFECTS.register(bus);
}
}
@@ -0,0 +1,26 @@
package net.krituximon.stalinium.effect;
import net.krituximon.stalinium.Stalinium;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
public class StaliniumChargeEffect extends MobEffect {
public StaliniumChargeEffect() {
super(MobEffectCategory.BENEFICIAL, 0xAAAAFF);
this.addAttributeModifier(
Attributes.MOVEMENT_SPEED,
ResourceLocation.fromNamespaceAndPath(Stalinium.MODID, "stalinium_charge_speed"),
0.2,
AttributeModifier.Operation.ADD_MULTIPLIED_BASE
);
this.addAttributeModifier(
Attributes.KNOCKBACK_RESISTANCE,
ResourceLocation.fromNamespaceAndPath(Stalinium.MODID, "stalinium_charge_knockback"),
0.5,
AttributeModifier.Operation.ADD_VALUE
);
}
}
@@ -1,100 +1,84 @@
package net.krituximon.stalinium.item;
import net.krituximon.stalinium.Stalinium;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.item.SwordItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.SwordItem;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.item.Tier;
import net.minecraft.world.level.Level;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraft.server.level.ServerPlayer;
import java.util.List;
public class StaliniumSwordItem extends SwordItem {
private static final double RANGE = 6.0;
private static final double HALF_ANGLE = Math.toRadians(30);
private static final double COS_HALF_ANGLE = Math.cos(HALF_ANGLE);
private static final double COS_HALF_ANG = Math.cos(HALF_ANGLE);
private static final int DURATION = 5 * 20;
private static final int SPEED_AMP = 1;
private static final int RESIST_AMP = 0;
private static final int AMP = 0;
private static final int COOLDOWN = 20 * 20; // 20s
public StaliniumSwordItem(Tier tier, Properties props) {
super(tier, props);
}
@Override
public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
Level world = attacker.getCommandSenderWorld();
if (!world.isClientSide && attacker instanceof Player player) {
AABB box = player.getBoundingBox().inflate(5.0);
List<Player> allies = world.getEntitiesOfClass(
Player.class, box,
p -> p instanceof ServerPlayer && player.isAlliedTo(p)
);
MobEffectInstance allyBuff = new MobEffectInstance(MobEffects.DAMAGE_BOOST, 100, 0, false, true);
for (Player ally : allies) {
ally.addEffect(allyBuff);
}
}
return super.hurtEnemy(stack, target, attacker);
}
@Override
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
// 1) if still on cooldown, fail
if (player.getCooldowns().isOnCooldown(this)) {
return InteractionResultHolder.fail(stack);
}
if (!world.isClientSide) {
player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SPEED, DURATION, SPEED_AMP, false, true));
player.addEffect(new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, DURATION, RESIST_AMP, false, true));
if (!world.isClientSide) {
Holder<MobEffect> chargeHolder = world
.registryAccess()
.registryOrThrow(Registries.MOB_EFFECT)
.getHolderOrThrow(
ResourceKey.create(
Registries.MOB_EFFECT,
ResourceLocation.fromNamespaceAndPath(Stalinium.MODID, "stalinium_charge")
)
);
player.addEffect(new MobEffectInstance(chargeHolder, DURATION, AMP, false, true));
AABB area = player.getBoundingBox().inflate(RANGE);
Vec3 look = player.getLookAngle();
List<Player> allies = world.getEntitiesOfClass(
Player.class, area,
p -> p instanceof ServerPlayer && player.isAlliedTo(p)
);
Vec3 look = player.getLookAngle();
for (Player ally : allies) {
Vec3 toAlly = ally.position().subtract(player.position()).normalize();
if (toAlly.dot(look) >= COS_HALF_ANGLE) {
ally.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SPEED, DURATION, SPEED_AMP, false, true));
ally.addEffect(new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, DURATION, RESIST_AMP, false, true));
if (toAlly.dot(look) >= COS_HALF_ANG) {
ally.addEffect(new MobEffectInstance(chargeHolder, DURATION, AMP, false, true));
}
}
player.getCooldowns().addCooldown(this, 20 * 20);
player.getCooldowns().addCooldown(this, COOLDOWN);
}
player.startUsingItem(hand);
player.swing(hand, true);
return InteractionResultHolder.sidedSuccess(stack, world.isClientSide);
}
@Override
public UseAnim getUseAnimation(ItemStack stack) {
return UseAnim.BOW;
}
@Override
public boolean isDamageable(ItemStack stack) {
return false;
}
@Override
public boolean isDamaged(ItemStack stack) {
return false;
}
@Override
public int getMaxDamage(ItemStack stack) {
return 2;
}
// keep it unbreakable
@Override public boolean isDamageable(ItemStack stack) { return false; }
@Override public boolean isDamaged(ItemStack stack) { return false; }
@Override public int getMaxDamage(ItemStack stack) { return 2; }
}