-
Notifications
You must be signed in to change notification settings - Fork 1
Registry - Keybinding - Skill - Config modules #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.21.1/master
Are you sure you want to change the base?
Changes from all commits
b7c196b
29ca84c
2a1bed4
14137e9
5f76f65
5b79bc2
ebdc01e
0bc6683
4cd521f
ba1bac3
ffcec17
183ac54
f0e357a
53efe10
a2a5c59
2e51185
608a737
6854739
e3508e4
3ae7405
c96dcb2
75ebe0c
db27667
d910e45
aa7649f
63ea442
34374fb
173c1eb
03f88e2
4456747
7f556fd
44852e2
a0ee047
3f31b47
b3e36f7
8b516bb
3beb0f4
a99d535
8a775e9
989d640
0674abf
85c565c
253ddc6
4ab6797
4388476
3ae207b
7754cae
9cc4696
3ec0700
d00bfbd
9bc00ca
2fd1983
be81457
93d1b64
65f0d1c
80aabe0
0bb208b
996a3ff
7e1968b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| /* | ||
| * Copyright (c) 2025. ManasMods | ||
| * GNU General Public License 3 | ||
| */ | ||
|
|
||
| loom { | ||
| accessWidenerPath = file('src/main/resources/manascore_attribute.accesswidener') | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation(project(path: ":network-common", configuration: 'namedElements')) { transitive false } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package io.github.manasmods.manascore.attribute; | ||
|
|
||
| import io.github.manasmods.manascore.attribute.api.ManasCoreAttributes; | ||
| import io.github.manasmods.manascore.attribute.impl.network.ManasCoreAttributeNetwork; | ||
|
|
||
| public class ManasCoreAttribute { | ||
| public static void init() { | ||
| ManasCoreAttributes.init(); | ||
| ManasCoreAttributeRegister.init(); | ||
| ManasCoreAttributeNetwork.init(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| /* | ||
| * Copyright (c) 2025. ManasMods | ||
| * GNU General Public License 3 | ||
| */ | ||
|
|
||
| package io.github.manasmods.manascore.attribute; | ||
|
|
||
| import dev.architectury.injectables.annotations.ExpectPlatform; | ||
| import net.minecraft.core.Holder; | ||
| import net.minecraft.world.entity.ai.attributes.Attribute; | ||
| import org.jetbrains.annotations.NotNull; | ||
|
|
||
| public class ManasCoreAttributeRegister { | ||
| /** | ||
| * Registers a player-specific attribute with the given parameters. | ||
| * | ||
| * @param modID The mod ID associated with this attribute. | ||
| * @param id The unique identifier for the attribute. | ||
| * @param name The display name of the attribute. | ||
| * @param amount The default base value of the attribute. | ||
| * @param min The minimum allowed value for the attribute. | ||
| * @param max The maximum allowed value for the attribute. | ||
| * @param syncable Whether the attribute should be synchronized between client and server. | ||
| * @param sentiment The sentiment classification of the attribute (e.g., beneficial or harmful). | ||
| * @return A {@link Holder} containing the registered player attribute. | ||
| */ | ||
| @ExpectPlatform | ||
| public static @NotNull Holder<Attribute> registerPlayerAttribute(String modID, String id, String name, double amount, | ||
| double min, double max, boolean syncable, Attribute.Sentiment sentiment) { | ||
| throw new AssertionError(); | ||
| } | ||
|
|
||
| /** | ||
| * Registers a generic attribute that applies to multiple entity types. | ||
| * | ||
| * @param modID The mod ID associated with this attribute. | ||
| * @param id The unique identifier for the attribute. | ||
| * @param name The display name of the attribute. | ||
| * @param amount The default base value of the attribute. | ||
| * @param min The minimum allowed value for the attribute. | ||
| * @param max The maximum allowed value for the attribute. | ||
| * @param syncable Whether the attribute should be synchronized between client and server. | ||
| * @param sentiment The sentiment classification of the attribute (e.g., beneficial or harmful). | ||
| * @return A {@link Holder} containing the registered generic attribute. | ||
| */ | ||
| @ExpectPlatform | ||
| public static @NotNull Holder<Attribute> registerGenericAttribute(String modID, String id, String name, double amount, | ||
| double min, double max, boolean syncable, Attribute.Sentiment sentiment) { | ||
| throw new AssertionError(); | ||
| } | ||
|
|
||
| @ExpectPlatform | ||
| public static void init() { | ||
| throw new AssertionError(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| /* | ||
| * Copyright (c) 2025. ManasMods | ||
| * GNU General Public License 3 | ||
| */ | ||
|
|
||
| package io.github.manasmods.manascore.attribute.api; | ||
|
|
||
| import dev.architectury.event.Event; | ||
| import dev.architectury.event.EventFactory; | ||
| import dev.architectury.event.EventResult; | ||
| import io.github.manasmods.manascore.network.api.util.Changeable; | ||
| import net.minecraft.world.entity.Entity; | ||
| import net.minecraft.world.entity.LivingEntity; | ||
|
|
||
| public interface AttributeEvents { | ||
| Event<CriticalAttackChanceEvent> CRITICAL_ATTACK_CHANCE_EVENT = EventFactory.createEventResult(); | ||
| Event<GlideEvent> START_GLIDE_EVENT = EventFactory.createEventResult(); | ||
| Event<GlideEvent> CONTINUE_GLIDE_EVENT = EventFactory.createEventResult(); | ||
|
|
||
| @FunctionalInterface | ||
| interface CriticalAttackChanceEvent { | ||
| EventResult applyCrit(LivingEntity attacker, Entity target, float originalMultiplier, Changeable<Float> multiplier, Changeable<Double> chance); | ||
| } | ||
|
|
||
| @FunctionalInterface | ||
| interface GlideEvent { | ||
| EventResult glide(LivingEntity glider, Changeable<Boolean> canGlide); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,58 @@ | ||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||
| * Copyright (c) 2025. ManasMods | ||||||||||||||||||||||||||||
| * GNU General Public License 3 | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| package io.github.manasmods.manascore.attribute.api; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| import io.github.manasmods.manascore.network.api.util.Changeable; | ||||||||||||||||||||||||||||
| import net.minecraft.network.protocol.game.ClientboundAnimatePacket; | ||||||||||||||||||||||||||||
| import net.minecraft.server.level.ServerLevel; | ||||||||||||||||||||||||||||
| import net.minecraft.sounds.SoundEvents; | ||||||||||||||||||||||||||||
| import net.minecraft.world.damagesource.DamageSource; | ||||||||||||||||||||||||||||
| import net.minecraft.world.effect.MobEffects; | ||||||||||||||||||||||||||||
| import net.minecraft.world.entity.Entity; | ||||||||||||||||||||||||||||
| import net.minecraft.world.entity.LivingEntity; | ||||||||||||||||||||||||||||
| import net.minecraft.world.entity.ai.attributes.AttributeInstance; | ||||||||||||||||||||||||||||
| import net.minecraft.world.entity.ai.attributes.AttributeModifier; | ||||||||||||||||||||||||||||
| import net.minecraft.world.entity.ai.attributes.Attributes; | ||||||||||||||||||||||||||||
| import net.minecraft.world.entity.player.Player; | ||||||||||||||||||||||||||||
| import net.minecraft.world.item.Item; | ||||||||||||||||||||||||||||
| import net.minecraft.world.item.enchantment.EnchantmentHelper; | ||||||||||||||||||||||||||||
| import org.jetbrains.annotations.Nullable; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| public class ManasCoreAttributeUtils { | ||||||||||||||||||||||||||||
| public static float getAttackDamage(Player player) { | ||||||||||||||||||||||||||||
| float f = (float) player.getAttributeValue(Attributes.ATTACK_DAMAGE); | ||||||||||||||||||||||||||||
| float h = player.getAttackStrengthScale(0.5F); | ||||||||||||||||||||||||||||
| f *= 0.2F + h * h * 0.8F; | ||||||||||||||||||||||||||||
| return f; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| public static float getWeaponDamage(LivingEntity attacker, @Nullable Entity target, @Nullable DamageSource source) { | ||||||||||||||||||||||||||||
| AttributeInstance attack = attacker.getAttribute(Attributes.ATTACK_DAMAGE); | ||||||||||||||||||||||||||||
| if (attack == null) return 0; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| float damage = 1F; | ||||||||||||||||||||||||||||
| AttributeModifier modifier = attack.getModifier(Item.BASE_ATTACK_DAMAGE_ID); | ||||||||||||||||||||||||||||
| if (modifier != null) damage += (float) modifier.amount(); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if (target != null && source != null && attacker.level() instanceof ServerLevel serverLevel) | ||||||||||||||||||||||||||||
| damage = EnchantmentHelper.modifyDamage(serverLevel, attacker.getWeaponItem(), target, source, damage); | ||||||||||||||||||||||||||||
| return damage; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
minheragon12345 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| public static void triggerCriticalAttackEffect(Entity target, Entity attacker) { | ||||||||||||||||||||||||||||
| target.level().playSound(null, target.getX(), target.getY(), target.getZ(), | ||||||||||||||||||||||||||||
| SoundEvents.PLAYER_ATTACK_CRIT, attacker.getSoundSource(), 1.0F, 1.0F); | ||||||||||||||||||||||||||||
| if (target.level() instanceof ServerLevel level) | ||||||||||||||||||||||||||||
| level.getChunkSource().broadcastAndSend(target, new ClientboundAnimatePacket(target, 4)); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| public static boolean canElytraGlide(LivingEntity entity, boolean additionalCheck) { | ||||||||||||||||||||||||||||
| Changeable<Boolean> glide = Changeable.of(additionalCheck && !entity.onGround() && !entity.isPassenger() | ||||||||||||||||||||||||||||
| && !entity.hasEffect(MobEffects.LEVITATION) && entity.getAttributeValue(ManasCoreAttributes.GLIDE_SPEED_MULTIPLIER) > 0); | ||||||||||||||||||||||||||||
| if (AttributeEvents.START_GLIDE_EVENT.invoker().glide(entity, glide).isFalse()) return false; | ||||||||||||||||||||||||||||
| return glide.get(); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+57
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Race condition:
- return glide.get();
+ Boolean result = glide.get();
+ return Boolean.TRUE.equals(result);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /* | ||
| * Copyright (c) 2025. ManasMods | ||
| * GNU General Public License 3 | ||
| */ | ||
|
|
||
| package io.github.manasmods.manascore.attribute.api; | ||
|
|
||
| import io.github.manasmods.manascore.attribute.ManasCoreAttributeRegister; | ||
| import io.github.manasmods.manascore.attribute.ModuleConstants; | ||
| 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.entity.ai.attributes.Attribute; | ||
|
|
||
| public class ManasCoreAttributes { | ||
| /** | ||
| * Determine how much the output damage is multiplied when the attacker does a critical attack. | ||
| */ | ||
| public static final Holder<Attribute> CRITICAL_DAMAGE_MULTIPLIER = ManasCoreAttributeRegister.registerGenericAttribute(ModuleConstants.MOD_ID, | ||
| "critical_damage_multiplier", "manascore.attribute.critical_damage_multiplier", | ||
| 1.5, 0, 1024, true, Attribute.Sentiment.POSITIVE); | ||
|
|
||
| /** | ||
| * Determine the percentage chance for the user to do a critical attack without jumping. | ||
| */ | ||
| public static final Holder<Attribute> CRITICAL_ATTACK_CHANCE = ManasCoreAttributeRegister.registerGenericAttribute(ModuleConstants.MOD_ID, | ||
| "critical_attack_chance", "manascore.attribute.critical_attack_chance", | ||
| 0, 0, 100, true, Attribute.Sentiment.POSITIVE); | ||
|
|
||
| /** | ||
| * Determine how fast the player can elytra glide without wearing an elytra. | ||
| * Sets higher than 0 to allow the player to glide. | ||
| * This also affects the speed of normal Elytra gliding speed. | ||
| */ | ||
| public static final Holder<Attribute> GLIDE_SPEED_MULTIPLIER = ManasCoreAttributeRegister.registerPlayerAttribute(ModuleConstants.MOD_ID, | ||
| "glide_speed_multiplier", "manascore.attribute.glide_speed_multiplier", | ||
| 0, 0, 1024, true, Attribute.Sentiment.POSITIVE); | ||
|
|
||
| /** | ||
| * Determine how fast the player can go inside Lava. | ||
| */ | ||
| public static final Holder<Attribute> LAVA_SPEED_MULTIPLIER = ManasCoreAttributeRegister.registerGenericAttribute(ModuleConstants.MOD_ID, | ||
| "lava_speed_multiplier", "manascore.attribute.lava_speed_multiplier", | ||
| 1, 0, 1024, true, Attribute.Sentiment.POSITIVE); | ||
|
|
||
| /** | ||
| * Determine how fast the player can swim in Water. | ||
| * Similar to NeoForge/Forge's Swim speed instead of Vanilla's Water Movement Efficiency. | ||
| */ | ||
| public static final Holder<Attribute> SWIM_SPEED_MULTIPLIER = ManasCoreAttributeRegister.registerGenericAttribute(ModuleConstants.MOD_ID, | ||
| "swim_speed_multiplier", "manascore.attribute.swim_speed_multiplier", | ||
| 1, 0, 1024, true, Attribute.Sentiment.POSITIVE); | ||
|
|
||
| public static ResourceKey<Attribute> getResourceKey(String modID, String path) { | ||
| return ResourceKey.create(Registries.ATTRIBUTE, ResourceLocation.fromNamespaceAndPath(modID, path)); | ||
| } | ||
|
|
||
| public static void init() { | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| /* | ||
| * Copyright (c) 2025. ManasMods | ||
| * GNU General Public License 3 | ||
| */ | ||
|
|
||
| package io.github.manasmods.manascore.attribute.impl.network; | ||
|
|
||
| import io.github.manasmods.manascore.attribute.impl.network.c2s.RequestGlideStartPacket; | ||
| import io.github.manasmods.manascore.network.api.util.NetworkUtils; | ||
|
|
||
| public class ManasCoreAttributeNetwork { | ||
| public static void init() { | ||
| NetworkUtils.registerC2SPayload(RequestGlideStartPacket.TYPE, RequestGlideStartPacket.STREAM_CODEC, RequestGlideStartPacket::handle); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| /* | ||
| * Copyright (c) 2025. ManasMods | ||
| * GNU General Public License 3 | ||
| */ | ||
|
|
||
| package io.github.manasmods.manascore.attribute.impl.network.c2s; | ||
|
|
||
| import dev.architectury.networking.NetworkManager; | ||
| import dev.architectury.utils.Env; | ||
| import io.github.manasmods.manascore.attribute.ModuleConstants; | ||
| import io.github.manasmods.manascore.attribute.api.ManasCoreAttributeUtils; | ||
| import net.minecraft.network.FriendlyByteBuf; | ||
| import net.minecraft.network.codec.StreamCodec; | ||
| import net.minecraft.network.protocol.common.custom.CustomPacketPayload; | ||
| import net.minecraft.resources.ResourceLocation; | ||
| import net.minecraft.world.entity.player.Player; | ||
| import org.jetbrains.annotations.NotNull; | ||
|
|
||
| public record RequestGlideStartPacket() implements CustomPacketPayload { | ||
| public static final Type<RequestGlideStartPacket> TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(ModuleConstants.MOD_ID, "request_glide_start")); | ||
| public static final StreamCodec<FriendlyByteBuf, RequestGlideStartPacket> STREAM_CODEC = CustomPacketPayload.codec(RequestGlideStartPacket::encode, RequestGlideStartPacket::new); | ||
|
|
||
| public RequestGlideStartPacket(FriendlyByteBuf buf) { | ||
| this(); | ||
| } | ||
|
|
||
| public void encode(FriendlyByteBuf buf) { | ||
| } | ||
|
|
||
| public void handle(NetworkManager.PacketContext context) { | ||
| if (context.getEnvironment() != Env.SERVER) return; | ||
| context.queue(() -> { | ||
| Player player = context.getPlayer(); | ||
| if (player == null) return; | ||
| player.stopFallFlying(); | ||
| if (ManasCoreAttributeUtils.canElytraGlide(player, !player.isFallFlying() && !player.isInLiquid())) | ||
| player.startFallFlying(); | ||
| }); | ||
| } | ||
minheragon12345 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| public @NotNull Type<RequestGlideStartPacket> type() { | ||
| return TYPE; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,63 @@ | ||||||||||||||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||||||||||||||
| * Copyright (c) 2025. ManasMods | ||||||||||||||||||||||||||||||||||||
| * GNU General Public License 3 | ||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| package io.github.manasmods.manascore.attribute.mixin; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import io.github.manasmods.manascore.attribute.api.AttributeEvents; | ||||||||||||||||||||||||||||||||||||
| import io.github.manasmods.manascore.attribute.api.ManasCoreAttributeUtils; | ||||||||||||||||||||||||||||||||||||
| import io.github.manasmods.manascore.attribute.api.ManasCoreAttributes; | ||||||||||||||||||||||||||||||||||||
| import io.github.manasmods.manascore.network.api.util.Changeable; | ||||||||||||||||||||||||||||||||||||
| import net.minecraft.world.entity.Entity; | ||||||||||||||||||||||||||||||||||||
| import net.minecraft.world.entity.EntityType; | ||||||||||||||||||||||||||||||||||||
| import net.minecraft.world.entity.LivingEntity; | ||||||||||||||||||||||||||||||||||||
| import net.minecraft.world.entity.ai.attributes.AttributeInstance; | ||||||||||||||||||||||||||||||||||||
| import net.minecraft.world.level.Level; | ||||||||||||||||||||||||||||||||||||
| import net.minecraft.world.phys.Vec3; | ||||||||||||||||||||||||||||||||||||
| import org.spongepowered.asm.mixin.Mixin; | ||||||||||||||||||||||||||||||||||||
| import org.spongepowered.asm.mixin.injection.At; | ||||||||||||||||||||||||||||||||||||
| import org.spongepowered.asm.mixin.injection.ModifyArg; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Mixin(LivingEntity.class) | ||||||||||||||||||||||||||||||||||||
| public abstract class MixinLivingEntity extends Entity { | ||||||||||||||||||||||||||||||||||||
| public MixinLivingEntity(EntityType<?> entityType, Level level) { | ||||||||||||||||||||||||||||||||||||
| super(entityType, level); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @ModifyArg(method = "updateFallFlying", at = @At(value = "INVOKE", | ||||||||||||||||||||||||||||||||||||
| target = "net/minecraft/world/entity/LivingEntity.setSharedFlag(IZ)V")) | ||||||||||||||||||||||||||||||||||||
| private boolean updateFallFlying(boolean value) { | ||||||||||||||||||||||||||||||||||||
| LivingEntity glider = (LivingEntity) (Object) this; | ||||||||||||||||||||||||||||||||||||
| Changeable<Boolean> glide = Changeable.of(value || ManasCoreAttributeUtils.canElytraGlide(glider, this.getSharedFlag(7))); | ||||||||||||||||||||||||||||||||||||
| if (AttributeEvents.CONTINUE_GLIDE_EVENT.invoker().glide(glider, glide).isFalse()) return false; | ||||||||||||||||||||||||||||||||||||
| return glide.get(); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @ModifyArg(method = "travel", at = @At(value = "INVOKE", | ||||||||||||||||||||||||||||||||||||
| target = "Lnet/minecraft/world/entity/LivingEntity;move(Lnet/minecraft/world/entity/MoverType;Lnet/minecraft/world/phys/Vec3;)V", ordinal = 2), index = 1) | ||||||||||||||||||||||||||||||||||||
| public Vec3 glideSpeed(Vec3 vec3) { | ||||||||||||||||||||||||||||||||||||
| LivingEntity entity = (LivingEntity) (Object) this; | ||||||||||||||||||||||||||||||||||||
| AttributeInstance instance = entity.getAttribute(ManasCoreAttributes.GLIDE_SPEED_MULTIPLIER); | ||||||||||||||||||||||||||||||||||||
| if (instance == null || instance.getValue() <= 0) return vec3; | ||||||||||||||||||||||||||||||||||||
| return vec3.multiply(instance.getValue(), 1, instance.getValue()); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @ModifyArg(method = "travel", at = @At(value = "INVOKE", | ||||||||||||||||||||||||||||||||||||
| target = "Lnet/minecraft/world/entity/LivingEntity;moveRelative(FLnet/minecraft/world/phys/Vec3;)V", ordinal = 1)) | ||||||||||||||||||||||||||||||||||||
| public float lavaSpeed(float speed) { | ||||||||||||||||||||||||||||||||||||
| LivingEntity entity = (LivingEntity) (Object) this; | ||||||||||||||||||||||||||||||||||||
| AttributeInstance instance = entity.getAttribute(ManasCoreAttributes.LAVA_SPEED_MULTIPLIER); | ||||||||||||||||||||||||||||||||||||
| if (instance == null) return speed; | ||||||||||||||||||||||||||||||||||||
| return (float) (speed * instance.getValue()); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+46
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Attribute values below zero will reverse movement
- return (float) (speed * instance.getValue());
+ double modifier = Math.max(0, instance.getValue());
+ return (float) (speed * modifier);Add safety clamps to maintain sane gameplay behaviour. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @ModifyArg(method = "travel", at = @At(value = "INVOKE", | ||||||||||||||||||||||||||||||||||||
| target = "Lnet/minecraft/world/entity/LivingEntity;moveRelative(FLnet/minecraft/world/phys/Vec3;)V", ordinal = 0)) | ||||||||||||||||||||||||||||||||||||
| public float swimSpeed(float speed) { | ||||||||||||||||||||||||||||||||||||
| LivingEntity entity = (LivingEntity) (Object) this; | ||||||||||||||||||||||||||||||||||||
| AttributeInstance instance = entity.getAttribute(ManasCoreAttributes.SWIM_SPEED_MULTIPLIER); | ||||||||||||||||||||||||||||||||||||
| if (instance == null) return speed; | ||||||||||||||||||||||||||||||||||||
| return (float) (speed * instance.getValue()); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| /* | ||
| * Copyright (c) 2025. ManasMods | ||
| * GNU General Public License 3 | ||
| */ | ||
|
|
||
| package io.github.manasmods.manascore.attribute.mixin; | ||
|
|
||
| import com.llamalad7.mixinextras.injector.wrapoperation.Operation; | ||
| import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; | ||
| import dev.architectury.networking.NetworkManager; | ||
| import io.github.manasmods.manascore.attribute.api.ManasCoreAttributeUtils; | ||
| import io.github.manasmods.manascore.attribute.impl.network.c2s.RequestGlideStartPacket; | ||
| import net.minecraft.client.Minecraft; | ||
| import net.minecraft.client.player.LocalPlayer; | ||
| import org.spongepowered.asm.mixin.Mixin; | ||
| import org.spongepowered.asm.mixin.injection.At; | ||
| import org.spongepowered.asm.mixin.injection.Inject; | ||
| import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
|
||
| @Mixin({LocalPlayer.class}) | ||
| public class MixinLocalPlayer { | ||
| @Inject(method = "aiStep", at = @At(value = "INVOKE_ASSIGN", | ||
| target = "net/minecraft/client/player/LocalPlayer.getItemBySlot(Lnet/minecraft/world/entity/EquipmentSlot;)Lnet/minecraft/world/item/ItemStack;")) | ||
| public void canStartGliding(CallbackInfo cb) { | ||
| LocalPlayer player = Minecraft.getInstance().player; | ||
| if (player == null) return; | ||
| if (ManasCoreAttributeUtils.canElytraGlide(player, !player.isFallFlying() && !player.isInLiquid())) { | ||
| player.startFallFlying(); | ||
| NetworkManager.sendToServer(new RequestGlideStartPacket()); | ||
| } | ||
| } | ||
|
|
||
| @WrapOperation( method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;tryToStartFallFlying()Z")) | ||
| public boolean shouldActivateEquippedElytra(LocalPlayer player, Operation<Boolean> original) { | ||
| if (ManasCoreAttributeUtils.canElytraGlide(player, !player.isFallFlying() && !player.isInLiquid())) return false; | ||
| return original.call(player); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Start from the full attack attribute value and add NPE-safe weapon bonuses
damageis initialised with a hard-coded1Fand only the singleBASE_ATTACK_DAMAGE_IDmodifier is added.This ignores:
attack.getValue()), which already contains all relevant modifiers (weapon, enchantments, attributes from skills, etc.).ItemStack.EMPTYresult fromattacker.getWeaponItem()–modifyDamagewill happily NPE on a nullItemStackin some modded environments.This yields correct vanilla parity, prevents silent under-damage, and avoids a null/EMPTY edge case.
📝 Committable suggestion